File Coverage

blib/lib/PDL/Fit/Levmar.pm
Criterion Covered Total %
statement 213 281 75.8
branch 104 156 66.6
condition 50 75 66.6
subroutine 17 20 85.0
pod 3 11 27.2
total 387 543 71.2


line stmt bran cond sub pod time code
1              
2             #
3             # GENERATED WITH PDL::PP! Don't modify!
4             #
5             package PDL::Fit::Levmar;
6              
7             @EXPORT_OK = qw( levmar levmar_report levmar_chkjac PDL::PP levmar_der_lb PDL::PP levmar_der_lb_ub PDL::PP levmar_der_ub PDL::PP levmar_der_ PDL::PP levmar_diff_lb PDL::PP levmar_diff_lb_ub PDL::PP levmar_diff_ub PDL::PP levmar_diff_ PDL::PP _levmar_chkjac PDL::PP _levmar_chkjac_no_t );
8             %EXPORT_TAGS = (Func=>[@EXPORT_OK]);
9              
10 7     7   1386890 use PDL::Core;
  7         29  
  7         35  
11 7     7   1426 use PDL::Exporter;
  7         11  
  7         31  
12 7     7   170 use DynaLoader;
  7         17  
  7         1332  
13              
14              
15              
16             $PDL::Fit::Levmar::VERSION = '0.0100';
17             @ISA = ( 'PDL::Exporter','DynaLoader' );
18             push @PDL::Core::PP, __PACKAGE__;
19             bootstrap PDL::Fit::Levmar $VERSION;
20              
21              
22              
23              
24             #use Data::Dumper;
25              
26             =head1 NAME
27              
28             PDL::Fit::Levmar - Levenberg-Marquardt fit/optimization routines
29              
30             =head1 DESCRIPTION
31              
32             Levenberg-Marquardt routines for least-squares fit to
33             functions non-linear in fit parameters.
34              
35             This module provides a L ( L ) interface to the non-linear fitting
36             library levmar 2.5 (written in C). Levmar is
37             L aware (in the L sense), provides support for analytic
38             or finite difference derivatives (in case no analytic
39             derivatives are supplied), L and/or L
40             and/or L
41             constraints (with L as a special
42             case) and pure single or double precision computation. The
43             routines are re-entrant, so they can be used in
44             multi-threaded applications (not tested!). Levmar is suited
45             both for data fitting and for optimization problems.
46              
47             The source code for the C levmar library is included in this
48             distribution. However, linearly-constrained fitting requires
49             that C be built with support for B
50             and B libraries. See the files F and
51             F, for more information. If
52             C is built without support for C,
53             the fitting options C, C, C, C, and C may
54             not be used. All other options, including C, do not
55             require C.
56              
57             User supplied fit functions can be written in perl code that
58             takes pdls as arguments, or, for efficiency, in in a simple
59             function description language (C), which is rapidly and
60             transparently translated to C, compiled, and dynamically
61             linked. Fit functions may also be written in pure C. If C
62             or C fit functions are used, the entire fitting
63             procedure is done in pure compiled C. The compilation and
64             linking is done only the first time the function is defined.
65              
66             There is a document distributed with this module
67             F<./doc/levmar.pdf> by the author of liblevmar describing
68             the fit algorithms. Additional information on liblevmar is available at
69             L
70              
71             Don't confuse this module with, but see also, L.
72              
73             =head1 SYNOPSIS
74              
75             use PDL::Fit::Levmar;
76             $result_hash = levmar($params,$x,$t, FUNC => '
77             function somename
78             x = p0 * exp(-t*t * p1);');
79             print levmar_report($result_hash);
80              
81              
82             =head1 EXAMPLES
83              
84              
85             A number of examples of invocations of C follow. The test
86             directory C<./t> in the module distribution contains many more examples.
87             The following seven examples are included as stand-alone scripts in the
88             ./examples/ directory. Some of the necessary lines are not repeated in
89             each example below.
90              
91             =over 3
92              
93             =item example--1
94              
95             In this example we fill co-ordinate $t and ordinate $x arrays
96             with 100 pairs of sample data. Then we call the fit routine
97             with initial guesses of the parameters.
98              
99             use PDL::LiteF;
100             use PDL::Fit::Levmar;
101             use PDL::NiceSlice;
102            
103             $n = 100;
104             $t = 10 * (sequence($n)/$n -1/2);
105             $x = 3 * exp(-$t*$t * .3 );
106             $p = pdl [ 1, 1 ]; # initial parameter guesses
107              
108             $h = levmar($p,$x,$t, FUNC =>
109             ' function
110             x = p0 * exp( -t*t * p1);
111             ');
112             print levmar_report($h);
113              
114             This example gives the output:
115              
116             Estimated parameters: [ 3 0.3]
117             Covariance:
118             [
119             [5.3772081e-25 7.1703376e-26]
120             [7.1703376e-26 2.8682471e-26]
121             ]
122              
123             ||e||_2 at initial parameters = 125.201
124             Errors at estimated parameters:
125             ||e||_2 = 8.03854e-22
126             ||J^T e||_inf = 2.69892e-05
127             ||Dp||_2 = 3.9274e-15
128             \mu/max[J^T J]_ii ] = 1.37223e-05
129             number of iterations = 15
130             reason for termination: = stopped by small ||e||_2
131             number of function evaluations = 20
132             number of jacobian evaluations = 2
133              
134             In the example above and all following examples, it is necessary
135             to include the three C statements at the top of the file.
136             The fit function in this example is in C code.
137             The parameter pdl $p is the input parameters (guesses)
138             levmar returns a hash with several elements including a
139             plain text report of the fit, which we chose to print.
140              
141             The interface is flexible-- we could have also called levmar like this
142              
143             $h = levmar($p,$x,$t, ' function
144             x = p0 * exp( -t*t * p1);
145             ');
146              
147             or like this
148              
149             $h = levmar(P =>$p, X => $x, T=> $t, FUNC => ' function
150             x = p0 * exp( -t*t * p1);
151             ');
152              
153             After the fit, the input parameters $p are left
154             unchanged. The output hash $h contains, among other things,
155             the optimized parameters in $h->{P}.
156              
157             =item example--2
158              
159             Next, we do the same fit, but with a perl/PDL fit function.
160              
161             $h = levmar($p,$x,$t, FUNC => sub {
162             my ($p,$x,$t) = @_;
163             my ($p0,$p1) = list $p;
164             $x .= $p0 * exp(-$t*$t * $p1);
165             });
166              
167             Using perl code (second example) results in slower execution
168             than using pure C (first example). How much slower depends
169             on the problem (see L below). See also the
170             section on L.
171              
172             =item example--3
173              
174             Next, we solve the same problem using a C fit routine.
175              
176             levmar($p,$x,$t, FUNC => '
177             #include
178             void gaussian(FLOAT *p, FLOAT *x, int m, int n, FLOAT *t)
179             {
180             int i;
181             for(i=0; i
182             x[i] = p[0] * exp( -t[i]*t[i] * p[1]);
183             }
184             ');
185              
186             The macro C is used rather than float or double because
187             the C code will be used for both single and double precision
188             routines. ( The code is automatically compiled twice; once
189             with C expanded to double and once expanded to float)
190             The correct version is used automatically depending on the
191             type of pdls you give levmar.
192              
193              
194             =item example--4
195              
196             We supply an analytic derivative ( analytic jacobian).
197              
198             $st = '
199             function
200             x = p0 * exp( -t*t * p1);
201              
202             jacobian
203             FLOAT ex, arg;
204             loop
205             arg = -t*t * p1;
206             ex = exp(arg);
207             d0 = ex;
208             d1 = -p0 * t*t * ex ;
209              
210             ';
211              
212             $h = levmar($p,$x,$t, FUNC => $st);
213              
214             If no jacobian function is supplied, levmar automatically
215             uses numeric difference derivatives. You can also explicitly
216             use numeric derivatives with the option C
217             C<< => 'numeric' >>.
218              
219             Note that the directives C and C begin
220             the function definitions. You can also supply a name if
221             you like, eg. C and C.
222              
223             In C, the co-ordinate data is always identified by 't', the
224             ordinate data by 'x' in the fit function and by 'dn', with n a
225             number, in the jacobian. The parameters are identified by
226             'p'. All other identifiers are pure C identifiers and
227             must be defined, as are C and C in the example.
228              
229             Referring to the example above, if the directive C appears
230             on a line by itself, code after it is wrapped in a loop over
231             the data; code before it is not. If C does not appear,
232             then all the code is wrapped in a loop. 'loop' must occur zero
233             or one times in each of the fit and jacobian definitions.
234             For some problems, you will not want a loop at all. In this
235             case the directive C is placed after the declarations.
236              
237             To see what C does, pass the option C C<< => 1 >> to levmar
238             and look at the C source file that is written.
239              
240             When defining the derivatives above (d0, d1) etc., you must
241             put the lines in the proper order ( eg, not d1,d0 ). (This
242             is for efficiency, see the generated C code.)
243              
244             One final note on this example-- we declared C and C to
245             be type C. Because they are temporary variables, we could
246             have hard coded them to double, in which case both the float
247             and double code versions would have used type double for them.
248             This is ok, because it doesn't cost any storage or cause
249             a memory fault because of incorrect pointer arithmetic.
250              
251              
252             =item example--5
253              
254             Here is an example from the liblevmar demo program that shows
255             one more bit of C syntax.
256              
257             $defst = "
258             function modros
259             noloop
260             x0 = 10 * (p1 -p0*p0);
261             x1 = 1.0 - p0;
262             x2 = 100;
263             jacobian jacmodros
264             noloop
265             d0[0] = -20 * p0;
266             d1[0] = 10;
267             d0[1] = -1;
268             d1[1] = 0;
269             d0[2] = 0;
270             d1[2] = 0;
271             ";
272             $p = pdl [-1.2, 1];
273             $x = pdl [0,0,0];
274             $h = levmar( $p,$x, FUNC => $defst );
275              
276             The directive C mentioned above has been used,
277             indicating that there are no implied loops in the
278             function. Note that this model function is designed only for
279             $x->nelem == 3. The additional syntax is in the
280             derivatives. Keeping in mind that there is no loop variable,
281             dq[r] means derivative w.r.t q evaluated at x[r]. (This is
282             translated by C to d[q+r*m], which is the index into a
283             1-d array.)
284              
285             =item example--6
286              
287             Here is an example that uses implicit threading. We create data
288             from a gaussian function with four different sets of parameters
289             and fit it all in one function call.
290              
291             $st = '
292             function
293             x = p0 * exp( -t*t * p1);
294             ';
295              
296             $n = 10;
297             $t = 10 * (sequence($n)/$n -1/2);
298             $x = zeroes($n,4);
299             map { $x(:,$_->[0]) .= $_->[1] * exp(-$t*$t * $_->[2] ) }
300             ( [0,3,.2], [1, 28, .1] , [2,2,.01], [3,3,.3] );
301             $p = [ 5, 1]; # initial guess
302             $h = levmar($p,$x,$t, FUNC => $st );
303             print $h->{P} . "\n";
304              
305             [
306             [ 3 0.2]
307             [ 28 0.1]
308             [ 2 0.01]
309             [ 3 0.3]
310             ]
311              
312              
313             =item example--7
314              
315             This example shows how to fit a bivariate Gaussian. Here
316             is the fit function.
317              
318             sub gauss2d {
319             my ($p,$xin,$t) = @_;
320             my ($p0,$p1,$p2) = list $p;
321             my $n = $t->nelem;
322             my $t1 = $t(:,*$n); # first coordinate
323             my $t2 = $t(*$n,:); # second coordinate
324             my $x = $xin->splitdim(0,$n);
325             $x .= $p0 * exp( -$p1*$t1*$t1 - $p2*$t2*$t2);
326             }
327              
328              
329             We would prefer a function that maps t(n,n) --> x(n,n) (with
330             p viewed as parameters.) But the levmar library expects one
331             dimensional x and t. So we design C to take
332             piddles with these dimensions: C, C,
333             C. For this example, we assume that both the co-ordinate
334             axes run over the same range, so we only need to pass n
335             values for t. The piddles t1 and t2 are (virtual) copies of
336             t with dummy dimensions inserted. Each represents
337             co-ordinate values along each of the two axes at each point
338             in the 2-d space, but independent of the position along the
339             other axis. For instance C and C
340             == t(j)>. We assume that the piddle xin is a flattened
341             version of the ordinate data, so we split the dimensions in
342             x. Then the entire bi-variate gaussian is calculated with
343             one line that operates on 2-d matrices. Now we create some
344             data,
345              
346             my $n = 101; # number of data points along each axis
347             my $scale = 3; # range of co-ordiate data
348             my $t = sequence($n); # co-ordinate data (used for both axes)
349             $t *= $scale/($n-1);
350             $t -= $scale/2; # rescale and shift.
351             my $x = zeroes($n,$n);
352             my $p = pdl [ .5,2,3]; # actual parameters
353             my $xlin = $x->clump(-1); # flatten the x data
354             gauss2d( $p, $xlin, $t->copy); # compute the bivariate gaussian data.
355              
356             Now x contains the ordinate data (so does xlin, but in a flattened shape.)
357             Finally, we fit the data with an incorrect set of initial parameters,
358              
359             my $p1 = pdl [ 1,1,1]; # not the parameters we used to make the data
360             my $h = levmar($p1,$xlin,$t,\&gauss2d);
361              
362             At this point C<$h->{P}> refers to the output parameter piddle C<[0.5, 2, 3]>.
363              
364             =back
365              
366             =head1 CONSTRAINTS
367              
368             Several of the options below are related to constraints. There are
369             three types: box, linear equation, and linear inequality. They may
370             be used in any combination. (But there is no testing if
371             there is a possible solution.) None or one or two of C and C may be
372             specified. None or both of C and C may be specified.
373             None or both of C and C may be specified.
374              
375             =head1 OPTIONS
376              
377             It is best to learn how to call levmar by looking at the
378             examples first, and looking at this section later.
379              
380             levmar() is called like this
381              
382             levmar($arg1, $arg2, ..., OPT1=>$val1, OPT2=>$val2, ...);
383             or this:
384             levmar($arg1, $arg2, ..., {OPT1=>$val1, OPT2=>$val2, ...});
385              
386             When calling levmar, the first 3 piddle arguments (or refs
387             to arrays), if present, are taken to be C<$p>,C<$x>, and C<$t>
388             (parameters, ordinate data, and co-ordinate data) in that
389             order. The first scalar value that can be interpreted as a
390             function will be. Everything else must be passed as an
391             option in a key-value pair. If you prefer, you can pass some
392             or all of C<$p,$x,$t> and the function as key-values in the
393             hash. Note that after the first key-value pair, you cannot
394             pass any more non-hash arguments. The following calls are equivalent
395             (where $func specifies the function as described in L ).
396              
397             levmar($p, $x, $t, $func);
398             levmar($func,$p, $x, $t);
399             levmar($p, $x, $t, FUNC=> $func);
400             levmar($p, $x, T=>$t, FUNC => $func);
401             levmar($p, X=>$x, T=>$t, FUNC => $func);
402             levmar(P=>$p, X=>$x, T=>$t, FUNC => $func);
403              
404             In the following, if the default value is not mentioned, it is undef.
405             C<$outh> refers to the output hash.
406              
407             Some of these options are actually options to Levmar::Func.
408             All options to Levmar::Func may by given in calls to levmar().
409              
410             =over 4
411              
412             =item FUNC
413              
414             This option is required (but it can be passed before the
415             options hash without the key C ) It can be
416             any of the following, which are auto-detected.
417              
418             a string containing lpp code
419             a string containing pure C code
420             the filename of a file containing lpp code (which must end in '.lpp' )
421             the filename of a file containing pure C code ( which must end in '.c' )
422             a reference to perl code
423             a reference to a previously created Levmar::Func object (which was
424             previously created via one of the preceeding methods.)
425              
426             If you are fitting a lot of data by doing many iterations over
427             a loop of perl code, it is by far most efficient to create a Func
428             object from C or lpp code and pass it to levmar. (Implicit threading
429             does not recompile code in any case.)
430              
431             You can also pass pure C code via the option CSRC.
432              
433             =item JFUNC
434              
435             This parameter is the jacobian as a ref to perl CODE. For
436             C and C code, the jacobian, if present, is always in the
437             same source file as the fit function; in this case, you
438             should leave C undefined. See L
439              
440             =item DERIVATIVE
441              
442             This takes the value 'numeric' or 'analytic'. If it is
443             set to 'analytic', but no analytic jacobian of the model
444             function is supplied, then the numeric algorithms will be used
445             anyway.
446              
447             =item NOCLEAN
448              
449             If defined (NOCLEAN => 1), files containing generated C
450             object and dynamic library code are not deleted. If not
451             defined, these files are deleted after they are no longer
452             needed. For the source and object (.c and .o) files, this
453             means immediately after the dynamic library (.so) is built.
454             The dynamic library file is deleted when the corresponding
455             Levmar::Func object is destroyed. (It could be deleted after
456             it is loaded, I suppose, and then be rebuilt if needed
457             again)
458              
459             =item FIX
460              
461             Example: Fix => [1,0,0,1,0].
462             This option takes a pdl (or array ref) of the same shape as
463             the parameters $p. Each element must have the value zero or
464             one. A zero corresponds to a free parameter and a one to a
465             fixed parameter. The best fit is found keeping the fixed
466             parameters at their input values and letting the free
467             parameters vary. This is implemented by using the linear
468             constraint option described below. Each element must be
469             either one or zero. This option currently cannot be
470             threaded. That is, if the array FIX has more than one
471             dimension you will not get correct results. Also, PDL will
472             not add dimension correctly if you pass additional
473             dimensions in other quantities. Threading will work if you
474             use linear contstraints directly via C and C.
475              
476             =item FIXB
477              
478             This option is almost the same as FIX. It takes the same
479             values with the same meanings. It fixes parameters at the value
480             of the input parameters, but uses
481             box constraints, i.e., UB and LB rather than linear
482             constraints A and B. You can specify all three of UB,LB, and FIXB.
483             In this case, first box constraints determined by UB and LB are applied
484             Then, for those elements of FIXB with value one, the corresponding
485             values of UB and LB are overridden.
486              
487             =item A
488              
489             Example: A =>pdl [ [1,0], [0,1] ] , B => pdl [ 1,2 ]
490              
491             Minimize with linear constraints $A x $p = $b. That is,
492             parameters $p are optimized over the subset of parameters
493             that solve the equation. The dimensions of the quantities
494             are A(k,m), b(m), p(m), where k is the number of
495             constraints. ( k <= m ). Note that $b is a vector (it has one
496             fewer dimensions than A), but the option key is a capital 'B'.
497              
498             =item B
499              
500             See C.
501              
502             =item UB
503              
504             Example: UB => [10,10,10], LB => [-10,0,-5].
505             Box constraints. These have the same shape as the parameter
506             pdl $p. The fit is done with ub forming upper bounds and lb
507             lower bounds on the parameter values. Use, for instance
508             PDL::Fit::Levmar::get_dbl_max() for parameters that you
509             don't want bounded. You can use either linear constraints or
510             box constraints, or both. That is, you may specify A, B, UB, and LB.
511              
512             =item LB
513              
514             See C.
515              
516              
517             =item WGHTS
518              
519             Penalty weights can be given optionally when box and linear equality
520             constraints are both passed to levmar. See the levmar documenation for
521             how to use this. Note that if C and D are used then the WGHTS must
522             not passed.
523              
524             =item C
525              
526             Example: C => [ [ -1, -2, -1, -1], [ -3, -1, -2, 1] ], D => [ -5, -0.4]
527             Linear inequality constraints. Minimize with constraints $C x $p >= $d.
528             The dimensions are C(k2,m), D(m), p(m).
529              
530             =item D
531              
532             See C
533              
534             =item P
535              
536             Keys P, X, and T can be used to send to the parameters, ordinates and coordinates.
537             Alternatively, you can send them as non-option arguments to levmar before
538             the option arguments.
539              
540             =item X
541              
542             See C

543              
544             =item T
545              
546             See C

547              
548             =item DIR
549              
550             The directory containing files created when compiling C
551             and C fit functions. This defaults to './tempcode'; The .c,
552             .o, and .so files will be written to this directory. This
553             option actually falls through to levmar_func. Such options
554             should be in separate section, or otherwise noted.
555              
556             =item GETOPTS
557              
558             If defined, return a ref to a hash containing the default
559             values of the parameters.
560              
561             =item WORK
562              
563             levmar() needs some storage for scratch space. Normally, you
564             are not concerned with this-- the storage is allocated and
565             deallocated automatically without you being aware. However
566             if you have very large data sets, and are doing several
567             fits, this allocation and deallocation may be time consuming
568             (the time required to allocate storage grows faster than
569             linearly with the amount of storage). If you are using
570             implicit threading, the storage is only allocated once
571             outside the threadloop even if you don't use this
572             option. However, you may want to do several fits on the perl
573             level and want to allocate the work space only once.
574              
575             If you set WORK to a null piddle (say $work) and keep the
576             reference and call levmar(), storage will be created before
577             the fit. If you continue to call levmar() with WORK =>
578             $work, no new storage will be created. In this example,
579              
580             sub somefitting {
581             my $work = PDL->null;
582             ...
583             while (1) {
584             my $h = levmar($p, ... ,WORK => $work);
585             ... change inputs based on results in $h
586             last if somecondition is true;
587             }
588             ...
589             }
590              
591             storage is created in the first call to C and is
592             destroyed upon leaving the subroutine C
593             (provided a reference to $work was not stored in some data
594             structure delclared in an block enclosing the subroutine.)
595              
596             The numeric-derivative algorithms require more storage than
597             the analytic-derivative algorithms. So if you create the
598             storage for $work on a call with DERIVATIVE=>'numeric' and
599             subsequently make a call with DERIVATIVE=>'analytic' you are
600             ok. But if you try it in the other order, you will get a
601             runtime error. You can also pass a pdl created elsewhere
602             with the correct type and enough or more than enough storage.
603              
604             There are several pdls used by levmar() that have a similar option.
605              
606             (see also in PDL::Indexing )
607              
608             =item COVAR
609              
610             Send a pdl reference for the output hash element COVAR. You may
611             want to test if this option is more efficient for
612             some problem. But unless the covariance matrix is very large,
613             it probably won't help much. On the other hand it almost certainly
614             won't make levmar() less efficient. See the section on WORK above.
615              
616             Note that levmar returns a piddle representing the covariance in
617             the output hash. This will be the the same piddle that you give
618             as input via this option. So, if you do the following,
619              
620             my $covar = PDL->null
621             my $h =levmar(...., COVAR => $covar);
622              
623             then $covar and $h->{COVAR} are references to the same
624             pdl. The storage for the pdl will not be destroyed until
625             both $covar and $h->{COVAR} become undefined. The option
626             C differs in this regard. That is, the piddle containing
627             the workspace is not returned in the hash.
628              
629             =item NOCOVAR
630              
631             If defined, no covariance matrix is computed.
632              
633             =item POUT
634              
635             Send a pdl reference for the output hash element P. Don't
636             confuse this with the option P which can be used to send the
637             initial guess for the parameters
638             (see C and C).
639              
640             =item INFO
641              
642             Send a pdl reference for the output hash element C.
643             (see C and C)
644              
645             =item RET
646              
647             Send a pdl reference for the output hash element C.
648             (see C and C)
649              
650              
651             =item MAXITS
652              
653             Maximum number of iterations to try before giving up. The default
654             is 100.
655              
656             =item MU
657              
658             The starting value of the parameter mu in the L-M algorithm.
659              
660             =item EPS1, EPS2, EPS3
661              
662             Stopping thresholds for C<||J^T e||_inf>, C<||Dp||_2> and
663             C<||e||_2>. (see the document levmar.pdf by the author of
664             liblevmar and distributed with this module) The algorithm
665             stops when the first threshold is reached (or C is reached). See
666             C for determining which threshold was reached.
667              
668             Here, C is a the vector of errors between the data and
669             the model function and C

is the vector of parameters.

670             S<||J^T e||_inf> is the gradient of C w.r.t C

671             at the current estimate of C

; C<||Dp||_2> is the amount

672             by which C

is currently being shifted at each iteration;

673             C<||e||_2> is a measure of the error between the model function
674             at the current estimate for C

and the data.

675              
676             =item DELTA
677              
678             This is a step size used in computing numeric derivatives. It is
679             not used if the analytic jacobian is used.
680              
681              
682             =item MKOBJ
683              
684             command to compile source into object code. This option is actually set in
685             the Levmar::Func object, but can be given in calls to levmar().
686             The default value is determined by the perl installation and can
687             be determined by examining the Levmar::Func object returned by
688             new or the output hash of a call to levmar. A typical value is
689             cc -c -O2 -fPIC -o %o %c
690              
691             =item MKSO
692              
693             command to convert object code to dynamic library code.
694             This option is actually set in the Levmar::Func object. A
695             typical default value is
696             cc -shared -L/usr/local/lib -fstack-protector %o -o %s
697              
698             =item CTOP
699              
700             The value of this string will be written at the top of the c code
701             written by Levmar::Func. This can be used to include headers and so forth.
702             This option is actually set in the Levmar::Func object. This code is also written
703             at the top of c code translated from lpp code.
704              
705              
706             =item FVERBOSE
707              
708             If true (eg 1) Print the compiling and linking commands to STDERR when compiling fit functions.
709             This option is actually passed to Levmar::Func. Default is 0.
710              
711             =item Default values
712              
713             Here are the default values
714             of some options
715              
716              
717             $Levmar_defaults = {
718             FUNC => undef, # Levmar::Func object, or function def, or ...
719             JFUNC => undef, # must be ref to perl sub
720             MAXITS => 100, # maximum iterations
721             MU => LM_INIT_MU, # These are described in levmar docs
722             EPS1 => LM_STOP_THRESH,
723             EPS2 => LM_STOP_THRESH,
724             EPS3 => LM_STOP_THRESH,
725             DELTA => LM_DIFF_DELTA,
726             DERIVATIVE => 'analytic',
727             FIX => undef,
728             A => undef,
729             B => undef,
730             C => undef,
731             D => undef,
732             UB = undef,
733             LB => undef,
734             X => undef,
735             P => undef,
736             T => undef,
737             WGHTS => undef,
738             # meant to be private
739             LFUNC => undef, # only Levmar::Func object, made from FUNC
740             };
741              
742             =back
743              
744              
745             =head1 OUTPUT
746              
747             This section describes the contents of the hash that
748             levmar takes as output. Do not confuse these hash keys with
749             the hash keys of the input options. It may be a good idea
750             to change the interface by prepending O to all of the output
751             keys that could be confused with options to levmar().
752              
753             =over 3
754              
755             =item P (output)
756              
757             pdl containing the optimized parameters. It has the same shape
758             as the input parameters.
759              
760             =item FUNC (output)
761              
762             ref to the Levmar::Func object. This object may have been created
763             during the call to levmar(). For instance, if you pass a string
764             contiaining an C definition, the compiled object (and associated
765             information) is contained in $outh->{FUNC}. Don't confuse this with
766             the input parameter of the same name.
767              
768             =item COVAR (output)
769              
770             a pdl representing covariance matrix.
771              
772             =item REASON
773              
774             an integer code representing the reason for terminating the
775             fit. (call levmar_report($outh) for an interpretation. The interpretations
776             are listed here as well (see the liblevmar documentation if you don't
777             find an explanation somewhere here.)
778              
779             1 stopped by small gradient J^T e
780             2 stopped by small Dp
781             3 stopped by itmax
782             4 singular matrix. Restart from current p with increased \mu
783             5 no further error reduction is possible. Restart with increased \mu
784             6 stopped by small ||e||_2
785              
786              
787             =item ERRI, ERR1, ERR2, ERR3, ERR4
788              
789             ERRI is C<||e||_2> at the initial paramters. ERR1 through
790             ERR3 are the actual values on termination of the quantities
791             corresponding to the thresholds EPS1 through EPS3 described
792             in the options section. ERR4 is C
793              
794             =item ITS
795              
796             Number of iterations performed
797              
798             =item NFUNC, NJAC, NLS
799              
800             Number of function evaluations, number of jacobian evaluations
801             and number of linear systems solved.
802              
803             =item INFO
804              
805             Array containing ERRI,ERR1, ..., ERR4, ITS, REASON, NFUNC, NJAC, NLS.
806              
807             =back
808              
809             =head1 FIT FUNCTIONS
810              
811             Fit functions, or model functions can be specified in the following
812             ways.
813              
814             =over 3
815              
816             =item lpp
817              
818             It is easier to learn to use C by reading the C section.
819              
820             C processes a function definition into C code. It writes
821             the opening and closing parts of the function, alters a
822             small number of identifiers if they appear, and wraps some
823             of the code in a loop. C recognizes four directives. They
824             must occur on a line with nothing else, not even comments.
825              
826             First, the directives are explained, then the substitutions.
827             The directive lines have a strict format. All other lines
828             can contain any C code including comments and B
829             macros. They will be written to a function in C after the
830             substitutions described below.
831              
832             =over 3
833              
834             =item C
835              
836             The first line of the fit function definition must be
837             C. The first line of the jacobian
838             definition, if the jacobian is to be defined, is C
839             funcname>. The function names can be any valid C function
840             name. The names may also be omitted as they are never needed
841             by the user. The names can be identical. (Note that a
842             numeric suffix will be automatically added to the function
843             name if the .so file already exists. This is because, if
844             another Func object has already loaded the shared library
845             from an .so file, dlopen will use this loaded library for
846             all C objects asking for that .so file, even if the
847             file has been overwritten, causing unexpected behavior)
848              
849             =item C
850              
851             The directive C says that all code before C is not
852             in the implicit loop, while all code following C is in
853             the implicit loop. If you omit the directive, then all the code
854             is wrapped in a loop.
855              
856             =item C
857              
858             The directive C says that there is no implicit loop anywhere
859             in the function.
860              
861             =item Out-of-loop substitutions
862              
863             These substitutions translate C to C in lines that occur
864             before the implied loop (or everywhere if there is no loop.)
865             In every case you can write the translated C code into your
866             function definition yourself and C will leave it
867             untouched.
868              
869             =over 3
870              
871             =item pq -> p[q]
872              
873             where q is a sequence of digits.
874              
875              
876             =item xq -> x[q]
877              
878             where q is a sequence of digits. This is applied only in the fit function,
879             not in the jacobian.
880              
881              
882             =item dq[r] -> d[q+m*r]
883              
884             (where m == $p->nelem), q and r are sequences of
885             digits. This applies only in the jacobian. You usually will
886             only use the fit functions with one value of m. It would
887             make faster code if you were to explicitly write, say C,
888             for each derivative at each point. Presumably there is a
889             small number of data points since this is outside a
890             loop. Some provisions should be added to C, say C to
891             hard code the value of C. But m is only explicitly used in
892             constructions involving this substitution.
893              
894              
895             =back
896              
897             =item In-loop substitutions
898              
899             These substitutions apply inside the implied loop. The loop variables are
900             i in the fit function and i and j in the jacobian.
901              
902             =over 3
903              
904             =item t -> t[i]
905              
906             (literal "i") You can also write t[i] or t[expression involving i] by hand.
907             Example: t*t -> t[i]*t[i].
908              
909              
910             =item pq -> p[q]
911              
912             where q is a sequence of digits. Example p3 -> p[3].
913              
914              
915             =item x -> x[i]
916              
917             only in fit function, not in jacobian.
918              
919              
920             =item (dr or dr[i]) -> d[j++]
921              
922             where r is a sequence of digits. Note that r and i are
923             ignored. So you are required to list the derivatives in
924             order. An example is
925              
926             d0 = t*t; // derivative w.r.t p[0] loop over all points
927             d1 = t;
928              
929             If you write C first and then C, lpp will incorrectly
930             assign the derivative functions.
931              
932             =back
933              
934              
935             =back
936              
937              
938              
939             =item C Code
940              
941             The jacobian name must start with 'jac' when a pure C function definition
942             is used. To see example of fit functions writen in C, call levmar
943             with lpp code and the option C. This will leave the C source
944             in the directory given by C. The C code you supply is mangled
945             slightly before passing it to the compiler: It is copied twice, with
946             FLOAT defined in one case as C and in the other as C.
947             The letter C is also appended to the function names in the latter
948             copy. The C code is parsed to find the fit function name and the
949             jacobian function name.
950              
951             We should make it possible to pass the function names as a separate option
952             rather than parsing the C code. This will allow auxiallary functions to
953             be defined in the C code; something that is currently not possible.
954              
955              
956             =item Perl_Subroutines
957              
958             This is how to use perl subroutines as fit functions... (see
959             the examples for now, e.g. L.) The
960             fit function takes piddles $p,$x, and $t, with dimensions
961             m,n, and tn. (often tn ==n ). These are references with
962             storage already allocated (by the user and liblevmar). So
963             you must use C<.=> when setting values. The jacobian takes
964             piddles $p,$d, and $t, where $d, the piddle of derivatives
965             has dimensions (m,n). For example
966              
967             $f = sub myexp {
968             my ($p,$x,$t) = @_;
969             my ($p0,$p1,$p2) = list($p);
970             $x .= exp($t/$p0);
971             $x *= $p1;
972             $x += $p2
973             }
974              
975             $jf = sub my expjac {
976             my ($p,$d,$t) = @_;
977             my ($p0,$p1,$p2) = list($p);
978             my $arg = $t/$p0;
979             my $ex = exp($arg);
980             $d((0)) .= -$p1*$ex*$arg/$p0;
981             $d((1)) .= $ex;
982             $d((2)) .= 1.0;
983             }
984              
985              
986              
987             =back
988              
989              
990             =head1 PDL::Fit::Levmar::Func Objects
991              
992             These objects are created every time you call levmar(). The hash
993             returned by levmar contains a ref to the Func object. For instance
994             if you do
995              
996             $outh = levmar( FUNC => ..., @opts);
997              
998             then $outh->{LFUNC} will contain a ref to the function object. The .so
999             file, if it exists, will not be deleted until the object is destroyed.
1000             This will happen, for instance if you do C<$outh = undef>.
1001              
1002              
1003             =head1 IMPLEMENTATION
1004              
1005             This section currently only refers to the interface and not the fit algorithms.
1006              
1007             =over 3
1008              
1009             =item C fit functions
1010              
1011             The module does not use perl interfaces to dlopen or the C
1012             compiler. The C compiler options are taken from
1013             %Config. This is mostly because I had already written those
1014             parts before I found the modules. I imagine the
1015             implementation here has less overhead, but is less portable.
1016              
1017              
1018             =item perl subroutine fit functions
1019              
1020             Null pdls are created in C code before the fit starts. They
1021             are passed in a struct to the C fit function and derivative
1022             routines that wrap the user's perl code. At each call the
1023             data pointers to the pdls are set to what liblevmar has sent
1024             to the fit functions. The pdls are deleted after the fit.
1025             Originally, all the information on the fit functions was
1026             supposed to be handled by Levmar::Func. But when I added
1027             perl subroutine support, it was less clumsy to move most of
1028             the code for perl subs to the Levmar module. So the current
1029             solution is not very clean.
1030              
1031             =item Efficiency
1032              
1033             Using C or C is faster than using perl subs, which is
1034             faster than using L, at least in all the tests I have
1035             done. For very large data sets, pure C was twice as fast as
1036             perl subs and three times as fast as Fit::LM. Some
1037             optimization problems have very small data sets and converge
1038             very slowly. As the data sets become smaller and the number
1039             of iterations increases the advantage of using pure C
1040             increases as expected. Also, if I fit a small data set
1041             (n=10) a large number of times (just looping over the same
1042             problem), Pure C is ten times faster than Fit::LM, while
1043             Levmar with perl subs is only about 1.15 times faster than
1044             Fit::LM. All of this was observed on only two different
1045             problems.
1046              
1047             =back
1048              
1049             =head1 FUNCTIONS
1050              
1051             =head2 levmar()
1052              
1053             =for ref
1054              
1055             Perform Levenberg-Marquardt non-linear least squares fit
1056             to data given a model function.
1057              
1058             =for usage
1059              
1060             use PDL::Fit::Levmar;
1061              
1062             $result_hash = levmar($p,$x,$t, FUNC => $func, %OPTIONS );
1063              
1064             $p is a pdl of input parameters
1065             $x is a pdl of ordinate data
1066             $t is an optional pdl of co-ordinate data
1067            
1068             levmar() is the main function in the Levmar package. See the
1069             PDL::Fit::Levmar for a complete description.
1070              
1071             =for signature
1072              
1073             p(m); x(n); t(nt); int itmax();
1074             [o] covar(m,m) ; int [o] returnval();
1075             [o] pout(m); [o] info(q=10);
1076              
1077             See the module documentation for information on passing
1078             these arguments to levmar. Threading is known to
1079             work with p(m) and x(n), but I have not tested the rest. In
1080             this case all of they output pdls get the correct number of
1081             dimensions (and correct values !). Notice that t(nt) has a
1082             different dimension than x(n). This is correct because in
1083             some problems there is no t at all, and in some it is
1084             pressed into the service of delivering other parameters to
1085             the fit routine. (Formally, even if you use t(n), they are
1086             parameters.)
1087              
1088              
1089             =head2 levmar_chkjac()
1090              
1091             =for ref
1092              
1093             Check the analytic jacobian of a function by computing
1094             the derivatives numerically.
1095              
1096             =for signature
1097            
1098             p(m); t(n); [o] err(n);
1099             This is the relevant part of the signature of the
1100             routine that does the work.
1101              
1102              
1103             =for usage
1104              
1105             use PDL::Fit::Levmar;
1106              
1107             $Gh = levmar_func(FUNC=>$Gf);
1108              
1109             $err = levmar_chkjac($Gh,$p,$t);
1110              
1111             $f is an object of type PDL::Fit::Levmar::Func
1112             $p is a pdl of input parameters
1113             $t is an pdl of co-ordinate data
1114             $err is a pdl of errors computed at the values $t.
1115              
1116             Note: No data $x is supplied to this function
1117              
1118             The Func object $Gh contains a function f, and a jacobian
1119             jf. The i_th element of $err measures the agreement between
1120             the numeric and analytic gradients of f with respect to $p
1121             at the i_th evaluation point f (normally determined by the
1122             i_th element of t). A value of 1 means that the analytic and
1123             numeric gradients agree well. A value of 0 mean they do not
1124             agree.
1125              
1126             Sometimes the number of evaluation points n is hardcoded
1127             into the function (as in almost all the examples taken from
1128             liblevmar and appearing in t/liblevmar.t. In this case the
1129             values that f returns depend only on $p and not on any other
1130             external data (nameley t). In this case, you must pass the
1131             number n as a perl scalar in place of t. For example
1132              
1133             $err = levmar_chkjac($Gh,$p,5);
1134              
1135              
1136             in the case that f is hardcoded to return five values.
1137              
1138             Need to put the description from the C code in here.
1139              
1140             =head2 levmar_report()
1141              
1142             =for ref
1143              
1144             Make a human readable report from the hash ref returned
1145             by lemvar().
1146              
1147             =for usage
1148              
1149             use PDL::Fit::Levmar;
1150              
1151             $h = levmar($p,$x,$t, $func);
1152              
1153             print levmar_report($h);
1154              
1155              
1156             =head1 BUGS
1157              
1158             With the levmar-2.5 code: Passing workspace currently does not work with
1159             linear inequality constraint. Some of the PDL threading no long works
1160             correctly. These are noted in the tests in t/thread.t. It is not clear
1161             if it is a threading issue or the fitting has changed.
1162              
1163            
1164             =cut
1165              
1166             #--------------------------------------------------------------------
1167             # Begining of module code
1168              
1169 7     7   40 use strict;
  7         7  
  7         160  
1170 7     7   3023 use PDL::Fit::Levmar::Func;
  7         20  
  7         44  
1171 7     7   832 use Carp;
  7         11  
  7         310  
1172 7     7   75 use PDL::NiceSlice;
  7         36  
  7         67  
1173 7     7   101230 use PDL::Core ':Internal'; # For topdl()
  7         12  
  7         52  
1174 7         18656 use vars ( '$Levmar_defaults', '$Levmar_defaults_order',
1175 7     7   793 '$Perl_func_wrapper', '$Perl_jac_wrapper', '$LPPEXT', '$DBLMAX' );
  7         13  
1176              
1177             # 'jac' refers to jacobian
1178             $Perl_func_wrapper = get_perl_func_wrapper();
1179             $Perl_jac_wrapper = get_perl_jac_wrapper();
1180             $DBLMAX = get_dbl_max();
1181              
1182             $LPPEXT = ".lpp";
1183              
1184              
1185 0     0 0 0 sub deb { print STDERR $_[0],"\n"}
1186              
1187              
1188              
1189             $PDL::Fit::Levmar::HAVE_LAPACK=0;
1190              
1191              
1192              
1193              
1194              
1195              
1196              
1197              
1198             # check if dims are equal in two pdls
1199             sub chk_eq_dims {
1200 0     0 0 0 my ($x,$y) = @_;
1201 0         0 my (@xd) = $x->dims();
1202 0         0 my (@yd) = $y->dims();
1203 0 0       0 return -2 if (scalar(@xd) != scalar(@yd) );
1204 0         0 my $ret = 1;
1205 0         0 foreach (@xd) {
1206 0 0       0 return -1 if ($_ != shift(@yd) );
1207             }
1208 0         0 return $ret;
1209             }
1210              
1211             @PDL::Fit::Levmar::reason_for_terminating = (
1212             '',
1213             'stopped by small gradient J^T e',
1214             'stopped by small Dp',
1215             'stopped by itmax',
1216             'singular matrix. Restart from current p with increased \mu',
1217             'no further error reduction is possible. Restart with increased \mu',
1218             'stopped by small ||e||_2'
1219             );
1220            
1221             sub levmar_report {
1222 8     8 1 1711 my $h = shift;
1223 8         49 make_report($h->{P},$h->{COVAR}, $h->{INFO});
1224             }
1225              
1226             # make a small report out of the results of the optimization
1227             sub make_report {
1228 8     8 0 31 my ($p,$covar,$info) = @_;
1229 8         51 my @ninf = list($info);
1230             # for(my $i=0;$i<9; $i++) { # Tried to get threading to work, but no!
1231             # $ninf[$i] = $info(($i));
1232             # }
1233 8         282 $ninf[6] =
1234             $PDL::Fit::Levmar::reason_for_terminating[$ninf[6]]; # replace int with string
1235 8         18 my $form = <<"EOFORM";
1236             Estimated parameters: %s
1237             Covariance: %s
1238             ||e||_2 at initial parameters = %g
1239             Errors at estimated parameters:
1240             ||e||_2\t = %g
1241             ||J^T e||_inf\t= %g
1242             ||Dp||_2\t= %g
1243             \\mu/max[J^T J]_ii ]\t= %g
1244             number of iterations\t= %d
1245             reason for termination: = %s
1246             number of function evaluations\t= %d
1247             number of jacobian evaluations\t= %d
1248             number of linear systems solved\t= %d
1249             EOFORM
1250 8         115 my $st = sprintf($form, $p,$covar,@ninf);
1251            
1252             }
1253              
1254             $Levmar_defaults_order = qw [
1255             FUNC
1256            
1257              
1258             ];
1259              
1260              
1261             $Levmar_defaults = {
1262             MAXITS => 100, # maximum iterations
1263             MU => LM_INIT_MU(),
1264             EPS1 => LM_STOP_THRESH(),
1265             EPS2 => LM_STOP_THRESH(),
1266             EPS3 => LM_STOP_THRESH(),
1267             DELTA => LM_DIFF_DELTA(),
1268             DERIVATIVE => 'analytic',
1269             NOCOVAR => undef,
1270             FIX => undef,
1271             FIXB => undef,
1272             A => undef,
1273             B => undef,
1274             C => undef,
1275             D => undef,
1276             UB => undef,
1277             LB => undef,
1278             FUNC => undef, # Levmar::Func object, or function def, or ...
1279             JFUNC => undef, # must be ref to perl sub
1280             X => undef,
1281             P => undef,
1282             T => undef,
1283             WGHTS => undef,
1284             COVAR => undef, # The next 5 params can be set to PDL->null
1285             WORK => undef, # work space
1286             POUT => undef, # ref for preallocated output parameters
1287             INFO => undef,
1288             RET => undef,
1289             # meant to be private
1290             LFUNC => undef, # only Levmar::Func object, made from FUNC
1291             };
1292              
1293             # This isn't meant to replace help. But for now its doing nothing.
1294             sub get_help_str {
1295 0     0 0 0 return '
1296             This is the help string for levmar.
1297              
1298             ';
1299             }
1300              
1301             #################################################################
1302             sub levmar {
1303 90     90 1 360545 my($p,$x,$t,$infunc);
1304 90         0 my $args;
1305             # get all args before the hash. p,x,t must come in that order
1306             # but (t), or (t and x), or (t,x,and p) can be in the hash
1307             # the function can be anywhere before the hash
1308 90         253 while (1) {
1309 176         481 $args = 0;
1310 176 100 66     1456 if ( (not defined $p ) and (ref($_[0]) eq 'PDL' or ref($_[0]) eq 'ARRAY')) {
      66        
1311 85         204 $p = shift ; $args++;
  85         213  
1312             }
1313 176 50       481 last if ( @_ == 0 );
1314 176 100 66     1168 if ( (not defined $x ) and (ref($_[0]) eq 'PDL' or ref($_[0]) eq 'ARRAY')) {
      66        
1315 77         184 $x = shift ; $args++;
  77         141  
1316             }
1317 176 50       494 last if ( @_ == 0 );
1318 176 100 66     998 if ( (not defined $t) and (ref($_[0]) eq 'PDL' or ref($_[0]) eq 'ARRAY')) {
      66        
1319 40         79 $t = shift ; $args++;
  40         104  
1320             }
1321 176 100       367 last if ( @_ == 0 );
1322 169 100 100     893 if ( not defined $infunc and ref($_[0]) =~ /Func|CODE/ ) {
1323 21         34 $infunc = shift; $args++;
  21         27  
1324             }
1325 169 100       393 last if ( @_ == 0 );
1326 166 100 66     1872 if ( (not defined $infunc) and
      66        
      66        
1327             ( not ref($_[0]) ) and ( $_[0] =~ /(\.c|$LPPEXT)$/o or $_[0] =~ /\n/ ) ) {
1328 8         23 $infunc = shift; $args++;
  8         14  
1329             }
1330 166 100 100     1459 last if ( @_ == 0 or $args == 0);
1331             }
1332 90         148 my $inh;
1333 90 100       368 $inh = shift if @_; # input parameter hash
1334 90 100       252 $inh = {} unless defined $inh;
1335 90 100       262 if(ref $inh ne 'HASH') { # turn list into anonymous hash
1336 79 50       480 $inh = defined $inh ? {$inh,@_} : {} ;
1337             }
1338 90 50       324 if( exists $inh->{HELP} ) {
1339 0         0 my $s = get_help_str();
1340 0         0 return $s;
1341             }
1342 90 100       335 if( exists $inh->{GETOPTS} ) {
1343 1         64 my %h = %$Levmar_defaults;
1344 1         10 return \%h;
1345             }
1346             # should already use a ref to string here
1347 89 100       283 $inh->{FUNC} = $infunc if defined $infunc;
1348             die "levmar: neither FUNC nor CSRC defined"
1349 89 50 66     439 unless defined $inh->{FUNC} or defined $inh->{CSRC};
1350              
1351              
1352              
1353            
1354 89         232 foreach (qw( A B C D FIX WGHT )) {
1355             barf "PDL::Fit::Levmar not built with lapack. Found parameter $_"
1356 534 50       1018 if exists $inh->{$_};
1357             }
1358            
1359              
1360              
1361            
1362             ######## Handle parameters
1363 89         158 my $h = {}; # parameter hash to be built from $inh and defaults
1364 89         151 my $funch = {}; # unrecognized parameter hash. This will be passed to Func.
1365 89         833 foreach ( keys %$Levmar_defaults ){ # copy defaults to final hash
1366 2492         3868 $h->{$_} = $Levmar_defaults->{$_};
1367             }
1368 89         550 foreach my $k (keys %$inh ) { # replace defaults with input params
1369 235 100       489 if ( exists $Levmar_defaults->{$k} ) {
1370 222         380 $h->{$k} = $inh->{$k};
1371             }
1372             else { # don't recognize, so pass to Func
1373 13         32 $funch->{$k} = $inh->{$k};
1374             }
1375             }
1376             ########## Set up input and output variables
1377              
1378             # These must come from parameters if not from the arg list
1379 89 100 66     703 $p = $h->{P} unless not defined $h->{P} and defined $p;
1380 89 100 66     468 $x = $h->{X} unless not defined $h->{X} and defined $p;
1381 89 100 66     451 $t = $h->{T} unless not defined $h->{T} and defined $p;
1382              
1383 89 100       370 $t = PDL->null unless defined $t; # sometimes $t not needed
1384              
1385 89 50       618 if ( not defined $p ) { # This looks like some kind of error thing that was
1386             # not implemented consistently
1387 0         0 my $st = "No parameter (P) pdl";
1388 0         0 warn $st;
1389 0         0 return {RET => -1, ERRS => [$st] };
1390             }
1391 89 50       202 if ( not defined $x ) {
1392 0         0 my $st = "No data (X) pdl";
1393 0         0 warn $st;
1394 0         0 return {RET => -1, ERRS => [$st] };
1395             }
1396              
1397             #-------------------------------------------------
1398             # Treat input and output piddles for pp_defs
1399 89         300 $x = topdl($x); # in case they are refs to arrays
1400 89         1478 $p = topdl($p);
1401 89         890 $t = topdl($t);
1402             ### output variables
1403 89         1030 my $pout;
1404             my $info;
1405 89         0 my $covar;
1406 89         0 my $ret;
1407 89         0 my $work;
1408 89         0 my $wghts;
1409              
1410             # should put this stuff in a loop
1411 89 100       218 $covar = $h->{COVAR} if defined $h->{COVAR};
1412 89 50       208 $pout = $h->{POUT} if defined $h->{POUT};
1413 89 50       224 $info = $h->{INFO} if defined $h->{INFO};
1414 89 50       303 $ret = $h->{RET} if defined $h->{RET};
1415 89 100       213 $work = $h->{WORK} if defined $h->{WORK};
1416 89 50       352 $wghts = $h->{WGHTS} if defined $h->{WGHTS};
1417              
1418             # If they are set here, then there will be no external ref.
1419 89 100       346 $covar = PDL->null unless defined $covar;
1420 89 50       1078 $pout = PDL->null unless defined $pout;
1421 89 50       925 $info = PDL->null unless defined $info;
1422 89 50       752 $ret = PDL->null unless defined $ret;
1423 89 100       822 $work = PDL->null unless defined $work;
1424 89 50       778 $wghts = PDL->null unless defined $wghts;
1425              
1426             # Input pdl contstructed in levmar
1427             # Currently, the elements are set from a hash; no convenient way to thread.
1428             # As an alternative, we could send them as a pdl, then we could thread them
1429 89         659 my $opts;
1430             # Careful about $m, it is used in construcing $A below (with fix). But this is
1431             # not correct when using implicit threading. Except threading may still be working.
1432             # Need to look into that.
1433 89         297 my $m = $p->nelem;
1434              
1435             #--------------------------------------------------------
1436             # Set up Func object
1437             #--------------------------------------------------------
1438 89 50       307 croak "No FUNC in options to levmar." unless exists $h->{FUNC};
1439 89 100 100     787 if ( ref($h->{FUNC}) =~ /CODE/ or
1440             not ref($h->{FUNC}) ) { # probably a string, convert to func object
1441 62         183 $funch->{FUNC} = $h->{FUNC};
1442 62         339 my @ret = PDL::Fit::Levmar::Func::levmar_func($funch);
1443 62 50       429 if ($ret[0] == -1 ) { # error in creating function
1444 0         0 shift(@ret);
1445             # deb "Error: " . join("\n",@ret); # can turn this off and on
1446 0         0 return {RET => -1, ERRS => [@ret] } ; # just return all the other messages.
1447             }
1448 62         320 $h->{LFUNC} = $ret[0];
1449             }
1450             else { # already a Func object
1451 27         68 $h->{LFUNC} = $h->{FUNC} ; # copy ref
1452 27         73 my @k = keys %$funch;
1453             # It would be good to check for valid options. But if a user switches from a
1454             # string to a Func oject in the call to levmar(), he may not delete the
1455             # other keys. Halting on an error would bit frustrating or puzzling.
1456             # Even a warning is perhaps too much
1457 27 50       82 if ( @k ) {
1458 0 0       0 my $s = ''; $s = 's' if @k>1;
  0         0  
1459 0         0 my $str = "Unrecognized or useless option$s to levmar: \n";
1460 0         0 foreach ( @k ) {
1461 0         0 $str .= " '$_' => '" . $funch->{$_} . "'\n" ;
1462             }
1463 0         0 warn $str ."";
1464             }
1465             }
1466             # C pointers to fit functions
1467             my ($funcn,$sfuncn,$jacn,$sjacn) = # single and double
1468 89         612 $h->{LFUNC}->get_fit_pointers();
1469 89         409 my $deriv = $h->{DERIVATIVE};
1470              
1471             # The DFP stuff is to wrap perl functions in C routines to pass to liblevmar.
1472             # It's probably cleaner to move most of this stuff into Levmar::Func
1473 89         170 my $DFP = 0; # routines check for $DFP == 0 to bypass perl wrapper
1474              
1475 89 100       342 if ( ref($h->{FUNC}) =~ /CODE/) { # setup perl wrapper stuff
1476 8         20 my $jfunc = 0;
1477 8         63 $DFP = DFP_create();
1478 8 100 66     74 if (defined $h->{JFUNC} and ref($h->{JFUNC}) =~ /CODE/) {
1479 6         18 $jfunc = $h->{JFUNC};
1480             }
1481 8 100 100     42 if ( $deriv eq 'analytic' and $jfunc == 0 ) {
1482             # warn "No jacobian function supplied, using numeric derivatives";
1483 2         4 $deriv = 'numeric';
1484 2         3 $h->{DERIVATIVE} = 'numeric';
1485             }
1486 8         35 DFP_set_perl_funcs($DFP, $h->{FUNC}, $h->{JFUNC});
1487 8         20 $funcn = $Perl_func_wrapper;
1488 8         12 $jacn = $Perl_jac_wrapper;
1489 8         9 $sfuncn = $Perl_func_wrapper; # Single and double can use same wrapper
1490 8         12 $sjacn = $Perl_jac_wrapper;
1491             }
1492              
1493             ############ Do a few sanity checks
1494              
1495 89 100       406 if ( $deriv eq 'analytic' ) {
    50          
1496 70 100 66     607 if (not defined $jacn or $jacn == 0 ) {
1497             # warn "No jacobian function supplied, using numeric derivatives";
1498 1         24 $deriv = 'numeric';
1499 1         15 $h->{DERIVATIVE} = 'numeric';
1500             }
1501             }
1502             elsif ( $deriv ne 'numeric' ) {
1503 0         0 croak "DERIVATIVE must be 'analytic' or 'numeric'";
1504             }
1505              
1506             # liblevmar uses 5 option for analytic and 6 for numeric.
1507             # We make an integer option array as well, for passing stuff , like maxits.
1508 89 100       292 if ($h->{DERIVATIVE} eq 'analytic') {
1509 69         964 $opts = pdl ($p->type, $h->{MU},$h->{EPS1},$h->{EPS2},$h->{EPS3});
1510             }
1511             else {
1512 20         358 $opts = pdl ($p->type,$h->{MU},$h->{EPS1},$h->{EPS2},$h->{EPS3},$h->{DELTA});
1513             }
1514 89         13186 my $iopts = pdl(long, $h->{MAXITS});
1515              
1516            
1517             ########### FIX holds some parameters constant using linear constraints.
1518             # It is a special case of more general constraints using A and b.
1519             # Notice that this fails if FIX has more than one dimension (ie, you are
1520             # threading. FIXB does the same but using box constraints.
1521              
1522 89 50       9540 if (defined $h->{FIX} ) {
    50          
1523 0         0 my $ip = topdl( $h->{FIX}); # take array ref or pdl
1524 0 0       0 if ( chk_eq_dims($ip,$p) < 0 ) {
1525 0         0 croak "p and FIX must have the same dimensions";
1526             }
1527 0         0 my $nc = $ip->sum; # number of fixed vars
1528 0 0       0 if ($nc > 0) {
1529 0         0 my $A = zeroes($p->type, $m,$nc);
1530 0         0 my $b = zeroes($p->type, $nc);
1531 0         0 my $j=0;
1532 0         0 for(my $i=0; $i<$m; $i++) {
1533 0 0       0 if ($ip->at($i) == 1) {
1534 0         0 $A($i,$j) .= 1;
1535 0         0 $b($j) .= $p->at($i);
1536 0         0 $j++;
1537             }
1538             }
1539 0         0 $h->{A} = $A;
1540 0         0 $h->{B} = $b;
1541             }
1542             }
1543             elsif ( defined $h->{FIXB} ) {
1544 0         0 my $f = topdl( $h->{FIXB}); # take array ref or pdl
1545 0 0       0 if ( chk_eq_dims($f,$p) < 0 ) {
1546 0         0 croak "p and FIX must have the same dimensions";
1547             }
1548 0 0       0 if ( not defined $h->{UB} ) {
1549 0         0 $h->{UB} = ones($p);
1550 0         0 $h->{UB} *= $DBLMAX;
1551             }
1552 0 0       0 if (not defined $h->{LB} ) {
1553 0         0 $h->{LB} = ones($p);
1554 0         0 $h->{LB} *= -$DBLMAX;
1555             }
1556 0         0 my $fi = PDL::Primitive::which($f == 1); # indices in p that we want to fix.
1557 0         0 $h->{UB}->flat->index($fi) .= $p->flat->index($fi);
1558 0         0 $h->{LB}->flat->index($fi) .= $p->flat->index($fi);
1559             # so ub and lb are now at maximum bounds where not fixed and at value of
1560             # p where fixed
1561             }
1562 89         370 my $want_covar = 1;
1563 89 50       292 if ( defined $h->{NOCOVAR} ) {
1564 0         0 $want_covar = 0;
1565             }
1566              
1567 89         691 my $errs = check_levmar_args($h);
1568 89 50       235 if ( @$errs > 0 ) {
1569             # print @$errs;
1570 0         0 return {RET => -1, ERRS => $errs };
1571             }
1572 89         329 my ($func_key, $arg_list) = build_constraint_arg_combination($h);
1573             # print "func key '$func_key'\n";
1574 89 50       325 if ( not defined $func_key ) {
1575 0         0 croak "Could not find function key";
1576             }
1577 89 50       298 if ( not exists $PDL::Fit::Levmar::PDL_Levmar_funcs{$func_key} ) {
1578 0         0 croak "Could not find function for key";
1579             }
1580 89         373 my $pdl_levmar_func = $PDL::Fit::Levmar::PDL_Levmar_funcs{$func_key};
1581             # print "func $pdl_levmar_func\n";
1582             # my $nargs = @$arg_list;
1583             # print "Got $nargs args\n";
1584 89         179 my @jacobians = ();
1585 89 100       269 if ( $h->{DERIVATIVE} eq 'analytic' ) {
1586 69         182 @jacobians = ( $jacn, $sjacn );
1587             }
1588 89         309583 &$pdl_levmar_func($p,$x,$t,@$arg_list,$iopts,$opts,$work,
1589             $covar, $ret, $pout, $info, $funcn, $sfuncn, @jacobians, $DFP, $want_covar);
1590              
1591 89 100       14425778 DFP_free($DFP) if $DFP;
1592              
1593             my $hout = {
1594             RET => $ret,
1595             COVAR => $covar,
1596             P => $pout,
1597             ERRI => $info((0)),
1598             ERR1 => $info((1)),
1599             ERR2 => $info((2)),
1600             ERR3 => $info((3)),
1601             ERR4 => $info((4)),
1602             ITS => $info((5)),
1603             REASON => $info((6)),
1604             NFUNC => $info((7)),
1605             NJAC => $info((8)),
1606             NLS => $info((9)),
1607             INFO => $info,
1608             FUNC => $h->{LFUNC},
1609 89         1316 };
1610 89         17809 return $hout;
1611            
1612             } # end levmar()
1613              
1614              
1615             sub PDL::Fit::Levmar::check_levmar_args {
1616 89     89 0 250 my ($h) = @_;
1617 89         1100 my @refargs = qw( LB UB A B C D );
1618 89         231 my @errs = ();
1619 89         382 foreach my $argname ( @refargs ) {
1620 534 100 66     2098 if ( exists $h->{$argname} and defined $h->{$argname} ) {
1621 28         124 my $arg = $h->{$argname};
1622 28 50       142 if ( not ref($arg) ) {
1623 0         0 push @errs, "$argname must be a pdl or ref to array.";
1624             }
1625             }
1626             }
1627 89         798 my @combs = ( [ 'A', 'B' ], [ 'C', 'D' ] );
1628 89         226 foreach my $comb (@combs ) {
1629 178         302 my $n = @$comb;
1630 178         310 my $nf = 0;
1631 178         271 foreach my $arg ( @$comb ) {
1632 356 50 33     1392 $nf++ if exists $h->{$arg} and defined $h->{$arg};
1633             }
1634 178 50 33     424 if ( $nf != 0 and $n != $nf ) {
1635 0         0 push @errs, 'none or all of ' . join(' and ',@$comb) . ' must be defined.';
1636             }
1637             }
1638 89         303 return \@errs;
1639             }
1640              
1641            
1642             # make a list of strings of names of constraint args that
1643             # have been passed.
1644             # hash is arg hash to top level call
1645             sub PDL::Fit::Levmar::build_constraint_arg_combination {
1646 89     89 0 189 my ($h) = @_;
1647 89         159 my @arg_comb = ();
1648 89         154 my @arg_list = ();
1649             # order is important in following
1650 89         567 my @possible_args = qw( LB UB A B C D );
1651 89         350 foreach ( @possible_args ) {
1652 534         1196 my $ucarg = $_;
1653             # $ucarg =~ tr/a-z/A-Z/; # should rewrite so that tr not needed
1654 534 100 66     1848 if ( exists $h->{$ucarg} and defined $h->{$ucarg} ) {
1655 28         64 push @arg_comb, $_;
1656 28         130 push @arg_list, topdl($h->{$ucarg});
1657             }
1658             }
1659 89         125 my $deriv_type;
1660 89 100       242 if ($h->{DERIVATIVE} eq 'analytic' ) {
1661 69         120 $deriv_type = 'DER';
1662             }
1663             else {
1664 20         111 $deriv_type = 'DIFF';
1665             }
1666 89 50 33     667 push @arg_list, topdl($h->{WGHTS}) if exists $h->{WGHTS} and defined $h->{WGHTS};
1667 89         361 my $fk = make_pdl_levmar_func_key(make_hash_key_from_arg_comb(\@arg_comb), $deriv_type);
1668 89         532 return ($fk,\@arg_list);
1669             }
1670              
1671             sub PDL::Fit::Levmar::make_hash_key_from_arg_comb {
1672 89     89 0 180 my ( $arg_comb ) = @_;
1673 89         630 return join( '_', @$arg_comb);
1674             }
1675              
1676              
1677             sub PDL::Fit::Levmar::make_pdl_levmar_func_key {
1678 89     89 0 255 my ($arg_str, $deriv_type) = @_;
1679 89         306 return $deriv_type . '_' . $arg_str;
1680             }
1681              
1682              
1683             %PDL::Fit::Levmar::PDL_Levmar_funcs = (
1684             DER_ => \&PDL::levmar_der_,
1685             DIFF_ => \&PDL::levmar_diff_,
1686             DER_LB_C_D => \&PDL::levmar_der_lb_C_d,
1687             DIFF_LB_C_D => \&PDL::levmar_diff_lb_C_d,
1688             DER_A_B => \&PDL::levmar_der_A_b,
1689             DIFF_A_B => \&PDL::levmar_diff_A_b,
1690             DER_UB_A_B => \&PDL::levmar_der_ub_A_b,
1691             DIFF_UB_A_B => \&PDL::levmar_diff_ub_A_b,
1692             DER_UB => \&PDL::levmar_der_ub,
1693             DIFF_UB => \&PDL::levmar_diff_ub,
1694             DER_A_B_C_D => \&PDL::levmar_der_A_b_C_d,
1695             DIFF_A_B_C_D => \&PDL::levmar_diff_A_b_C_d,
1696             DER_LB_UB_A_B_C_D => \&PDL::levmar_der_lb_ub_A_b_C_d,
1697             DIFF_LB_UB_A_B_C_D => \&PDL::levmar_diff_lb_ub_A_b_C_d,
1698             DER_LB => \&PDL::levmar_der_lb,
1699             DIFF_LB => \&PDL::levmar_diff_lb,
1700             DER_LB_A_B_C_D => \&PDL::levmar_der_lb_A_b_C_d,
1701             DIFF_LB_A_B_C_D => \&PDL::levmar_diff_lb_A_b_C_d,
1702             DER_UB_A_B_C_D => \&PDL::levmar_der_ub_A_b_C_d,
1703             DIFF_UB_A_B_C_D => \&PDL::levmar_diff_ub_A_b_C_d,
1704             DER_LB_UB => \&PDL::levmar_der_lb_ub,
1705             DIFF_LB_UB => \&PDL::levmar_diff_lb_ub,
1706             DER_LB_A_B => \&PDL::levmar_der_lb_A_b,
1707             DIFF_LB_A_B => \&PDL::levmar_diff_lb_A_b,
1708             DER_UB_C_D => \&PDL::levmar_der_ub_C_d,
1709             DIFF_UB_C_D => \&PDL::levmar_diff_ub_C_d,
1710             DER_LB_UB_A_B => \&PDL::levmar_der_lb_ub_A_b,
1711             DIFF_LB_UB_A_B => \&PDL::levmar_diff_lb_ub_A_b,
1712             DER_LB_UB_C_D => \&PDL::levmar_der_lb_ub_C_d,
1713             DIFF_LB_UB_C_D => \&PDL::levmar_diff_lb_ub_C_d,
1714             DER_C_D => \&PDL::levmar_der_C_d,
1715             DIFF_C_D => \&PDL::levmar_diff_C_d,
1716             );
1717              
1718              
1719              
1720              
1721             sub levmar_chkjac {
1722 4     4 1 815 my ($f,$p,$t) = @_;
1723 4         10 my $r = ref $f;
1724 4 50       15 if ( not $r =~ /Levmar::Func/ ) {
1725 0         0 warn "levmar_chkjac: not a Levmar::Func object ";
1726 0         0 return;
1727             }
1728 4         10 my $N;
1729 4 50       14 if ( not ref($t) =~ /PDL/ ) {
1730 0         0 $N = $t; # in case there is no t for this func
1731 0         0 $t = zeroes( $p->type, 1); just some pdl
  0         0  
1732             }
1733 4         5 my $DFP = 0;
1734 4         6 my ($funcn,$sfuncn,$jacn,$sjacn);
1735 4 100       12 if ( ref($f->{FUNC}) =~ /CODE/) { # setup perl wrapper stuff
1736 2         3 my $jfunc = 0;
1737 2         7 $DFP = DFP_create();
1738 2 50 33     27 if (not (defined $f->{JFUNC} and ref($f->{FUNC}) =~ /CODE/ ) ) {
1739 0         0 warn "levmar_chkjac: no perl code jacobian supplied in JFUNC.";
1740 0         0 return undef;
1741             }
1742 2         11 DFP_set_perl_funcs($DFP, $f->{FUNC}, $f->{JFUNC});
1743 2         4 $funcn = $Perl_func_wrapper;
1744 2         3 $jacn = $Perl_jac_wrapper;
1745 2         2 $sfuncn = $Perl_func_wrapper;
1746 2         3 $sjacn = $Perl_jac_wrapper;
1747             }
1748             else { # pointers to native c functions.
1749 2         7 ($funcn,$sfuncn,$jacn,$sjacn) =
1750             $f->get_fit_pointers();
1751             }
1752 4         6 my $err;
1753 4 50       12 if ( defined $N ) {
1754 0         0 $err = _levmar_chkjac_no_t($p,$funcn,$sfuncn,$jacn,$sjacn,$N,$DFP);
1755             }
1756             else {
1757 4         128 $err = _levmar_chkjac($p,$t,$funcn,$sfuncn,$jacn,$sjacn,$DFP);
1758             }
1759 4         681 DFP_free($DFP);
1760 4         14 return $err;
1761             }
1762              
1763              
1764              
1765              
1766              
1767             *levmar_der_lb = \&PDL::levmar_der_lb;
1768              
1769              
1770              
1771              
1772              
1773             *levmar_der_lb_ub = \&PDL::levmar_der_lb_ub;
1774              
1775              
1776              
1777              
1778              
1779             *levmar_der_ub = \&PDL::levmar_der_ub;
1780              
1781              
1782              
1783              
1784              
1785             *levmar_der_ = \&PDL::levmar_der_;
1786              
1787              
1788              
1789              
1790              
1791             *levmar_diff_lb = \&PDL::levmar_diff_lb;
1792              
1793              
1794              
1795              
1796              
1797             *levmar_diff_lb_ub = \&PDL::levmar_diff_lb_ub;
1798              
1799              
1800              
1801              
1802              
1803             *levmar_diff_ub = \&PDL::levmar_diff_ub;
1804              
1805              
1806              
1807              
1808              
1809             *levmar_diff_ = \&PDL::levmar_diff_;
1810              
1811              
1812              
1813              
1814              
1815             *_levmar_chkjac = \&PDL::_levmar_chkjac;
1816              
1817              
1818              
1819              
1820              
1821             *_levmar_chkjac_no_t = \&PDL::_levmar_chkjac_no_t;
1822              
1823              
1824              
1825             ;
1826              
1827              
1828              
1829             =head1 AUTHORS
1830              
1831             PDL code for Levmar Copyright (C) 2006 John Lapeyre. C
1832             library code Copyright (C) 2006 Manolis Lourakis, licensed
1833             here under the Gnu Public License.
1834              
1835             All rights reserved. There is no warranty. You are allowed
1836             to redistribute this software / documentation under certain
1837             conditions. For details, see the file COPYING in the PDL
1838             distribution. If this file is separated from the PDL
1839             distribution, the copyright notice should be included in the
1840             file.
1841              
1842             =cut
1843              
1844              
1845              
1846              
1847              
1848             # Exit with OK status
1849              
1850             1;
1851              
1852