lfit.pl
author Andreas Thurnherr <ant@ldeo.columbia.edu>
Mon, 13 Apr 2020 11:06:22 -0400
changeset 40 c1803ae2540f
parent 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
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     4
#                    dlm: Mon May 18 10:07:47 2015
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 1999 A.M. Thurnherr
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     6
#                    uE-Info: 20 61 NIL 0 0 72 2 2 4 NIL ofnI
0
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
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    20
#	May 18, 2015: - added firstRec, lastRec parameters (V6.1)
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#   - x,y,sig are field numbers for data in $ants_
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#	- funcs is passed the current index & xfnr instead of the x-value
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
#   - if sig is a negative number, -sig is used as constant input stddev
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
#   - @a, @ia, @covar, &funcs passed as refs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
#	- chi square is returned
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
require "$ANTS/nrutil.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
require "$ANTS/covsrt.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
require "$ANTS/gaussj.pl";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    33
sub lfit(@)
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
{
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    35
	my($xfnr,$yfnr,$sig,$aR,$iaR,$covarR,$funcsR,$firstRec,$lastRec) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    36
	$firstRec = 0 unless defined($firstRec);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    37
	$lastRec = $#ants_ unless defined($lastRec);
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
	my($i,$j,$k,$l,$m,$mfit);			# int
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
	my($ym,$wt,$sum,$sig2i,$chisq);		# float
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
	my(@beta,@afunc);					# float[]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
	&matrix(\@beta,1,$#{$aR},1,1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
	&vector(\@afunc,1,$#{$aR});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    45
	for ($j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
		$mfit++ if ($iaR->[$j]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
	croak("lfit: no parameters to be fitted") if ($mfit == 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
	for ($j=1; $j<=$mfit; $j++) {		# REQUIRED FOR SOME PERL VERSIONS!!!
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
		for ($k=1;$ k<=$mfit; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
			$covarR->[$j][$k] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
		$beta[$j][1] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
	}
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    55
	for ($i=$firstRec; $i<=$lastRec; $i++) {
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
		next if ($antsFlagged[$i]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
		next unless numberp($ants_[$i][$xfnr]) && numberp($ants_[$i][$yfnr]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
		&$funcsR($i,$xfnr,\@afunc);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
		$ym = $ants_[$i][$yfnr];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
		if ($mfit < $#{$aR}) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
			for ($j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
				$ym -= $aR->[$j]*$afunc[$j] if (!$iaR->[$j]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
        if ($sig > 0) {                                 # field number
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
            $sig2i = 1.0/($ants_[$i][$sig]*$ants_[$i][$sig]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
        } else {                                        # const value
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
            $sig2i = 1.0/($sig*$sig);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
        }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
		for ($j=0,$l=1; $l<=$#{$aR}; $l++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
			if ($iaR->[$l]) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
				$wt = $afunc[$l]*$sig2i;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
				for ($j++,$k=0,$m=1; $m<=$l; $m++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
					$covarR->[$j][++$k] += $wt*$afunc[$m] if ($iaR->[$m]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
				}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
				$beta[$j][1] += $ym*$wt;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
	for ($j=2; $j<=$mfit; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
		for ($k=1;$k<$j;$k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
			$covarR->[$k][$j] = $covarR->[$j][$k];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
#			print(STDERR "covarR[$k][$j] = $covarR->[$k][$j]\n");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
	&gaussj($covarR,\@beta);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
	for ($j=0,$l=1;$l<=$#{$aR};$l++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
		$aR->[$l]=$beta[++$j][1] if ($iaR->[$l]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
	}
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    90
	for ($i=$firstRec; $i<=$lastRec; $i++) {
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
		next if ($antsFlagged[$i]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
		next unless numberp($ants_[$i][$xfnr]) && numberp($ants_[$i][$yfnr]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
		&$funcsR($i,$xfnr,\@afunc);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
		for ($sum=0,$j=1; $j<=$#{$aR}; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
			$sum += $aR->[$j]*$afunc[$j];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
		my($tmpval) = ($sig > 0) ?
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
			($ants_[$i][$yfnr] - $sum) / $ants_[$i][$sig] :
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
			($ants_[$i][$yfnr] - $sum) / -$sig;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
		$chisq += $tmpval * $tmpval;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
	&covsrt($covarR,$iaR);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
	return $chisq;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105