TPCCLIB
Loading...
Searching...
No Matches
praxis.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "tpcclibConfig.h"
7/*****************************************************************************/
8#include <stdio.h>
9#include <stdlib.h>
10#include <math.h>
11#include <time.h>
12#include <string.h>
13/*****************************************************************************/
14#include "tpcextensions.h"
15#include "tpcrand.h"
16/*****************************************************************************/
17#include "tpcnlopt.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
22/* Local functions */
23int praxisMin(
24 int j, unsigned int nits, double *d2, double *x1, double f1,
25 unsigned int fk, double *fx, double **v, unsigned int n, double h, double t,
26 double macheps, double m2, double m4, double small,
27 double dmin, double ldt, unsigned int *nl,
28 unsigned int *nf, double qd0, double qd1, double *q0, double *q1,
29 double *p, double (*_fun)(int, double*, void*), void *_fundata
30);
31double praxisFlin(
32 double l, int j, double **v, unsigned int n,
33 unsigned int *nf, double qd0, double qd1, double *q0, double *q1,
34 double *p, double (*_fun)(int, double*, void*), void *_fundata
35);
36int praxisMinfit(
37 int n, double eps, double tol, double **ab, double *q
38);
39void praxisSort(double *d, double **v, unsigned int n);
41/*****************************************************************************/
42
43/*****************************************************************************/
65 NLOPT *nlo,
71 unsigned int ktm,
73 TPCSTATUS *status
74) {
75 int verbose=0; if(status!=NULL) verbose=status->verbose;
76 if(verbose>0) printf("%s()\n", __func__);
77 if(nlo==NULL) {
78 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
79 return TPCERROR_FAIL;
80 }
81 if(nlo->totalNr<1 || nlo->xfull==NULL || nlo->_fun==NULL) {
82 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
83 return TPCERROR_NO_DATA;
84 }
85
86
87 /* Check deltas */
88 unsigned int fixedNr=0;
89 for(unsigned int i=0; i<nlo->totalNr; i++) if(nlo->xdelta[i]<=0.0) fixedNr++;
90 if(fixedNr==nlo->totalNr) {
91 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_PARNR);
93 }
94
95
96 /* Set a safe machine epsilon and related values */
97 double macheps=doubleMachEps()*100.0;
98 if(verbose>1) printf("macheps := %g\n", macheps);
99 double m2=sqrt(macheps);
100 double m4=sqrt(m2);
101 if(verbose>1) {
102 printf("m2 := %e\n", m2);
103 printf("m4 := %e\n", m4);
104 }
105 double small=macheps*macheps;
106 double vsmall=small*small;
107 double large=1.0/small;
108 double vlarge=1.0/vsmall;
109 if(verbose>1) {
110 printf("small := %e\n", small);
111 printf("vsmall := %e\n", vsmall);
112 printf("large := %e\n", large);
113 printf("vlarge := %e\n", vlarge);
114 }
115
116 /* Set common initial step size and scaling parameter */
117 double h=0.0, scbd=1.0, t=0.0, t2;
118 {
119 unsigned int i;
120 double min=nan(""), max=nan("");
121 for(i=0; i<nlo->totalNr; i++) if(nlo->xdelta[i]>0.0) {
122 h+=nlo->xdelta[i];
123 t+=nlo->xtol[i];
124 if(isnan(min) || nlo->xdelta[i]<min) min=nlo->xdelta[i];
125 if(isnan(max) || nlo->xdelta[i]>max) max=nlo->xdelta[i];
126 }
127 h/=(double)(nlo->totalNr-fixedNr);
128 t/=(double)(nlo->totalNr-fixedNr);
129 if(verbose>2) {printf("xdelta_min := %g\nxdelta_max := %g\n", min, max); fflush(stdout);}
130 scbd+=log10(max/min); // >1 if param scales are different
131 t2=small+fabs(t); t=t2;
132 if(h<100.0*t) h=100.0*t;
133 }
134 if(verbose>1) {
135 printf("step := %g\n", h);
136 printf("scbd := %g\n", scbd);
137 printf("t(2) := %g\n", t);
138 fflush(stdout);
139 }
140 if(isnan(scbd)) { // checking that user provided xdeltas
141 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
143 }
144
145
146 /* Is the problem ill-conditioned (1) or not?
147 This variable is automatically set, when Praxis finds the problem to be
148 ill-conditioned during iterations. */
149 int illc=0;
150
151 /* Initialize */
152 if(verbose>2) {printf("initializing\n"); fflush(stdout);}
153 unsigned int i, j, dim=nlo->totalNr;
154 double ldfac; if(illc) ldfac=0.1; else ldfac=0.01;
155 unsigned int nl=0, kt=0;
156 unsigned int nf=0; // nr of objective function calls
157 double dmin=small;
158 double ldt=h;
159 double d[dim], y[dim], z[dim];
160 // double v[dim][dim];
161 double **v=malloc(dim*sizeof(double *)); if(v==NULL) {
162 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
164 }
165 for(i=0; i<dim; i++) {
166 v[i]=malloc(dim*sizeof(double));
167 if(v[i]==NULL) {
168 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
170 }
171 }
172 /* Make a copy of parameter list */
173 if(verbose>2) {printf("copying parameters\n"); fflush(stdout);}
174 double p[dim];
175 for(i=0; i<dim; i++) p[i]=nlo->xfull[i];
176
177 for(i=0; i<dim; i++) {
178 d[i]=y[i]=z[i]=0.0;
179 for(j=0; j<dim; j++) v[i][j]=(i==j ? 1.0 : 0.0);
180 }
181 double qd0=0.0, q0[dim], q1[dim];
182 for(i=0; i<dim; i++) q1[i]=q0[i]=nlo->xfull[i];
183
184
185 /* Calculate function value with the initial guess */
186 if(verbose>2) {printf("evaluating initial guess\n"); fflush(stdout);}
187 double fx, qf1;
188 fx=qf1=(*nlo->_fun)(nlo->totalNr, nlo->xfull, nlo->fundata);
189 nf++;
190 if(!isfinite(fx)) {
191 for(i=0; i<dim; i++) free(v[i]);
192 free(v);
193 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
195 }
196 if(verbose>1) {printf("initial_objfunc := %g\n", fx); fflush(stdout);}
197
198
199 /* The main loop */
200 double sf, s, dn, qd1=0.0;
201 int done=0, nLoop=0, ret=0;
202 while(!done) {
203 nLoop++;
204 if(verbose>2) {
205 printf("\n-------------------------------\nloop %d, with %d fcalls\n", nLoop, nf);
206 fflush(stdout);
207 }
208 sf=d[0]; s=d[0]=0.0;
209
210 /* Minimize along the first direction */
211 ret=praxisMin(0, 2, &d[0], &s, fx, 0, &fx, v, dim, h, t,
212 macheps, m2, m4, small, dmin, ldt, &nl,
213 &nf, qd0, qd1, q0, q1,
214 p, nlo->_fun, nlo->fundata);
215 if(ret) {
216 if(verbose>0) printf("Error %d in praxisMin()\n", ret);
217 for(i=0; i<dim; i++) free(v[i]);
218 free(v);
219 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
220 return TPCERROR_FAIL;
221 }
222
223 if((sf<=(0.9*d[0])) || ((0.9*sf)>=d[0])) for(i=1; i<dim; i++) d[i]=0.0;
224
225 /* Other directions */
226 unsigned int k, kl=0, k2;
227 double sl, df, f1, lds;
228 for(k=1; k<dim; k++) {
229 if(verbose>5) printf("direction %d\n", k);
230 for(i=0; i<dim; i++) y[i]=p[i];
231 sf=fx; if(kt>0) illc=1;
232 do { // Usually only once, but twice if noticed here that ill-conditioned
233 kl=k; df=0.0;
234 /* If ill-conditioned, take random step to get off resolution valley */
235 if(illc) {
236 for(i=0; i<dim; i++) {
237 z[i]=(0.1*ldt+t2*pow(10.0,(double)kt)) * (drand()-0.5);
238 s=z[i]; for(j=0; j<dim; j++) p[j]+=s*v[j][i];
239 }
240 /* Calculate function value */
241 fx=(*nlo->_fun)(dim, p, nlo->fundata);
242 if(!isfinite(fx)) {
243 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
245 }
246 nf++;
247 }
248 /* Minimize along non-conjugate directions */
249 for(k2=k; k2<dim; k2++) {
250 if(verbose>6) printf(" non-conjugate direction %d\n", k2);
251 sl=fx; s=0.0;
252 ret=praxisMin(k2, 2, &d[k2], &s, fx, 0, &fx, v, dim, h, t,
253 macheps, m2, m4, small, dmin, ldt, &nl,
254 &nf, qd0, qd1, q0, q1,
255 p, nlo->_fun, nlo->fundata);
256 if(ret) {
257 if(verbose>0) printf("Error %d in praxisMin()\n", ret);
258 for(i=0; i<dim; i++) free(v[i]);
259 free(v);
260 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
261 return TPCERROR_FAIL;
262 }
263 if(illc) s=d[k2]*(s+z[k2])*(s+z[k2]); else s=sl-fx;
264 if(df<s) {df=s; kl=k2;}
265 }
266 if(illc) break;
267 if(df>=fabs(100.0*macheps*fx)) break;
268 illc=1;
269 } while(1);
270
271 /* Minimize along conjugate directions */
272 for(k2=0; k2<k; k2++) { // WHY NOT UNTIL k2==k ??????
273// for(k2=0; k2<=k; k2++) {
274 if(verbose>6) printf(" conjugate direction %d\n", k2);
275 s=0.0;
276 ret=praxisMin(k2, 2, &d[k2], &s, fx, 0, &fx, v, dim, h, t,
277 macheps, m2, m4, small, dmin, ldt, &nl,
278 &nf, qd0, qd1, q0, q1,
279 p, nlo->_fun, nlo->fundata);
280 if(ret) {
281 if(verbose>0) printf("Error %d in praxisMin()\n", ret);
282 for(i=0; i<dim; i++) free(v[i]);
283 free(v);
284 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
285 return TPCERROR_FAIL;
286 }
287 }
288 f1=fx; fx=sf; lds=0.0;
289 for(i=0; i<dim; i++) {
290 sl=p[i]; p[i]=y[i]; y[i]=sl-y[i]; sl=y[i]; lds+=sl*sl;
291 }
292 lds=sqrt(lds);
293 if(lds>small) {
294 for(i=kl-1; i>=k; i--) {
295 for(j=0; j<dim; j++) v[j][i+1]=v[j][i];
296 d[i+1]=d[i];
297 }
298 d[k]=0.0; for(i=0; i<dim; i++) v[i][k]=y[i]/lds;
299 ret=praxisMin(k, 4, &d[k], &lds, f1, 1, &fx, v, dim, h, t,
300 macheps, m2, m4, small, dmin, ldt, &nl,
301 &nf, qd0, qd1, q0, q1,
302 p, nlo->_fun, nlo->fundata);
303 if(ret) {
304 if(verbose>0) printf("Error %d in praxisMin()\n", ret);
305 for(i=0; i<dim; i++) free(v[i]);
306 free(v);
307 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
308 return TPCERROR_FAIL;
309 }
310 if(lds<=0.0) {lds=-lds; for(i=0; i<dim; i++) v[i][k]=-v[i][k];}
311 }
312 ldt*=ldfac; if(ldt<lds) ldt=lds;
313 for(i=0, t2=0.0; i<dim; i++) t2+=p[i]*p[i];
314 t2=sqrt(t2); t2*=m2; t2+=t;
315
316 if(verbose>1) printf(" objfunc := %g\n", fx);
317
318 /* Stopping criterion */
319 if(ldt>(0.5*t2)) kt=0; else kt++;
320 if(verbose>3 && kt>0) printf(" kt := %d\n", kt);
321 if(kt>ktm) {done=1; break;}
322
323 } // next direction k
324 if(done) break;
325
326 /*
327 * We are probably in a curved valley, try quadratic extrapolation
328 */
329 /* but only if we have more than one parameter to fit */
330 if(dim<2) {
331 if(nf>1000) done=1;
332 continue;
333 }
334
335 /* Praxis quad:
336 looks for the minimum along a curve defined by q0, q1, and x (q2). */
337 {
338 double qa, qb, qc, qs, ql;
339 qs=fx; fx=qf1; qf1=qs;
340 for(i=0, qd1=0.0; i<dim; i++) {
341 qs=p[i]; ql=q1[i]; p[i]=ql; q1[i]=qs;
342 qd1+=(qs-ql)*(qs-ql);
343 }
344 qd1=sqrt(qd1); ql=qd1; qs=0.0;
345 if(qd0>0.0 && qd1>0.0 && nl>=3*dim*dim) {
346 ret=praxisMin(-1, 2, &qs, &ql, qf1, 1, &fx, v, dim, h, t,
347 macheps, m2, m4, small, dmin, ldt, &nl,
348 &nf, qd0, qd1, q0, q1,
349 p, nlo->_fun, nlo->fundata);
350 if(ret) {
351 if(verbose>0) printf("Error %d in praxisMin()\n", ret);
352 for(i=0; i<dim; i++) free(v[i]);
353 free(v);
354 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
355 return TPCERROR_FAIL;
356 }
357 qa = ql*(ql-qd1)/(qd0*(qd0+qd1));
358 qb = (ql+qd0)*(qd1-ql)/(qd0*qd1);
359 qc = ql*(ql+qd0)/(qd1*(qd0+qd1));
360 } else {
361 fx=qf1; qa=qb=0.0; qc=1.0;
362 }
363 if(!isfinite(qa)) qa=0.0;
364 if(!isfinite(qb)) qb=0.0;
365 if(!isfinite(qc)) qc=1.0;
366 qd0=qd1;
367 for(i=0; i<dim; i++) {
368 qs=q0[i]; q0[i]=p[i];
369 p[i]=qa*s + qb*p[i] + qc*q1[i];
370 }
371 }
372 dn=0.0;
373 for(i=0; i<dim; i++) {d[i]=1.0/sqrt(d[i]); if(dn<d[i]) dn=d[i];}
374 for(j=0; j<dim; j++) {
375 s=d[j]/dn;
376 if(isfinite(s)) for(i=0; i<dim; i++) v[i][j]*=s;
377 }
378 /* Scale axis to reduce condition number */
379 if(scbd>1.0) {
380 s=vlarge;
381 for(i=0; i<dim; i++) {
382 sl=0.0;
383 for(j=0; j<dim; j++) sl+=v[i][j]*v[i][j];
384 z[i]=sqrt(sl); if(!isfinite(z[i]) || z[i]<m4) z[i]=m4;
385 if(s>z[i]) s=z[i];
386 }
387 for(i=0; i<dim; i++) {
388 sl=s/z[i]; z[i]=1.0/sl;
389 if(z[i]>scbd) {sl=1.0/scbd; z[i]=scbd;}
390 for(j=0; j<dim; j++) v[i][j]*=sl;
391 }
392 }
393 /* Calculate new set of orthogonal directions before repeating
394 the main loop; first, transpose v[][] for the Praxis minfit */
395 for(i=1; i<dim; i++) for(j=0; j<i; j++) {
396 s=v[i][j]; v[i][j]=v[j][i]; v[j][i]=s;
397 }
398 /* Call Praxis minfit to find the SVD of v[][].
399 This gives the principal values and principal directions of approximating
400 quadratic form without squaring the condition number */
401 ret=praxisMinfit((int)dim, macheps, vsmall, v, d);
402 if(ret) {
403 if(verbose>0) printf("Error %d in praxisMinfit()\n", ret);
404 for(i=0; i<dim; i++) free(v[i]);
405 free(v);
406 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
407 return TPCERROR_FAIL;
408 }
409 if(scbd>1.0) {
410 for(i=0; i<dim; i++) {s=z[i]; for(j=0; j<dim; j++) v[i][j]*=s;}
411 for(i=0; i<dim; i++) {
412 s=0.0; for(j=0; j<dim; j++) s+=v[j][i]*v[j][i];
413 s=sqrt(s); d[i]*=s; s=1.0/s; for(j=0; j<dim; j++) v[j][i]*=s;
414 }
415 }
416 for(i=0; i<dim; i++) {
417 if((dn*d[i]) > large) d[i]=vsmall; // dn was calculated above
418 else if((dn*d[i]) < small) d[i]=vlarge;
419 else d[i]=pow(dn*d[i], -2.0);
420 }
421 /* the new eigenvalues and eigenvectors */
422 praxisSort(d, v, dim);
423 dmin=d[dim-1]; if(dmin<small) dmin=small;
424 illc=(m2*d[0]) > dmin;
425
426
427
428
429 if(nf>1000) done=1;
430 }
431 if(verbose>1) printf("func_evals := %d\n", nf);
432
433
434 /* Free allocated memory */
435 for(i=0; i<dim; i++) free(v[i]);
436 free(v);
437
438 /* If ok, then copy parameters to the provided struct */
439 for(i=0; i<dim; i++) nlo->xfull[i]=p[i];
440
441
442 // Just to prevent warning for now
443 if(sf>0.0) sf=0.0;
444 if(kt>0) kt=0;
445 if(nl>0) nl=0;
446 if(ldfac>0.0) ldfac=0.0;
447 if(ktm>0) ktm=0;
448
449
450 return TPCERROR_OK;
451}
452/*****************************************************************************/
453
454/*****************************************************************************/
456
459int praxisMin(
461 int j,
463 unsigned int nits,
464 double *d2,
465 double *x1,
466 double f1,
467 unsigned int fk,
468 double *fx,
470 double **v,
472 unsigned int dim,
473 double h,
474 double t,
476 double macheps,
478 double m2,
480 double m4,
482 double small,
484 double dmin,
486 double ldt,
488 unsigned int *nl,
490 unsigned int *nf,
492 double qd0,
494 double qd1,
496 double *q0,
498 double *q1,
500 double *p,
502 double (*_fun)(int, double*, void*),
504 void *_fundata
505) {
506 /* Check input */
507 if(dim<1 || d2==NULL || x1==NULL || fx==NULL || v==NULL) return(1);
508
509 /* Initialize */
510 double sf1=f1;
511 double sx1=*x1;
512 double xm=0.0;
513 double fm=*fx;
514 double f0=*fx;
515 int dz; if((*d2)<macheps) dz=1; else dz=0; // prevent div by (almost) zero
516 // find step size
517 unsigned int i;
518 double s=0.0; for(i=0; i<dim; i++) s+=p[i]*p[i]; s=sqrt(s);
519 double t2;
520 if(dz) t2=m4*sqrt(fabs(*fx)/dmin + s*ldt) + m2*ldt;
521 else t2=m4*sqrt(fabs(*fx)/(*d2) + s*ldt) + m2*ldt;
522 if(!isfinite(t2)) return(2);
523 s*=m4; s+=t; if(dz && t2>s) t2=s;
524 if(t2<small) t2=small;
525 if(t2>0.01*h) t2=0.01*h;
526 if(fk && f1<=fm) {xm=*x1; fm=f1;}
527 if(!fk || fabs(*x1)<t2) {
528 *x1=(*x1>0.0 ? t2:-t2);
529 f1 = praxisFlin(*x1, j, v, dim,
530 nf, qd0, qd1, q0, q1,
531 p, _fun, _fundata);
532 if(!isfinite(f1)) return(2);
533 }
534 if(f1<=fm) {xm=*x1; fm=f1;}
535
536 int done=1;
537 unsigned int k=0;
538 double x2, f2, d1;
539 do {
540 if(dz) {
541 x2=(f0<f1 ? -(*x1) : 2.0*(*x1));
542 f2=praxisFlin(x2, j, v, dim,
543 nf, qd0, qd1, q0, q1,
544 p, _fun, _fundata);
545 if(!isfinite(f2)) return(3);
546 if(f2<=fm) {xm=x2; fm=f2;}
547 *d2=(x2*(f1-f0)-(*x1)*(f2-f0))/((*x1)*x2*((*x1)-x2));
548 }
549 d1=(f1-f0)/(*x1) - (*x1)*(*d2); dz=1;
550 if(*d2<=small) x2=(d1<0 ? h:-h); else x2=-0.5*d1/(*d2);
551 if(fabs(x2)>h) x2=(x2>0 ? h:-h);
552 f2=praxisFlin(x2, j, v, dim,
553 nf, qd0, qd1, q0, q1,
554 p, _fun, _fundata);
555 if(!isfinite(f2)) return(4);
556 done=1;
557 while((k<nits) && (f2>f0)) {
558 k++;
559 if((f0<f1) && ((*x1)*x2>0.0)) {done=0; break;}
560 x2*=0.5;
561 f2=praxisFlin(x2, j, v, dim,
562 nf, qd0, qd1, q0, q1,
563 p, _fun, _fundata);
564 if(!isfinite(f2)) return(5);
565 }
566 } while(!done);
567
568 *nl=(*nl)+1;
569 if(f2>fm) x2=xm; else fm=f2;
570 if(fabs(x2*(x2-(*x1))) > small) {
571 *d2=(x2*(f1-f0) - (*x1)*(fm-f0))/((*x1)*x2*((*x1)-x2));
572 } else {
573 if(k>0) *d2=0.0;
574 }
575 if(*d2<small) *d2=small;
576 *x1=x2; *fx=fm; if(sf1<*fx) {*fx=sf1; *x1=sx1;}
577 if(j!=-1) for(i=0; i<dim; i++) p[i]+=(*x1)*v[i][j];
578
579 return(0);
580}
581/*****************************************************************************/
582
583/*****************************************************************************/
587double praxisFlin(
588 double la,
590 int j,
592 double **v,
594 unsigned int dim,
596 unsigned int *nf,
598 double qd0,
600 double qd1,
602 double *q0,
604 double *q1,
606 double *p,
608 double (*_fun)(int, double*, void*),
610 void *_fundata
611) {
612 unsigned int i;
613 double tflin[dim];
614
615 if(j<-1 || j>=(int)dim) return(nan(""));
616
617 if(j>=0) { // linear search
618 for(i=0; i<dim; i++) tflin[i]=p[i]+la*v[i][j];
619 } else { // search along parabolic space curve
620 double qa, qb, qc, f=qd0+qd1;
621 if(qd0*f!=0.0) qa=la*(la-qd1)/(qd0*f); else qa=0.0;
622 if(!isfinite(qa)) qa=0.0;
623 if(f!=0.0) qb=(la+qd0)*(qd1-la)/f; else qb=0.;
624 if(!isfinite(qb)) qb=0.0;
625 if(qd1*f!=0.0) qc=la*(la+qd0)/(qd1*f); else qc=0.;
626 if(!isfinite(qc)) qc=0.0;
627 for(i=0; i<dim; i++) tflin[i]= qa*q0[i] + qb*p[i] + qc*q1[i];
628 }
629 *nf=(*nf)+1;
630 return(*_fun)(dim, tflin, _fundata);
631}
632/*****************************************************************************/
633
634/*****************************************************************************/
638int praxisMinfit(
640 int n,
642 double eps,
644 double tol,
646 double **ab,
648 double *q
649) {
650 int l, kt, l2, i, j, k, done, fdone;
651 double c, f, g, h, s, x, y, z;
652 double e[n];
653
654 /* Check the input */
655 if(n<1) return(1);
656 if(eps<=0.0 || ab==NULL || q==NULL) return(2);
657 if(tol<eps) tol=eps;
658 if(n==1) {
659 q[0]=ab[0][0]; ab[0][0]=1.0;
660 return(0);
661 }
662
663 /* Householder's reduction to bidiagonal form */
664 for(i=0, x=g=0.0; i<n; i++) {
665 e[i]=g; s=0.0; l=i+1; for(j=i; j<n; j++) s+=ab[j][i]*ab[j][i];
666 if(s<tol) {
667 g=0.0;
668 } else {
669 g=sqrt(s); f=ab[i][i]; if(f>=0.0) g=-g;
670 h=f*g-s; ab[i][i]=f-g;
671 for(j=l; j<n; j++) {
672 f=0.0; for(k=i; k<n; k++) f+=ab[k][i]*ab[k][j];
673 f/=h; for(k=i; k<n; k++) ab[k][j]+=f*ab[k][i];
674 }
675 }
676 q[i]=g; s=0.0;
677 if(i<n) for(j=l; j<n; j++) s+=ab[i][j]*ab[i][j];
678 if(s<tol || i>n-2) {
679 g=0.0;
680 } else {
681 f=ab[i][i+1];
682 g=sqrt(s); if(f>=0.0) g=-g;
683 h=f*g-s;
684 ab[i][i+1]=f-g;
685 for(j=l; j<n; j++) e[j]=ab[i][j]/h;
686 for(j=l; j<n; j++) {
687 s=0.0;
688 for(k=l; k<n; k++) s+=ab[j][k]*ab[i][k];
689 for(k=l; k<n; k++) ab[j][k]+=s*e[k];
690 }
691 }
692 y=fabs(q[i])+fabs(e[i]);
693 if(y>x) x=y;
694 }
695
696 /* Accumulation of right-hand transformations */
697 l=n-1; ab[l][l]=1.0; g=e[l];
698 for(i=l-1; i>=0; i--) {
699 if(g!=0.0) {
700 h=ab[i][i+1]*g;
701 for(j=l; j<n; j++) ab[j][i]=ab[i][j]/h;
702 for(j=l; j<n; j++) {
703 for(k=l, s=0.0; k<n; k++) s+=ab[i][k]*ab[k][j];
704 for(k=l; k<n; k++) ab[k][j]+=s*ab[k][i];
705 }
706 }
707 for(j=l; j<n; j++) ab[i][j]=ab[j][i]=0.0;
708 ab[i][i]=1.0; g=e[i]; l=i;
709 }
710
711 /* Diagonalization to bi-diagonal form */
712 eps*=x;
713 for(k=n-1; k>=0; k--) {
714 kt=0; done=0;
715 while(!done) {
716 if(++kt>30) e[k]=0.0; // QR failed
717 fdone=0;
718 for(l2=k; l2>=0; l2--) {
719 l=l2;
720 if(fabs(e[l])<=eps) {fdone=1; break;} // F convergence
721 if(l>0 && fabs(q[l-1])<=eps) break;
722 }
723 if(!fdone) for(i=l, c=0.0, s=1.0; i<=k; i++) {
724 f=s*e[i]; e[i]*=c; if(fabs(f)<=eps) break; // F convergence
725 g=q[i];
726 if(fabs(f)<fabs(g)) {
727 double fg=f/g; h=fabs(g)*sqrt(1.0+fg*fg);
728 } else {
729 double gf=g/f; h=(f!=0.0 ? fabs(f)*sqrt(1.0+gf*gf) : 0.0);
730 }
731 q[i]=h; if(h==0.0) {h=1.0; g=1.0;}
732 c=g/h; s=-f/h;
733 }
734 /* test convergence */
735 z=q[k]; if(l==k) {done=1; break;} // convergence
736 /* Also stop if k==0 because below there is index k-1 */
737 if(k==0) {done=1; break;}
738 // Shift from bottom 2x2 minor
739 x=q[l];
740 y=q[k-1]; // In many source codes index is k-L but in Brents book k-1
741 g=e[k-1];
742 h=e[k];
743 if(h!=0.0 && y!=0.0) f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); else f=0.0;
744 g=sqrt(f*f+1.0);
745 if(f<=0.0) f=((x-z)*(x+z)+h*(y/(f-g)-h))/x;
746 else f=((x-z)*(x+z)+h*(y/(f+g)-h))/x;
747 // Next QR transformation
748 for(i=l+1, s=c=1.0; i<=k; i++) {
749 g=e[i]; y=q[i]; h=s*g; g*=c;
750 if(fabs(f)<fabs(h)) {
751 double fh=f/h; z=fabs(h)*sqrt(1.0+fh*fh);
752 } else {
753 double hf=h/f; z=(f!=0.0 ? fabs(f)*sqrt(1.0+hf*hf) : 0.0);
754 }
755 e[i-1]=z; if(z==0.0) f=z=1.0;
756 c=f/z; s=h/z; f=x*c+g*s; g=-x*s+g*c; h=y*s; y*=c;
757 for(j=0; j<n; j++) {
758 x=ab[j][i-1]; z=ab[j][i]; ab[j][i-1]=x*c+z*s; ab[j][i]=-x*s+z*c; }
759 if(fabs(f)<fabs(h)) {
760 double fh=f/h; z=fabs(h)*sqrt(1.0+fh*fh);
761 } else {
762 double hf=h/f; z=(f!=0.0 ? fabs(f)*sqrt(1.0+hf*hf) : 0.0);
763 }
764 q[i-1]=z; if(z==0.0) z=f=1.0; c=f/z; s=h/z; f=c*g+s*y; x=-s*g+c*y;
765 }
766 e[l]=0.0; e[k]=f; q[k]=x;
767 } // while !done
768 if(z<0.0) {q[k]=-z; for(j=0; j<n; j++) ab[j][k]=-ab[j][k]; }
769 }
770 return(0);
771}
772/*****************************************************************************/
773
774/*****************************************************************************/
778void praxisSort(
780 double *d,
782 double **v,
784 unsigned int n
785) {
786 unsigned int k, i, j;
787 double s;
788
789 for(i=0; i<n-1; i++) {
790 k=i; s=d[i];
791 for(j=i+1; j<n; j++) {if(d[j]>s) {k=j; s=d[j];}}
792 if(k>i) {
793 d[k]=d[i]; d[i]=s;
794 for(j=0; j<n; j++) {s=v[j][i]; v[j][i]=v[j][k]; v[j][k]=s;}
795 }
796 }
797}
798/*****************************************************************************/
799
800/*****************************************************************************/
double doubleMachEps()
Definition doubleutil.c:105
double drand()
Definition gaussdev.c:66
int nloptPowellBrent(NLOPT *nlo, unsigned int ktm, TPCSTATUS *status)
Powell-Brent (Praxis) non-linear unconstrained optimization.
Definition praxis.c:59
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
double(* _fun)(int, double *, void *)
Definition tpcnlopt.h:42
void * fundata
Definition tpcnlopt.h:44
double * xfull
Definition tpcnlopt.h:29
double * xdelta
Definition tpcnlopt.h:36
double * xtol
Definition tpcnlopt.h:39
unsigned int totalNr
Definition tpcnlopt.h:27
int verbose
Verbose level, used by statusPrint() etc.
Header file for library libtpcextensions.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_INVALID_PARNR
Invalid number of parameters.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
Header file for library libtpcnlopt.
Header file for libtpcrand.