MathGroup Archive 2007

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

Search the Archive

Re: compile speed

  • To: mathgroup at smc.vnet.net
  • Subject: [mg74456] Re: compile speed
  • From: Peter Pein <petsie at dordos.net>
  • Date: Thu, 22 Mar 2007 01:08:22 -0500 (EST)
  • References: <etqnm3$nf$1@smc.vnet.net>

Boson schrieb:
> 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
> 
> 

Hi Sandro,

using nx=100 and ny0, I get:

Clear[test];
test = Compile[
  {{mat1, _Integer, 2}, {mat2, _Integer, 2},
   {n1, _Integer}, {n2, _Integer},
   {pp1, _Real}, {pp2, _Real}},
  Block[{m1 = Transpose[mat1], m2 = Transpose[Take[mat2, n1]], tmp = mat2},
    Do[
      tmp[[i,j]] =
        Fold[If[#2 =!= 0, If[Random[] < {pp2, pp1}[[#2]], #2 - 1, #1], #1]&,
          tmp[[i,j]],
          m1[[j]] + m2[[i]]],
    {i, n2}, {j, n2}];
  tmp],
  {{tmp | m1 | m2, _Integer, 2}, {i | j, _Integer}}];

(* the uncompiled function from your posting above *)
tnc = First[Timing[resnc = testnocomp[tabrect, tabsq, nx, ny, p1, p2]; ]]
(* the compiled Version *)
tc = First[Timing[res = test[tabrect, tabsq, nx, ny, p1, p2]; ]]
Print["Speedup: ", tnc/tc, " times"];

34.328 Second
 1.703 Second
Speedup: 20.157369348209365 times


HTH,
Peter


  • Prev by Date: Re: Definite Integration in Mathematica
  • Next by Date: Re: Integrate
  • Previous by thread: Re: compile speed
  • Next by thread: Re: compile speed