lfit.pl
author A.M. Thurnherr <ant@ldeo.columbia.edu>
Mon, 11 Jun 2012 13:17:59 -0400
changeset 2 75410953a4d5
parent 0 a5233793bf69
child 20 7ea1fd9d64e6
permissions -rw-r--r--
.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    L F I T . P L 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Sat Jul 31 11:24:47 1999
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     4
#                    dlm: Thu Jan  5 12:53:11 2012
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 1999 A.M. Thurnherr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     6
#                    uE-Info: 19 60 NIL 0 0 72 2 2 4 NIL ofnI
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     7
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     8
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     9
# LFIT routine from Numerical Recipes adapted to ANTS
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	Jul 31, 1999: - manually converted from c-source
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	Aug 01, 1999: - changed funcs() interface
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#	Sep 26, 1999: - made sure right version of covsrt is used
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	Jun 28, 2001: - re-added commented out code 'cause it's required
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
#					on some perl versions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#	Jan  5, 2012: - BUG: non-numeric x/y were not handled correctly;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
#						 this was only easily apparent when the last
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#						 record contained non-numeric values
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
#   - x,y,sig are field numbers for data in $ants_
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#	- funcs is passed the current index & xfnr instead of the x-value
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#   - if sig is a negative number, -sig is used as constant input stddev
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
#   - @a, @ia, @covar, &funcs passed as refs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
#	- chi square is returned
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
require "$ANTS/nrutil.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
require "$ANTS/covsrt.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
require "$ANTS/gaussj.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
sub lfit($$$$$$$)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
	my($xfnr,$yfnr,$sig,$aR,$iaR,$covarR,$funcsR) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
	my($i,$j,$k,$l,$m,$mfit);			# int
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
	my($ym,$wt,$sum,$sig2i,$chisq);		# float
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
	my(@beta,@afunc);					# float[]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
	&matrix(\@beta,1,$#{$aR},1,1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
	&vector(\@afunc,1,$#{$aR});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
	for ($j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
		$mfit++ if ($iaR->[$j]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    45
	croak("lfit: no parameters to be fitted") if ($mfit == 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
	for ($j=1; $j<=$mfit; $j++) {		# REQUIRED FOR SOME PERL VERSIONS!!!
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
		for ($k=1;$ k<=$mfit; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
			$covarR->[$j][$k] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
		$beta[$j][1] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
	for ($i=0; $i<=$#ants_; $i++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
		next if ($antsFlagged[$i]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
		next unless numberp($ants_[$i][$xfnr]) && numberp($ants_[$i][$yfnr]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
		&$funcsR($i,$xfnr,\@afunc);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
		$ym = $ants_[$i][$yfnr];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
		if ($mfit < $#{$aR}) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
			for ($j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
				$ym -= $aR->[$j]*$afunc[$j] if (!$iaR->[$j]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
        if ($sig > 0) {                                 # field number
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
            $sig2i = 1.0/($ants_[$i][$sig]*$ants_[$i][$sig]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
        } else {                                        # const value
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
            $sig2i = 1.0/($sig*$sig);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
        }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
		for ($j=0,$l=1; $l<=$#{$aR}; $l++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
			if ($iaR->[$l]) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
				$wt = $afunc[$l]*$sig2i;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
				for ($j++,$k=0,$m=1; $m<=$l; $m++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
					$covarR->[$j][++$k] += $wt*$afunc[$m] if ($iaR->[$m]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
				}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
				$beta[$j][1] += $ym*$wt;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
	for ($j=2; $j<=$mfit; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
		for ($k=1;$k<$j;$k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
			$covarR->[$k][$j] = $covarR->[$j][$k];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
#			print(STDERR "covarR[$k][$j] = $covarR->[$k][$j]\n");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
	&gaussj($covarR,\@beta);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
	for ($j=0,$l=1;$l<=$#{$aR};$l++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
		$aR->[$l]=$beta[++$j][1] if ($iaR->[$l]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
	for ($i=0; $i<=$#ants_; $i++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
		next if ($antsFlagged[$i]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
		next unless numberp($ants_[$i][$xfnr]) && numberp($ants_[$i][$yfnr]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
		&$funcsR($i,$xfnr,\@afunc);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
		for ($sum=0,$j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
			$sum += $aR->[$j]*$afunc[$j];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
		my($tmpval) = ($sig > 0) ?
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
			($ants_[$i][$yfnr] - $sum) / $ants_[$i][$sig] :
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
			($ants_[$i][$yfnr] - $sum) / -$sig;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
		$chisq += $tmpval * $tmpval;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
	&covsrt($covarR,$iaR);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
	return $chisq;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102