RE: Re: Need faster way to combine arrays
- To: mathgroup at smc.vnet.net
- Subject: [mg36090] RE: [mg36064] Re: [mg36045] Need faster way to combine arrays
- From: "DrBob" <majort at cox-internet.com>
- Date: Wed, 21 Aug 2002 05:51:55 -0400 (EDT)
- Reply-to: <drbob at bigfoot.com>
- Sender: owner-wri-mathgroup at wolfram.com
For those of you asked, I'm using Mathematica 4.2 and Windows XP Home. Also, Sseziwa speculated that t4 might be faster than t2 because of time spent forming {r,g,b} which is cached when t3 is evaluated. I tested that and it doesn't seem to be a significant factor. In the code below I've randomized the order in which the methods are tried on each random color map, gathered statistics in the right order, calculated means and standard deviations, and charted the 95% confidence intervals on a logarithmic scale. The trials took four or five minutes on my machine, so you may want to cut down the number of trials before running it on yours. You can also copy my logStats output and graph it yourself. t2, t3, and t4 are the same as t5, t6, and t7, except that the latter 3 use u (preformed) instead of {r,g,b}. << Statistics`DescriptiveStatistics` << Graphics`MultipleListPlot` n = 1000; draw := (u = {r, g, b} = Table[Table[Random[Integer], {n}, {n}], {3}];) t1[] := Table[{r[[i, j]], g[[i, j]], b[[i, j]]}, {i, Length[r]}, {j, Length[r[[1]]]}] t2[] := Transpose /@ Transpose[{r, g, b}] t3[] := Transpose[{r, g, b}, {3, 1, 2}] t4[] := Partition[Transpose[Flatten /@ {r, g, b}], n] t5[] := Transpose /@ Transpose[u] t6[] := Transpose[u, {3, 1, 2}] t7[] := Partition[Transpose[Flatten /@ u], n] randomOrder := Sort[solvers, Random[] > 0.5 &] solvers = {t1, t2, t3, t4, t5, t6, t7}; trial := (s = randomOrder; t = Ordering@ s; draw; (First@Timing[#[];]/Second & /@ s)[[t]]) trials = Transpose[trial & /@ Range[100]]; stats = Transpose@{Mean /@ trials, StandardDeviation[#] & /@ trials} {{1.67894,0.0474062},{0.07033,0.0217219},{0.29387,0.0256242}, {0.03985,0.0143937},{0.07747,0.0209547},{0.29566,0.0238295}, {0.03517,0.0143436}} f[{mu_, sd_}] := {Log@mu, ErrorBar[{Log[1 - 1.96sd/mu], Log[1+1.96sd/mu]}]} logStats = f /@ stats {{0.518163, ErrorBar[{-0.0569325, 0.0538651}]}, {-2.65456, \ ErrorBar[{-0.929777, 0.473347}]}, {-1.22462, ErrorBar[{-0.187419, \ 0.157776}]}, {-3.22263, ErrorBar[{-1.23082, 0.535292}]}, {-2.55786, \ ErrorBar[{-0.755356, 0.42537}]}, {-1.21855, ErrorBar[{-0.171941, 0.146669}]}, \ {-3.34756, ErrorBar[{-1.60623, 0.58743}]}} MultipleListPlot[logStats, PlotRange -> All] Randomizing execution order doesn't change results much, and t4 is still almost twice as fast as t2... but there's considerable overlap in the confidence intervals. Bobby Treat -----Original Message----- From: DrBob [mailto:majort at cox-internet.com] To: mathgroup at smc.vnet.net 'BobHanlon at aol.com'; 'Selwyn Hollis'; 'Johannes Ludsteck' Subject: [mg36090] RE: [mg36064] Re: [mg36045] Need faster way to combine arrays I've timed the methods that work (several don't), and Sseziwa's solution looks best by a considerable margin. I would have expected t3 to be fastest, because it's a single Mathematica function. n = 1000; {r, g, b} = Table[Table[Random[Integer], {n}, {n}], {3}]; Timing[t1 = Table[{r[[i, j]], g[[i, j]], b[[i, j]]}, {i, Length[r]}, {j, Length[r[[1]]]}];] Timing[t2 = Transpose /@ Transpose[{r, g, b}];] t1 == t2 Timing[t3 = Transpose[{r, g, b}, {3, 1, 2}];] t1 == t3 Timing[t4 = Partition[Transpose[Flatten /@ {r, g, b}], n];] t4 == t1 {1.7650000000000006*Second, Null} {0.07800000000000118*Second, Null} True {0.264999999999997*Second, Null} True {0.015000000000000568*Second, Null} True Bobby -----Original Message----- From: Sseziwa Mukasa [mailto:mukasa at jeol.com] To: mathgroup at smc.vnet.net Subject: [mg36090] [mg36064] Re: [mg36045] Need faster way to combine arrays On Wednesday, August 14, 2002, at 05:35 AM, Kevin Gross wrote: > Hello all, > > I've been using Mathematica for a while, but only recently for image > processing. Suppose I have the following 2D intensity arrays: > > r={{a1,b1},{c1,d1}}; > g={{a2,b2},{c2,d2}}; > b={{a3,b3},{c3,d3}}; > > Now I'd like to combine them to produce a color image. > > color=Table[{r[[i,j]],g[[i,j]],b[[i,j]]},{i,2},{j,2}] > > This returns > > {{{a1, a2, a3}, {b1, b2, b3}}, {{c1, c2, c3}, {d1, d2, d3}}} > > which can be viewed as a color image with > > Graphics[Raster[color,ColorFunction->RGBColor]]//Show > > When the 2D arrays are large, combining them to form the color tensor as > above is very time consuming. Surely there is a more efficient, clever > way to combine them than my use of Table, right? > > Many thanks, > > Kevin Gross > > PS Any comments pro/con from users of the Digital Image Processing > package are also welcome. > I'm not a user of the Digital Image Processing package but I got the following results combining 3 1000x1000 arrays on a 1GHz Mac with version 4.2: In[5]:= n=1000; {r,g,b}=Table[Table[Random[Integer],{n},{n}],{3}]; In[3]:= Timing[Table[{r[[i,j]],g[[i,j]],b[[i,j]]},{i,Length[r]},{j,Length[r [[1]]]}];] Timing[Partition[Transpose[{Flatten[r],Flatten[g],Flatten[b]}],n];] Out[3]= {3.11 Second,Null} Out[4]= {0.2 Second,Null} With n=10000 I run out of memory however. Regards, Ssezi