Downhill simplex function minimization routine.
Note that if any constraints are required for the parameter values they must be set in the function.
45 {
46 int i, j, Meas, it;
47 double Max, Min, Max2, Min2, LastChi;
48 int NextBest, New2, Best;
49
50
51 if(verbose>0) printf("%s(func, %d, p[], delta[], %g, %d)\n", __func__, parNr, maxerr, maxiter);
52
53 _simplexFunc=_fun;
54 _simplexParNr=parNr; it=0; NewPnt=_simplexParNr+1;
55 for(i=0; i<_simplexParNr; i++) for(Meas=0; Meas<_simplexParNr+3; Meas++) _simplexP[Meas][i]=par[i];
56 if(verbose>1) {
57 for(int i=0; i<_simplexParNr; i++) printf("%12g %12g\n", _simplexP[0][i], delta[i]);
58 printf("ChiSqr of guesses: %f\n", (*_simplexFunc)(_simplexP[0]));
59 }
60 New2=NewPnt+1;
61 for(Meas=0; Meas<=_simplexParNr; Meas++) {
62 it++;
63 _simplexR[Meas] = (*_simplexFunc)(_simplexP[Meas]);
64 for (i=0; i<_simplexParNr; i++) {
65 if(i==Meas) delta[i]= -delta[i];
66 _simplexP[Meas+1][i] = _simplexP[Meas][i] + delta[i];
67 }
68 }
69
70
71 LastChi = 1.0E30; NextBest=Best=0;
72 do {
73 for(j=0; j<100; j++) {
74
75 Max=0.; Min=1.0E30;
76 for (i=0; i<=_simplexParNr; i++) {
77 if(_simplexR[i] > Max) {Max=_simplexR[i]; Worst=i;}
78 if(_simplexR[i] < Min) {Min=_simplexR[i]; Best=i; }
79 }
80
81 Max2=0.; Min2=1.0E30;
82 for (i=0; i<=_simplexParNr; i++) {
83 if((_simplexR[i] > Max2) && (_simplexR[i] < Max)) Max2=_simplexR[i];
84 if((_simplexR[i] < Min2) && (_simplexR[i] > Min)) {
85 Min2=_simplexR[i]; NextBest=i;}
86 }
87
88 for(i=0; i<_simplexParNr; i++) {
89 _simplexC[i]=0.;
90 for(Meas=0; Meas<=_simplexParNr; Meas++)
91 if(Meas!=Worst) _simplexC[i]+=_simplexP[Meas][i];
92 _simplexC[i]/=(double)_simplexParNr;
93 }
94
95 for(i=0; i<_simplexParNr; i++)
96 _simplexP[NewPnt][i] = 2.*_simplexC[i] - _simplexP[Worst][i];
97 _simplexR[NewPnt]= (*_simplexFunc)(_simplexP[NewPnt]);
98 it++;
99
100
101 if(_simplexR[NewPnt] < _simplexR[Best]) {
102 _simplexGenNew(New2,2.0); it++;
103 } else {
104
105
106 if(_simplexR[NewPnt] > _simplexR[Worst]) {
107 _simplexGenNew(New2,-0.5); it++;
108 } else {
109
110
111
112 if((_simplexR[NextBest] < _simplexR[NewPnt]) &&
113 (_simplexR[NewPnt] < _simplexR[Worst])) {
114 _simplexGenNew(New2,0.5); it++;
115 } else {
116
117 for(i=0; i<_simplexParNr; i++)
118 _simplexP[Worst][i] = _simplexP[NewPnt][i];
119 _simplexR[Worst] = _simplexR[NewPnt];
120 }
121 }
122 }
123 }
124 if(verbose>1) printf(" it=%i; ChiSqr=%f\n", it, _simplexR[Best]);
125 if(verbose>2)
126 for(i=0; i<_simplexParNr; i++) printf(" %12g\n", _simplexP[Best][i]);
127
128 if(_simplexR[Best] == LastChi) {
129 for(i=0; i<_simplexParNr; i++) par[i]=_simplexP[Best][i];
130 return _simplexR[Best];
131 }
132 LastChi = _simplexR[Best];
133 } while ((_simplexR[Best]>maxerr) && (it<=maxiter));
134
135 for(i=0; i<_simplexParNr; i++) par[i]=_simplexP[Best][i];
136 return _simplexR[Best];
137}