MathGroup Archive 2007

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

Search the Archive

Re: compile speed

  • To: mathgroup at smc.vnet.net
  • Subject: [mg74459] Re: compile speed
  • From: "Szabolcs" <szhorvat at gmail.com>
  • Date: Thu, 22 Mar 2007 01:09:58 -0500 (EST)
  • References: <etqnm3$nf$1@smc.vnet.net>

On Mar 21, 8:42 am, "Boson" <sandro.romani at gmail.com> wrote:
> dear mathematica users,
>
> i've written a simple function that works on a pair of binary
> matrices:
> (mathematica 5.2 linux, on a 32 bit platform)
>
> tab[nx_, ny_, frac_] := Table[If[Random[] < frac, 1, 0], {nx}, {ny}]
>
> nx = 25; ny = 50; frac1 = 0.1; frac2 = 0.5;
> p1 = 0.4; p2 = 0.2;
> tabrect = tab[nx, ny, frac1];
> tabsq = tab[ny, ny, frac2];
>
> testnocomp[mat1_, mat2_, n1_, n2_, pp1_, pp2_] := Module[{tmp, sum,
> val},
>     tmp = mat2; Do[sum = mat1[[k,j]] + mat2[[k,i]];
>        val = Which[sum == 2, If[Random[] < pp1, 1, tmp[[i,j]]], sum ==
> 1,
>          If[Random[] < pp2, 0, tmp[[i,j]]], sum == 0, tmp[[i,j]]];
> tmp[[i,j]] = val,
>       {k, n1}, {i, n2}, {j, n2}]; tmp];
>
> Timing[resnc = testnocomp[tabrect, tabsq, nx, ny, p1, p2]; ]
>
> the result of the timing is
> {0.7558840000000013*Second, Null}
>
> since i need high values of nx,ny (~5000) and the loop scales as
> nx*ny^2,
> i tried to implement a compiled version of the previous function:
>
> test := Compile[{{mat1, _Integer, 2}, {mat2, _Integer, 2}, {n1,
> _Integer}, {n2, _Integer},
>      {pp1, _Real}, {pp2, _Real}}, Module[{tmp, sum, val},
>      tmp = mat2; Do[sum = mat1[[k,j]] + mat2[[k,i]];
>         val = Which[sum == 2, If[Random[] < pp1, 1, tmp[[i,j]]], sum
> == 1,
>           If[Random[] < pp2, 0, tmp[[i,j]]], sum == 0, tmp[[i,j]]];
> tmp[[i,j]] = val,
>        {k, n1}, {i, n2}, {j, n2}]; tmp], {{Random[_], _Real}}];
>
> Timing[res = test[tabrect, tabsq, nx, ny, p1, p2]; ]
>
> results are a disaster:
> {14.814747999999996*Second, Null}
>
> i'm sure this is related to my poor mathematica programming
> experience..
>
> could you suggest me a faster version to solve this problem?
>
> regards,
> sandro

Unfortunately I don't understand why the compiled version is so slow.
But here are two (uncompiled) faster versions:

In[1]:=
tab[nx_,ny_,frac_]:=Table[If[Random[]<frac,1,0],{nx},{ny}]
nx=50;ny=100;
tabsq=tab[ny,ny,.5];
tabrect=tab[nx,ny,.1];

* This is your original version (the reference for the Timing value):

In[5]:=
testnocomp1[mat1_, mat2_, n1_, n2_, pp1_, pp2_]:=
  Module[{tmp, sum, val},
    tmp = mat2;
    Do[
      sum = mat1[[k,j]] + mat2[[k,i]];
      val=Which[
          sum == 2, If[Random[]<pp1, 1, tmp[[i,j]] ],
          sum == 1, If[Random[]<pp2, 0, tmp[[i,j]] ],
          sum == 0, tmp[[i,j]] ];
      tmp[[i,j]] = val,
      {k,n1}, {i,n2}, {j,n2}];
    tmp]

In[6]:=
Timing[testnocomp1[tabrect,tabsq,nx,ny,.4,.2];]

Out[6]=
{6.094 Second,Null}


* Here's my first try at improving performance:

In[7]:=
testnocomp2[mat1_,mat2_,n1_,n2_,pp1_,pp2_]:=
  Module[{tmp},
    tmp=mat2;
    Do[
      Switch[ mat1[[k,j]] + mat2[[k,i]],
          2, If[Random[] < pp1, tmp[[i,j]]=1],
          1, If[Random[] < pp2, tmp[[i,j]]=0] ];,
      {k,n1}, {i,n2}, {j,n2}];
    tmp]

In[8]:=
Timing[testnocomp2[tabrect,tabsq,nx,ny,.4,.2];]

Out[8]=
{3.297 Second,Null}


* Second try:

In[9]:=
testnocomp3[mat1_,mat2_,n1_,n2_,pp1_,pp2_]:=
  Inner[Plus, Transpose[mat1], Take[mat2,n1],
    Fold[
        Switch[#2,
            2, If[Random[]<pp1, 1, #1],
            1, If[Random[]<pp2, 0, #1],
            0, #1] &,
        -1, {##}] &
    ]

In[10]:=
Timing[testnocomp3[tabrect,tabsq,nx,ny,.4,.2];]

Out[10]=
{2.453 Second,Null}

But here you still need to replace all -1's in the result with the
corresponding elements from tabsq.

The compiled versions of testnocomp2 and testnocomp3 do not work and
if I compile only the Switch or the Fold part from testnocomp3,
performance becomes much worse.



  • Prev by Date: Re: Integrate
  • Next by Date: a suprising result from Integrate (Null appeared in the result!)
  • Previous by thread: Re: compile speed
  • Next by thread: Re: compile speed