[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: multiplication



James Kuyper wrote:
> 
> meron@cars3.uchicago.edu wrote:
> >
> > In article <38E03BDC.868B8396@hotmail.com>, marc <m_schellens@hotmail.com> writes:
> > >Is there a function like TOTAL but for multiplication.
> > >Like the big PI symbol in mathematical notation.
> > >Or this really something for the for loop?
> > >
> > >I.E.
> > >
> > >a=[1,2,3,...]
> > >
> > >result=a[1]*a[2]*a[3]...
> > >
> > if all the elements of a are positive then you can simply do
> >
> > result = exp(total(alog(a)))
> ...
> > If some of the elements are negative, you can still handle it.  do
> >
> > dum = where(a lt 0, ndum)
> > sig = (-1)^ndum
> > result = sig*exp(total(alog(abs(a))))
> 
> You can't honestly be suggesting that this is a good technique? Ignore
> for a momement what happens if any element of 'a' is 0. That code
> performs two transcendental function evaluations per element of 'a'. IDL
> would have to be very badly engineered (which I suppose is possible),
> for a 'for' loop to execute more slowly than your code.

Only one transcendental is computed for each a, alog().  The exp occurs on the
single value after the total.  Results for a 10,000 element random floating
array finely tuned to avoid under or overflow:

Loop Method:

Average Time:      0.017213961
   0.00528653

Log Method:

Average Time:     0.0049092293
   0.00528580

4 times as fast.  Suppose you'd like to do an array with 100,000 double
elements... you get:

Loop Method:

% Loop limit expression too large for loop variable type.
  <LONG     (       99999)>.

Log Method:

Average Time:      0.050116260
  7.92382e+10

And if you hack it with two nested loops to avoid the loop limit error:

c=1. & for j=0L,n/100-1 do for k=0L,99L do c=c*a[j*100L+k]

you get:

Hacked Loop Method

Average Time:       0.30190306
      0.97063262

Log Method:

Average Time:      0.068175601
      0.97063262

A full 5 times faster.  

And now, just for fun, the same data set, but with multiplication computed in a
heavily optimized C program.  The core of the C code is simply the
straightforward: "for(i=0;i<N;i++) res*=a[i]";  The result: 

Got 0.97063262 (Average Time: 0.001710 s)


Ouch!  Another speedup of by a factor of 40!  

Morals: IDL loops are pitifully slow, and you can't loop over very large arrays
without trickery, and for many operations, compiled C is *significantly* faster.

JD

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