How to compile this module?

How to compile this module?

Post by P_te » Thu, 06 Sep 2007 15:32:29


Hello,
I have some code in a Module and I would like to compile it so that Mathematica does not give complaints in execution:
myM[lst_, W_] := Module [ {i, j = 1, len = Length@lst, res},
Reap[For[i = 1, i <= len, i++,
While[lst[[j]] - lst[[i]] <= W && j < len, j++];
Sow[j - i]]; res]
]
It works on this special constructed list (with a large number at the end):
lst = {1, 2, 4, 5, 6, 9, 10, 12, 15, 1000};
The following is compiled by Mathematica:
myC = Compile[{{lst, _Integer}, {W, _Integer}},
Module [ {i, j = 1, len = Length@lst, s, res},
Reap[For[i = 1, i <= len, i++,
While[lst[[j]] - lst[[i]] <= W && j < len, j++];
Sow[j - i]]; res]
], {{res, _Integer, 4}}
]
If Mathematica executes: myC[lst,2], it gives a message that the argument lst at position 1 should be a machine-size integer.
Can anyone help?
with friendly greetings,
P_ter
 
 
 

How to compile this module?

Post by Szabolc » Fri, 07 Sep 2007 18:23:14


There is something in your code I do not understand: what is the purpose
of that stray 'res' at the end of Reap?

The first problem is that 'lst' is a 1D list of Integers, so instead of
{lst, _Integer}, use {lst, _Integer, 1}.

The second problem is that Reap and Sow cannot be compiled (IMO they
were not really meant to be used with this procedural style of
programming). You can see this if you check the InputForm of the
compiled function (InputForm[myC]). One solution is to use AppendTo
instead.

(See this page:
http://www.yqcomputer.com/ )

This function works:

myC = Compile[{{lst,_Integer,1},{W,_Integer}},
Module[{i,j=1,len=Length@lst,ols={}},
For[i=1,i<=len,i++,
While[
lst[[j]]-lst[[i]]<=W && j<len,
j++
];
AppendTo[ols,j-i]
];
ols
]]

Now I just wish I could figure out how to prevent Mathematica from
treating 'ols' as a vector of Reals without initialising it to {0}.
Specifying its type in Compile does not seem to work.

Szabolcs

 
 
 

How to compile this module?

Post by Szabolc » Fri, 07 Sep 2007 18:57:28


Oops ... it works but it's damn slow.

Here's a better version:

myM2[lst_,W_]:=
Module[
{i,j=1,len=Length@lst},
Table[
While[lst[[j]]-lst[[i]] <= W && j < len, j++]; j-i,
{i,1,len}
]
]

myC2:=
Compile[{{lst,_Integer,1},{W,_Integer}},
Module[
{i,j=1,len=Length@lst},
Table[
While[lst[[j]]-lst[[i]] <= W && j < len, j++]; j-i,
{i,1,len}
]
]
]

Szabolcs
 
 
 

How to compile this module?

Post by DrMajorBo » Fri, 07 Sep 2007 19:16:04

The "myM" function returns "res" as the result but doesn't set it in any
way, so it couldn't possibly work on lst = {1, 2, 4, 5, 6, 9, 10, 12, 15,
1000} or any other list. Ditto for "myC". If your code doesn't work and

you haven't told us what it's supposed to do, so how can anyone correct it
for you?

That said, there are some obvious problems with your Compile statement.
Since the first argument is a list, you have to declare this to
Mathematica, something like

Compile[{{lst, _Integer, 1}, {W, _Integer}},
Module[{i, j = 1, len = Length@lst, s, res},
Reap[For[i = 1, i <= len, i++,
While[lst[[j]] - lst[[i]] <= W && j < len, j++];
Sow[j - i]]; res]], {{res, _Integer, 4}}]

But Compile won't allow every possible Mathematica expression. I doubt
that Reap and Sow will qualify, for instance. (And you still haven't given
"res" a value.)

Bobby

On Wed, 05 Sep 2007 01:41:12 -0500, P_ter < XXXX@XXXXX.COM >





--

XXXX@XXXXX.COM
 
 
 

How to compile this module?

Post by Jean-Marc » Fri, 07 Sep 2007 19:17:04


Note that it is not a good idea to use the Reap/Sow construct in a
function you want to compile. Also, the local symbol 'res' has never
been assigned any value before exiting the function.

Having said that, I believe that the code below should do what you are
looking for. (res is initialize to an empty list, then the value of j-1,
when necessary, is appended to the variable res, finally the vector res
is returned.)

In[1]:=
lst = {1, 2, 4, 5, 6, 9, 10, 12, 15, 1000};

myC = Compile[{{lst, _Integer, 1}, {W, _Integer}},
Module[{i, j = 1, len = Length@lst, res = {}},
For[i = 1, i <= len, i++,
While[lst[[j]] - lst[[i]] <= W && j < len, j++];
AppendTo[res, j - i]]; res]];

myC[lst, 2]

Out[3]= {2., 2., 3., 2., 1., 2., 2., 1., 1., 0.}

--
Jean-Marc
 
 
 

How to compile this module?

Post by P_te » Sat, 08 Sep 2007 15:15:37

Thanks to all. I had also response outside this group.

Well, this is my impression: compiling with Mathematica is of a special nature. Compiling in C can take in library functions which are written in assembly. Also, it seems that a list must be of type Real. Return variables, so I was told, can be tensors: but not irregular arrays.

Yet, some mails to me contained code which gave a speed-up of 30 (in my case of a special built list of 30 0000 integers). I used Sow/Reap because that was in the documents. The speed-up was established by taking other basic functions, like Table and Do, instead of For.

As for now: I am not able to find out myself if Sow/Reap, as compiled, are no big deal. That is a pity. There can be good reasons from the point of view of Mathematica, but I have no idea why/how/why not etc. From my view point this is a limitation.

Thanks to all.
with friendly greetings,
P_ter