FreeMat  4.2-Source
About: FreeMat is a free environment for rapid engineering and scientific prototyping and data processing (similar to MATLAB and GNU Octave). It provides visualization, image manipulation, and plotting as well as parallel programming.
  Fossies Dox: FreeMat-4.2-Source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

levmar.c
Go to the documentation of this file.
1 /* ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Matlab MEX file for the Levenberg - Marquardt minimization algorithm
4 // Copyright (C) 2007 Manolis Lourakis (lourakis at ics forth gr)
5 // Institute of Computer Science, Foundation for Research & Technology - Hellas
6 // Heraklion, Crete, Greece.
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <math.h>
24 #include <string.h>
25 #include <ctype.h>
26 
27 #include <lm.h>
28 
29 #include <mex.h>
30 
35 #ifndef HAVE_LAPACK
36 #ifdef _MSC_VER
37 #pragma message("LAPACK not available, certain functionalities cannot be compiled!")
38 #else
39 #warning LAPACK not available, certain functionalities cannot be compiled
40 #endif /* _MSC_VER */
41 #endif /* HAVE_LAPACK */
42 
43 #define __MAX__(A, B) ((A)>=(B)? (A) : (B))
44 
45 #define MIN_UNCONSTRAINED 0
46 #define MIN_CONSTRAINED_BC 1
47 #define MIN_CONSTRAINED_LEC 2
48 #define MIN_CONSTRAINED_BLEC 3
49 
50 struct mexdata {
51  /* matlab names of the fitting function & its Jacobian */
52  char *fname, *jacname;
53 
54  /* binary flags specifying if input p0 is a row or column vector */
55  int isrow_p0;
56 
57  /* rhs args to be passed to matlab. rhs[0] is reserved for
58  * passing the parameter vector. If present, problem-specific
59  * data are passed in rhs[1], rhs[2], etc
60  */
62  int nrhs; /* >= 1 */
63 };
64 
65 /* display printf-style error messages in matlab */
66 static void matlabFmtdErrMsgTxt(char *fmt, ...)
67 {
68 char buf[256];
69 va_list args;
70 
71  va_start(args, fmt);
72  vsprintf(buf, fmt, args);
73  va_end(args);
74 
76 }
77 
78 /* display printf-style warning messages in matlab */
79 static void matlabFmtdWarnMsgTxt(char *fmt, ...)
80 {
81 char buf[256];
82 va_list args;
83 
84  va_start(args, fmt);
85  vsprintf(buf, fmt, args);
86  va_end(args);
87 
89 }
90 
91 static void func(double *p, double *hx, int m, int n, void *adata)
92 {
93 mxArray *lhs[1];
94 double *mp, *mx;
95 register int i;
96 struct mexdata *dat=(struct mexdata *)adata;
97 
98  /* prepare to call matlab */
99  mp=mxGetPr(dat->rhs[0]);
100  for(i=0; i<m; ++i)
101  mp[i]=p[i];
102 
103  /* invoke matlab */
104  mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->fname);
105 
106  /* copy back results & cleanup */
107  mx=mxGetPr(lhs[0]);
108  for(i=0; i<n; ++i)
109  hx[i]=mx[i];
110 
111  /* delete the matrix created by matlab */
112  mxDestroyArray(lhs[0]);
113 }
114 
115 static void jacfunc(double *p, double *j, int m, int n, void *adata)
116 {
117 mxArray *lhs[1];
118 double *mp;
119 double *mj;
120 register int i, k;
121 struct mexdata *dat=(struct mexdata *)adata;
122 
123  /* prepare to call matlab */
124  mp=mxGetPr(dat->rhs[0]);
125  for(i=0; i<m; ++i)
126  mp[i]=p[i];
127 
128  /* invoke matlab */
129  mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->jacname);
130 
131  /* copy back results & cleanup. Note that the nxm Jacobian
132  * computed by matlab should be transposed so that
133  * levmar gets it in row major, as expected
134  */
135  mj=mxGetPr(lhs[0]);
136  for(i=0; i<n; ++i)
137  for(k=0; k<m; ++k)
138  j[i*m+k]=mj[i+k*n];
139 
140  /* delete the matrix created by matlab */
141  mxDestroyArray(lhs[0]);
142 }
143 
144 /* matlab matrices are in column-major, this routine converts them to row major for levmar */
145 static double *getTranspose(mxArray *Am)
146 {
147 int m, n;
148 double *At, *A;
149 register int i, j;
150 
151  m=mxGetM(Am);
152  n=mxGetN(Am);
153  A=mxGetPr(Am);
154  At=mxMalloc(m*n*sizeof(double));
155 
156  for(i=0; i<m; i++)
157  for(j=0; j<n; j++)
158  At[i*n+j]=A[i+j*m];
159 
160  return At;
161 }
162 
163 /* check the supplied matlab function and its Jacobian. Returns 1 on error, 0 otherwise */
164 static int checkFuncAndJacobian(double *p, int m, int n, int havejac, struct mexdata *dat)
165 {
166 mxArray *lhs[1];
167 register int i;
168 int ret=0;
169 double *mp;
170 
171  mexSetTrapFlag(1); /* handle errors in the MEX-file */
172 
173  mp=mxGetPr(dat->rhs[0]);
174  for(i=0; i<m; ++i)
175  mp[i]=p[i];
176 
177  /* attempt to call the supplied func */
178  i=mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->fname);
179  if(i){
180  fprintf(stderr, "levmar: error calling '%s'.\n", dat->fname);
181  ret=1;
182  }
183  else if(!mxIsDouble(lhs[0]) || mxIsComplex(lhs[0]) || !(mxGetM(lhs[0])==1 || mxGetN(lhs[0])==1) ||
184  __MAX__(mxGetM(lhs[0]), mxGetN(lhs[0]))!=n){
185  fprintf(stderr, "levmar: '%s' should produce a real vector with %d elements (got %d).\n",
186  dat->fname, m, __MAX__(mxGetM(lhs[0]), mxGetN(lhs[0])));
187  ret=1;
188  }
189  /* delete the matrix created by matlab */
190  mxDestroyArray(lhs[0]);
191 
192  if(havejac){
193  /* attempt to call the supplied jac */
194  i=mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->jacname);
195  if(i){
196  fprintf(stderr, "levmar: error calling '%s'.\n", dat->jacname);
197  ret=1;
198  }
199  else if(!mxIsDouble(lhs[0]) || mxIsComplex(lhs[0]) || mxGetM(lhs[0])!=n || mxGetN(lhs[0])!=m){
200  fprintf(stderr, "levmar: '%s' should produce a real %dx%d matrix (got %dx%d).\n",
201  dat->jacname, n, m, mxGetM(lhs[0]), mxGetN(lhs[0]));
202  ret=1;
203  }
204  else if(mxIsSparse(lhs[0])){
205  fprintf(stderr, "levmar: '%s' should produce a real dense matrix (got a sparse one).\n", dat->jacname);
206  ret=1;
207  }
208  /* delete the matrix created by matlab */
209  mxDestroyArray(lhs[0]);
210  }
211 
212  mexSetTrapFlag(0); /* on error terminate the MEX-file and return control to the MATLAB prompt */
213 
214  return ret;
215 }
216 
217 
218 /*
219 [ret, p, info, covar]=levmar_der (f, j, p0, x, itmax, opts, 'unc' ...)
220 [ret, p, info, covar]=levmar_bc (f, j, p0, x, itmax, opts, 'bc', lb, ub, ...)
221 [ret, p, info, covar]=levmar_lec (f, j, p0, x, itmax, opts, 'lec', A, b, ...)
222 [ret, p, info, covar]=levmar_blec(f, j, p0, x, itmax, opts, 'blec', lb, ub, A, b, wghts, ...)
223 */
224 
225 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *Prhs[])
226 {
227 register int i;
228 register double *pdbl;
229 mxArray **prhs=(mxArray **)&Prhs[0], *At;
230 struct mexdata mdata;
231 int len, status;
232 double *p, *p0, *ret, *x;
233 int m, n, havejac, Arows, itmax, nopts, mintype, nextra;
235 double info[LM_INFO_SZ];
236 double *lb=NULL, *ub=NULL, *A=NULL, *b=NULL, *wghts=NULL, *covar=NULL;
237 
238  /* parse input args; start by checking their number */
239  if((nrhs<5))
240  matlabFmtdErrMsgTxt("levmar: at least 5 input arguments required (got %d).", nrhs);
241  if(nlhs>4)
242  matlabFmtdErrMsgTxt("levmar: too many output arguments (max. 4, got %d).", nlhs);
243  else if(nlhs<2)
244  matlabFmtdErrMsgTxt("levmar: too few output arguments (min. 2, got %d).", nlhs);
245 
246  /* note that in order to accommodate optional args, prhs & nrhs are adjusted accordingly below */
247 
249  /* first argument must be a string , i.e. a char row vector */
250  if(mxIsChar(prhs[0])!=1)
251  mexErrMsgTxt("levmar: first argument must be a string.");
252  if(mxGetM(prhs[0])!=1)
253  mexErrMsgTxt("levmar: first argument must be a string (i.e. char row vector).");
254  /* store supplied name */
255  len=mxGetN(prhs[0])+1;
256  mdata.fname=mxCalloc(len, sizeof(char));
257  status=mxGetString(prhs[0], mdata.fname, len);
258  if(status!=0)
259  mexErrMsgTxt("levmar: not enough space. String is truncated.");
260 
262  /* check whether second argument is a string */
263  if(mxIsChar(prhs[1])==1){
264  if(mxGetM(prhs[1])!=1)
265  mexErrMsgTxt("levmar: second argument must be a string (i.e. row vector).");
266  /* store supplied name */
267  len=mxGetN(prhs[1])+1;
268  mdata.jacname=mxCalloc(len, sizeof(char));
269  status=mxGetString(prhs[1], mdata.jacname, len);
270  if(status!=0)
271  mexErrMsgTxt("levmar: not enough space. String is truncated.");
272  havejac=1;
273 
274  ++prhs;
275  --nrhs;
276  }
277  else{
278  mdata.jacname=NULL;
279  havejac=0;
280  }
281 
282 #ifdef DEBUG
283  fflush(stderr);
284  fprintf(stderr, "LEVMAR: %s analytic Jacobian\n", havejac? "with" : "no");
285 #endif /* DEBUG */
286 
287 /* CHECK
288 if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 && mxGetN(prhs[1])==1))
289 */
290 
292  /* the second required argument must be a real row or column vector */
293  if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 || mxGetN(prhs[1])==1))
294  mexErrMsgTxt("levmar: p0 must be a real vector.");
295  p0=mxGetPr(prhs[1]);
296  /* determine if we have a row or column vector and retrieve its
297  * size, i.e. the number of parameters
298  */
299  if(mxGetM(prhs[1])==1){
300  m=mxGetN(prhs[1]);
301  mdata.isrow_p0=1;
302  }
303  else{
304  m=mxGetM(prhs[1]);
305  mdata.isrow_p0=0;
306  }
307  /* copy input parameter vector to avoid destroying it */
308  p=mxMalloc(m*sizeof(double));
309  for(i=0; i<m; ++i)
310  p[i]=p0[i];
311 
313  /* the third required argument must be a real row or column vector */
314  if(!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || !(mxGetM(prhs[2])==1 || mxGetN(prhs[2])==1))
315  mexErrMsgTxt("levmar: x must be a real vector.");
316  x=mxGetPr(prhs[2]);
317  n=__MAX__(mxGetM(prhs[2]), mxGetN(prhs[2]));
318 
320  /* the fourth required argument must be a scalar */
321  if(!mxIsDouble(prhs[3]) || mxIsComplex(prhs[3]) || mxGetM(prhs[3])!=1 || mxGetN(prhs[3])!=1)
322  mexErrMsgTxt("levmar: itmax must be a scalar.");
323  itmax=(int)mxGetScalar(prhs[3]);
324 
326  /* the fifth required argument must be a real row or column vector */
327  if(!mxIsDouble(prhs[4]) || mxIsComplex(prhs[4]) || (!(mxGetM(prhs[4])==1 || mxGetN(prhs[4])==1) &&
328  !(mxGetM(prhs[4])==0 && mxGetN(prhs[4])==0)))
329  mexErrMsgTxt("levmar: opts must be a real vector.");
330  pdbl=mxGetPr(prhs[4]);
331  nopts=__MAX__(mxGetM(prhs[4]), mxGetN(prhs[4]));
332  if(nopts!=0){ /* if opts==[], nothing needs to be done and the defaults are used */
333  if(nopts>LM_OPTS_SZ)
334  matlabFmtdErrMsgTxt("levmar: opts must have at most %d elements, got %d.", LM_OPTS_SZ, nopts);
335  else if(nopts<((havejac)? LM_OPTS_SZ-1 : LM_OPTS_SZ))
336  matlabFmtdWarnMsgTxt("levmar: only the %d first elements of opts specified, remaining set to defaults.", nopts);
337  for(i=0; i<nopts; ++i)
338  opts[i]=pdbl[i];
339  }
340 #ifdef DEBUG
341  else{
342  fflush(stderr);
343  fprintf(stderr, "LEVMAR: empty options vector, using defaults\n");
344  }
345 #endif /* DEBUG */
346 
348  /* check whether sixth argument is a string */
349  if(nrhs>=6 && mxIsChar(prhs[5])==1 && mxGetM(prhs[5])==1){
350  char *minhowto;
351 
352  /* examine supplied name */
353  len=mxGetN(prhs[5])+1;
354  minhowto=mxCalloc(len, sizeof(char));
355  status=mxGetString(prhs[5], minhowto, len);
356  if(status!=0)
357  mexErrMsgTxt("levmar: not enough space. String is truncated.");
358 
359  for(i=0; minhowto[i]; ++i)
360  minhowto[i]=tolower(minhowto[i]);
361  if(!strncmp(minhowto, "unc", 3)) mintype=MIN_UNCONSTRAINED;
362  else if(!strncmp(minhowto, "bc", 2)) mintype=MIN_CONSTRAINED_BC;
363  else if(!strncmp(minhowto, "lec", 3)) mintype=MIN_CONSTRAINED_LEC;
364  else if(!strncmp(minhowto, "blec", 4)) mintype=MIN_CONSTRAINED_BLEC;
365  else matlabFmtdErrMsgTxt("levmar: unknown minimization type '%s'.", minhowto);
366 
367  mxFree(minhowto);
368 
369  ++prhs;
370  --nrhs;
371  }
372  else
373  mintype=MIN_UNCONSTRAINED;
374 
375  if(mintype==MIN_UNCONSTRAINED) goto extraargs;
376 
377  /* arguments below this point are optional and their presence depends
378  * upon the minimization type determined above
379  */
381  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_BC || mintype==MIN_CONSTRAINED_BLEC)){
382  /* check if the next two arguments are real row or column vectors */
383  if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
384  if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
385  if((i=__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5])))!=m)
386  matlabFmtdErrMsgTxt("levmar: lb must have %d elements, got %d.", m, i);
387  if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=m)
388  matlabFmtdErrMsgTxt("levmar: ub must have %d elements, got %d.", m, i);
389 
390  lb=mxGetPr(prhs[5]);
391  ub=mxGetPr(prhs[6]);
392 
393  prhs+=2;
394  nrhs-=2;
395  }
396  }
397  }
398 
400  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_LEC || mintype==MIN_CONSTRAINED_BLEC)){
401  /* check if the next two arguments are a real matrix and a real row or column vector */
402  if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && mxGetM(prhs[5])>=1 && mxGetN(prhs[5])>=1){
403  if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
404  if((i=mxGetN(prhs[5]))!=m)
405  matlabFmtdErrMsgTxt("levmar: A must have %d columns, got %d.", m, i);
406  if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=(Arows=mxGetM(prhs[5])))
407  matlabFmtdErrMsgTxt("levmar: b must have %d elements, got %d.", Arows, i);
408 
409  At=prhs[5];
410  b=mxGetPr(prhs[6]);
411  A=getTranspose(At);
412 
413  prhs+=2;
414  nrhs-=2;
415  }
416  }
417  }
418 
419  /* wghts */
420  /* check if we have a weights vector */
421  if(nrhs>=6 && mintype==MIN_CONSTRAINED_BLEC){ /* only check if we have seen both box & linear constraints */
422  if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
423  if(__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5]))==m){
424  wghts=mxGetPr(prhs[5]);
425 
426  ++prhs;
427  --nrhs;
428  }
429  }
430  }
431  /* arguments below this point are assumed to be extra arguments passed
432  * to every invocation of the fitting function and its Jacobian
433  */
434 
435 extraargs:
436  /* handle any extra args and allocate memory for
437  * passing the current parameter estimate to matlab
438  */
439  nextra=nrhs-5;
440  mdata.nrhs=nextra+1;
441  mdata.rhs=(mxArray **)mxMalloc(mdata.nrhs*sizeof(mxArray *));
442  for(i=0; i<nextra; ++i)
443  mdata.rhs[i+1]=(mxArray *)prhs[nrhs-nextra+i]; /* discard 'const' modifier */
444 #ifdef DEBUG
445  fflush(stderr);
446  fprintf(stderr, "LEVMAR: %d extra args\n", nextra);
447 #endif /* DEBUG */
448 
449  if(mdata.isrow_p0){ /* row vector */
450  mdata.rhs[0]=mxCreateDoubleMatrix(1, m, mxREAL);
451  /*
452  mxSetM(mdata.rhs[0], 1);
453  mxSetN(mdata.rhs[0], m);
454  */
455  }
456  else{ /* column vector */
457  mdata.rhs[0]=mxCreateDoubleMatrix(m, 1, mxREAL);
458  /*
459  mxSetM(mdata.rhs[0], m);
460  mxSetN(mdata.rhs[0], 1);
461  */
462  }
463 
464  /* ensure that the supplied function & Jacobian are as expected */
465  if(checkFuncAndJacobian(p, m, n, havejac, &mdata)){
467  goto cleanup;
468  }
469 
470  if(nlhs>3) /* covariance output required */
471  covar=mxMalloc(m*m*sizeof(double));
472 
473  /* invoke levmar */
474  if(!lb && !ub){
475  if(!A && !b){ /* no constraints */
476  if(havejac)
477  status=dlevmar_der(func, jacfunc, p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
478  else
479  status=dlevmar_dif(func, p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
480 #ifdef DEBUG
481  fflush(stderr);
482  fprintf(stderr, "LEVMAR: calling dlevmar_der()/dlevmar_dif()\n");
483 #endif /* DEBUG */
484  }
485  else{ /* linear constraints */
486 #ifdef HAVE_LAPACK
487  if(havejac)
488  status=dlevmar_lec_der(func, jacfunc, p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
489  else
490  status=dlevmar_lec_dif(func, p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
491 #else
492  mexErrMsgTxt("levmar: no linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
493 #endif /* HAVE_LAPACK */
494 
495 #ifdef DEBUG
496  fflush(stderr);
497  fprintf(stderr, "LEVMAR: calling dlevmar_lec_der()/dlevmar_lec_dif()\n");
498 #endif /* DEBUG */
499  }
500  }
501  else{
502  if(!A && !b){ /* box constraints */
503  if(havejac)
504  status=dlevmar_bc_der(func, jacfunc, p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
505  else
506  status=dlevmar_bc_dif(func, p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
507 #ifdef DEBUG
508  fflush(stderr);
509  fprintf(stderr, "LEVMAR: calling dlevmar_bc_der()/dlevmar_bc_dif()\n");
510 #endif /* DEBUG */
511  }
512  else{ /* box & linear constraints */
513 #ifdef HAVE_LAPACK
514  if(havejac)
515  status=dlevmar_blec_der(func, jacfunc, p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
516  else
517  status=dlevmar_blec_dif(func, p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
518 #else
519  mexErrMsgTxt("levmar: no box & linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
520 #endif /* HAVE_LAPACK */
521 
522 #ifdef DEBUG
523  fflush(stderr);
524  fprintf(stderr, "LEVMAR: calling dlevmar_blec_der()/dlevmar_blec_dif()\n");
525 #endif /* DEBUG */
526  }
527  }
528 #ifdef DEBUG
529  fflush(stderr);
530  printf("LEVMAR: minimization returned %d in %g iter, reason %g\n\tSolution: ", status, info[5], info[6]);
531  for(i=0; i<m; ++i)
532  printf("%.7g ", p[i]);
533  printf("\n\n\tMinimization info:\n\t");
534  for(i=0; i<LM_INFO_SZ; ++i)
535  printf("%g ", info[i]);
536  printf("\n");
537 #endif /* DEBUG */
538 
539  /* copy back return results */
541  plhs[0]=mxCreateDoubleMatrix(1, 1, mxREAL);
542  ret=mxGetPr(plhs[0]);
543  ret[0]=(double)status;
544 
546  plhs[1]=(mdata.isrow_p0==1)? mxCreateDoubleMatrix(1, m, mxREAL) : mxCreateDoubleMatrix(m, 1, mxREAL);
547  pdbl=mxGetPr(plhs[1]);
548  for(i=0; i<m; ++i)
549  pdbl[i]=p[i];
550 
552  if(nlhs>2){
554  pdbl=mxGetPr(plhs[2]);
555  for(i=0; i<LM_INFO_SZ; ++i)
556  pdbl[i]=info[i];
557  }
558 
560  if(nlhs>3){
561  plhs[3]=mxCreateDoubleMatrix(m, m, mxREAL);
562  pdbl=mxGetPr(plhs[3]);
563  for(i=0; i<m*m; ++i) /* covariance matrices are symmetric, thus no need to transpose! */
564  pdbl[i]=covar[i];
565  }
566 
567 cleanup:
568  /* cleanup */
569  mxDestroyArray(mdata.rhs[0]);
570  if(A) mxFree(A);
571 
572  mxFree(mdata.fname);
573  if(havejac) mxFree(mdata.jacname);
574  mxFree(p);
575  mxFree(mdata.rhs);
576  if(covar) mxFree(covar);
577 
578  if(status==LM_ERROR)
579  mexWarnMsgTxt("levmar: optimization returned with an error!");
580 }
#define MIN_CONSTRAINED_BLEC
Definition: levmar.c:48
int isrow_p0
Definition: levmar.c:55
char * jacname
Definition: levmar.c:52
double mxGetScalar(const mxArray *array_ptr)
Definition: mxArray.cpp:401
#define LM_INIT_MU
Definition: lm.h:84
b
Definition: chain1.m:3
Definition: mex.h:62
printf('Function has been called %d times\n', ccount)
void mexErrMsgTxt(const char *error_msg)
Definition: mxArray.cpp:695
static void func(double *p, double *hx, int m, int n, void *adata)
Definition: levmar.c:91
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
mxArray ** rhs
Definition: levmar.c:61
static void jacfunc(double *p, double *j, int m, int n, void *adata)
Definition: levmar.c:115
int dlevmar_lec_dif(void(*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
int dlevmar_bc_dif(void(*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
bool mxIsDouble(const mxArray *array_ptr)
Definition: mxArray.cpp:497
voidpf void * buf
Definition: ioapi.h:39
#define MIN_UNCONSTRAINED
Definition: levmar.c:45
mxArray * mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)
Definition: mxArray.cpp:202
default args
Definition: inline.m:11
int dlevmar_dif(void(*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
void mexSetTrapFlag(int trap_flag)
static double * getTranspose(mxArray *Am)
Definition: levmar.c:145
static int checkFuncAndJacobian(double *p, int m, int n, int havejac, struct mexdata *dat)
Definition: levmar.c:164
int mxGetN(const mxArray *array_ptr)
Definition: mxArray.cpp:373
int dlevmar_blec_der(void(*func)(double *p, double *hx, int m, int n, void *adata), void(*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
int nrhs
Definition: levmar.c:62
static void matlabFmtdWarnMsgTxt(char *fmt,...)
Definition: levmar.c:79
Definition: levmar.c:50
#define LM_DIFF_DELTA
Definition: lm.h:86
fprintf(fp, 'a line of text\n')
Definition: mex.h:58
id p0()
#define MIN_CONSTRAINED_LEC
Definition: levmar.c:47
n
Definition: evenoddtest.m:8
#define LM_INFO_SZ
Definition: lm.h:82
void mexWarnMsgTxt(const char *warning_msg)
#define __MAX__(A, B)
Definition: levmar.c:43
function ret
Definition: return_func.m:1
else len
Definition: length.m:10
#define LM_ERROR
Definition: lm.h:83
strncmp(x1, x2, 4) strncmp(x1
ub
Definition: lmdemo.m:65
int dlevmar_der(void(*func)(double *p, double *hx, int m, int n, void *adata), void(*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
void * mxMalloc(size_t n)
Definition: mxArray.cpp:624
end Read the fmt block fmt
Definition: wavread.m:74
adata
Definition: lmdemo.m:47
int dlevmar_blec_dif(void(*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
void * mxCalloc(size_t n, size_t size)
Definition: mxArray.cpp:159
#define MIN_CONSTRAINED_BC
Definition: levmar.c:46
int dlevmar_bc_der(void(*func)(double *p, double *hx, int m, int n, void *adata), void(*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
#define LM_STOP_THRESH
Definition: lm.h:85
#define LM_OPTS_SZ
Definition: lm.h:81
bool mxIsSparse(const mxArray *array_ptr)
Definition: mxArray.cpp:600
static void matlabFmtdErrMsgTxt(char *fmt,...)
Definition: levmar.c:66
double * mxGetPr(const mxArray *array_ptr)
Definition: mxArray.cpp:397
int dlevmar_lec_der(void(*func)(double *p, double *hx, int m, int n, void *adata), void(*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k, int itmax, double *opts, double *info, double *work, double *covar, void *adata)
lb
Definition: lmdemo.m:64
void mxFree(void *ptr)
Definition: mxArray.cpp:304
else status
Definition: mkdir.m:10
int mxGetM(const mxArray *array_ptr)
Definition: mxArray.cpp:369
m
Definition: jacbt3.m:3
bool mxIsChar(const mxArray *array_ptr)
Definition: mxArray.cpp:457
for j
Definition: cumtrapz.m:21
char * fname
Definition: levmar.c:52
int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *command_name)
void mxDestroyArray(mxArray *array_ptr)
Definition: mxArray.cpp:262
int mxGetString(const mxArray *array_ptr, char *buf, int buflen)
Definition: mxArray.cpp:436
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *Prhs[])
Definition: levmar.c:225
bool mxIsComplex(const mxArray *array_ptr)
Definition: mxArray.cpp:493
i
Definition: break_ex.m:3