00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 #include <math.h>
00110 #include <stddef.h>
00111 #include <stdlib.h>
00112 #include <string.h>
00113 #include <stdio.h>
00114 #include "cmaes_interface.h"
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 long random_init(random_t *, long unsigned seed );
00125 void random_exit(random_t *);
00126 double random_Gauss(random_t *);
00127 double random_Uniform(random_t *);
00128 long random_Start(random_t *, long unsigned seed );
00129
00130 void timings_start(timings_t *timing);
00131 double timings_update(timings_t *timing);
00132 void timings_tic(timings_t *timing);
00133 double timings_toc(timings_t *timing);
00134
00135 void readpara_init (readpara_t *, int dim, int seed, const double * xstart,
00136 const double * sigma, int lambda, const char * filename);
00137 void readpara_exit(readpara_t *);
00138 void readpara_ReadFromFile(readpara_t *, const char *szFileName);
00139 void readpara_SupplementDefaults(readpara_t *);
00140 void readpara_SetWeights(readpara_t *, const char * mode);
00141 void readpara_WriteToFile(readpara_t *, const char *filenamedest,
00142 const char *parafilesource);
00143
00144 double const * cmaes_SetMean(cmaes_t *, const double *xmean);
00145 void cmaes_WriteToFile(cmaes_t *, const char *key, const char *name);
00146 void cmaes_WriteToFileAW(cmaes_t *t, const char *key, const char *name,
00147 const char * append);
00148 void cmaes_WriteToFilePtr(cmaes_t *, const char *key, FILE *fp);
00149 void cmaes_ReadFromFilePtr(cmaes_t *, FILE *fp);
00150 void cmaes_FATAL(char const *s1, char const *s2,
00151 char const *s3, char const *s4);
00152
00153
00154
00155
00156 static char * getTimeStr(void);
00157 static void TestMinStdDevs( cmaes_t *);
00158
00159
00160 static void Eigen( int N, double **C, double *diag, double **Q,
00161 double *rgtmp);
00162 static int Check_Eigen( int N, double **C, double *diag, double **Q);
00163 static void QLalgo2 (int n, double *d, double *e, double **V);
00164 static void Householder2(int n, double **V, double *d, double *e);
00165 static void Adapt_C2(cmaes_t *t, int hsig);
00166
00167 static void FATAL(char const *sz1, char const *s2,
00168 char const *s3, char const *s4);
00169 static void ERRORMESSAGE(char const *sz1, char const *s2,
00170 char const *s3, char const *s4);
00171 static void Sorted_index( const double *rgFunVal, int *index, int n);
00172 static int SignOfDiff( const void *d1, const void * d2);
00173 static double rgdouMax( const double *rgd, int len);
00174 static double rgdouMin( const double *rgd, int len);
00175 static double douMax( double d1, double d2);
00176 static double douMin( double d1, double d2);
00177 static int intMin( int i, int j);
00178 static int MaxIdx( const double *rgd, int len);
00179 static int MinIdx( const double *rgd, int len);
00180 static double myhypot(double a, double b);
00181 static double * new_double( int n);
00182 static void * new_void( int n, size_t size);
00183
00184
00185
00186
00187
00188 static char *
00189 getTimeStr(void) {
00190 time_t tm = time(NULL);
00191 static char s[33];
00192
00193
00194 strncpy(s, ctime(&tm), 24);
00195 s[24] = '\0';
00196 return s;
00197 }
00198
00199 char *
00200 cmaes_SayHello(cmaes_t *t)
00201 {
00202
00203 sprintf(t->sOutString,
00204 "(%d,%d)-CMA-ES(mu_eff=%.1f), Ver=\"%s\", dimension=%d, randomSeed=%d (%s)",
00205 t->sp.mu, t->sp.lambda, t->sp.mueff, t->version, t->sp.N,
00206 t->sp.seed, getTimeStr());
00207
00208 return t->sOutString;
00209 }
00210
00211 double *
00212 cmaes_init(cmaes_t *t,
00213 int dimension,
00214 double *inxstart,
00215 double *inrgstddev,
00216 long int inseed,
00217 int lambda,
00218 const char *input_parameter_filename)
00219 {
00220 int i, j, N;
00221 double dtest, trace;
00222
00223 t->version="3.02.03.beta";
00224
00225 readpara_init (&t->sp, dimension, inseed, inxstart, inrgstddev,
00226 lambda, input_parameter_filename);
00227 t->sp.seed = random_init( &t->rand, (unsigned) t->sp.seed);
00228
00229 N = t->sp.N;
00230
00231
00232 for (i = 0, trace = 0.; i < N; ++i)
00233 trace += t->sp.rgInitialStds[i]*t->sp.rgInitialStds[i];
00234 t->sigma = sqrt(trace/N);
00235
00236 t->chiN = sqrt((double) N) * (1. - 1./(4.*N) + 1./(21.*N*N));
00237 t->flgEigensysIsUptodate = 1;
00238 t->flgCheckEigen = 0;
00239 t->genOfEigensysUpdate = 0;
00240 timings_start(&t->eigenTimings);
00241 t->flgIniphase = 0;
00242 t->flgresumedone = 0;
00243 t->flgStop = 0;
00244
00245 for (dtest = 1.; dtest && dtest < 1.1 * dtest; dtest *= 2.)
00246 if (dtest == dtest + 1.)
00247 break;
00248 t->dMaxSignifKond = dtest / 1000.;
00249
00250 t->gen = 0;
00251 t->countevals = 0;
00252 t->state = 0;
00253 t->dLastMinEWgroesserNull = 1.0;
00254 t->printtime = t->writetime = t->firstwritetime = t->firstprinttime = 0;
00255
00256 t->rgpc = new_double(N);
00257 t->rgps = new_double(N);
00258 t->rgdTmp = new_double(N+1);
00259 t->rgBDz = new_double(N);
00260 t->rgxmean = new_double(N+2); t->rgxmean[0] = N; ++t->rgxmean;
00261 t->rgxold = new_double(N+2); t->rgxold[0] = N; ++t->rgxold;
00262 t->rgxbestever = new_double(N+3); t->rgxbestever[0] = N; ++t->rgxbestever;
00263 t->rgout = new_double(N+2); t->rgout[0] = N; ++t->rgout;
00264 t->rgD = new_double(N);
00265 t->C = (double**)new_void(N, sizeof(double*));
00266 t->B = (double**)new_void(N, sizeof(double*));
00267 t->publicFitness = new_double(t->sp.lambda);
00268 t->rgFuncValue = new_double(t->sp.lambda+1);
00269 t->rgFuncValue[0]=t->sp.lambda; ++t->rgFuncValue;
00270 t->arFuncValueHist = new_double(10+(int)ceil(3.*10.*N/t->sp.lambda)+1);
00271 t->arFuncValueHist[0] = (double)(10+(int)ceil(3.*10.*N/t->sp.lambda));
00272 t->arFuncValueHist++;
00273
00274 for (i = 0; i < N; ++i) {
00275 t->C[i] = new_double(i+1);
00276 t->B[i] = new_double(N);
00277 }
00278 t->index = (int *) new_void(t->sp.lambda, sizeof(int));
00279 for (i = 0; i < t->sp.lambda; ++i)
00280 t->index[i] = i;
00281 t->rgrgx = (double **)new_void(t->sp.lambda, sizeof(double*));
00282 for (i = 0; i < t->sp.lambda; ++i) {
00283 t->rgrgx[i] = new_double(N+2);
00284 t->rgrgx[i][0] = N;
00285 t->rgrgx[i]++;
00286 }
00287
00288
00289
00290 for (i = 0; i < N; ++i)
00291 for (j = 0; j < i; ++j)
00292 t->C[i][j] = t->B[i][j] = t->B[j][i] = 0.;
00293
00294 for (i = 0; i < N; ++i)
00295 {
00296 t->B[i][i] = 1.;
00297 t->C[i][i] = t->rgD[i] = t->sp.rgInitialStds[i] * sqrt(N / trace);
00298 t->C[i][i] *= t->C[i][i];
00299 t->rgpc[i] = t->rgps[i] = 0.;
00300 }
00301
00302 t->minEW = rgdouMin(t->rgD, N); t->minEW = t->minEW * t->minEW;
00303 t->maxEW = rgdouMax(t->rgD, N); t->maxEW = t->maxEW * t->maxEW;
00304
00305 t->maxdiagC=t->C[0][0]; for(i=1;i<N;++i) if(t->maxdiagC<t->C[i][i]) t->maxdiagC=t->C[i][i];
00306 t->mindiagC=t->C[0][0]; for(i=1;i<N;++i) if(t->mindiagC>t->C[i][i]) t->mindiagC=t->C[i][i];
00307
00308
00309 for (i = 0; i < N; ++i)
00310 t->rgxmean[i] = t->rgxold[i] = t->sp.xstart[i];
00311
00312 if (t->sp.typicalXcase)
00313 for (i = 0; i < N; ++i)
00314 t->rgxmean[i] += t->sigma * t->rgD[i] * random_Gauss(&t->rand);
00315
00316 if (strcmp(t->sp.resumefile, "_no_") != 0)
00317 cmaes_resume_distribution(t, t->sp.resumefile);
00318
00319 return (t->publicFitness);
00320
00321 }
00322
00323
00324
00325
00326 void
00327 cmaes_resume_distribution(cmaes_t *t, char *filename)
00328 {
00329 int i, j, res, n;
00330 double d;
00331 FILE *fp = fopen( filename, "r");
00332 if(fp == NULL) {
00333 ERRORMESSAGE("cmaes_resume_distribution(): could not open '",
00334 filename, "'",0);
00335 return;
00336 }
00337
00338 i = 0; res = 0;
00339 while (1) {
00340 if ((res = fscanf(fp, " resume %lg", &d)) == EOF)
00341 break;
00342 else if (res==0)
00343 fscanf(fp, " %*s");
00344 else if(res > 0)
00345 i += 1;
00346 }
00347
00348
00349 n = i; i = 0; res = 0; rewind(fp);
00350 while (i<n) {
00351 if ((res = fscanf(fp, " resume %lg", &d)) == EOF)
00352 FATAL("cmaes_resume_distribution(): Unexpected error, bug",0,0,0);
00353 else if (res==0)
00354 fscanf(fp, " %*s");
00355 else if(res > 0)
00356 ++i;
00357 }
00358 if (d != t->sp.N)
00359 FATAL("cmaes_resume_distribution(): Dimension numbers do not match",0,0,0);
00360
00361
00362 while (1) {
00363 if ((res = fscanf(fp, " xmean %lg", &d)) == EOF)
00364 FATAL("cmaes_resume_distribution(): 'xmean' not found",0,0,0);
00365 else if (res==0)
00366 fscanf(fp, " %*s");
00367 else if(res > 0)
00368 break;
00369 }
00370
00371
00372 t->rgxmean[0] = d; res = 1;
00373 for(i = 1; i < t->sp.N; ++i)
00374 res += fscanf(fp, " %lg", &t->rgxmean[i]);
00375 if (res != t->sp.N)
00376 FATAL("cmaes_resume_distribution(): xmean: dimensions differ",0,0,0);
00377
00378
00379 while (1) {
00380 if ((res = fscanf(fp, " path for sigma %lg", &d)) == EOF)
00381 FATAL("cmaes_resume_distribution(): 'path for sigma' not found",0,0,0);
00382 else if (res==0)
00383 fscanf(fp, " %*s");
00384 else if(res > 0)
00385 break;
00386 }
00387
00388
00389 t->rgps[0] = d; res = 1;
00390 for(i = 1; i < t->sp.N; ++i)
00391 res += fscanf(fp, " %lg", &t->rgps[i]);
00392 if (res != t->sp.N)
00393 FATAL("cmaes_resume_distribution(): ps: dimensions differ",0,0,0);
00394
00395
00396 while (1) {
00397 if ((res = fscanf(fp, " path for C %lg", &d)) == EOF)
00398 FATAL("cmaes_resume_distribution(): 'path for C' not found",0,0,0);
00399 else if (res==0)
00400 fscanf(fp, " %*s");
00401 else if(res > 0)
00402 break;
00403 }
00404
00405 t->rgpc[0] = d; res = 1;
00406 for(i = 1; i < t->sp.N; ++i)
00407 res += fscanf(fp, " %lg", &t->rgpc[i]);
00408 if (res != t->sp.N)
00409 FATAL("cmaes_resume_distribution(): pc: dimensions differ",0,0,0);
00410
00411
00412 while (1) {
00413 if ((res = fscanf(fp, " sigma %lg", &d)) == EOF)
00414 FATAL("cmaes_resume_distribution(): 'sigma' not found",0,0,0);
00415 else if (res==0)
00416 fscanf(fp, " %*s");
00417 else if(res > 0)
00418 break;
00419 }
00420 t->sigma = d;
00421
00422
00423 while (1) {
00424 if ((res = fscanf(fp, " covariance matrix %lg", &d)) == EOF)
00425 FATAL("cmaes_resume_distribution(): 'covariance matrix' not found",0,0,0);
00426 else if (res==0)
00427 fscanf(fp, " %*s");
00428 else if(res > 0)
00429 break;
00430 }
00431
00432 t->C[0][0] = d; res = 1;
00433 for (i = 1; i < t->sp.N; ++i)
00434 for (j = 0; j <= i; ++j)
00435 res += fscanf(fp, " %lg", &t->C[i][j]);
00436 if (res != (t->sp.N*t->sp.N+t->sp.N)/2)
00437 FATAL("cmaes_resume_distribution(): C: dimensions differ",0,0,0);
00438
00439 t->flgIniphase = 0;
00440 t->flgEigensysIsUptodate = 0;
00441 t->flgresumedone = 1;
00442 cmaes_UpdateEigensystem(t, 1);
00443
00444 }
00445
00446
00447
00448 void
00449 cmaes_exit(cmaes_t *t)
00450 {
00451 int i, N = t->sp.N;
00452 t->state = -1;
00453 free( t->rgpc);
00454 free( t->rgps);
00455 free( t->rgdTmp);
00456 free( t->rgBDz);
00457 free( --t->rgxmean);
00458 free( --t->rgxold);
00459 free( --t->rgxbestever);
00460 free( --t->rgout);
00461 free( t->rgD);
00462 for (i = 0; i < N; ++i) {
00463 free( t->C[i]);
00464 free( t->B[i]);
00465 }
00466 for (i = 0; i < t->sp.lambda; ++i)
00467 free( --t->rgrgx[i]);
00468 free( t->rgrgx);
00469 free( t->C);
00470 free( t->B);
00471 free( t->index);
00472 free( t->publicFitness);
00473 free( --t->rgFuncValue);
00474 free( --t->arFuncValueHist);
00475 random_exit (&t->rand);
00476 readpara_exit (&t->sp);
00477 }
00478
00479
00480
00481
00482 double const *
00483 cmaes_SetMean(cmaes_t *t, const double *xmean)
00484
00485
00486
00487
00488 {
00489 int i, N=t->sp.N;
00490
00491 if (t->state >= 1 && t->state < 3)
00492 FATAL("cmaes_SetMean: mean cannot be set inbetween the calls of ",
00493 "SamplePopulation and UpdateDistribution",0,0);
00494
00495 if (xmean != NULL && xmean != t->rgxmean)
00496 for(i = 0; i < N; ++i)
00497 t->rgxmean[i] = xmean[i];
00498 else
00499 xmean = t->rgxmean;
00500
00501 return xmean;
00502 }
00503
00504
00505
00506 double * const *
00507 cmaes_SamplePopulation(cmaes_t *t)
00508 {
00509 int iNk, i, j, N=t->sp.N;
00510 double sum;
00511 double const *xmean = t->rgxmean;
00512
00513
00514
00515
00516 cmaes_UpdateEigensystem(t, 0);
00517
00518
00519 TestMinStdDevs(t);
00520
00521 for (iNk = 0; iNk < t->sp.lambda; ++iNk)
00522 {
00523 for (i = 0; i < N; ++i)
00524 t->rgdTmp[i] = t->rgD[i] * random_Gauss(&t->rand);
00525
00526 for (i = 0; i < N; ++i) {
00527 for (j = 0, sum = 0.; j < N; ++j)
00528 sum += t->B[i][j] * t->rgdTmp[j];
00529 t->rgrgx[iNk][i] = xmean[i] + t->sigma * sum;
00530 }
00531 }
00532 if(t->state == 3 || t->gen == 0)
00533 ++t->gen;
00534 t->state = 1;
00535
00536 return(t->rgrgx);
00537 }
00538
00539
00540
00541 double const *
00542 cmaes_ReSampleSingle_old( cmaes_t *t, double *rgx)
00543 {
00544 int i, j, N=t->sp.N;
00545 double sum;
00546
00547 if (rgx == NULL)
00548 FATAL("cmaes_ReSampleSingle(): Missing input double *x",0,0,0);
00549
00550 for (i = 0; i < N; ++i)
00551 t->rgdTmp[i] = t->rgD[i] * random_Gauss(&t->rand);
00552
00553 for (i = 0; i < N; ++i) {
00554 for (j = 0, sum = 0.; j < N; ++j)
00555 sum += t->B[i][j] * t->rgdTmp[j];
00556 rgx[i] = t->rgxmean[i] + t->sigma * sum;
00557 }
00558 return rgx;
00559 }
00560
00561
00562
00563 double * const *
00564 cmaes_ReSampleSingle( cmaes_t *t, int index)
00565 {
00566 int i, j, N=t->sp.N;
00567 double *rgx;
00568 double sum;
00569 static char s[99];
00570
00571 if (index < 0 || index >= t->sp.lambda) {
00572 sprintf(s, "index==%d must be between 0 and %d", index, t->sp.lambda);
00573 FATAL("cmaes_ReSampleSingle(): Population member ",s,0,0);
00574 }
00575 rgx = t->rgrgx[index];
00576
00577 for (i = 0; i < N; ++i)
00578 t->rgdTmp[i] = t->rgD[i] * random_Gauss(&t->rand);
00579
00580 for (i = 0; i < N; ++i) {
00581 for (j = 0, sum = 0.; j < N; ++j)
00582 sum += t->B[i][j] * t->rgdTmp[j];
00583 rgx[i] = t->rgxmean[i] + t->sigma * sum;
00584 }
00585 return(t->rgrgx);
00586 }
00587
00588
00589
00590 double *
00591 cmaes_SampleSingleInto( cmaes_t *t, double *rgx)
00592 {
00593 int i, j, N=t->sp.N;
00594 double sum;
00595
00596 if (rgx == NULL)
00597 rgx = new_double(N);
00598
00599 for (i = 0; i < N; ++i)
00600 t->rgdTmp[i] = t->rgD[i] * random_Gauss(&t->rand);
00601
00602 for (i = 0; i < N; ++i) {
00603 for (j = 0, sum = 0.; j < N; ++j)
00604 sum += t->B[i][j] * t->rgdTmp[j];
00605 rgx[i] = t->rgxmean[i] + t->sigma * sum;
00606 }
00607 return rgx;
00608 }
00609
00610
00611
00612 double *
00613 cmaes_UpdateDistribution( cmaes_t *t, const double *rgFunVal)
00614 {
00615 int i, j, iNk, hsig, N=t->sp.N;
00616 double sum;
00617 double psxps;
00618
00619 if(t->state == 3)
00620 FATAL("cmaes_UpdateDistribution(): You need to call \n",
00621 "SamplePopulation() before update can take place.",0,0);
00622 if(rgFunVal == NULL)
00623 FATAL("cmaes_UpdateDistribution(): ",
00624 "Fitness function value array input is missing.",0,0);
00625
00626 if(t->state == 1)
00627 t->countevals += t->sp.lambda;
00628 else
00629 ERRORMESSAGE("cmaes_UpdateDistribution(): unexpected state",0,0,0);
00630
00631
00632 for (i=0; i < t->sp.lambda; ++i)
00633 t->rgrgx[i][N] = t->rgFuncValue[i] = rgFunVal[i];
00634
00635
00636
00637 Sorted_index(rgFunVal, t->index, t->sp.lambda);
00638
00639
00640 if (t->rgFuncValue[t->index[0]] ==
00641 t->rgFuncValue[t->index[(int)t->sp.lambda/2]]) {
00642 t->sigma *= exp(0.2+t->sp.cs/t->sp.damps);
00643 ERRORMESSAGE("Warning: sigma increased due to equal function values\n",
00644 " Reconsider the formulation of the objective function",0,0);
00645 }
00646
00647
00648 for(i = (int)*(t->arFuncValueHist-1)-1; i > 0; --i)
00649 t->arFuncValueHist[i] = t->arFuncValueHist[i-1];
00650 t->arFuncValueHist[0] = rgFunVal[t->index[0]];
00651
00652
00653 if (t->rgxbestever[N] > t->rgrgx[t->index[0]][N] || t->gen == 1)
00654 for (i = 0; i <= N; ++i) {
00655 t->rgxbestever[i] = t->rgrgx[t->index[0]][i];
00656 t->rgxbestever[N+1] = t->countevals;
00657 }
00658
00659
00660 for (i = 0; i < N; ++i) {
00661 t->rgxold[i] = t->rgxmean[i];
00662 t->rgxmean[i] = 0.;
00663 for (iNk = 0; iNk < t->sp.mu; ++iNk)
00664 t->rgxmean[i] += t->sp.weights[iNk] * t->rgrgx[t->index[iNk]][i];
00665 t->rgBDz[i] = sqrt(t->sp.mueff)*(t->rgxmean[i] - t->rgxold[i])/t->sigma;
00666 }
00667
00668
00669 for (i = 0; i < N; ++i) {
00670 for (j = 0, sum = 0.; j < N; ++j)
00671 sum += t->B[j][i] * t->rgBDz[j];
00672 t->rgdTmp[i] = sum / t->rgD[i];
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 for (i = 0; i < N; ++i) {
00690 for (j = 0, sum = 0.; j < N; ++j)
00691 sum += t->B[i][j] * t->rgdTmp[j];
00692 t->rgps[i] = (1. - t->sp.cs) * t->rgps[i] +
00693 sqrt(t->sp.cs * (2. - t->sp.cs)) * sum;
00694 }
00695
00696
00697 for (i = 0, psxps = 0.; i < N; ++i)
00698 psxps += t->rgps[i] * t->rgps[i];
00699
00700
00701 hsig = sqrt(psxps) / sqrt(1. - pow(1.-t->sp.cs, 2*t->gen)) / t->chiN
00702 < 1.4 + 2./(N+1);
00703 for (i = 0; i < N; ++i) {
00704 t->rgpc[i] = (1. - t->sp.ccumcov) * t->rgpc[i] +
00705 hsig * sqrt(t->sp.ccumcov * (2. - t->sp.ccumcov)) * t->rgBDz[i];
00706 }
00707
00708
00709 if (t->flgIniphase &&
00710 t->gen > douMin(1/t->sp.cs, 1+N/t->sp.mucov))
00711 {
00712 if (psxps / t->sp.damps / (1.-pow((1. - t->sp.cs), t->gen))
00713 < N * 1.05)
00714 t->flgIniphase = 0;
00715 }
00716
00717 #if 0
00718
00719
00720 if(psxps/N > 1.5 + 10.*sqrt(2./N)
00721 && t->arFuncValueHist[0] > t->arFuncValueHist[1]
00722 && t->arFuncValueHist[0] > t->arFuncValueHist[2]) {
00723 double tfac = sqrt((1 + douMax(0, log(psxps/N))) * N / psxps);
00724 for (i=0; i<N; ++i)
00725 t->rgps[i] *= tfac;
00726 psxps *= tfac*tfac;
00727 }
00728 #endif
00729
00730
00731
00732 Adapt_C2(t, hsig);
00733
00734
00735
00736 #if 0
00737 if (t->sp.ccov != 0. && t->flgIniphase == 0) {
00738 int k;
00739
00740 t->flgEigensysIsUptodate = 0;
00741
00742
00743 for (i = 0; i < N; ++i)
00744 for (j = 0; j <=i; ++j) {
00745 t->C[i][j] = (1 - t->sp.ccov) * t->C[i][j]
00746 + t->sp.ccov * (1./t->sp.mucov)
00747 * (t->rgpc[i] * t->rgpc[j]
00748 + (1-hsig)*t->sp.ccumcov*(2.-t->sp.ccumcov) * t->C[i][j]);
00749 for (k = 0; k < t->sp.mu; ++k)
00750 t->C[i][j] += t->sp.ccov * (1-1./t->sp.mucov) * t->sp.weights[k]
00751 * (t->rgrgx[t->index[k]][i] - t->rgxold[i])
00752 * (t->rgrgx[t->index[k]][j] - t->rgxold[j])
00753 / t->sigma / t->sigma;
00754 }
00755 }
00756 #endif
00757
00758
00759
00760 t->sigma *= exp(((sqrt(psxps)/t->chiN)-1.)*t->sp.cs/t->sp.damps);
00761
00762 t->state = 3;
00763
00764 return (t->rgxmean);
00765
00766 }
00767
00768
00769
00770
00771 static void
00772 Adapt_C2(cmaes_t *t, int hsig)
00773 {
00774 int i, j, k, N=t->sp.N;
00775 if (t->sp.ccov != 0. && t->flgIniphase == 0) {
00776
00777
00778 double ccovmu = t->sp.ccov * (1-1./t->sp.mucov);
00779 double sigmasquare = t->sigma * t->sigma;
00780
00781 t->flgEigensysIsUptodate = 0;
00782
00783
00784 for (i = 0; i < N; ++i)
00785 for (j = 0; j <=i; ++j) {
00786 t->C[i][j] = (1 - t->sp.ccov) * t->C[i][j]
00787 + t->sp.ccov * (1./t->sp.mucov)
00788 * (t->rgpc[i] * t->rgpc[j]
00789 + (1-hsig)*t->sp.ccumcov*(2.-t->sp.ccumcov) * t->C[i][j]);
00790 for (k = 0; k < t->sp.mu; ++k) {
00791 t->C[i][j] += ccovmu * t->sp.weights[k]
00792 * (t->rgrgx[t->index[k]][i] - t->rgxold[i])
00793 * (t->rgrgx[t->index[k]][j] - t->rgxold[j])
00794 / sigmasquare;
00795 }
00796 }
00797
00798 t->maxdiagC = t->mindiagC = t->C[0][0];
00799 for (i = 1; i < N; ++i) {
00800 if (t->maxdiagC < t->C[i][i])
00801 t->maxdiagC = t->C[i][i];
00802 else if (t->mindiagC > t->C[i][i])
00803 t->mindiagC = t->C[i][i];
00804 }
00805 }
00806 }
00807
00808
00809
00810
00811 static void
00812 TestMinStdDevs(cmaes_t *t)
00813
00814 {
00815 int i, N = t->sp.N;
00816 if (t->sp.rgDiffMinChange == NULL)
00817 return;
00818
00819 for (i = 0; i < N; ++i)
00820 while (t->sigma * sqrt(t->C[i][i]) < t->sp.rgDiffMinChange[i])
00821 t->sigma *= exp(0.05+t->sp.cs/t->sp.damps);
00822
00823 }
00824
00825
00826
00827
00828 void cmaes_WriteToFile(cmaes_t *t, const char *key, const char *name)
00829 {
00830 cmaes_WriteToFileAW(t, key, name, strdup("a"));
00831 }
00832
00833
00834
00835 void cmaes_WriteToFileAW(cmaes_t *t, const char *key, const char *name,
00836 const char *appendwrite)
00837 {
00838 const char *s = "tmpcmaes.dat";
00839 FILE *fp;
00840
00841 if (name == NULL)
00842 name = s;
00843
00844 fp = fopen( name, appendwrite);
00845
00846 if(fp == NULL) {
00847 ERRORMESSAGE("cmaes_WriteToFile(): could not open '", name,
00848 "' with flag ", appendwrite);
00849 return;
00850 }
00851
00852 if (appendwrite[0] == 'w') {
00853
00854 fprintf(fp, "%% # %s (randomSeed=%d, %s)\n", key, t->sp.seed, getTimeStr());
00855 } else
00856 if (t->gen > 0 || strncmp(name, "outcmaesfit", 11) != 0)
00857 cmaes_WriteToFilePtr(t, key, fp);
00858
00859 fclose(fp);
00860
00861 }
00862
00863
00864 void cmaes_WriteToFilePtr(cmaes_t *t, const char *key, FILE *fp)
00865
00866
00867
00868
00869
00870
00871
00872
00873 {
00874 int i, k, N=(t ? t->sp.N : 0);
00875 char const *keyend, *keystart;
00876 const char *s = "few";
00877 if (key == NULL)
00878 key = s;
00879 keystart = key;
00880 keyend = key + strlen(key);
00881
00882 while (key < keyend)
00883 {
00884 if (strncmp(key, "axisratio", 9) == 0)
00885 {
00886 fprintf(fp, "%.2e", sqrt(t->maxEW/t->minEW));
00887 while (*key != '+' && *key != '\0' && key < keyend)
00888 ++key;
00889 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00890 }
00891 if (strncmp(key, "idxminSD", 8) == 0)
00892 {
00893 int mini=0; for(i=N-1;i>0;--i) if(t->mindiagC==t->C[i][i]) mini=i;
00894 fprintf(fp, "%d", mini+1);
00895 while (*key != '+' && *key != '\0' && key < keyend)
00896 ++key;
00897 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00898 }
00899 if (strncmp(key, "idxmaxSD", 8) == 0)
00900 {
00901 int maxi=0; for(i=N-1;i>0;--i) if(t->maxdiagC==t->C[i][i]) maxi=i;
00902 fprintf(fp, "%d", maxi+1);
00903 while (*key != '+' && *key != '\0' && key < keyend)
00904 ++key;
00905 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00906 }
00907
00908 if (strncmp(key, "B", 1) == 0)
00909 {
00910
00911 int j, *index=(int*)(new_void(N,sizeof(int)));
00912 Sorted_index(t->rgD, index, N);
00913
00914 for (i = 0; i < N; ++i)
00915 for (j = 0; j < N; ++j)
00916 fprintf(fp, "%g%c", t->B[j][index[N-1-i]], (j==N-1)?'\n':'\t');
00917 ++key;
00918 free(index);
00919 }
00920
00921 if (strncmp(key, "C", 1) == 0)
00922 {
00923 int j;
00924 for (i = 0; i < N; ++i)
00925 for (j = 0; j <= i; ++j)
00926 fprintf(fp, "%g%c", t->C[i][j], (j==i)?'\n':'\t');
00927 ++key;
00928 }
00929
00930 if (strncmp(key, "clock", 4) == 0)
00931 {
00932 timings_update(&t->eigenTimings);
00933 fprintf(fp, "%.1f %.1f", t->eigenTimings.totaltime,
00934 t->eigenTimings.tictoctime);
00935 while (*key != '+' && *key != '\0' && key < keyend)
00936 ++key;
00937 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00938 }
00939
00940 if (strncmp(key, "stddevratio", 11) == 0)
00941 {
00942 fprintf(fp, "%g", sqrt(t->maxdiagC/t->mindiagC));
00943 while (*key != '+' && *key != '\0' && key < keyend)
00944 ++key;
00945 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00946 }
00947
00948 if (strncmp(key, "coorstddev", 10) == 0
00949 || strncmp(key, "stddev", 6) == 0)
00950 {
00951 for (i = 0; i < N; ++i)
00952 fprintf(fp, "%s%g", (i==0) ? "":"\t", t->sigma*sqrt(t->C[i][i]));
00953 while (*key != '+' && *key != '\0' && key < keyend)
00954 ++key;
00955 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00956 }
00957
00958 if (strncmp(key, "diag(D)", 7) == 0)
00959 {
00960 for (i = 0; i < N; ++i)
00961 t->rgdTmp[i] = t->rgD[i];
00962 qsort(t->rgdTmp, (unsigned) N, sizeof(double), &SignOfDiff);
00963 for (i = 0; i < N; ++i)
00964 fprintf(fp, "%s%g", (i==0) ? "":"\t", t->rgdTmp[i]);
00965 while (*key != '+' && *key != '\0' && key < keyend)
00966 ++key;
00967 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00968 }
00969 if (strncmp(key, "dim", 3) == 0)
00970 {
00971 fprintf(fp, "%d", N);
00972 while (*key != '+' && *key != '\0' && key < keyend)
00973 ++key;
00974 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00975 }
00976 if (strncmp(key, "eval", 4) == 0)
00977 {
00978 fprintf(fp, "%.0f", t->countevals);
00979 while (*key != '+' && *key != '\0' && key < keyend)
00980 ++key;
00981 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
00982 }
00983 if (strncmp(key, "few(diag(D))", 12) == 0)
00984 {
00985 int add = (int)(0.5 + (N + 1.) / 5.);
00986 for (i = 0; i < N; ++i)
00987 t->rgdTmp[i] = t->rgD[i];
00988 qsort(t->rgdTmp, (unsigned) N, sizeof(double), &SignOfDiff);
00989 for (i = 0; i < N-1; i+=add)
00990 fprintf(fp, "%s%g", (i==0) ? "":"\t", t->rgdTmp[N-1-i]);
00991 fprintf(fp, "\t%g\n", t->rgdTmp[0]);
00992 break;
00993 }
00994 if (strncmp(key, "fewinfo", 7) == 0) {
00995 fprintf(fp," Fevals Function Value Sigma ");
00996 fprintf(fp, "MaxCoorDev MinCoorDev AxisRatio MinDii Time in eig\n");
00997 while (*key != '+' && *key != '\0' && key < keyend)
00998 ++key;
00999 }
01000 if (strncmp(key, "few", 3) == 0) {
01001 fprintf(fp, " %5.0f ", t->countevals);
01002 fprintf(fp, "%.15e", t->rgFuncValue[t->index[0]]);
01003 fprintf(fp, " %.2e %.2e %.2e", t->sigma, t->sigma*sqrt(t->maxdiagC),
01004 t->sigma*sqrt(t->mindiagC));
01005 fprintf(fp, " %.2e %.2e", sqrt(t->maxEW/t->minEW), sqrt(t->minEW));
01006 while (*key != '+' && *key != '\0' && key < keyend)
01007 ++key;
01008 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01009 }
01010 if (strncmp(key, "funval", 6) == 0 || strncmp(key, "fitness", 6) == 0)
01011 {
01012 fprintf(fp, "%.15e", t->rgFuncValue[t->index[0]]);
01013 while (*key != '+' && *key != '\0' && key < keyend)
01014 ++key;
01015 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01016 }
01017 if (strncmp(key, "fbestever", 9) == 0)
01018 {
01019 fprintf(fp, "%.15e", t->rgxbestever[N]);
01020 while (*key != '+' && *key != '\0' && key < keyend)
01021 ++key;
01022 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01023 }
01024 if (strncmp(key, "fmedian", 7) == 0)
01025 {
01026 fprintf(fp, "%.15e", t->rgFuncValue[t->index[(int)(t->sp.lambda/2)]]);
01027 while (*key != '+' && *key != '\0' && key < keyend)
01028 ++key;
01029 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01030 }
01031 if (strncmp(key, "fworst", 6) == 0)
01032 {
01033 fprintf(fp, "%.15e", t->rgFuncValue[t->index[t->sp.lambda-1]]);
01034 while (*key != '+' && *key != '\0' && key < keyend)
01035 ++key;
01036 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01037 }
01038 if (strncmp(key, "arfunval", 8) == 0 || strncmp(key, "arfitness", 8) == 0)
01039 {
01040 for (i = 0; i < N; ++i)
01041 fprintf(fp, "%s%.10e", (i==0) ? "" : "\t",
01042 t->rgFuncValue[t->index[i]]);
01043 while (*key != '+' && *key != '\0' && key < keyend)
01044 ++key;
01045 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01046 }
01047 if (strncmp(key, "gen", 3) == 0)
01048 {
01049 fprintf(fp, "%.0f", t->gen);
01050 while (*key != '+' && *key != '\0' && key < keyend)
01051 ++key;
01052 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01053 }
01054 if (strncmp(key, "iter", 4) == 0)
01055 {
01056 fprintf(fp, "%.0f", t->gen);
01057 while (*key != '+' && *key != '\0' && key < keyend)
01058 ++key;
01059 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01060 }
01061 if (strncmp(key, "sigma", 5) == 0)
01062 {
01063 fprintf(fp, "%.4e", t->sigma);
01064 while (*key != '+' && *key != '\0' && key < keyend)
01065 ++key;
01066 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01067 }
01068 if (strncmp(key, "minSD", 5) == 0)
01069 {
01070 fprintf(fp, "%.4e", sqrt(t->mindiagC));
01071 while (*key != '+' && *key != '\0' && key < keyend)
01072 ++key;
01073 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01074 }
01075 if (strncmp(key, "maxSD", 5) == 0)
01076 {
01077 fprintf(fp, "%.4e", sqrt(t->maxdiagC));
01078 while (*key != '+' && *key != '\0' && key < keyend)
01079 ++key;
01080 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01081 }
01082 if (strncmp(key, "mindii", 6) == 0)
01083 {
01084 fprintf(fp, "%.4e", sqrt(t->minEW));
01085 while (*key != '+' && *key != '\0' && key < keyend)
01086 ++key;
01087 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01088 }
01089 if (strncmp(key, "0", 1) == 0)
01090 {
01091 fprintf(fp, "0");
01092 ++key;
01093 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01094 }
01095 if (strncmp(key, "lambda", 6) == 0)
01096 {
01097 fprintf(fp, "%d", t->sp.lambda);
01098 while (*key != '+' && *key != '\0' && key < keyend)
01099 ++key;
01100 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01101 }
01102 if (strncmp(key, "N", 1) == 0)
01103 {
01104 fprintf(fp, "%d", N);
01105 ++key;
01106 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01107 }
01108 if (strncmp(key, "resume", 6) == 0)
01109 {
01110 fprintf(fp, "\n# resume %d\n", N);
01111 fprintf(fp, "xmean\n");
01112 cmaes_WriteToFilePtr(t, "xmean", fp);
01113 fprintf(fp, "path for sigma\n");
01114 for(i=0; i<N; ++i)
01115 fprintf(fp, "%g%s", t->rgps[i], (i==N-1) ? "\n":"\t");
01116 fprintf(fp, "path for C\n");
01117 for(i=0; i<N; ++i)
01118 fprintf(fp, "%g%s", t->rgpc[i], (i==N-1) ? "\n":"\t");
01119 fprintf(fp, "sigma %g\n", t->sigma);
01120
01121 fprintf(fp, "covariance matrix\n");
01122 cmaes_WriteToFilePtr(t, "C", fp);
01123 while (*key != '+' && *key != '\0' && key < keyend)
01124 ++key;
01125 }
01126 if (strncmp(key, "xbest", 5) == 0) {
01127 for(i=0; i<N; ++i)
01128 fprintf(fp, "%s%g", (i==0) ? "":"\t", t->rgrgx[t->index[0]][i]);
01129 while (*key != '+' && *key != '\0' && key < keyend)
01130 ++key;
01131 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01132 }
01133 if (strncmp(key, "xmean", 5) == 0) {
01134 for(i=0; i<N; ++i)
01135 fprintf(fp, "%s%g", (i==0) ? "":"\t", t->rgxmean[i]);
01136 while (*key != '+' && *key != '\0' && key < keyend)
01137 ++key;
01138 fprintf(fp, "%c", (*key=='+') ? '\t':'\n');
01139 }
01140 if (strncmp(key, "all", 3) == 0)
01141 {
01142 time_t ti = time(NULL);
01143 fprintf(fp, "\n# --------- %s\n", asctime(localtime(&ti)));
01144 fprintf(fp, " N %d\n", N);
01145 fprintf(fp, " seed %d\n", t->sp.seed);
01146 fprintf(fp, "function evaluations %.0f\n", t->countevals);
01147 fprintf(fp, "elapsed (CPU) time [s] %.2f\n", t->eigenTimings.totaltime);
01148 fprintf(fp, "function value f(x)=%g\n", t->rgrgx[t->index[0]][N]);
01149 fprintf(fp, "maximal standard deviation %g\n", t->sigma*sqrt(t->maxdiagC));
01150 fprintf(fp, "minimal standard deviation %g\n", t->sigma*sqrt(t->mindiagC));
01151 fprintf(fp, "sigma %g\n", t->sigma);
01152 fprintf(fp, "axisratio %g\n", rgdouMax(t->rgD, N)/rgdouMin(t->rgD, N));
01153 fprintf(fp, "xbestever found after %.0f evaluations, function value %g\n",
01154 t->rgxbestever[N+1], t->rgxbestever[N]);
01155 for(i=0; i<N; ++i)
01156 fprintf(fp, " %12g%c", t->rgxbestever[i],
01157 (i%5==4||i==N-1)?'\n':' ');
01158 fprintf(fp, "xbest (of last generation, function value %g)\n",
01159 t->rgrgx[t->index[0]][N]);
01160 for(i=0; i<N; ++i)
01161 fprintf(fp, " %12g%c", t->rgrgx[t->index[0]][i],
01162 (i%5==4||i==N-1)?'\n':' ');
01163 fprintf(fp, "xmean \n");
01164 for(i=0; i<N; ++i)
01165 fprintf(fp, " %12g%c", t->rgxmean[i],
01166 (i%5==4||i==N-1)?'\n':' ');
01167 fprintf(fp, "Standard deviation of coordinate axes (sigma*sqrt(diag(C)))\n");
01168 for(i=0; i<N; ++i)
01169 fprintf(fp, " %12g%c", t->sigma*sqrt(t->C[i][i]),
01170 (i%5==4||i==N-1)?'\n':' ');
01171 fprintf(fp, "Main axis lengths of mutation ellipsoid (sigma*diag(D))\n");
01172 for (i = 0; i < N; ++i)
01173 t->rgdTmp[i] = t->rgD[i];
01174 qsort(t->rgdTmp, (unsigned) N, sizeof(double), &SignOfDiff);
01175 for(i=0; i<N; ++i)
01176 fprintf(fp, " %12g%c", t->sigma*t->rgdTmp[N-1-i],
01177 (i%5==4||i==N-1)?'\n':' ');
01178 fprintf(fp, "Longest axis (b_i where d_ii=max(diag(D))\n");
01179 k = MaxIdx(t->rgD, N);
01180 for(i=0; i<N; ++i)
01181 fprintf(fp, " %12g%c", t->B[i][k], (i%5==4||i==N-1)?'\n':' ');
01182 fprintf(fp, "Shortest axis (b_i where d_ii=max(diag(D))\n");
01183 k = MinIdx(t->rgD, N);
01184 for(i=0; i<N; ++i)
01185 fprintf(fp, " %12g%c", t->B[i][k], (i%5==4||i==N-1)?'\n':' ');
01186 while (*key != '+' && *key != '\0' && key < keyend)
01187 ++key;
01188 }
01189
01190 #if 0
01191 s0 = key;
01192 d = cmaes_Get(t, key);
01193 if (key == s0)
01194 {
01195
01196
01197 }
01198 #endif
01199
01200 if (*key == '\0')
01201 break;
01202 else if (*key != '+') {
01203 ERRORMESSAGE("cmaes_t:WriteToFilePtr(): unrecognized key '", key, "'", 0);
01204 while (*key != '+' && *key != '\0' && key < keyend)
01205 ++key;
01206 }
01207 while (*key == '+')
01208 ++key;
01209 }
01210
01211 if (key > keyend)
01212 FATAL("cmaes_t:WriteToFilePtr(): BUG regarding key sequence",0,0,0);
01213
01214 }
01215
01216
01217 double
01218 cmaes_Get( cmaes_t *t, char const *s)
01219 {
01220 int N=t->sp.N;
01221
01222 if (strncmp(s, "axisratio", 5) == 0) {
01223 return (rgdouMax(t->rgD, N)/rgdouMin(t->rgD, N));
01224 }
01225 else if (strncmp(s, "eval", 4) == 0) {
01226 return (t->countevals);
01227 }
01228 else if (strncmp(s, "fctvalue", 6) == 0
01229 || strncmp(s, "funcvalue", 6) == 0
01230 || strncmp(s, "funvalue", 6) == 0
01231 || strncmp(s, "fitness", 3) == 0) {
01232 return(t->rgFuncValue[t->index[0]]);
01233 }
01234 else if (strncmp(s, "fbestever", 7) == 0) {
01235 return(t->rgxbestever[N]);
01236 }
01237 else if (strncmp(s, "generation", 3) == 0
01238 || strncmp(s, "iteration", 4) == 0) {
01239 return(t->gen);
01240 }
01241 else if (strncmp(s, "maxeval", 4) == 0
01242 || strncmp(s, "MaxFunEvals", 8) == 0
01243 || strncmp(s, "stopMaxFunEvals", 12) == 0) {
01244 return(t->sp.stopMaxFunEvals);
01245 }
01246 else if (strncmp(s, "maxgen", 4) == 0
01247 || strncmp(s, "MaxIter", 7) == 0
01248 || strncmp(s, "stopMaxIter", 11) == 0) {
01249 return(ceil(t->sp.stopMaxIter));
01250 }
01251 else if (strncmp(s, "maxaxislength", 5) == 0) {
01252 return(t->sigma * sqrt(t->maxEW));
01253 }
01254 else if (strncmp(s, "minaxislength", 5) == 0) {
01255 return(t->sigma * sqrt(t->minEW));
01256 }
01257 else if (strncmp(s, "maxstddev", 4) == 0) {
01258 return(t->sigma * sqrt(t->maxdiagC));
01259 }
01260 else if (strncmp(s, "minstddev", 4) == 0) {
01261 return(t->sigma * sqrt(t->mindiagC));
01262 }
01263 else if (strncmp(s, "N", 1) == 0 || strcmp(s, "n") == 0 ||
01264 strncmp(s, "dimension", 3) == 0) {
01265 return (N);
01266 }
01267 else if (strncmp(s, "lambda", 3) == 0
01268 || strncmp(s, "samplesize", 8) == 0
01269 || strncmp(s, "popsize", 7) == 0) {
01270 return(t->sp.lambda);
01271 }
01272 else if (strncmp(s, "sigma", 3) == 0) {
01273 return(t->sigma);
01274 }
01275 FATAL( "cmaes_Get(cmaes_t, char const * s): No match found for s='", s, "'",0);
01276 return(0);
01277 }
01278
01279
01280 double *
01281 cmaes_GetInto( cmaes_t *t, char const *s, double *res)
01282 {
01283 int i, N = t->sp.N;
01284 double const * res0 = cmaes_GetPtr(t, s);
01285 if (res == NULL)
01286 res = new_double(N);
01287 for (i = 0; i < N; ++i)
01288 res[i] = res0[i];
01289 return res;
01290 }
01291
01292
01293 double *
01294 cmaes_GetNew( cmaes_t *t, char const *s)
01295 {
01296 return (cmaes_GetInto(t, s, NULL));
01297 }
01298
01299
01300 const double *
01301 cmaes_GetPtr( cmaes_t *t, char const *s)
01302 {
01303 int i, N=t->sp.N;
01304
01305
01306 if (strncmp(s, "diag(C)", 7) == 0) {
01307 for (i = 0; i < N; ++i)
01308 t->rgout[i] = t->C[i][i];
01309 return(t->rgout);
01310 }
01311
01312 else if (strncmp(s, "diag(D)", 7) == 0) {
01313 return(t->rgD);
01314 }
01315
01316 else if (strncmp(s, "stddev", 3) == 0) {
01317 for (i = 0; i < N; ++i)
01318 t->rgout[i] = t->sigma * sqrt(t->C[i][i]);
01319 return(t->rgout);
01320 }
01321
01322 else if (strncmp(s, "xbestever", 7) == 0)
01323 return(t->rgxbestever);
01324
01325 else if (strncmp(s, "xbest", 5) == 0)
01326 return(t->rgrgx[t->index[0]]);
01327
01328 else if (strncmp(s, "xmean", 1) == 0)
01329 return(t->rgxmean);
01330
01331 return(NULL);
01332 }
01333
01334
01335
01336
01337
01338
01339 const char *
01340 cmaes_TestForTermination( cmaes_t *t)
01341 {
01342 double range, fac;
01343 int iAchse, iKoo;
01344 static char sTestOutString[3024];
01345 char * cp = sTestOutString;
01346 int i, cTemp, N=t->sp.N;
01347 cp[0] = '\0';
01348
01349
01350 if ((t->gen > 1 || t->state > 1) && t->sp.stStopFitness.flg &&
01351 t->rgFuncValue[t->index[0]] <= t->sp.stStopFitness.val)
01352 cp += sprintf(cp, "Fitness: function value %7.2e <= stopFitness (%7.2e)\n",
01353 t->rgFuncValue[t->index[0]], t->sp.stStopFitness.val);
01354
01355
01356 range = douMax(rgdouMax(t->arFuncValueHist, (int)douMin(t->gen,*(t->arFuncValueHist-1))),
01357 rgdouMax(t->rgFuncValue, t->sp.lambda)) -
01358 douMin(rgdouMin(t->arFuncValueHist, (int)douMin(t->gen, *(t->arFuncValueHist-1))),
01359 rgdouMin(t->rgFuncValue, t->sp.lambda));
01360
01361 if (t->gen > 0 && range <= t->sp.stopTolFun) {
01362 cp += sprintf(cp,
01363 "TolFun: function value differences %7.2e < stopTolFun=%7.2e\n",
01364 range, t->sp.stopTolFun);
01365 }
01366
01367
01368 if (t->gen > *(t->arFuncValueHist-1)) {
01369 range = rgdouMax(t->arFuncValueHist, (int)*(t->arFuncValueHist-1))
01370 - rgdouMin(t->arFuncValueHist, (int)*(t->arFuncValueHist-1));
01371 if (range <= t->sp.stopTolFunHist)
01372 cp += sprintf(cp,
01373 "TolFunHist: history of function value changes %7.2e stopTolFunHist=%7.2e",
01374 range, t->sp.stopTolFunHist);
01375 }
01376
01377
01378 for(i=0, cTemp=0; i<N; ++i) {
01379 cTemp += (t->sigma * sqrt(t->C[i][i]) < t->sp.stopTolX) ? 1 : 0;
01380 cTemp += (t->sigma * t->rgpc[i] < t->sp.stopTolX) ? 1 : 0;
01381 }
01382 if (cTemp == 2*N) {
01383 cp += sprintf(cp,
01384 "TolX: object variable changes below %7.2e \n",
01385 t->sp.stopTolX);
01386 }
01387
01388
01389 for(i=0; i<N; ++i) {
01390 if (t->sigma * sqrt(t->C[i][i]) > t->sp.stopTolUpXFactor * t->sp.rgInitialStds[i])
01391 break;
01392 }
01393 if (i < N) {
01394 cp += sprintf(cp,
01395 "TolUpX: standard deviation increased by more than %7.2e, larger initial standard deviation recommended \n",
01396 t->sp.stopTolUpXFactor);
01397 }
01398
01399
01400 if (t->maxEW >= t->minEW * t->dMaxSignifKond) {
01401 cp += sprintf(cp,
01402 "ConditionNumber: maximal condition number %7.2e reached. maxEW=%7.2e,minEW=%7.2e,maxdiagC=%7.2e,mindiagC=%7.2e\n",
01403 t->dMaxSignifKond, t->maxEW, t->minEW, t->maxdiagC, t->mindiagC);
01404 }
01405
01406
01407
01408 for (iAchse = 0; iAchse < N; ++iAchse)
01409 {
01410 fac = 0.1 * t->sigma * t->rgD[iAchse];
01411 for (iKoo = 0; iKoo < N; ++iKoo){
01412 if (t->rgxmean[iKoo] != t->rgxmean[iKoo] + fac * t->B[iKoo][iAchse])
01413 break;
01414 }
01415 if (iKoo == N)
01416 {
01417
01418 cp += sprintf(cp,
01419 "NoEffectAxis: standard deviation 0.1*%7.2e in principal axis %d without effect\n",
01420 fac/0.1, iAchse);
01421 break;
01422 }
01423 }
01424
01425
01426 for (iKoo = 0; iKoo < N; ++iKoo)
01427 {
01428 if (t->rgxmean[iKoo] == t->rgxmean[iKoo] +
01429 0.2*t->sigma*sqrt(t->C[iKoo][iKoo]))
01430 {
01431
01432
01433 cp += sprintf(cp,
01434 "NoEffectCoordinate: standard deviation 0.2*%7.2e in coordinate %d without effect\n",
01435 t->sigma*sqrt(t->C[iKoo][iKoo]), iKoo);
01436 break;
01437 }
01438
01439 }
01440
01441
01442 if(t->countevals >= t->sp.stopMaxFunEvals)
01443 cp += sprintf(cp, "MaxFunEvals: conducted function evaluations %.0f >= %g\n",
01444 t->countevals, t->sp.stopMaxFunEvals);
01445
01446
01447
01448
01449 if(t->flgStop)
01450 cp += sprintf(cp, "Manual: stop signal read\n");
01451
01452 #if 0
01453 else if (0) {
01454 for(i=0, cTemp=0; i<N; ++i) {
01455 cTemp += (sigma * sqrt(C[i][i]) < stopdx) ? 1 : 0;
01456 cTemp += (sigma * rgpc[i] < stopdx) ? 1 : 0;
01457 }
01458 if (cTemp == 2*N)
01459 flgStop = 1;
01460 }
01461 #endif
01462
01463 if (cp - sTestOutString>320)
01464 ERRORMESSAGE("Bug in cmaes_t:Test(): sTestOutString too short",0,0,0);
01465
01466 if (cp != sTestOutString) {
01467 return sTestOutString;
01468 }
01469
01470 return(NULL);
01471
01472 }
01473
01474
01475 void cmaes_ReadSignals(cmaes_t *t, char const *filename)
01476 {
01477 const char *s = "signals.par";
01478 FILE *fp;
01479 if (filename == NULL)
01480 filename = s;
01481 fp = fopen( filename, "r");
01482 if(fp == NULL) {
01483 return;
01484 }
01485 cmaes_ReadFromFilePtr( t, fp);
01486 fclose(fp);
01487 }
01488
01489 void cmaes_ReadFromFilePtr( cmaes_t *t, FILE *fp)
01490
01491
01492 {
01493 const char *keys[15];
01494 char s[199], sin1[99], sin2[129], sin3[99], sin4[99];
01495 int ikey, ckeys, nb;
01496 double d;
01497 static int flglockprint = 0;
01498 static int flglockwrite = 0;
01499 static long countiterlastwritten;
01500 static long maxdiffitertowrite;
01501 int flgprinted = 0;
01502 int flgwritten = 0;
01503 double deltaprinttime = time(NULL)-t->printtime;
01504 double deltawritetime = time(NULL)-t->writetime;
01505 double deltaprinttimefirst = t->firstprinttime ? time(NULL)-t->firstprinttime : 0;
01506 double deltawritetimefirst = t->firstwritetime ? time(NULL)-t->firstwritetime : 0;
01507 if (countiterlastwritten > t->gen) {
01508 maxdiffitertowrite = 0;
01509 countiterlastwritten = 0;
01510 }
01511
01512 keys[0] = " stop%98s %98s";
01513
01514 keys[1] = " print %98s %98s";
01515 keys[2] = " write %98s %128s %98s";
01516 keys[3] = " check%98s %98s";
01517 keys[4] = " maxTimeFractionForEigendecompostion %98s";
01518 ckeys = 5;
01519 strcpy(sin2, "tmpcmaes.dat");
01520
01521 if (cmaes_TestForTermination(t))
01522 {
01523 deltaprinttime = time(NULL);
01524 deltawritetime = time(NULL);
01525 }
01526 while(fgets(s, sizeof(s), fp) != NULL)
01527 {
01528 if (s[0] == '#' || s[0] == '%')
01529 continue;
01530 sin1[0] = sin2[0] = sin3[0] = sin4[0] = '\0';
01531 for (ikey=0; ikey < ckeys; ++ikey)
01532 {
01533 if((nb=sscanf(s, keys[ikey], sin1, sin2, sin3, sin4)) >= 1)
01534 {
01535 switch(ikey) {
01536 case 0 :
01537 if (strncmp(sin1, "now", 3) == 0)
01538 t->flgStop = 1;
01539 else if (strncmp(sin1, "MaxFunEvals", 11) == 0) {
01540 if (sscanf(sin2, " %lg", &d) == 1)
01541 t->sp.stopMaxFunEvals = d;
01542 }
01543 else if (strncmp(sin1, "MaxIter", 4) == 0) {
01544 if (sscanf(sin2, " %lg", &d) == 1)
01545 t->sp.stopMaxIter = d;
01546 }
01547 else if (strncmp(sin1, "Fitness", 7) == 0) {
01548 if (sscanf(sin2, " %lg", &d) == 1)
01549 {
01550 t->sp.stStopFitness.flg = 1;
01551 t->sp.stStopFitness.val = d;
01552 }
01553 }
01554 else if (strncmp(sin1, "TolFunHist", 10) == 0) {
01555 if (sscanf(sin2, " %lg", &d) == 1)
01556 t->sp.stopTolFunHist = d;
01557 }
01558 else if (strncmp(sin1, "TolFun", 6) == 0) {
01559 if (sscanf(sin2, " %lg", &d) == 1)
01560 t->sp.stopTolFun = d;
01561 }
01562 else if (strncmp(sin1, "TolX", 4) == 0) {
01563 if (sscanf(sin2, " %lg", &d) == 1)
01564 t->sp.stopTolX = d;
01565 }
01566 else if (strncmp(sin1, "TolUpXFactor", 4) == 0) {
01567 if (sscanf(sin2, " %lg", &d) == 1)
01568 t->sp.stopTolUpXFactor = d;
01569 }
01570 break;
01571 case 1 :
01572 d = 1;
01573 if (sscanf(sin2, "%lg", &d) < 1 && deltaprinttimefirst < 1)
01574 d = 0;
01575 if (deltaprinttime >= d && !flglockprint) {
01576 cmaes_WriteToFilePtr(t, sin1, stdout);
01577 flgprinted = 1;
01578 }
01579 if(d < 0)
01580 flglockprint += 2;
01581 break;
01582 case 2 :
01583
01584 if (t->countevals < t->sp.lambda && t->flgresumedone == 0)
01585 cmaes_WriteToFileAW(t, sin1, sin2, "w");
01586 d = 0.9;
01587 if (sscanf(sin3, "%lg", &d) < 1 && deltawritetimefirst < 2)
01588 d = 0;
01589 if(d < 0)
01590 flglockwrite += 2;
01591 if (!flglockwrite) {
01592 if (deltawritetime >= d) {
01593 cmaes_WriteToFile(t, sin1, sin2);
01594 flgwritten = 1;
01595 } else if (d < 1
01596 && t->gen-countiterlastwritten > maxdiffitertowrite) {
01597 cmaes_WriteToFile(t, sin1, sin2);
01598 flgwritten = 1;
01599 }
01600 }
01601 break;
01602 case 3 :
01603 if (strncmp(sin1, "eigen", 5) == 0) {
01604 if (sscanf(sin2, " %lg", &d) == 1) {
01605 if (d > 0)
01606 t->flgCheckEigen = 1;
01607 else
01608 t->flgCheckEigen = 0;
01609 }
01610 else
01611 t->flgCheckEigen = 0;
01612 }
01613 break;
01614 case 4 :
01615 if (sscanf(sin1, " %lg", &d) == 1)
01616 t->sp.updateCmode.maxtime = d;
01617 break;
01618 default :
01619 break;
01620 }
01621 break;
01622 }
01623 }
01624 }
01625 if (t->writetime == 0)
01626 t->firstwritetime = time(NULL);
01627 if (t->printtime == 0)
01628 t->firstprinttime = time(NULL);
01629
01630 if (flgprinted)
01631 t->printtime = time(NULL);
01632 if (flgwritten) {
01633 t->writetime = time(NULL);
01634 if (t->gen-countiterlastwritten > maxdiffitertowrite)
01635 ++maxdiffitertowrite;
01636 countiterlastwritten = (long int) t->gen;
01637 }
01638 --flglockprint;
01639 --flglockwrite;
01640 flglockprint = (flglockprint > 0) ? 1 : 0;
01641 flglockwrite = (flglockwrite > 0) ? 1 : 0;
01642 }
01643
01644
01645 static int
01646 Check_Eigen( int N, double **C, double *diag, double **Q)
01647
01648
01649
01650
01651
01652
01653
01654 {
01655
01656 int i, j, k, res = 0;
01657 double cc, dd;
01658 static char s[324];
01659
01660 for (i=0; i < N; ++i)
01661 for (j=0; j < N; ++j) {
01662 for (cc=0.,dd=0., k=0; k < N; ++k) {
01663 cc += diag[k] * Q[i][k] * Q[j][k];
01664 dd += Q[i][k] * Q[j][k];
01665 }
01666
01667 if (fabs(cc - C[i>j?i:j][i>j?j:i])/sqrt(C[i][i]*C[j][j]) > 1e-10
01668 && fabs(cc - C[i>j?i:j][i>j?j:i]) > 3e-14) {
01669 sprintf(s, "%d %d: %.17e %.17e, %e",
01670 i, j, cc, C[i>j?i:j][i>j?j:i], cc-C[i>j?i:j][i>j?j:i]);
01671 ERRORMESSAGE("cmaes_t:Eigen(): imprecise result detected ",
01672 s, 0, 0);
01673 ++res;
01674 }
01675 if (fabs(dd - (i==j)) > 1e-10) {
01676 sprintf(s, "%d %d %.17e ", i, j, dd);
01677 ERRORMESSAGE("cmaes_t:Eigen(): imprecise result detected (Q not orthog.)",
01678 s, 0, 0);
01679 ++res;
01680 }
01681 }
01682 return res;
01683 }
01684
01685
01686
01687 void
01688 cmaes_UpdateEigensystem(cmaes_t *t, int flgforce)
01689 {
01690 int i, N = t->sp.N;
01691
01692 timings_update(&t->eigenTimings);
01693
01694 if(flgforce == 0) {
01695 if (t->flgEigensysIsUptodate == 1)
01696 return;
01697
01698
01699 if (t->sp.updateCmode.flgalways == 0
01700 && t->gen < t->genOfEigensysUpdate + t->sp.updateCmode.modulo
01701 )
01702 return;
01703
01704
01705 if (t->sp.updateCmode.maxtime < 1.00
01706 && t->eigenTimings.tictoctime > t->sp.updateCmode.maxtime * t->eigenTimings.totaltime
01707 && t->eigenTimings.tictoctime > 0.0002)
01708 return;
01709 }
01710 timings_tic(&t->eigenTimings);
01711
01712 Eigen( N, t->C, t->rgD, t->B, t->rgdTmp);
01713
01714 timings_toc(&t->eigenTimings);
01715
01716
01717 t->minEW = rgdouMin(t->rgD, N);
01718 t->maxEW = rgdouMax(t->rgD, N);
01719
01720 if (t->flgCheckEigen)
01721
01722 i = Check_Eigen( N, t->C, t->rgD, t->B);
01723
01724 #if 0
01725
01726 if (t->maxEW > t->minEW * t->dMaxSignifKond) {
01727 ERRORMESSAGE("Warning: Condition number of covariance matrix at upper limit.",
01728 " Consider a rescaling or redesign of the objective function. " ,"","");
01729 printf("\nWarning: Condition number of covariance matrix at upper limit\n");
01730 tmp = t->maxEW/t->dMaxSignifKond - t->minEW;
01731 tmp = t->maxEW/t->dMaxSignifKond;
01732 t->minEW += tmp;
01733 for (i=0;i<N;++i) {
01734 t->C[i][i] += tmp;
01735 t->rgD[i] += tmp;
01736 }
01737 }
01738 t->dLastMinEWgroesserNull = minEW;
01739 #endif
01740
01741 for (i = 0; i < N; ++i)
01742 t->rgD[i] = sqrt(t->rgD[i]);
01743
01744 t->flgEigensysIsUptodate = 1;
01745 t->genOfEigensysUpdate = t->gen;
01746
01747 return;
01748
01749 }
01750
01751
01752
01753 static void
01754 Eigen( int N, double **C, double *diag, double **Q, double *rgtmp)
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766 {
01767 int i, j;
01768
01769 if (rgtmp == NULL)
01770 FATAL("cmaes_t:Eigen(): input parameter double *rgtmp must be non-NULL", 0,0,0);
01771
01772
01773 if (C != Q) {
01774 for (i=0; i < N; ++i)
01775 for (j = 0; j <= i; ++j)
01776 Q[i][j] = Q[j][i] = C[i][j];
01777 }
01778
01779 #if 0
01780 Householder( N, Q, diag, rgtmp);
01781 QLalgo( N, diag, Q, 30*N, rgtmp+1);
01782 #else
01783 Householder2( N, Q, diag, rgtmp);
01784 QLalgo2( N, diag, rgtmp, Q);
01785 #endif
01786
01787 }
01788
01789
01790
01791 static void
01792 QLalgo2 (int n, double *d, double *e, double **V) {
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808 int i, k, l, m;
01809 double f = 0.0;
01810 double tst1 = 0.0;
01811 double eps = 2.22e-16;
01812
01813
01814 for (i = 1; i < n; i++) {
01815 e[i-1] = e[i];
01816 }
01817 e[n-1] = 0.0;
01818
01819 for (l = 0; l < n; l++) {
01820
01821
01822
01823 if (tst1 < fabs(d[l]) + fabs(e[l]))
01824 tst1 = fabs(d[l]) + fabs(e[l]);
01825 m = l;
01826 while (m < n) {
01827 if (fabs(e[m]) <= eps*tst1) {
01828
01829 break;
01830 }
01831 m++;
01832 }
01833
01834
01835
01836
01837 if (m > l) {
01838 int iter = 0;
01839 do {
01840 double dl1, h;
01841 double g = d[l];
01842 double p = (d[l+1] - g) / (2.0 * e[l]);
01843 double r = myhypot(p, 1.);
01844
01845 iter = iter + 1;
01846
01847
01848
01849 if (p < 0) {
01850 r = -r;
01851 }
01852 d[l] = e[l] / (p + r);
01853 d[l+1] = e[l] * (p + r);
01854 dl1 = d[l+1];
01855 h = g - d[l];
01856 for (i = l+2; i < n; i++) {
01857 d[i] -= h;
01858 }
01859 f = f + h;
01860
01861
01862
01863 p = d[m];
01864 {
01865 double c = 1.0;
01866 double c2 = c;
01867 double c3 = c;
01868 double el1 = e[l+1];
01869 double s = 0.0;
01870 double s2 = 0.0;
01871 for (i = m-1; i >= l; i--) {
01872 c3 = c2;
01873 c2 = c;
01874 s2 = s;
01875 g = c * e[i];
01876 h = c * p;
01877 r = myhypot(p, e[i]);
01878 e[i+1] = s * r;
01879 s = e[i] / r;
01880 c = p / r;
01881 p = c * d[i] - s * g;
01882 d[i+1] = h + s * (c * g + s * d[i]);
01883
01884
01885
01886 for (k = 0; k < n; k++) {
01887 h = V[k][i+1];
01888 V[k][i+1] = s * V[k][i] + c * h;
01889 V[k][i] = c * V[k][i] - s * h;
01890 }
01891 }
01892 p = -s * s2 * c3 * el1 * e[l] / dl1;
01893 e[l] = s * p;
01894 d[l] = c * p;
01895 }
01896
01897
01898
01899 } while (fabs(e[l]) > eps*tst1);
01900 }
01901 d[l] = d[l] + f;
01902 e[l] = 0.0;
01903 }
01904
01905
01906 #if 1
01907
01908 {
01909 int j;
01910 double p;
01911 for (i = 0; i < n-1; i++) {
01912 k = i;
01913 p = d[i];
01914 for (j = i+1; j < n; j++) {
01915 if (d[j] < p) {
01916 k = j;
01917 p = d[j];
01918 }
01919 }
01920 if (k != i) {
01921 d[k] = d[i];
01922 d[i] = p;
01923 for (j = 0; j < n; j++) {
01924 p = V[j][i];
01925 V[j][i] = V[j][k];
01926 V[j][k] = p;
01927 }
01928 }
01929 }
01930 }
01931 #endif
01932 }
01933
01934
01935
01936 static void
01937 Householder2(int n, double **V, double *d, double *e) {
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951 int i,j,k;
01952
01953 for (j = 0; j < n; j++) {
01954 d[j] = V[n-1][j];
01955 }
01956
01957
01958
01959 for (i = n-1; i > 0; i--) {
01960
01961
01962
01963 double scale = 0.0;
01964 double h = 0.0;
01965 for (k = 0; k < i; k++) {
01966 scale = scale + fabs(d[k]);
01967 }
01968 if (scale == 0.0) {
01969 e[i] = d[i-1];
01970 for (j = 0; j < i; j++) {
01971 d[j] = V[i-1][j];
01972 V[i][j] = 0.0;
01973 V[j][i] = 0.0;
01974 }
01975 } else {
01976
01977
01978
01979 double f, g, hh;
01980
01981 for (k = 0; k < i; k++) {
01982 d[k] /= scale;
01983 h += d[k] * d[k];
01984 }
01985 f = d[i-1];
01986 g = sqrt(h);
01987 if (f > 0) {
01988 g = -g;
01989 }
01990 e[i] = scale * g;
01991 h = h - f * g;
01992 d[i-1] = f - g;
01993 for (j = 0; j < i; j++) {
01994 e[j] = 0.0;
01995 }
01996
01997
01998
01999 for (j = 0; j < i; j++) {
02000 f = d[j];
02001 V[j][i] = f;
02002 g = e[j] + V[j][j] * f;
02003 for (k = j+1; k <= i-1; k++) {
02004 g += V[k][j] * d[k];
02005 e[k] += V[k][j] * f;
02006 }
02007 e[j] = g;
02008 }
02009 f = 0.0;
02010 for (j = 0; j < i; j++) {
02011 e[j] /= h;
02012 f += e[j] * d[j];
02013 }
02014 hh = f / (h + h);
02015 for (j = 0; j < i; j++) {
02016 e[j] -= hh * d[j];
02017 }
02018 for (j = 0; j < i; j++) {
02019 f = d[j];
02020 g = e[j];
02021 for (k = j; k <= i-1; k++) {
02022 V[k][j] -= (f * e[k] + g * d[k]);
02023 }
02024 d[j] = V[i-1][j];
02025 V[i][j] = 0.0;
02026 }
02027 }
02028 d[i] = h;
02029 }
02030
02031
02032
02033 for (i = 0; i < n-1; i++) {
02034 double h;
02035 V[n-1][i] = V[i][i];
02036 V[i][i] = 1.0;
02037 h = d[i+1];
02038 if (h != 0.0) {
02039 for (k = 0; k <= i; k++) {
02040 d[k] = V[k][i+1] / h;
02041 }
02042 for (j = 0; j <= i; j++) {
02043 double g = 0.0;
02044 for (k = 0; k <= i; k++) {
02045 g += V[k][i+1] * V[k][j];
02046 }
02047 for (k = 0; k <= i; k++) {
02048 V[k][j] -= g * d[k];
02049 }
02050 }
02051 }
02052 for (k = 0; k <= i; k++) {
02053 V[k][i+1] = 0.0;
02054 }
02055 }
02056 for (j = 0; j < n; j++) {
02057 d[j] = V[n-1][j];
02058 V[n-1][j] = 0.0;
02059 }
02060 V[n-1][n-1] = 1.0;
02061 e[0] = 0.0;
02062
02063 }
02064
02065
02066 #if 0
02067
02068 static void
02069 WriteMaxErrorInfo(cmaes_t *t)
02070 {
02071 int i,j, N=t->sp.N;
02072 char *s = (char *)new_void(200+30*(N+2), sizeof(char)); s[0] = '\0';
02073
02074 sprintf( s+strlen(s),"\nKomplett-Info\n");
02075 sprintf( s+strlen(s)," Gen %20.12g\n", t->gen);
02076 sprintf( s+strlen(s)," Dimension %d\n", N);
02077 sprintf( s+strlen(s)," sigma %e\n", t->sigma);
02078 sprintf( s+strlen(s)," lastminEW %e\n",
02079 t->dLastMinEWgroesserNull);
02080 sprintf( s+strlen(s)," maxKond %e\n\n", t->dMaxSignifKond);
02081 sprintf( s+strlen(s)," x-Vektor rgD Basis...\n");
02082 ERRORMESSAGE( s,0,0,0);
02083 s[0] = '\0';
02084 for (i = 0; i < N; ++i)
02085 {
02086 sprintf( s+strlen(s), " %20.12e", t->rgxmean[i]);
02087 sprintf( s+strlen(s), " %10.4e", t->rgD[i]);
02088 for (j = 0; j < N; ++j)
02089 sprintf( s+strlen(s), " %10.2e", t->B[i][j]);
02090 ERRORMESSAGE( s,0,0,0);
02091 s[0] = '\0';
02092 }
02093 ERRORMESSAGE( "\n",0,0,0);
02094 free( s);
02095 }
02096 #endif
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108 void
02109 timings_start(timings_t *t) {
02110 t->totaltime = 0;
02111 t->tictoctime = 0;
02112 t->lasttictoctime = 0;
02113 t->istic = 0;
02114 t->lastclock = clock();
02115 t->lasttime = time(NULL);
02116 t->lastdiff = 0;
02117 t->tictoczwischensumme = 0;
02118 t->isstarted = 1;
02119 }
02120
02121 double
02122 timings_update(timings_t *t) {
02123
02124
02125
02126 double diffc, difft;
02127 clock_t lc = t->lastclock;
02128 time_t lt = t->lasttime;
02129
02130 if (t->isstarted != 1)
02131 FATAL("timings_started() must be called before using timings... functions",0,0,0);
02132
02133 t->lastclock = clock();
02134 t->lasttime = time(NULL);
02135
02136 diffc = (double)(t->lastclock - lc) / CLOCKS_PER_SEC;
02137 difft = difftime(t->lasttime, lt);
02138
02139 t->lastdiff = difft;
02140
02141
02142 if (diffc > 0 && difft < 1000)
02143 t->lastdiff = diffc;
02144
02145 if (t->lastdiff < 0)
02146 FATAL("BUG in time measurement", 0, 0, 0);
02147
02148 t->totaltime += t->lastdiff;
02149 if (t->istic) {
02150 t->tictoczwischensumme += t->lastdiff;
02151 t->tictoctime += t->lastdiff;
02152 }
02153
02154 return t->lastdiff;
02155 }
02156
02157 void
02158 timings_tic(timings_t *t) {
02159 if (t->istic) {
02160 ERRORMESSAGE("Warning: timings_tic called twice without toc",0,0,0);
02161 return;
02162 }
02163 timings_update(t);
02164 t->istic = 1;
02165 }
02166
02167 double
02168 timings_toc(timings_t *t) {
02169 if (!t->istic) {
02170 ERRORMESSAGE("Warning: timings_toc called without tic",0,0,0);
02171 return -1;
02172 }
02173 timings_update(t);
02174 t->lasttictoctime = t->tictoczwischensumme;
02175 t->tictoczwischensumme = 0;
02176 t->istic = 0;
02177 return t->lasttictoctime;
02178 }
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195 long
02196 random_init( random_t *t, long unsigned inseed)
02197 {
02198 clock_t cloc = clock();
02199
02200 t->flgstored = 0;
02201 t->rgrand = (long *) new_void(32, sizeof(long));
02202 if (inseed < 1) {
02203 while ((long) (cloc - clock()) == 0)
02204 ;
02205 inseed = (long)abs(100*time(NULL)+clock());
02206 }
02207 return random_Start(t, inseed);
02208 }
02209
02210 void
02211 random_exit(random_t *t)
02212 {
02213 free( t->rgrand);
02214 }
02215
02216
02217 long random_Start( random_t *t, long unsigned inseed)
02218 {
02219 long tmp;
02220 int i;
02221
02222 t->flgstored = 0;
02223 t->startseed = inseed;
02224 if (inseed < 1)
02225 inseed = 1;
02226 t->aktseed = inseed;
02227 for (i = 39; i >= 0; --i)
02228 {
02229 tmp = t->aktseed/127773;
02230 t->aktseed = 16807 * (t->aktseed - tmp * 127773)
02231 - 2836 * tmp;
02232 if (t->aktseed < 0) t->aktseed += 2147483647;
02233 if (i < 32)
02234 t->rgrand[i] = t->aktseed;
02235 }
02236 t->aktrand = t->rgrand[0];
02237 return inseed;
02238 }
02239
02240
02241 double random_Gauss(random_t *t)
02242 {
02243 double x1, x2, rquad, fac;
02244
02245 if (t->flgstored)
02246 {
02247 t->flgstored = 0;
02248 return t->hold;
02249 }
02250 do
02251 {
02252 x1 = 2.0 * random_Uniform(t) - 1.0;
02253 x2 = 2.0 * random_Uniform(t) - 1.0;
02254 rquad = x1*x1 + x2*x2;
02255 } while(rquad >= 1 || rquad <= 0);
02256 fac = sqrt(-2.0*log(rquad)/rquad);
02257 t->flgstored = 1;
02258 t->hold = fac * x1;
02259 return fac * x2;
02260 }
02261
02262
02263 double random_Uniform( random_t *t)
02264 {
02265 long tmp;
02266
02267 tmp = t->aktseed/127773;
02268 t->aktseed = 16807 * (t->aktseed - tmp * 127773)
02269 - 2836 * tmp;
02270 if (t->aktseed < 0)
02271 t->aktseed += 2147483647;
02272 tmp = t->aktrand / 67108865;
02273 t->aktrand = t->rgrand[tmp];
02274 t->rgrand[tmp] = t->aktseed;
02275 return (double)(t->aktrand)/(2.147483647e9);
02276 }
02277
02278 static char *
02279 szCat(const char *sz1, const char*sz2,
02280 const char *sz3, const char *sz4);
02281
02282
02283
02284
02285 void
02286 readpara_init (readpara_t *t,
02287 int dim,
02288 int inseed,
02289 const double * inxstart,
02290 const double * inrgsigma,
02291 int lambda,
02292 const char * filename)
02293 {
02294 int i, N;
02295 t->rgsformat = (const char **) new_void(45, sizeof(char *));
02296 t->rgpadr = (void **) new_void(45, sizeof(void *));
02297 t->rgskeyar = (const char **) new_void(11, sizeof(char *));
02298 t->rgp2adr = (double ***) new_void(11, sizeof(double **));
02299 t->weigkey = (char *)new_void(7, sizeof(char));
02300
02301
02302 i = 0;
02303 t->rgsformat[i] = " N %d"; t->rgpadr[i++] = (void *) &t->N;
02304 t->rgsformat[i] = " seed %d"; t->rgpadr[i++] = (void *) &t->seed;
02305 t->rgsformat[i] = " stopMaxFunEvals %lg"; t->rgpadr[i++] = (void *) &t->stopMaxFunEvals;
02306 t->rgsformat[i] = " stopMaxIter %lg"; t->rgpadr[i++] = (void *) &t->stopMaxIter;
02307 t->rgsformat[i] = " stopFitness %lg"; t->rgpadr[i++]=(void *) &t->stStopFitness.val;
02308 t->rgsformat[i] = " stopTolFun %lg"; t->rgpadr[i++]=(void *) &t->stopTolFun;
02309 t->rgsformat[i] = " stopTolFunHist %lg"; t->rgpadr[i++]=(void *) &t->stopTolFunHist;
02310 t->rgsformat[i] = " stopTolX %lg"; t->rgpadr[i++]=(void *) &t->stopTolX;
02311 t->rgsformat[i] = " stopTolUpXFactor %lg"; t->rgpadr[i++]=(void *) &t->stopTolUpXFactor;
02312 t->rgsformat[i] = " lambda %d"; t->rgpadr[i++] = (void *) &t->lambda;
02313 t->rgsformat[i] = " mu %d"; t->rgpadr[i++] = (void *) &t->mu;
02314 t->rgsformat[i] = " weights %5s"; t->rgpadr[i++] = (void *) t->weigkey;
02315 t->rgsformat[i] = " fac*cs %lg";t->rgpadr[i++] = (void *) &t->cs;
02316 t->rgsformat[i] = " fac*damps %lg"; t->rgpadr[i++] = (void *) &t->damps;
02317 t->rgsformat[i] = " ccumcov %lg"; t->rgpadr[i++] = (void *) &t->ccumcov;
02318 t->rgsformat[i] = " mucov %lg"; t->rgpadr[i++] = (void *) &t->mucov;
02319 t->rgsformat[i] = " fac*ccov %lg"; t->rgpadr[i++]=(void *) &t->ccov;
02320 t->rgsformat[i] = " updatecov %lg"; t->rgpadr[i++]=(void *) &t->updateCmode.modulo;
02321 t->rgsformat[i] = " maxTimeFractionForEigendecompostion %lg"; t->rgpadr[i++]=(void *) &t->updateCmode.maxtime;
02322 t->rgsformat[i] = " resume %59s"; t->rgpadr[i++] = (void *) t->resumefile;
02323 t->rgsformat[i] = " fac*maxFunEvals %lg"; t->rgpadr[i++] = (void *) &t->facmaxeval;
02324 t->rgsformat[i] = " fac*updatecov %lg"; t->rgpadr[i++]=(void *) &t->facupdateCmode;
02325 t->n1para = i;
02326 t->n1outpara = i-2;
02327
02328
02329 i = 0;
02330 t->rgskeyar[i] = " typicalX %d"; t->rgp2adr[i++] = &t->typicalX;
02331 t->rgskeyar[i] = " initialX %d"; t->rgp2adr[i++] = &t->xstart;
02332 t->rgskeyar[i] = " initialStandardDeviations %d"; t->rgp2adr[i++] = &t->rgInitialStds;
02333 t->rgskeyar[i] = " diffMinChange %d"; t->rgp2adr[i++] = &t->rgDiffMinChange;
02334 t->n2para = i;
02335
02336 t->N = dim;
02337 t->seed = inseed;
02338 t->xstart = NULL;
02339 t->typicalX = NULL;
02340 t->typicalXcase = 0;
02341 t->rgInitialStds = NULL;
02342 t->rgDiffMinChange = NULL;
02343 t->stopMaxFunEvals = -1;
02344 t->stopMaxIter = -1;
02345 t->facmaxeval = 1;
02346 t->stStopFitness.flg = -1;
02347 t->stopTolFun = 1e-12;
02348 t->stopTolFunHist = 1e-13;
02349 t->stopTolX = 0;
02350 t->stopTolUpXFactor = 1e3;
02351
02352 t->lambda = lambda;
02353 t->mu = -1;
02354 t->mucov = -1;
02355 t->weights = NULL;
02356 strcpy(t->weigkey, "log");
02357
02358 t->cs = -1;
02359 t->ccumcov = -1;
02360 t->damps = -1;
02361 t->ccov = -1;
02362
02363 t->updateCmode.modulo = -1;
02364 t->updateCmode.maxtime = -1;
02365 t->updateCmode.flgalways = 0;
02366 t->facupdateCmode = 1;
02367 strcpy(t->resumefile, "_no_");
02368
02369 if (strcmp(filename, "non") != 0 && strcmp(filename, "writeonly") != 0)
02370 readpara_ReadFromFile(t, filename);
02371
02372 if (t->N <= 0)
02373 t->N = dim;
02374
02375 N = t->N;
02376 if (N == 0)
02377 FATAL("readpara_readpara_t(): problem dimension N undefined.\n",
02378 " (no default value available).",0,0);
02379 if (t->xstart == NULL && inxstart == NULL && t->typicalX == NULL) {
02380 ERRORMESSAGE("Warning: initialX undefined. typicalX = 0.5...0.5 used.","","","");
02381 printf("\nWarning: initialX undefined. typicalX = 0.5...0.5 used.\n");
02382 }
02383 if (t->rgInitialStds == NULL && inrgsigma == NULL) {
02384
02385 ERRORMESSAGE("Warning: initialStandardDeviations undefined. 0.3...0.3 used.","","","");
02386 printf("\nWarning: initialStandardDeviations. 0.3...0.3 used.\n");
02387 }
02388
02389 if (t->xstart == NULL) {
02390 t->xstart = new_double(N);
02391
02392
02393 if (inxstart != NULL) {
02394 for (i=0; i<N; ++i)
02395 t->xstart[i] = inxstart[i];
02396 }
02397
02398 else {
02399 t->typicalXcase = 1;
02400 for (i=0; i<N; ++i)
02401 t->xstart[i] = (t->typicalX == NULL) ? 0.5 : t->typicalX[i];
02402 }
02403 }
02404
02405 if (t->rgInitialStds == NULL) {
02406 t->rgInitialStds = new_double(N);
02407 for (i=0; i<N; ++i)
02408 t->rgInitialStds[i] = (inrgsigma == NULL) ? 0.3 : inrgsigma[i];
02409 }
02410
02411 readpara_SupplementDefaults(t);
02412
02413
02414 }
02415
02416
02417
02418 void readpara_exit(readpara_t *t)
02419 {
02420 if (t->xstart != NULL)
02421 free( t->xstart);
02422 if (t->typicalX != NULL)
02423 free( t->typicalX);
02424 if (t->rgInitialStds != NULL)
02425 free( t->rgInitialStds);
02426 if (t->rgDiffMinChange != NULL)
02427 free( t->rgDiffMinChange);
02428 if (t->weights != NULL)
02429 free( t->weights);
02430
02431 free(t->rgsformat);
02432 free(t->rgpadr);
02433 free(t->rgskeyar);
02434 free(t->rgp2adr);
02435 free(t->weigkey);
02436 }
02437
02438
02439
02440 void
02441 readpara_ReadFromFile(readpara_t *t, const char * filename)
02442 {
02443 char s[1000];
02444 const char *ss = "initials.par";
02445 int ipara, i;
02446 int size;
02447 FILE *fp;
02448 if (filename == NULL)
02449 filename = ss;
02450 fp = fopen( filename, "r");
02451 if(fp == NULL) {
02452 ERRORMESSAGE("cmaes_ReadFromFile(): could not open '", filename, "'",0);
02453 return;
02454 }
02455 for (ipara=0; ipara < t->n1para; ++ipara)
02456 {
02457 rewind(fp);
02458 while(fgets(s, sizeof(s), fp) != NULL)
02459 {
02460 if (s[0] == '#' || s[0] == '%')
02461 continue;
02462 if(sscanf(s, t->rgsformat[ipara], t->rgpadr[ipara]) == 1) {
02463 if (strncmp(t->rgsformat[ipara], " stopFitness ", 13) == 0)
02464 t->stStopFitness.flg = 1;
02465 break;
02466 }
02467 }
02468 }
02469 if (t->N <= 0)
02470 FATAL("readpara_ReadFromFile(): No valid dimension N",0,0,0);
02471 for (ipara=0; ipara < t->n2para; ++ipara)
02472 {
02473 rewind(fp);
02474 while(fgets(s, sizeof(s), fp) != NULL)
02475 {
02476 if (s[0] == '#' || s[0] == '%')
02477 continue;
02478 if(sscanf(s, t->rgskeyar[ipara], &size) == 1) {
02479 if (size > 0) {
02480 *t->rgp2adr[ipara] = new_double(t->N);
02481 for (i=0;i<size&&i<t->N;++i)
02482 if (fscanf(fp, " %lf", &(*t->rgp2adr[ipara])[i]) != 1)
02483 break;
02484 if (i<size && i < t->N) {
02485 ERRORMESSAGE("readpara_ReadFromFile ", filename, ": ",0);
02486 FATAL( "'", t->rgskeyar[ipara],
02487 "' not enough values found.\n",
02488 " Remove all comments between numbers.");
02489 }
02490 for (; i < t->N; ++i)
02491 (*t->rgp2adr[ipara])[i] = (*t->rgp2adr[ipara])[i%size];
02492 }
02493 }
02494 }
02495 }
02496 fclose(fp);
02497 return;
02498 }
02499
02500
02501
02502 void
02503 readpara_WriteToFile(readpara_t *t, const char *filenamedest,
02504 const char *filenamesource)
02505 {
02506 int ipara, i;
02507 size_t len;
02508 time_t ti = time(NULL);
02509 FILE *fp = fopen( filenamedest, "a");
02510 if(fp == NULL) {
02511 ERRORMESSAGE("cmaes_WriteToFile(): could not open '",
02512 filenamedest, "'",0);
02513 return;
02514 }
02515 fprintf(fp, "\n# Read from %s at %s\n", filenamesource,
02516 asctime(localtime(&ti)));
02517 for (ipara=0; ipara < 1; ++ipara) {
02518 fprintf(fp, t->rgsformat[ipara], *(int *)t->rgpadr[ipara]);
02519 fprintf(fp, "\n");
02520 }
02521 for (ipara=0; ipara < t->n2para; ++ipara) {
02522 if(*t->rgp2adr[ipara] == NULL)
02523 continue;
02524 fprintf(fp, t->rgskeyar[ipara], t->N);
02525 fprintf(fp, "\n");
02526 for (i=0; i<t->N; ++i)
02527 fprintf(fp, "%7.3g%c", (*t->rgp2adr[ipara])[i], (i%5==4)?'\n':' ');
02528 fprintf(fp, "\n");
02529 }
02530 for (ipara=1; ipara < t->n1outpara; ++ipara) {
02531 if (strncmp(t->rgsformat[ipara], " stopFitness ", 13) == 0)
02532 if(t->stStopFitness.flg == 0) {
02533 fprintf(fp, " stopFitness\n");
02534 continue;
02535 }
02536 len = strlen(t->rgsformat[ipara]);
02537 if (t->rgsformat[ipara][len-1] == 'd')
02538 fprintf(fp, t->rgsformat[ipara], *(int *)t->rgpadr[ipara]);
02539 else if (t->rgsformat[ipara][len-1] == 's')
02540 fprintf(fp, t->rgsformat[ipara], (char *)t->rgpadr[ipara]);
02541 else {
02542 if (strncmp(" fac*", t->rgsformat[ipara], 5) == 0) {
02543 fprintf(fp, " ");
02544 fprintf(fp, t->rgsformat[ipara]+5, *(double *)t->rgpadr[ipara]);
02545 } else
02546 fprintf(fp, t->rgsformat[ipara], *(double *)t->rgpadr[ipara]);
02547 }
02548 fprintf(fp, "\n");
02549 }
02550 fprintf(fp, "\n");
02551 fclose(fp);
02552 }
02553
02554
02555
02556 void
02557 readpara_SupplementDefaults(readpara_t *t)
02558 {
02559 double t1, t2;
02560 int N = t->N;
02561 clock_t cloc = clock();
02562
02563 if (t->seed < 1) {
02564 while ((int) (cloc - clock()) == 0)
02565 ;
02566 t->seed = (unsigned int)abs(100*time(NULL)+clock());
02567 }
02568
02569 if (t->stStopFitness.flg == -1)
02570 t->stStopFitness.flg = 0;
02571
02572 if (t->lambda < 2)
02573 t->lambda = 4+(int)(3*log((double)N));
02574 if (t->mu == -1) {
02575 t->mu = t->lambda/2;
02576 readpara_SetWeights(t, t->weigkey);
02577 }
02578 if (t->weights == NULL)
02579 readpara_SetWeights(t, t->weigkey);
02580
02581 if (t->cs > 0)
02582 t->cs *= (t->mueff + 2.) / (N + t->mueff + 3.);
02583 if (t->cs <= 0 || t->cs >= 1)
02584 t->cs = (t->mueff + 2.) / (N + t->mueff + 3.);
02585
02586 if (t->ccumcov <= 0 || t->ccumcov > 1)
02587 t->ccumcov = 4. / (N + 4);
02588
02589 if (t->mucov < 1) {
02590 t->mucov = t->mueff;
02591 }
02592 t1 = 2. / ((N+1.4142)*(N+1.4142));
02593 t2 = (2.*t->mueff-1.) / ((N+2.)*(N+2.)+t->mueff);
02594 t2 = (t2 > 1) ? 1 : t2;
02595 t2 = (1./t->mucov) * t1 + (1.-1./t->mucov) * t2;
02596 if (t->ccov >= 0)
02597 t->ccov *= t2;
02598 if (t->ccov < 0 || t->ccov > 1)
02599 t->ccov = t2;
02600
02601 if (t->stopMaxFunEvals == -1)
02602 t->stopMaxFunEvals = t->facmaxeval*900*(N+3)*(N+3);
02603 else
02604 t->stopMaxFunEvals *= t->facmaxeval;
02605
02606 if (t->stopMaxIter == -1)
02607 t->stopMaxIter = ceil((double)(t->stopMaxFunEvals / t->lambda));
02608
02609 if (t->damps < 0)
02610 t->damps = 1;
02611 t->damps = t->damps
02612 * (1 + 2*douMax(0., sqrt((t->mueff-1.)/(N+1.)) - 1))
02613 * douMax(0.3, 1. -
02614 (double)N / (1e-6+douMin(t->stopMaxIter, t->stopMaxFunEvals/t->lambda)))
02615 + t->cs;
02616
02617 if (t->updateCmode.modulo < 1)
02618 t->updateCmode.modulo = 1./t->ccov/(double)(N)/10.;
02619 t->updateCmode.modulo *= t->facupdateCmode;
02620 if (t->updateCmode.maxtime < 0)
02621 t->updateCmode.maxtime = 0.20;
02622
02623 }
02624
02625
02626
02627
02628 void
02629 readpara_SetWeights(readpara_t *t, const char * mode)
02630 {
02631 double s1, s2;
02632 int i;
02633
02634 if(t->weights != NULL)
02635 free( t->weights);
02636 t->weights = new_double(t->mu);
02637 if (strcmp(mode, "lin") == 0)
02638 for (i=0; i<t->mu; ++i)
02639 t->weights[i] = t->mu - i;
02640 else if (strncmp(mode, "equal", 3) == 0)
02641 for (i=0; i<t->mu; ++i)
02642 t->weights[i] = 1;
02643 else if (strcmp(mode, "log") == 0)
02644 for (i=0; i<t->mu; ++i)
02645 t->weights[i] = log(t->mu+1.)-log(i+1.);
02646 else
02647 for (i=0; i<t->mu; ++i)
02648 t->weights[i] = log(t->mu+1.)-log(i+1.);
02649
02650
02651 for (i=0, s1=0, s2=0; i<t->mu; ++i) {
02652 s1 += t->weights[i];
02653 s2 += t->weights[i]*t->weights[i];
02654 }
02655 t->mueff = s1*s1/s2;
02656 for (i=0; i<t->mu; ++i)
02657 t->weights[i] /= s1;
02658
02659 if(t->mu < 1 || t->mu > t->lambda ||
02660 (t->mu==t->lambda && t->weights[0]==t->weights[t->mu-1]))
02661 FATAL("readpara_SetWeights(): invalid setting of mu or lambda",0,0,0);
02662
02663 }
02664
02665
02666
02667 static int
02668 intMin( int i, int j)
02669 {
02670 return i < j ? i : j;
02671 }
02672 static double
02673 douMax( double i, double j)
02674 {
02675 return i > j ? i : j;
02676 }
02677 static double
02678 douMin( double i, double j)
02679 {
02680 return i < j ? i : j;
02681 }
02682 static double
02683 rgdouMax( const double *rgd, int len)
02684 {
02685 int i;
02686 double max = rgd[0];
02687 for (i = 1; i < len; ++i)
02688 max = (max < rgd[i]) ? rgd[i] : max;
02689 return max;
02690 }
02691
02692 static double
02693 rgdouMin( const double *rgd, int len)
02694 {
02695 int i;
02696 double min = rgd[0];
02697 for (i = 1; i < len; ++i)
02698 min = (min > rgd[i]) ? rgd[i] : min;
02699 return min;
02700 }
02701
02702 static int
02703 MaxIdx( const double *rgd, int len)
02704 {
02705 int i, res;
02706 for(i=1, res=0; i<len; ++i)
02707 if(rgd[i] > rgd[res])
02708 res = i;
02709 return res;
02710 }
02711 static int
02712 MinIdx( const double *rgd, int len)
02713 {
02714 int i, res;
02715 for(i=1, res=0; i<len; ++i)
02716 if(rgd[i] < rgd[res])
02717 res = i;
02718 return res;
02719 }
02720
02721 static double
02722 myhypot(double a, double b)
02723
02724 {
02725 double r = 0;
02726 if (fabs(a) > fabs(b)) {
02727 r = b/a;
02728 r = fabs(a)*sqrt(1+r*r);
02729 } else if (b != 0) {
02730 r = a/b;
02731 r = fabs(b)*sqrt(1+r*r);
02732 }
02733 return r;
02734 }
02735
02736 static int SignOfDiff(const void *d1, const void * d2)
02737 {
02738 return *((double *) d1) > *((double *) d2) ? 1 : -1;
02739 }
02740
02741 #if 1
02742
02743 static void Sorted_index(const double *rgFunVal, int *index, int n)
02744 {
02745 int i, j;
02746 for (i=1, index[0]=0; i<n; ++i) {
02747 for (j=i; j>0; --j) {
02748 if (rgFunVal[index[j-1]] < rgFunVal[i])
02749 break;
02750 index[j] = index[j-1];
02751 }
02752 index[j] = i;
02753 }
02754 }
02755 #endif
02756
02757 static void * new_void(int n, size_t size)
02758 {
02759 static char s[70];
02760 void *p = calloc((unsigned) n, size);
02761 if (p == NULL) {
02762 sprintf(s, "new_void(): calloc(%ld,%ld) failed",(long)n,(long)size);
02763 FATAL(s,0,0,0);
02764 }
02765 return p;
02766 }
02767
02768 double *
02769 cmaes_NewDouble(int n)
02770 {
02771 return new_double(n);
02772 }
02773
02774 static double * new_double(int n)
02775 {
02776 static char s[170];
02777 double *p = (double *) calloc((unsigned) n, sizeof(double));
02778 if (p == NULL) {
02779 sprintf(s, "new_double(): calloc(%ld,%ld) failed",
02780 (long)n,(long)sizeof(double));
02781 FATAL(s,0,0,0);
02782 }
02783 return p;
02784 }
02785
02786
02787
02788
02789
02790 void
02791 cmaes_FATAL(char const *s1, char const *s2, char const *s3,
02792 char const *s4)
02793 {
02794 time_t t = time(NULL);
02795 ERRORMESSAGE( s1, s2, s3, s4);
02796 ERRORMESSAGE("*** Exiting cmaes_t ***",0,0,0);
02797 printf("\n -- %s %s\n", asctime(localtime(&t)),
02798 s2 ? szCat(s1, s2, s3, s4) : s1);
02799 printf(" *** CMA-ES ABORTED, see errcmaes.err *** \n");
02800 fflush(stdout);
02801 exit(1);
02802 }
02803
02804
02805 static void
02806 FATAL(char const *s1, char const *s2, char const *s3,
02807 char const *s4)
02808 {
02809 cmaes_FATAL(s1, s2, s3, s4);
02810 }
02811
02812
02813 void ERRORMESSAGE( char const *s1, char const *s2,
02814 char const *s3, char const *s4)
02815 {
02816 #if 0
02817
02818
02819
02820 time_t t = time(NULL);
02821 FILE *fp = fopen( "errcmaes.err", "a");
02822 if (!fp)
02823 {
02824 printf("\nFATAL ERROR: %s\n", s2 ? szCat(s1, s2, s3, s4) : s1);
02825 printf("cmaes_t could not open file 'errcmaes.err'.");
02826 printf("\n *** CMA-ES ABORTED *** ");
02827 fflush(stdout);
02828 exit(1);
02829 }
02830 fprintf( fp, "\n -- %s %s\n", asctime(localtime(&t)),
02831 s2 ? szCat(s1, s2, s3, s4) : s1);
02832 fclose (fp);
02833 #endif
02834 }
02835
02836
02837 char *szCat(const char *sz1, const char*sz2,
02838 const char *sz3, const char *sz4)
02839 {
02840 static char szBuf[700];
02841
02842 if (!sz1)
02843 FATAL("szCat() : Invalid Arguments",0,0,0);
02844
02845 strncpy ((char *)szBuf, sz1, (unsigned)intMin( (int)strlen(sz1), 698));
02846 szBuf[intMin( (int)strlen(sz1), 698)] = '\0';
02847 if (sz2)
02848 strncat ((char *)szBuf, sz2,
02849 (unsigned)intMin((int)strlen(sz2)+1, 698 - (int)strlen((char const *)szBuf)));
02850 if (sz3)
02851 strncat((char *)szBuf, sz3,
02852 (unsigned)intMin((int)strlen(sz3)+1, 698 - (int)strlen((char const *)szBuf)));
02853 if (sz4)
02854 strncat((char *)szBuf, sz4,
02855 (unsigned)intMin((int)strlen(sz4)+1, 698 - (int)strlen((char const *)szBuf)));
02856 return (char *) szBuf;
02857 }
02858
02859