Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2014

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

Search the Archive

Re: Efficient function to accumulate a list of {value,coord} into array

  • To: mathgroup at smc.vnet.net
  • Subject: [mg132507] Re: Efficient function to accumulate a list of {value,coord} into array
  • From: "Dr. Wolfgang Hintze" <weh at snafu.de>
  • Date: Fri, 4 Apr 2014 03:55:38 -0400 (EDT)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • Delivered-to: l-mathgroup@wolfram.com
  • Delivered-to: mathgroup-outx@smc.vnet.net
  • Delivered-to: mathgroup-newsendx@smc.vnet.net
  • References: <lhiudg$dij$1@smc.vnet.net>

schrieb im Newsbeitrag news:lhiudg$dij$1 at smc.vnet.net...

Dear all,

I am struggling with how to convert a list of (value, coords) tuples into an 
array such that the an element in the array should represent the sum of all 
value elements in that list with matching coords, and zero if no matches, 
e.g.

{ {3.6, 7,4}, {3,4, 8,6}, {2.1, 7,4} }

if it were a 10X10 element array would become all zero's, except element 
(7,4)->(3.6+2.1) and (8,6)->3.4

I've got some code which does what I want:

ParticleToDensity[particles_] := (
  arr = ConstantArray[0, {144, 300}];
  For[l = 1, l < NoParticles, l++,
   (tp = particles[[l]];
    If[tp[[2]] != 0,
     arr[[Round[tp[[3]]], Round[tp[[2]]]]] += tp[[1]]]
    )];
  arr)

So, the argument to the function is a list of "particles", and the first 
element of this particle is the value in the array I'd like to accumulate, 
and the next two elements in that particle say where in the array they 
should be accumulated.

It seems to work, but it is slow. I can see that this isn't really the 
Mathematica way of doing things, but I'm struggling to think of a better 
way.

For reference, NoParticles is typically set to something like 10,000, and it 
takes about 0.1 secs to process on my machine. However this needs to be done 
frequently, hence I am hoping for a better way.



Any help greatly appreciated.

Thanks,
Julian.


Julian,
try this function (I don't know how the speed compares to your code)

acum = {#[[1]], Plus @@ Drop[#, 1]} &[
      Sort[Union[Flatten[#, 1]], OrderedQ[{#2, #1}] &]] & /@
    Split[Sort[{{#[[2]], #[[3]]}, #[[1]]} & /@ #],
     First[#1] == First[#2] &] &;

Example

x = {{3.6, 7, 4}, {3.4, 8, 6}, {2.1, 7, 4}};

acum[x]
{{{7, 4}, 5.7}, {{8, 6}, 3.4}}

The format is a bit different from the flat elements, but in this way it can 
be treated easier by Mathematica functions.
You could apply

In[102]:= Flatten[{#[[2]], #[[1]]}] & /@ %
Out[102]= {{5.7, 7, 4}, {3.4, 8, 6}}

Best regards,
Wolfgang




  • Prev by Date: Re: Mathematica nb file => TeX file ?
  • Next by Date: Parallelization sometimes a plus, sometimes not
  • Previous by thread: Re: Efficient function to accumulate a list of
  • Next by thread: Re: Efficient function to accumulate a list of {value,coord} into array