in reply to Re: How do I get the root mean square of a list?
in thread How do I get the root mean square of a list?

Pass-by-reference isn't winning you anything here, since you are explicitly dereferencing and iterating over the entire array anyway. I would rewrite as:
sub std_dev { my ($sum, $avg, $variance, $t); $sum += $_ for @_; $avg = $sum / @_; $variance += ($t = ($avg - $_)) * $t for @_; $variance /= @_; sqrt $variance; }
This benchmarks over twice as fast, mostly because it's not calling outside subs for summation and averaging. There's a little intermediate result optimization in there as well.

I wonder, however, if there isn't a more efficient algorithm for calculating standard deviation, that doesn't require iterating twice... tilly?

   MeowChow                                   
               s aamecha.s a..a\u$&owag.print

Replies are listed 'Best First'.
Re (tilly) 2: Answer: How do I get the root mean square of a list?
by tilly (Archbishop) on Jun 04, 2001 at 21:15 UTC
    You need to iterate twice. However the following version should be slightly faster and I think is numerically more stable:
    sub std_dev { my ($sum, $sqr_sum); for (@_) { $sum += $_; $sqr_sum += $_ * $_; } sqrt(($sqr_sum - $sum * $sum / @_)/@_); }
    And, of course, if your set of numbers is a sample set from a random distribution, the standard deviation of the numbers is a biased predictor of the true standard deviation, so you may prefer the following:
    # Produces an unbiased estimate of a standard deviation # from a sample sub std_dev_samp { my ($sum, $sqr_sum); for (@_) { $sum += $_; $sqr_sum += $_ * $_; } sqrt(($sqr_sum - $sum * $sum / @_)/$#_); }
Re: Re: Answer: How do I get the root mean square of a list?
by princepawn (Parson) on Jun 04, 2001 at 21:16 UTC
    you have heard of PDL havent you? it handles array ops as fast as C within Perl. and it does have rms as part of its stats() function.