Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
1998
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 1998

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • 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