17 #if defined(DEBUG) || defined(WARNINGMSG)
28 class GradientCalculator;
30 FunctionMinimum SimplexBuilder::Minimum(
const MnFcn& mfcn,
const GradientCalculator&,
const MinimumSeed& seed,
const MnStrategy&,
unsigned int maxfcn,
double minedm)
const {
36 std::cout <<
"Running Simplex with maxfcn = " << maxfcn <<
" minedm = " << minedm << std::endl;
39 const MnMachinePrecision& prec = seed.Precision();
40 MnAlgebraicVector x = seed.Parameters().Vec();
41 MnAlgebraicVector step = 10.*seed.Gradient().Gstep();
43 unsigned int n = x.size();
44 double wg = 1./double(n);
45 double alpha = 1., beta = 0.5, gamma = 2., rhomin = 4., rhomax = 8.;
46 double rho1 = 1. + alpha;
49 double rho2 = 1. + alpha*gamma;
52 std::vector<std::pair<double, MnAlgebraicVector> > simpl; simpl.reserve(n+1);
53 simpl.push_back(std::pair<double, MnAlgebraicVector>(seed.Fval(), x));
55 unsigned int jl = 0, jh = 0;
56 double amin = seed.Fval(), aming = seed.Fval();
58 for(
unsigned int i = 0; i < n; i++) {
59 double dmin = 8.*prec.Eps2()*(fabs(x(i)) + prec.Eps2());
60 if(step(i) < dmin) step(i) = dmin;
71 simpl.push_back(std::pair<double, MnAlgebraicVector>(tmp, x));
74 SimplexParameters simplex(simpl, jh, jl);
77 std::cout <<
"simplex initial parameters - min " << jl <<
" " << amin <<
" max " << jh <<
" " << aming << std::endl;
78 for (
unsigned int i = 0; i < simplex.Simplex().size(); ++i)
79 std::cout <<
" i = " << i <<
" x = " << simplex(i).second <<
" fval(x) = " << simplex(i).first << std::endl;
82 double edmPrev = simplex.Edm();
87 amin = simplex(jl).first;
88 edmPrev = simplex.Edm();
91 std::cout <<
"\n\nsimplex iteration: edm = " << simplex.Edm()
92 <<
"\n--> Min Param is " << jl <<
" pmin " << simplex(jl).second <<
" f(pmin) " << amin
93 <<
"\n--> Max param is " << jh <<
" " << simplex(jh).first << std::endl;
101 if (TraceIter() ) TraceIteration(niterations, MinimumState(MinimumParameters(simplex(jl).second,simplex(jl).first), simplex.Edm(), mfcn.NumOfCalls()) );
102 if (PrintLevel() > 1) MnPrint::PrintState(std::cout,simplex(jl).first, simplex.Edm(),mfcn.NumOfCalls(),
"Simplex: Iteration # ", niterations);
106 MnAlgebraicVector pbar(n);
107 for(
unsigned int i = 0; i < n+1; i++) {
108 if(i == jh)
continue;
109 pbar += (wg*simplex(i).second);
112 MnAlgebraicVector pstar = (1. + alpha)*pbar - alpha*simplex(jh).second;
113 double ystar = mfcn(pstar);
116 std::cout <<
" pbar = " << pbar << std::endl;
117 std::cout <<
" pstar = " << pstar <<
" f(pstar) = " << ystar << std::endl;
121 if(ystar < simplex(jh).first) {
122 simplex.Update(ystar, pstar);
123 if(jh != simplex.Jh())
continue;
125 MnAlgebraicVector pstst = beta*simplex(jh).second + (1. - beta)*pbar;
126 double ystst = mfcn(pstst);
128 std::cout <<
"Reduced simplex pstst = " << pstst <<
" f(pstst) = " << ystst << std::endl;
130 if(ystst > simplex(jh).first)
break;
131 simplex.Update(ystst, pstst);
135 MnAlgebraicVector pstst = gamma*pstar + (1. - gamma)*pbar;
136 double ystst = mfcn(pstst);
138 std::cout <<
" pstst = " << pstst <<
" f(pstst) = " << ystst << std::endl;
141 double y1 = (ystar - simplex(jh).first)*rho2;
142 double y2 = (ystst - simplex(jh).first)*rho1;
143 double rho = 0.5*(rho2*y1 - rho1*y2)/(y1 - y2);
145 if(ystst < simplex(jl).first) simplex.Update(ystst, pstst);
146 else simplex.Update(ystar, pstar);
149 if(rho > rhomax) rho = rhomax;
150 MnAlgebraicVector prho = rho*pbar + (1. - rho)*simplex(jh).second;
151 double yrho = mfcn(prho);
153 std::cout <<
" prho = " << prho <<
" f(prho) = " << yrho << std::endl;
155 if(yrho < simplex(jl).first && yrho < ystst) {
156 simplex.Update(yrho, prho);
159 if(ystst < simplex(jl).first) {
160 simplex.Update(ystst, pstst);
163 if(yrho > simplex(jl).first) {
164 if(ystst < simplex(jl).first) simplex.Update(ystst, pstst);
165 else simplex.Update(ystar, pstar);
168 if(ystar > simplex(jh).first) {
169 pstst = beta*simplex(jh).second + (1. - beta)*pbar;
171 if(ystst > simplex(jh).first)
break;
172 simplex.Update(ystst, pstst);
175 std::cout <<
"End loop : edm = " << simplex.Edm() <<
" pstst = " << pstst <<
" f(pstst) = " << ystst << std::endl;
177 }
while( (simplex.Edm() > minedm || edmPrev > minedm ) && mfcn.NumOfCalls() < maxfcn);
181 amin = simplex(jl).first;
183 MnAlgebraicVector pbar(n);
184 for(
unsigned int i = 0; i < n+1; i++) {
185 if(i == jh)
continue;
186 pbar += (wg*simplex(i).second);
188 double ybar = mfcn(pbar);
189 if(ybar < amin) simplex.Update(ybar, pbar);
191 pbar = simplex(jl).second;
192 ybar = simplex(jl).first;
195 MnAlgebraicVector dirin = simplex.Dirin();
197 dirin *= sqrt(mfcn.Up()/simplex.Edm());
200 std::cout <<
"End simplex " << simplex.Edm() <<
" pbar = " << pbar <<
" f(p) = " << ybar << std::endl;
204 MinimumState st(MinimumParameters(pbar, dirin, ybar), simplex.Edm(), mfcn.NumOfCalls());
206 if (PrintLevel() > 1)
207 MnPrint::PrintState(std::cout,st,
"Simplex: Final iteration");
208 if (TraceIter() ) TraceIteration(niterations, st);
210 if(mfcn.NumOfCalls() > maxfcn) {
212 MN_INFO_MSG(
"Simplex did not converge, #fcn calls exhausted.");
214 return FunctionMinimum(seed, std::vector<MinimumState>(1, st), mfcn.Up(), FunctionMinimum::MnReachedCallLimit());
216 if(simplex.Edm() > minedm) {
218 MN_INFO_MSG(
"Simplex did not converge, edm > minedm.");
220 return FunctionMinimum(seed, std::vector<MinimumState>(1, st), mfcn.Up(), FunctionMinimum::MnAboveMaxEdm());
223 return FunctionMinimum(seed, std::vector<MinimumState>(1, st), mfcn.Up());