Re: [functional approach should give] an even faster way
- To: mathgroup at smc.vnet.net
- Subject: [mg85660] Re: [mg85648] [functional approach should give] an even faster way
- From: Bob Hanlon <hanlonr at cox.net>
- Date: Tue, 19 Feb 2008 01:45:42 -0500 (EST)
- Reply-to: hanlonr at cox.net
Your second method is not 15% faster than your first method it is almost 6 times faster. test = Table[RandomReal[{-0.1, 1.25}], {512}, {512}, {3}]; Note that the test data is skewed so that it is more likely to be out of bounds on the high side data1 = test; imax = Length[data1]; jmax = Length[data1[[1]]]; t1 = Timing[For[i = 1, i <= imax, i++, For[j = 1, j <= jmax, j++, If[((data1[[i, j, 1]] < 0) || (data1[[i, j, 1]] > 1) || (data1[[i, j, 2]] < 0) || (data1[[i, j, 2]] > 1) || (data1[[i, j, 3]] < 0) || (data1[[i, j, 3]] > 1)), data1[[i, j]] = {0., 0., 0.}]]]][[1]]; data2 = test; t2 = Timing[ data2 = Map[ If[#[[1]] < 0 || #[[1]] > 1 || #[[2]] < 0 || #[[2]] > 1 || #[[3]] < 0 || #[[3]] > 1, {0., 0., 0.}, #] &, data2, {2}];][[1]]; This approach can be written more compactly as data3 = test; t3 = Timing[data3 = Map[If[Min[#] < 0 || Max[#] > 1, {0., 0., 0.}, #] &, data3, {2}];][[1]]; data4 = test; The same method but checking first within the Or for the more likely out of bounds condition t4 = Timing[data4 = Map[If[Max[#] > 1 || Min[#] < 0, {0., 0., 0.}, #] &, data4, {2}];][[1]]; data1 == data2 == data3 == data4 True {t1, t2, t3, t4}/t1 {1.,0.17293,0.18388,0.1759} 1/% {1.,5.78268,5.43834,5.68505} Note that method 4 (checking first for the more likely out of bounds condition) is slightly faster than method 3. Presumably the Or evaluation terminates as soon as a True condition is encountered. If you have prior knowledge of the data statistics this may help. Bob Hanlon ---- congruentialuminaire at yahoo.com wrote: > Hello UG: > > I have a 512x512 array of 3-tuples. I want to make any tuple with a > value outside of 0 <--> 1, become {0.,0.,0.}. > > The first version has this loop: > > For[i = 1, i <= graphSize, i++, > For[j = 1, j <= graphSize, j++, > If[((sum[[i, j, 1]] < 0) || (sum[[i, j, 1]] > 1) || > (sum[[i, j, 2]] < 0) || (sum[[i, j, 2]] > 1) || > (sum[[i, j, 3]] < 0) || (sum[[i, j, 3]] > 1)), > sum[[i, j]] = {0., 0., 0.} > ] > ] > ]; > > After scratching my head for a while I came up with this (equivalent) > Map statement. > > sum = Map[ > If[#[[1]] < 0 || #[[1]] > 1 || #[[2]] < 0 || #[[2]] > 1 || #[[3]] < > 0 || #[[3]] > 1, {0., 0., 0.}, #] &, sum, {2}]; > > It is faster but only by about 15%. > > It is unreasonable to believe some other construction can accomplish > this with a bigger payoff? > > Thanks in advance. > > Regards..Roger W. >