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