Reputation:
I have an array (@BondLength) of integers with about 14 digits each:
1.4913648111713
1.49444103262725
1.49324445420032
1.49781641064584
1.49375901670919
1.48388476641551
1.49205194279556
1.48573550809019
1.48486531375745
1.48899462725693
1.48455818343371
1.49451162591664
1.49687975468973
1.48919777061343
1.48460466118088
I put them as the "data" field, plus their "average" (which I was also successfully able to get to 10-digits) into a subroutine:
sub stdev{
my($data) = @_;
my $average = $_;
if(@$data == 1){
return 0;
}
my $sqtotal = 0;
foreach(@$data) {
$sqtotal += ($average-$_) ** 2;
}
my $std = ($sqtotal / (@$data-1)) ** 0.5;
return $std;
}
But when I call this subroutine with the necessary parameters:
my $stdev = &stdev(@BondLength, $average);
printf("\nThe standard deviation NCABondLength: $stdev");
I get simply "0" outputted. I know it has values larger than zero up to the tenth-decimal place because I inputted it into Excel. What am I doing wrong in this script? (I have tinkered with it too much now by reading things off the web, but still keep getting "0").
Thanks.
Upvotes: 1
Views: 89
Reputation: 1872
There is a problem in the second line of your code. You only assign one value from the list of parameters when you say my($data) = @_
This is the reason why your subroutine is returning with a zero value. you can try this instead.
#!/usr/bin/perl
use strict;
use warnings;
sub average {
my $data = shift;
my $count = @$data;
my $sum;
foreach my $element (@$data){
$sum += $element;
}
return $sum / $count;
}
sub stdev {
my ($average, $data) = @_;
my $count = @$data;
my $sum;
my $variance;
$sum += (($_ - $average) ** 2) foreach @$data;
$variance = $sum / $count;
return $variance ** 0.5;
}
}
my @array = qw/
1.4913648111713
1.49444103262725
1.49324445420032
1.49781641064584
1.49375901670919
1.48388476641551
1.49205194279556
1.48573550809019
1.48486531375745
1.48899462725693
1.48455818343371
1.49451162591664
1.49687975468973
1.48919777061343
1.48460466118088
/;
my $average = average(\@array);
my $deviation = stdev($average, \@array);
printf "Standard deviation is %.5f\n", $deviation; #print number to five decimal places.
#output 0.00461
Upvotes: 3