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());