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
- Organization: Universidad del Valle
- 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