| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
=head1 NAME |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
PDL::Fit::LM -- Levenberg-Marquardt fitting routine for PDL |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
This module provides fitting functions for PDL. Currently, only |
|
8
|
|
|
|
|
|
|
Levenberg-Marquardt fitting is implemented. Other procedures should |
|
9
|
|
|
|
|
|
|
be added as required. For a fairly concise overview on fitting |
|
10
|
|
|
|
|
|
|
see Numerical Recipes, chapter 15 "Modeling of data". |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use PDL::Fit::LM; |
|
15
|
|
|
|
|
|
|
$ym = lmfit $x, $y, $sigma, \&expfunc, $initp, {Maxiter => 300}; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=cut |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
package PDL::Fit::LM; |
|
22
|
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
|
234437
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
46
|
|
|
24
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
80
|
|
|
25
|
1
|
|
|
1
|
|
8
|
use PDL::Core; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
10
|
|
|
26
|
1
|
|
|
1
|
|
564
|
use PDL::Exporter; |
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
8
|
|
|
27
|
1
|
|
|
1
|
|
48
|
use PDL::Options; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
116
|
|
|
28
|
1
|
|
|
1
|
|
7
|
use PDL::MatrixOps qw(lu_decomp lu_backsub inv); # for matrix inversion |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
15
|
|
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
our @EXPORT_OK = qw(lmfit tlmfit); |
|
31
|
|
|
|
|
|
|
our %EXPORT_TAGS = (Func=>\@EXPORT_OK); |
|
32
|
|
|
|
|
|
|
our @ISA = qw( PDL::Exporter ); |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head2 lmfit |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=for ref |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Levenberg-Marquardt fitting of a user supplied model function |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=for example |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
($ym,$finalp,$covar,$iters) = |
|
43
|
|
|
|
|
|
|
lmfit $x, $y, $sigma, \&expfunc, $initp, {Maxiter => 300, Eps => 1e-3}; |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
where $x is the independent variable and $y the value of the dependent variable at each $x, $sigma is the estimate of the uncertainty (i.e., standard deviation) of $y at each data point, the fourth argument is a subroutine reference (see below), and $initp the initial values of the parameters to be adjusted. |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Options: |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=for options |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Maxiter: maximum number of iterations before giving up |
|
52
|
|
|
|
|
|
|
Eps: convergence criterion for fit; success when normalized change |
|
53
|
|
|
|
|
|
|
in chisquare smaller than Eps |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
The user supplied sub routine reference should accept 4 arguments |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=over 4 |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=item * |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
a vector of independent values $x |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item * |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
a vector of fitting parameters |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item * |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
a vector of dependent variables that will be assigned upon return |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item * |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
a matrix of partial derivatives with respect to the fitting parameters |
|
74
|
|
|
|
|
|
|
that will be assigned upon return |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=back |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
As an example take this definition of a single exponential with |
|
79
|
|
|
|
|
|
|
3 parameters (width, amplitude, offset): |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub expdec { |
|
82
|
|
|
|
|
|
|
my ($x,$par,$ym,$dyda) = @_; |
|
83
|
|
|
|
|
|
|
my ($width,$amp,$off) = map {$par->slice("($_)")} (0..2); |
|
84
|
|
|
|
|
|
|
my $arg = $x/$width; |
|
85
|
|
|
|
|
|
|
my $ex = exp($arg); |
|
86
|
|
|
|
|
|
|
$ym .= $amp*$ex+$off; |
|
87
|
|
|
|
|
|
|
my (@dy) = map {$dyda->slice(",($_)")} (0..2); |
|
88
|
|
|
|
|
|
|
$dy[0] .= -$amp*$ex*$arg/$width; |
|
89
|
|
|
|
|
|
|
$dy[1] .= $ex; |
|
90
|
|
|
|
|
|
|
$dy[2] .= 1; |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
Note usage of the C<.=> operator for assignment |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
In scalar context returns a vector of the fitted dependent |
|
96
|
|
|
|
|
|
|
variable. In list context returns fitted y-values, vector |
|
97
|
|
|
|
|
|
|
of fitted parameters, an estimate of the covariance matrix |
|
98
|
|
|
|
|
|
|
(as an indicator of goodness of fit) and number of iterations |
|
99
|
|
|
|
|
|
|
performed. |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub PDL::lmfit { |
|
104
|
2
|
|
|
2
|
0
|
321922
|
my ($x,$y,$sig,$func,$c,$opt) = @_; # not using $ia right now |
|
105
|
2
|
|
|
|
|
28
|
$opt = {iparse( { Maxiter => 200, |
|
106
|
|
|
|
|
|
|
Eps => 1e-4}, ifhref($opt))}; |
|
107
|
2
|
|
|
|
|
886
|
my ($maxiter,$eps) = map {$opt->{$_}} qw/Maxiter Eps/; |
|
|
4
|
|
|
|
|
39
|
|
|
108
|
|
|
|
|
|
|
# initialize some variables |
|
109
|
2
|
|
|
|
|
17
|
my ($isig2,$chisq) = (1/($sig*$sig),0); #$isig2="inverse of sigma squared" |
|
110
|
|
|
|
|
|
|
my ($ym,$al,$cov,$bet,$oldbet,$olda,$oldal,$ochisq,$di) = |
|
111
|
2
|
|
|
|
|
71
|
map {null} (0..10); |
|
|
22
|
|
|
|
|
227
|
|
|
112
|
2
|
|
|
|
|
37
|
my ($aldiag,$codiag); # the diagonals for later updating |
|
113
|
|
|
|
|
|
|
# this will break broadcasting |
|
114
|
2
|
|
|
|
|
11
|
my $dyda = zeroes($x->type,$x->getdim(0),$c->getdim(0)); |
|
115
|
2
|
|
|
|
|
121
|
my $alv = zeroes($x->type,$x->getdim(0),$c->getdim(0),$c->getdim(0)); |
|
116
|
2
|
|
|
|
|
113
|
my ($iter,$lambda) = (0,0.001); |
|
117
|
|
|
|
|
|
|
|
|
118
|
2
|
|
66
|
|
|
5
|
do { |
|
|
|
|
100
|
|
|
|
|
|
119
|
12
|
100
|
|
|
|
1415
|
if ($iter>0) { |
|
120
|
10
|
|
|
|
|
46
|
$cov .= $al; |
|
121
|
|
|
|
|
|
|
# local $PDL::debug = 1; |
|
122
|
10
|
|
|
|
|
174
|
$codiag .= $aldiag*(1+$lambda); |
|
123
|
10
|
|
|
|
|
459
|
my ($lu, $perm, $par) = lu_decomp($cov); |
|
124
|
10
|
|
|
|
|
61663
|
$bet .= lu_backsub($lu,$perm,$par, $bet); |
|
125
|
|
|
|
|
|
|
# print "changing by $da\n"; |
|
126
|
10
|
|
|
|
|
22675
|
$c += $bet; # what we used to call $da is now $bet |
|
127
|
|
|
|
|
|
|
} |
|
128
|
12
|
|
|
|
|
498
|
&$func($x,$c,$ym,$dyda); |
|
129
|
12
|
|
|
|
|
10721
|
$chisq = ($y-$ym)*($y-$ym); |
|
130
|
12
|
|
|
|
|
541
|
$chisq *= $isig2; |
|
131
|
12
|
|
|
|
|
464
|
$chisq = $chisq->sumover; # calculate chi^2 |
|
132
|
12
|
|
|
|
|
193
|
$dyda->transpose->outer($dyda->transpose,$alv->mv(0,2)); |
|
133
|
12
|
|
|
|
|
1077
|
$alv *= $isig2; |
|
134
|
12
|
|
|
|
|
469
|
$alv->sumover($al); # calculate alpha |
|
135
|
12
|
|
|
|
|
43
|
(($y-$ym)*$isig2*$dyda)->sumover($bet); # calculate beta |
|
136
|
12
|
100
|
|
|
|
795
|
if ($iter == 0) {$olda .= $c; $ochisq .= $chisq; $oldbet .= $bet; |
|
|
2
|
|
|
|
|
12
|
|
|
|
2
|
|
|
|
|
41
|
|
|
|
2
|
|
|
|
|
24
|
|
|
137
|
2
|
|
|
|
|
21
|
$oldal .= $al; $aldiag = $al->diagonal(0,1); |
|
|
2
|
|
|
|
|
29
|
|
|
138
|
2
|
|
|
|
|
65
|
$cov .= $al; $codiag = $cov->diagonal(0,1)} |
|
|
2
|
|
|
|
|
29
|
|
|
139
|
12
|
|
|
|
|
71
|
$di .= abs($chisq-$ochisq); |
|
140
|
|
|
|
|
|
|
# print "$iter: chisq, lambda, dlambda: $chisq, $lambda,",$di/$chisq,"\n"; |
|
141
|
12
|
100
|
|
|
|
1276
|
if ($chisq < $ochisq) { |
|
142
|
9
|
|
|
|
|
922
|
$lambda *= 0.1; |
|
143
|
9
|
|
|
|
|
37
|
$ochisq .= $chisq; |
|
144
|
9
|
|
|
|
|
135
|
$olda .= $c; |
|
145
|
9
|
|
|
|
|
105
|
$oldbet .= $bet; |
|
146
|
9
|
|
|
|
|
95
|
$oldal .= $al; |
|
147
|
|
|
|
|
|
|
} else { |
|
148
|
3
|
|
|
|
|
380
|
$lambda *= 10; |
|
149
|
3
|
|
|
|
|
12
|
$chisq .= $ochisq; |
|
150
|
3
|
|
|
|
|
45
|
$c .= $olda; # go back to previous a |
|
151
|
3
|
|
|
|
|
38
|
$bet .= $oldbet; # and beta |
|
152
|
3
|
|
|
|
|
30
|
$al .= $oldal; # and alpha |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
} while ($iter++==0 || $iter < $maxiter && $di/$chisq > $eps); |
|
155
|
2
|
50
|
33
|
|
|
366
|
barf "iteration did not converge" if $iter >= $maxiter && $di/$chisq > $eps; |
|
156
|
|
|
|
|
|
|
# return inv $al as estimate of covariance matrix |
|
157
|
2
|
50
|
|
|
|
23
|
return wantarray ? ($ym,$c,inv($al),$iter) : $ym; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
*lmfit = \&PDL::lmfit; |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=pod |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
An extended example script that uses lmfit is included below. |
|
164
|
|
|
|
|
|
|
This nice example was provided by John Gehman and should |
|
165
|
|
|
|
|
|
|
help you to master the initial hurdles. It can also be found in |
|
166
|
|
|
|
|
|
|
the F directory. |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
use PDL; |
|
169
|
|
|
|
|
|
|
use PDL::Math; |
|
170
|
|
|
|
|
|
|
use PDL::Fit::LM; |
|
171
|
|
|
|
|
|
|
use strict; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
### fit using pdl's lmfit (Marquardt-Levenberg non-linear least squares fitting) |
|
175
|
|
|
|
|
|
|
### |
|
176
|
|
|
|
|
|
|
### `lmfit' Syntax: |
|
177
|
|
|
|
|
|
|
### |
|
178
|
|
|
|
|
|
|
### ($ym,$finalp,$covar,$iters) |
|
179
|
|
|
|
|
|
|
### = lmfit $x, $y, $sigma, \&fn, $initp, {Maxiter => 300, Eps => 1e-3}; |
|
180
|
|
|
|
|
|
|
### |
|
181
|
|
|
|
|
|
|
### Explanation of variables |
|
182
|
|
|
|
|
|
|
### |
|
183
|
|
|
|
|
|
|
### OUTPUT |
|
184
|
|
|
|
|
|
|
### $ym = pdl of fitted values |
|
185
|
|
|
|
|
|
|
### $finalp = pdl of parameters |
|
186
|
|
|
|
|
|
|
### $covar = covariance matrix |
|
187
|
|
|
|
|
|
|
### $iters = number of iterations actually used |
|
188
|
|
|
|
|
|
|
### |
|
189
|
|
|
|
|
|
|
### INPUT |
|
190
|
|
|
|
|
|
|
### $x = x data |
|
191
|
|
|
|
|
|
|
### $y = y data |
|
192
|
|
|
|
|
|
|
### $sigma = ndarray of y-uncertainties for each value of $y (can be set to scalar 1 for equal weighting) |
|
193
|
|
|
|
|
|
|
### \&fn = reference to function provided by user (more on this below) |
|
194
|
|
|
|
|
|
|
### $initp = initial values for floating parameters |
|
195
|
|
|
|
|
|
|
### (needs to be explicitly set prior to use of lmfit) |
|
196
|
|
|
|
|
|
|
### Maxiter = maximum iterations |
|
197
|
|
|
|
|
|
|
### Eps = convergence criterion (maximum normalized change in Chi Sq.) |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
### Example: |
|
200
|
|
|
|
|
|
|
# make up experimental data: |
|
201
|
|
|
|
|
|
|
my $xdata = pdl sequence 5; |
|
202
|
|
|
|
|
|
|
my $ydata = pdl [1.1,1.9,3.05,4,4.9]; |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
# set initial prameters in a pdl (order in accord with fit function below) |
|
205
|
|
|
|
|
|
|
my $initp = pdl [0,1]; |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# Weight all y data equally (else specify different uncertainties in a pdl) |
|
208
|
|
|
|
|
|
|
my $sigma = 1; |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Use lmfit. Fourth input argument is reference to user-defined |
|
211
|
|
|
|
|
|
|
# subroutine ( here \&linefit ) detailed below. |
|
212
|
|
|
|
|
|
|
my ($yf,$pf,$cf,$if) = lmfit $xdata, $ydata, $sigma, \&linefit, $initp; |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# Note output |
|
215
|
|
|
|
|
|
|
print "\nXDATA\n$xdata\nY DATA\n$ydata\n\nY DATA FIT\n$yf\n\n"; |
|
216
|
|
|
|
|
|
|
print "Slope and Intercept\n$pf\n\nCOVARIANCE MATRIX\n$cf\n\n"; |
|
217
|
|
|
|
|
|
|
print "NUMBER ITERATIONS\n$if\n\n"; |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# simple example of user defined fit function. Guidelines included on |
|
221
|
|
|
|
|
|
|
# how to write your own function subroutine. |
|
222
|
|
|
|
|
|
|
sub linefit { |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# leave this line as is |
|
225
|
|
|
|
|
|
|
my ($x,$par,$ym,$dyda) = @_; |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# $m and $c are fit parameters, internal to this function |
|
228
|
|
|
|
|
|
|
# call them whatever make sense to you, but replace (0..1) |
|
229
|
|
|
|
|
|
|
# with (0..x) where x is equal to your number of fit parameters |
|
230
|
|
|
|
|
|
|
# minus 1 |
|
231
|
|
|
|
|
|
|
my ($m,$c) = map { $par->slice("($_)") } (0..1); |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# Write function with dependent variable $ym, |
|
234
|
|
|
|
|
|
|
# independent variable $x, and fit parameters as specified above. |
|
235
|
|
|
|
|
|
|
# Use the .= (dot equals) assignment operator to express the equality |
|
236
|
|
|
|
|
|
|
# (not just a plain equals) |
|
237
|
|
|
|
|
|
|
$ym .= $m * $x + $c; |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# Edit only the (0..1) part to (0..x) as above |
|
240
|
|
|
|
|
|
|
my (@dy) = map {$dyda -> slice(",($_)") } (0..1); |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# Partial derivative of the function with respect to first |
|
243
|
|
|
|
|
|
|
# fit parameter ($m in this case). Again, note .= assignment |
|
244
|
|
|
|
|
|
|
# operator (not just "equals") |
|
245
|
|
|
|
|
|
|
$dy[0] .= $x; |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
# Partial derivative of the function with respect to next |
|
248
|
|
|
|
|
|
|
# fit parameter ($y in this case) |
|
249
|
|
|
|
|
|
|
$dy[1] .= 1; |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Add $dy[ ] .= () lines as necessary to supply |
|
252
|
|
|
|
|
|
|
# partial derivatives for all floating parameters. |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=cut |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# the OtherPar is the sub routine ref |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=head2 tlmfit |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=for ref |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
broadcasted version of Levenberg-Marquardt fitting routine mfit |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=for example |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
tlmfit $x, $y, float(1)->dummy(0), $na, float(200), float(1e-4), |
|
268
|
|
|
|
|
|
|
$ym=null, $afit=null, \&expdec; |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=for sig |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
Signature: tlmfit(x(n);y(n);sigma(n);initp(m);iter();eps();[o] ym(n);[o] finalp(m); |
|
274
|
|
|
|
|
|
|
OtherPar => subref) |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
a broadcasted version of C by using perl broadcasting. Direct |
|
277
|
|
|
|
|
|
|
broadcasting in C seemed difficult since we have an if condition |
|
278
|
|
|
|
|
|
|
in the iteration. In principle that can be worked around by |
|
279
|
|
|
|
|
|
|
using C but .... Send a broadcasted C version if |
|
280
|
|
|
|
|
|
|
you work it out! |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
Since we are using perl broadcasting here speed is not really great |
|
283
|
|
|
|
|
|
|
but it is just convenient to have a broadcasted version for many |
|
284
|
|
|
|
|
|
|
applications (no explicit for-loops required, etc). Suffers from |
|
285
|
|
|
|
|
|
|
some of the current limitations of perl level broadcasting. |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=cut |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
broadcast_define 'tlmfit(x(n);y(n);sigma(n);initp(m);iter();eps();[o] ym(n);[o] finalp(m)), |
|
291
|
|
|
|
|
|
|
NOtherPars => 1', |
|
292
|
|
|
|
|
|
|
over { |
|
293
|
|
|
|
|
|
|
$_[7] .= $_[3]; # copy our parameter guess into the output |
|
294
|
|
|
|
|
|
|
$_[6] .= PDL::lmfit $_[0],$_[1],$_[2],$_[8],$_[7],{Maxiter => $_[4], |
|
295
|
|
|
|
|
|
|
Eps => $_[5]}; |
|
296
|
|
|
|
|
|
|
}; |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
1; |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head1 BUGS |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
Not known yet. |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=head1 AUTHOR |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
This file copyright (C) 1999, Christian Soeller |
|
307
|
|
|
|
|
|
|
(c.soeller@auckland.ac.nz). All rights reserved. There is no |
|
308
|
|
|
|
|
|
|
warranty. You are allowed to redistribute this software documentation |
|
309
|
|
|
|
|
|
|
under certain conditions. For details, see the file COPYING in the PDL |
|
310
|
|
|
|
|
|
|
distribution. If this file is separated from the PDL distribution, the |
|
311
|
|
|
|
|
|
|
copyright notice should be included in the file. |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=cut |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# return true |
|
316
|
|
|
|
|
|
|
1; |