Re: efficiently adding many 2D Gaussians

• To: mathgroup at smc.vnet.net
• Subject: [mg91572] Re: [mg91562] efficiently adding many 2D Gaussians
• From: Carl Woll <carlw at wolfram.com>
• Date: Thu, 28 Aug 2008 03:15:28 -0400 (EDT)
• References: <200808271043.GAA21263@smc.vnet.net>

```M.Roellig wrote:

>Dear group,
>
>I need some help on reducing run time and memory usage for the
>following problem:
>
>I want to place a large number N (10000+)  of 2D Gaussians in a plane
>(on a large array, m x m ) and add them up.
>I came up with a few approaches but they all fail, or become very slow
>once N >10000 or m>100.
>Here are my ideas so far (not bothering about dimensions, units, etc.
>and using 1000 positions only):
>
>SeedRandom[1111111];
>posTab =
> RandomReal[NormalDistribution[0, 1], {1000, 2}];
>
>1. idea (fastest I could get):
>
>gsum = Compile[{{x, _Real, 1}},
>   Evaluate[
>    Total[Map[(1.*
>         Exp[-(((x[[1]] - #[[1]])^2 + (x[[2]] - #[[2]])^2)/(
>            2. 0.25^2.))]) &, posTab]]]];
>
>(* Warning Output:
>-----------------------
>Part::partd: Part specification x[[1]] is longer than depth of \
>object. >>
>
>Part::partd: Part specification x[[2]] is longer than depth of \
>object. >>
>------------------------*)
>
>xyArray = Array[{#1, #2} &, {100, 100}] // MatrixForm;
>map1e4 = Map[gsum, xyArray, {3}]; // Timing
>
>Out[22]= {11.843, Null}
>
>
>
>2. idea (trying to use mapping, and came up with a very inefficient
>solution :-)
>
>Total[
>   Table[Exp[-(((x - #[[1]])^2 + (y - #[[2]])^2)/0.125)], {x, -5,
>       5, .1}, {y, -5, 5, .1}] & /@ posTab]; // Timing
>
>Out[9]= {85.375, Null}
>
>Using more than 1000 Gaussians doesn't fit into my memory and makes
>WinXp swapping memory to disk
>basically making the computation time unbearable. Of course this is no
>big surprise since I create one array for each individual Gaussian
>before adding them up.
>
> 3. completely different approach hoping to take advantage of internal
>mathematica optimization:
>
>SeedRandom[1111111]; posTab =
> RandomReal[NormalDistribution[0, 100], {1000, 2}];
>clumpSum =
>  Total[Map[(1.*
>       Exp[-(((x - #[[1]])^2 + (y - #[[2]])^2)/(2. 10.^2.))]) &,
>    posTab]];
>clumpEm100 =
>   Plot3D[clumpSum, {x, -350, 350}, {y, -350, 350}, PlotRange -> All,
>    PlotPoints -> 100, MaxRecursion -> 0]; // Timing
>
>mapEm100 = clumpEm100[[1]] /. GraphicsComplex[pts_, __] -> pts;
>
>
>Out[25]= {53.485, Null}
>
>I am grateful for any advice on how to do this faster and more
>efficiently.
>I guess a clever usage of Fold/Nest could do it, but I failed to get
>it done.
>
>The code I use now is a little more complex, since I need to add up
>Gaussians with
>different sizes and amplitudes, which I take from a list:
>
>--------------------
>
>fullEns ={{1/1000, 63095, 374775., 0.00237989, 112.101, 0.818147},
>{1/100,
>  10000, 185962., 0.00647649, 20.143, 2.22645}, {1/10, 1584, 92273.2,
>  0.0176247, 5.91138, 6.05894}, {1, 251, 45785.5, 0.0479629, 0.837552,
>   16.4884}, {10, 39, 22718.5, 0.130523, 0.156455, 44.8706}, {100, 6,
>  11272.8, 0.355198, 0.220978, 122.108}, {1000, 1, 5593.51, 0.966614,
>  0.240513, 332.297}}
>
>(*In each sublist element 2 is the number, element 5 the amplitude,
>element 6 the stand.dev.
>I am discarding the first to rows to reduce total numbers. *)
>
>SeedRandom[1111111]; posEnsTab =
> Append[Table[
>   RandomReal[NormalDistribution[0, 100], {fullEns[[j, 2]], 2}], {j,
>    1, Length[fullEns] - 1}], {{0., 0.}}];
>ensSum = Plus @@
>   Table[Total[
>     Map[( fullEns[[j, 5]]*
>         Exp[-(((x - #[[1]])^2 + (y - #[[2]])^2)/(
>            2. fullEns[[j, 6]]^2.))]) &, posEnsTab[[j]]]], {j, 3,
>     Length[fullEns]}];
>ensSum100 =
>   Plot3D[ensSum, {x, -350, 350}, {y, -350, 350}, PlotRange -> All,
>    PlotPoints -> 100, MaxRecursion -> 0]; // Timing
>
>(* Out: {116.453, Null} *)
>
>ensMap100 = ensSum100[[1]] /. GraphicsComplex[pts_, __] -> pts;
>ListPlot3D[ensMap100, PlotRange -> All]
>
>Hope somebody can help me.
>
>Cheers,
>
>Markus
>
>
Perhaps the following will help:

SeedRandom[1111111];
posTab = RandomReal[NormalDistribution[0, 1], {2000, 2}];

In[3]:= MemoryInUse[]
MaxMemoryUsed[]

Out[3]= 5898936

Out[4]= 7225904

In[5]:= Table[Total[Exp[-((x - posTab[[All, 1]])^2 + (y - posTab[[All,
2]])^2)/.125]], {x, -5, 5, .1}, {y, -5, 5, .1}]; // Timing

Out[5]= {10.031,Null}

In[6]:= MemoryInUse[]
MaxMemoryUsed[]

Out[6]= 7098408

Out[7]= 7237848

Carl Woll
Wolfram Research

```

• Prev by Date: Re: Mathematica and F#
• Next by Date: Re: efficiently adding many 2D Gaussians
• Previous by thread: efficiently adding many 2D Gaussians
• Next by thread: Re: efficiently adding many 2D Gaussians