Re: Help needed with compiling a function

• To: mathgroup at smc.vnet.net
• Subject: [mg14978] Re: [mg14971] Help needed with compiling a function
• From: Jurgen Tischer <jtischer at col2.telecom.com.co>
• Date: Wed, 2 Dec 1998 03:59:00 -0500
• References: <199811280856.DAA07506@smc.vnet.net.>
• Sender: owner-wri-mathgroup at wolfram.com

Wagner,
good news: I got it working.
bad news: the compiled version is (three times) slower than the
uncompiled.
good news: I changed your function a bit and now it's twice as fast
(uncompiled).
better news: The new function compiles and is now really fast (15 times
faster).

1. This is your StdAlg, changed a bit:

StdAlg =
Compile[ {{theXset, _Real, 2}, {theRset, _Integer, 1}, {theM,
_Integer}},
Module[ {TRNsetSize, d, w, m, p, u, j, x, r, h, s},
TRNsetSize = Length[theXset];
d = Length[First[theXset]];
w = Table[Random[Real, {-1.0, 1.0}], {d}];
m = 0; p = 0; u = 0;
While[ m <= theM && p < TRNsetSize,
m++; p = 0;
For[ j = 1, j <= TRNsetSize, j++,
x = theXset[[j]]; r = theRset[[j]]; h = w . x;
If[r == 1 && h > 0 || r == -1 && h <= 0, p++];
If[r == 1 && h <= 0 || r == -1 && h > 0, u++; w = w +
r*x;
]]];
{u, m}
]
]

You will observe that the Return is missing, there is no need if {u,m}
is the last statement, I changed := to = (you don't want Mathematica to
compile each time you call StdAlg), but the semicolon at the end of the
second If made the difference. Don't ask me why, I have no idea. I'd
call it a bug, but who knows.

2. This is a variant of your Module which is faster, but doesn't
compile. I have used the fact that {h==0} is a set of measure zero, so
I check only for same sign. The first input is the (normal, not Dot)
product of exRset and exXset.

fu2[theXset_,theM_]:=Module[ {TRNsetSize, w, m=0, p=0, u=0, j,x},
TRNsetSize=Length[theXset];
w = Table[Random[Real, {-1.0, 1.0}], {Length[First[theXset]]}];
Do[m++;
For[ j = 1, j <= TRNsetSize, j++,x=theXset[[j]];
If[ w.x>0, p++,u++; w = w + x]];
If[p>=TRNsetSize,Break[],p=0],{theM}];
{u, m}
]

3. This is another variant which does compile, it needs the same
superfluous ";" to compile.

fu3[theXset_,theM_]:=Module[ {TRNsetSize, w, m=0, p=0, u=0, j},
TRNsetSize=Length[theXset];
w = Table[Random[Real, {-1.0, 1.0}], {Length[First[theXset]]}];
Do[
w= Fold[If[#1.#2>0,p++;#1,u++;#1+#2]&,w,theXset];m++;
If[p>=TRNsetSize,Break[],p=0],{theM}];
{u, m}
]

4. This is the compiled version of fu3.

StdAlg1= Compile[ {{theXset, _Real, 2}, {theM, _Integer}},Module[
{TRNsetSize, w, m=0, p=0, u=0, j},
TRNsetSize=Length[theXset];
w = Table[Random[Real, {-1.0, 1.0}], {Length[First[theXset]]}];
Do[
w= Fold[If[#1.#2>0,p++;#1,u++;#1+#2]&,w,theXset];m++;
If[p>=TRNsetSize,Break[],p=0;],{theM}];
{u, m}
]]

5. Timings (fu is the original function)

In[1]:= tt=exRset exXset;

In[2]:= Timing[Do[fu[exXset,exRset,1000],{1000}]]

Out[2]= {105.07 Second,Null}

In[3]:= Timing[Do[StdAlg[exXset,exRset,1000],{1000}]]

Out[3]= {358.5 Second,Null}

In[4]:= Timing[Do[fu2[tt,1000],{1000}]]

Out[4]= {50.37 Second,Null}

In[5]:= Timing[Do[fu3[tt,1000],{1000}]]

Out[5]= {45.97 Second,Null}

In[6]:= Timing[Do[StdAlg1[tt,1000],{1000}]]

Out[6]= {3.63 Second,Null}

Jurgen

Wagner Truppel wrote:
>
> Hello,
>
> I'm having trouble compiling a function which will be called a large
> number  of times from another part of the code (hence the need for a
> compiled  version) and would appreciate some help in clarifying what's
> going on.
>
> The function takes as input a list of lists of reals (a rank-2 tensor of
> reals), a list of integers, and an integer. Its output should be a list
> of  2 integers:
>
> StdAlg :=
>    Compile[ {{theXset, _Real, 2}, {theRset, _Integer, 1}, {theM,
> _Integer}},
>       Module[ {TRNsetSize, d, w, m, p, u, j, x, r, h, s},
>          TRNsetSize = Length[theXset];
>          d = Length[First[theXset]];
>          w = Table[Random[Real, {-1.0, 1.0}], {d}];
>          m = 0; p = 0; u = 0;
>          While[ m <= theM && p < TRNsetSize,
>             m++; p = 0;
>             For[ j = 1, j <= TRNsetSize, j++,
>                x = theXset[[j]]; r = theRset[[j]]; h = w . x;
>                If[r == 1 && h > 0 || r == -1 && h <= 0, p++];
>                If[r == 1 && h <= 0 || r == -1 && h > 0, u++; w = w + r*x
> ]]];
>           Return[{u, m}];
>       ];
>    ];
>
> However, when I try it out, I get the error messages below:
>
> CompiledFunction::"ccts":
>   "Expression Null should be a machine-size tensor with correct rank and
> type."
>
> CompiledFunction::"cfex":
>   "External evaluation error at instruction 66; proceeding with
> uncompiled  evaluation."
>
> Sometimes (after tweaking things a bit) I get another message that says
> that the return value types are incompatible and that the return value
> should be a boolean.
>
> If anyone can help me sort this out, I'd be very grateful. If you need
> code  to generate an example to run StdAlg, try this:
>
> GenTDS[theTRNsetSize_, theDim_] :=
>    Module[ {sol, tSet, x, r, teg},
>       sol = Table[Random[Real, {-1.0, 1.0}], {theDim + 1}];
>       tSet = {};
>       Do[
>          x = Table[Random[Real, {-1.0, 1.0}], {theDim + 1}];
>          x[[theDim + 1]] = 1.0;
>          If[sol . x > 0.0, r = 1, r = -1];
>          tSet = {tSet, teg[x, r]},
>          {theTRNsetSize}];
>       tSet = Flatten[tSet] /. teg -> List;
>       Return[tSet];
>    ];
>
> tSet = Transpose[ GenTDS[50, 2] ];
> exXset = First[tSet];
> exRset = Last[tSet];
>
> StdAlg[exXset, exRset, 1000]
>
> Thank you all in advance.
>
> Wagner

• Prev by Date: Re: Pemutations/Knapsack Problem
• Next by Date: Re: Many data points = frustration
• Previous by thread: Re: Pemutations/Knapsack Problem
• Next by thread: Re: Many data points = frustration