comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Center of mass???
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Return to the default flat view Create a new topic Submit Reply
Re: Center of mass??? [message #17695 is a reply to message #17692] Tue, 09 November 1999 00:00 Go to previous messageGo to previous message
J.D. Smith is currently offline  J.D. Smith
Messages: 214
Registered: August 1996
Senior Member
David Fanning wrote:
>
> Paul Hick (pphick@ucsd.edu) writes:
>
>> Reasoning by analogy to the 2D case, this should work, I think:
>>
>> xcm = Total( Total(Total(array,3),2) * Indgen(s[0])) / totalMass
>> ycm = Total( Total(Total(array,3),1) * Indgen(s[1])) / totalMass
>> zcm = Total( Total(Total(array,2),1) * Indgen(s[2])) / totalMass
>
> Well, it seems to work in the simple-minded cases I
> tried it on. :-)
>
> I'll write it up in an article if no one else has
> serious objections.
>

Why stop at 3 dimensions? How about any dimension:


function com, arr,DOUBLE=dbl
s=size(arr,/DIMENSIONS)
n=n_elements(s)
tot=total(arr,DOUBLE=dbl)
if keyword_set(dbl) then ret=dblarr(n,/NOZERO) else
ret=fltarr(n,/NOZERO)
for i=0,n-1 do begin
tmp=arr
for j=0,i-1 do tmp=total(tmp,1,DOUBLE=dbl)
for j=i+1,n-1 do tmp=total(tmp,2,DOUBLE=dbl)
ret[i]=total(findgen(s[i])*tmp,DOUBLE=dbl)/tot
endfor
return,ret
end

I would have posted this yesterday, but I couldn't help but feel there
must be a better way to do it.

Here's why:

In the 3D example above, Paul calculates total(array,3) twice, which
means once too many. It could have been saved between steps.

The number of times total() is called on the array in this
straightforward, brute-force method is n*(n-1) (for each of n dimensions
total the array over the other n-1), not counting the final index
total. And many of those are repeats to the exact same total() call
with the exact same array! Since we needed to do all directional
sub-totals, there must be a more efficient way, analogous to the 3D case
of saving total(array,3).

After a bit of scratching on paper, I found that I could do it with only
(n-1)(n+2)/2 calls to total(), by working simultaneously from the last
dimension backward and the first dimension forward, saving sub-totals
which can be shared by subsequent calls in both cases. For 10
dimensions that becomes 54 vs. 90 calls to total() (though only 5 vs. 6
for 3 dimens -- 1 saved call as described above). The problem is how to
code this model. Two reciprocating mutually recursive functions should
do the trick, but I haven't had time to explore. Any takers? Anybody
think they can save more calls to total()?

This may be folly, since few will use it for more than 3D, but it's an
interesting problem.

JD

P.S. Another wrinkle: The total()'s you'd prefer to save are the ones
that do the most work... those which total the "largest" dimensions. So
sorting by dimension size first of all might speed things up even more.

--
J.D. Smith |*| WORK: (607) 255-5842
Cornell University Dept. of Astronomy |*| (607) 255-6263
304 Space Sciences Bldg. |*| FAX: (607) 255-5875
Ithaca, NY 14853 |*|
[Message index]
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: Re: Object Widgets
Next Topic: Re: where() and IEEE NaN

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 18:38:20 PDT 2025

Total time taken to generate the page: 0.00417 seconds