TPCCLIB
Loading...
Searching...
No Matches
nlopt.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/*****************************************************************************/
27 NLOPT *nlo
28) {
29 if(nlo==NULL) return;
30 nlo->totalNr=0;
31 nlo->xfull=NULL;
32 nlo->xlower=NULL;
33 nlo->xupper=NULL;
34 nlo->xdelta=NULL;
35 nlo->xtol=NULL;
36 nlo->_fun=NULL;
37 nlo->fundata=NULL;
38 nlo->maxFunCalls=0;
39 nlo->funCalls=0;
40 nlo->funval=nan("");
41 nlo->usePList=0;
42 nlo->plist=NULL;
43}
44/*****************************************************************************/
45
46/*****************************************************************************/
54 NLOPT *nlo
55) {
56 if(nlo==NULL) return;
57 free(nlo->xfull);
58 free(nlo->xlower);
59 free(nlo->xupper);
60 free(nlo->xdelta);
61 free(nlo->xtol);
62 free(nlo->plist);
63 // then set everything to zero or NULL again
64 nloptInit(nlo);
65}
66/*****************************************************************************/
67
68/*****************************************************************************/
76 NLOPT *nlo,
78 unsigned int parNr
79) {
80 if(nlo==NULL) return TPCERROR_FAIL;
81 /* Delete any previous contents */
82 nloptFree(nlo);
83 /* If no memory is requested, then just return */
84 if(parNr<1) return TPCERROR_OK;
85
86 /* Allocate memory for arrays */
87 nlo->xfull=calloc(parNr, sizeof(double));
88 if(nlo->xfull==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
89 nlo->xlower=calloc(parNr, sizeof(double));
90 if(nlo->xlower==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
91 nlo->xupper=calloc(parNr, sizeof(double));
92 if(nlo->xupper==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
93 nlo->xdelta=calloc(parNr, sizeof(double));
94 if(nlo->xdelta==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
95 nlo->xtol=calloc(parNr, sizeof(double));
96 if(nlo->xtol==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
97 /* Set array length */
98 nlo->totalNr=parNr;
99 return TPCERROR_OK;
100}
101/*****************************************************************************/
102
103/*****************************************************************************/
114 NLOPT *nlo1,
116 NLOPT *nlo2
117) {
118 if(nlo1==NULL || nlo2==NULL) return(TPCERROR_FAIL);
119 nloptFree(nlo2); if(nlo1->totalNr<1) return(TPCERROR_OK);
120
121 int ret=nloptAllocate(nlo2, nlo1->totalNr);
122 if(ret!=TPCERROR_OK) return(ret);
123
124 nlo2->totalNr=nlo1->totalNr;
125 for(unsigned int i=0; i<nlo1->totalNr; i++) nlo2->xfull[i]=nlo1->xfull[i];
126 for(unsigned int i=0; i<nlo1->totalNr; i++) nlo2->xlower[i]=nlo1->xlower[i];
127 for(unsigned int i=0; i<nlo1->totalNr; i++) nlo2->xupper[i]=nlo1->xupper[i];
128 for(unsigned int i=0; i<nlo1->totalNr; i++) nlo2->xdelta[i]=nlo1->xdelta[i];
129 for(unsigned int i=0; i<nlo1->totalNr; i++) nlo2->xtol[i]=nlo1->xtol[i];
130 nlo2->_fun=nlo1->_fun;
131 nlo2->fundata=nlo1->fundata;
132 nlo2->maxFunCalls=nlo1->maxFunCalls;
133 nlo2->funCalls=nlo1->funCalls;
134 nlo2->funval=nlo1->funval;
135 nlo2->usePList=nlo1->usePList;
136 return(TPCERROR_OK);
137}
138/*****************************************************************************/
139
140/*****************************************************************************/
151 NLOPT *nlo,
153 double *p,
155 double funval
156) {
157 if(nlo==NULL || nlo->totalNr<1 || nlo->funCalls<1) return TPCERROR_FAIL;
158 if(nlo->usePList==0) return TPCERROR_OK;
159 if(nlo->plist==NULL || nlo->funCalls==1) {
160 /* Allocate memory, if this is the first list item */
161 nlo->plist=(double*)malloc((nlo->totalNr+1)*sizeof(double));
162 } else {
163 /* Reallocate memory, if this is not the first list item */
164 nlo->plist=(double*)realloc(nlo->plist, (nlo->funCalls)*(nlo->totalNr+1)*sizeof(double));
165 }
166 if(nlo->plist==NULL) {nloptFree(nlo); return TPCERROR_OUT_OF_MEMORY;}
167 /* Copy the values */
168 for(unsigned int i=0; i<nlo->totalNr; i++)
169 nlo->plist[(nlo->funCalls-1)*(nlo->totalNr+1)+i]=p[i];
170 nlo->plist[(nlo->funCalls-1)*(nlo->totalNr+1)+nlo->totalNr]=funval;
171 return TPCERROR_OK;
172}
173/*****************************************************************************/
174
175/*****************************************************************************/
184 NLOPT *nlo
185) {
186 if(nlo==NULL) return(TPCERROR_FAIL);
187 if(nlo->usePList==0 || nlo->plist==NULL || nlo->totalNr<1) return(TPCERROR_NO_DATA);
188 if(nlo->funCalls<2) return(TPCERROR_OK); // nothing to sort
189
190 unsigned int dim=nlo->totalNr;
191 unsigned int nr=nlo->funCalls;
192 for(unsigned int i=0; i<nr-1; i++)
193 for(unsigned int j=i+1; j<nr; j++) {
194 if( (!isfinite(nlo->plist[i*(dim+1)+dim]) && isfinite(nlo->plist[j*(dim+1)+dim]))
195 || nlo->plist[i*(dim+1)+dim] > nlo->plist[j*(dim+1)+dim])
196 {
197 for(unsigned int k=0; k<=dim; k++) {
198 double d=nlo->plist[i*(dim+1)+k];
199 nlo->plist[i*(dim+1)+k]=nlo->plist[j*(dim+1)+k]; nlo->plist[j*(dim+1)+k]=d;
200 }
201 }
202 }
203 return(TPCERROR_OK);
204}
205/*****************************************************************************/
206
207/*****************************************************************************/
221 NLOPT *nlo,
223 unsigned int nr,
225 double *meanp,
227 double *sdp
228) {
229 if(nlo==NULL || meanp==NULL) return(TPCERROR_FAIL);
230 if(nlo->usePList==0 || nlo->plist==NULL || nlo->totalNr<1) return(TPCERROR_NO_DATA);
231 if(nlo->funCalls<1) return(TPCERROR_OK);
232 if(nr<1 || nr>nlo->funCalls) nr=nlo->funCalls;
233
234 unsigned int dim=nlo->totalNr;
235 for(unsigned int j=0; j<dim; j++) {
236 unsigned int n=0;
237 meanp[j]=0.0;
238 for(unsigned int i=0; i<nr; i++) {
239 if(isfinite(nlo->plist[i*(dim+1)+j])) meanp[j]+=nlo->plist[i*(dim+1)+j];
240 n++;
241 }
242 if(n<1) return(TPCERROR_NO_DATA);
243 meanp[j]/=(double)n;
244 }
245
246 /* Calculate SDs if required */
247 if(sdp==NULL) return(TPCERROR_OK);
248 for(unsigned int j=0; j<dim; j++) {
249 sdp[j]=0.0;
250 unsigned int n=0;
251 double sqrsum=0.0, sumsqr=0.0;
252 for(unsigned int i=0; i<nr; i++) {
253 if(isfinite(nlo->plist[i*(dim+1)+j])) {
254 sqrsum+=nlo->plist[i*(dim+1)+j];
255 sumsqr+=nlo->plist[i*(dim+1)+j]*nlo->plist[i*(dim+1)+j];
256 n++;
257 }
258 }
259 if(n<2) continue; // SD=0 if n==1
260 sqrsum*=sqrsum;
261 double ff=sumsqr - sqrsum/(double)n;
262 if(!(ff>0.0)) sdp[j]=0.0;
263 else sdp[j]=sqrt( ff / (double)(n-1) );
264 }
265 return(TPCERROR_OK);
266}
267/*****************************************************************************/
268
269/*****************************************************************************/
276 NLOPT *nlo,
278 unsigned int nr,
280 FILE *fp
281) {
282 if(nlo==NULL || fp==NULL) return;
283 if(nlo->usePList==0 || nlo->plist==NULL || nlo->totalNr<1) return;
284 fprintf(fp, "\nSampled points:\n");
285 if(nlo->funCalls<1) return;
286 if(nr<1 || nr>nlo->funCalls) nr=nlo->funCalls;
287
288 unsigned int dim=nlo->totalNr;
289 for(unsigned int si=0; si<nr; si++) {
290 fprintf(fp, "%d\t", 1+si);
291 for(unsigned int i=0; i<dim; i++) fprintf(fp, "%e ", nlo->plist[si*(dim+1)+i]);
292 fprintf(fp, "=> %e\n", nlo->plist[si*(dim+1)+dim]);
293 }
294 fflush(fp);
295}
296/*****************************************************************************/
297
298/*****************************************************************************/
304 NLOPT *d,
306 FILE *fp
307) {
308 if(d==NULL || fp==NULL) return;
309 if(d->totalNr==0) {fprintf(fp, "NLOPT is empty\n"); return;}
310 fprintf(fp, "param xfull xlower xupper xdelta xtol\n");
311 for(unsigned int i=0; i<d->totalNr; i++) {
312 fprintf(fp, "%5d", 1+i);
313 fprintf(fp, " %10.5f", d->xfull[i]);
314 fprintf(fp, " %10.5f", d->xlower[i]);
315 fprintf(fp, " %10.5f", d->xupper[i]);
316 fprintf(fp, " %10.5f", d->xdelta[i]);
317 fprintf(fp, " %10.5f\n", d->xtol[i]);
318 }
319 fprintf(fp, "maxFunCalls := %d\n", d->maxFunCalls);
320 fprintf(fp, "funCalls := %d\n", d->funCalls);
321 fprintf(fp, "funval := %g\n", d->funval);
322 fprintf(fp, "usePList := %d\n", d->usePList);
323 fflush(fp);
324 return;
325}
326/*****************************************************************************/
327
328/*****************************************************************************/
333unsigned int nloptLimitFixedNr(
335 NLOPT *d
336) {
337 if(d==NULL || d->totalNr<1) return(0);
338 if(d->xlower==NULL || d->xupper==NULL) return(0);
339 unsigned int n=0;
340 double macheps=doubleMachEps();
341 for(unsigned int i=0; i<d->totalNr; i++) {
342 double r=d->xupper[i]-d->xlower[i];
343 if(!isnan(r) && r<macheps) n++;
344 }
345 return(n);
346}
347/*****************************************************************************/
348
349/*****************************************************************************/
354unsigned int nloptFixedNr(
356 NLOPT *d
357) {
358 if(d==NULL || d->totalNr<1) return(0);
359 unsigned int i, ln=0, dn=0;
360 double macheps=doubleMachEps();
361 /* based on limits */
362 if(d->xlower!=NULL && d->xupper!=NULL) {
363 double r;
364 for(i=0; i<d->totalNr; i++) {
365 r=d->xupper[i]-d->xlower[i];
366 if(!isnan(r) && r<macheps) ln++;
367 }
368 }
369 /* based on deltas */
370 if(d->xdelta!=NULL) {
371 for(i=0; i<d->totalNr; i++) {
372//printf(" %g %g\n", d->xdelta[i], macheps);
373 if(!isnan(d->xdelta[i]) && fabs(d->xdelta[i])<macheps) dn++;
374 }
375 }
376//printf(" %u %u\n", ln, dn);
377 /* the one that is nonzero is probably used */
378 if(dn==0) return(ln);
379 if(ln==0) return(dn);
380 /* Both seem to be used; thus check both together */
381 unsigned int n=0;
382 double r;
383 for(i=0; i<d->totalNr; i++) {
384 if(!isnan(d->xdelta[i]) && fabs(d->xdelta[i])<macheps) {n++; continue;}
385 r=d->xupper[i]-d->xlower[i];
386 if(!isnan(r) && r<macheps) {n++; continue;}
387 }
388 return(n);
389}
390/*****************************************************************************/
391
392/*****************************************************************************/
399 NLOPT *d
400) {
401 if(d==NULL || d->totalNr<1) return;
402 unsigned int i=0, j;
403 while(i<d->totalNr) {
404 if(!isnan(d->xfull[i]) && !isnan(d->xdelta[i])) {i++; continue;}
405 for(j=i+1; j<d->totalNr; j++) {
406 d->xfull[j-1]=d->xfull[j];
407 d->xlower[j-1]=d->xlower[j];
408 d->xupper[j-1]=d->xupper[j];
409 d->xdelta[j-1]=d->xdelta[j];
410 d->xtol[j-1]=d->xtol[j];
411 }
412 d->totalNr--;
413 }
414 return;
415}
416/*****************************************************************************/
417
418/*****************************************************************************/
425 NLOPT_DATA *d
426) {
427 if(d==NULL) return;
428 d->n=0;
429 d->x=d->y=d->w=d->sy=NULL;
430 d->verbose=0;
431 d->fp=stdout;
432}
433/*****************************************************************************/
434
435/*****************************************************************************/
double doubleMachEps()
Definition doubleutil.c:105
void nloptInit(NLOPT *nlo)
Definition nlopt.c:25
int nloptAllocate(NLOPT *nlo, unsigned int parNr)
Definition nlopt.c:74
unsigned int nloptLimitFixedNr(NLOPT *d)
Definition nlopt.c:333
int nloptMeanP(NLOPT *nlo, unsigned int nr, double *meanp, double *sdp)
Definition nlopt.c:219
unsigned int nloptFixedNr(NLOPT *d)
Definition nlopt.c:354
void nloptRemoveEmpties(NLOPT *d)
Definition nlopt.c:398
void nloptPrintP(NLOPT *nlo, unsigned int nr, FILE *fp)
Definition nlopt.c:274
void nloptFree(NLOPT *nlo)
Definition nlopt.c:52
int nloptAddP(NLOPT *nlo, double *p, double funval)
Definition nlopt.c:149
void nloptdataInit(NLOPT_DATA *d)
Definition nlopt.c:423
int nloptDuplicate(NLOPT *nlo1, NLOPT *nlo2)
Definition nlopt.c:112
void nloptWrite(NLOPT *d, FILE *fp)
Definition nlopt.c:302
int nloptSortP(NLOPT *nlo)
Definition nlopt.c:182
double * w
Definition tpcnlopt.h:73
double * y
Definition tpcnlopt.h:71
double * sy
Definition tpcnlopt.h:75
FILE * fp
Definition tpcnlopt.h:79
double * x
Definition tpcnlopt.h:69
unsigned int n
Definition tpcnlopt.h:67
int verbose
Definition tpcnlopt.h:77
double(* _fun)(int, double *, void *)
Definition tpcnlopt.h:42
double funval
Definition tpcnlopt.h:50
unsigned int maxFunCalls
Definition tpcnlopt.h:46
double * xupper
Definition tpcnlopt.h:33
double * xlower
Definition tpcnlopt.h:31
void * fundata
Definition tpcnlopt.h:44
double * xfull
Definition tpcnlopt.h:29
unsigned int funCalls
Definition tpcnlopt.h:48
double * xdelta
Definition tpcnlopt.h:36
unsigned int usePList
Definition tpcnlopt.h:52
double * xtol
Definition tpcnlopt.h:39
double * plist
Definition tpcnlopt.h:56
unsigned int totalNr
Definition tpcnlopt.h:27
Header file for library libtpcextensions.
@ 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.