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