MathGroup Archive 2008

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

Search the Archive

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.
> 



  • Prev by Date: A Use for Interpretation
  • Next by Date: Re: [functional approach should give] an even faster way
  • Previous by thread: Re: Re: A Use for Interpretation
  • Next by thread: Multiple data sets with ListPlot and different PointSizes - Mesh