Hi, all: I'm getting a disturbingly-large discrepancy in running an identical script on different machines, and hoping that someone can suggest a cause and perhaps a fix. I'm suspecting a possible bug in my perl version.

Code being executed (@ARGV = qw/data.txt 636/):

`#!/usr/bin/perl -w
use strict;
# Least square fit to quadratic function; input up to ~1k data pairs a
+s space-separated columns.
#
# $Revision: 1.1 $ $Date: 2010-06-28 17:31:23-04 $
# $Source: /home/vogelke/notebook/2010/0628/polynomial-fit/RCS/pfit,v
+$
# $UUID: 631e046d-f070-38bb-b287-bdd10b1d0efa $
#
# John Lapeyre Tue Jan 28 18:45:19 MST 2003
# lapeyre@physics.arizona.edu
# http://www.johnlapeyre.com/computers.html
# http://www.johnlapeyre.com/pfit
#
# $Revision: 1.2 $ $Date: 2010-10-04 17:08:40-05 $
# Revised by Ben Okopnik
# Added usage message, code strictures, input filtering/validation
#
# fit to A x^2 + B x + C
# Works by solving matrix equation M.c = v.
# c = (A,B,C)
# v = (v1,v2,v3), where vn = \sum_i y_i x_i^(n-1)
# m = ( (m4,m3,m2), (m3,m2,m1), (m2,m1,m0))
# where mn = \sum_i x_i^n
die "Usage: ", $0 =~ /([^\/]+)$/, " <input_file> <target_number>\n"
unless @ARGV == 2;
my $tgt = pop;
my ($m0, $v1, $v2, $v3, $m1, $m2, $m3, $m4, $d, @x, @y) = 0;
while (<>) {
next unless /^\s*(\d+)(?:$|\s+(\d+)\s*$)/;
push @y, $+;
push @x, defined $2 ? $1 : $m0;
$m0++;
}
die "Badly-formatted data (one or two numerical columns required)\n"
unless $m0;
for (0 .. $#x) {
my $x = $x[$_];
my $y = $y[$_];
$v1 += $y * $x**2;
$v2 += $y * $x;
$v3 += $y;
$m1 += $x;
$m2 += $x * $x;
$m3 += $x**3;
$m4 += $x**4;
}
# Used mathematica to invert the matrix and translated to perl
$d = $m2**3 + $m0 * $m3**2 + $m1**2 * $m4 - $m2 * (2 * $m1 * $m3 + $m0
+ * $m4);
my $A = ($m1**2 * $v1 - $m0 * $m2 * $v1 + $m0 * $m3 * $v2 + $m2**2 * $
+v3 -
$m1 * ($m2 * $v2 + $m3 * $v3)) / $d;
my $B = (-($m1 * $m2 * $v1) + $m0 * $m3 * $v1 + $m2**2 * $v2 - $m0 * $
+m4 * $v2 -
$m2 * $m3 * $v3 + $m1 * $m4 * $v3) / $d;
my $C = ($m2**2 * $v1 - $m1 * $m3 * $v1 + $m1 * $m4 * $v2 + $m3**2 * $
+v3 -
$m2 * ($m3 * $v2 + $m4 * $v3)) / $d;
# A x^2 + B x + C
printf "%f\t%f\t%f\n", $A, $B, $C;
# Correct $C for final value
$C -= $tgt;
# PE solver
my $y1 = (-$B + sqrt($B**2 - 4 * $A * $C)) / (2 * $A);
my $y2 = (-$B - sqrt($B**2 - 4 * $A * $C)) / (2 * $A);
printf "Roots: %.3f or %.3f\n\n", $y1, $y2;
`

The data being processed (CO2 measurements at Mauna Loa):

`1962 318
1982 341
2002 373
`

The results:

`# i686 running Linux with perl-5.10.0
0.011256 -43.244877 41833.442623
Roots: 2093.870 or 1747.905
# IBM x3400 running Linux with perl-5.10.1
0.011250 -43.220086 41809.478563
Roots: 2083.912 or 1757.866
# Sparc running Solaris-10 with perl-5.10.1
0.011250 -43.220086 41809.478563
Roots: 2083.912 or 1757.866
# After adding "use bignum;" on either of the last two
0.011250 -43.220000 41809.395000
Roots: 2083.912 or 1757.866
`

Any help or suggestions would be appreciated.

--

"Language shapes the way we think, and determines what we can think about."

-- B. L. Whorf

Comment onCalculation discrepancy between Perl versionsSelectorDownloadCode