int InterPolynomial::getGoodInterPolationSites(Matrix d, int k, double rho, Vector *v) // input: k,rho // output: d,r { //not tested unsigned i, N=nPtsUsed, n=dim(); int ii, j,r=0; Polynomial *pp=NewtonBasis; Vector *xx=NewtonPoints, xk,vd; Vector Distance(N); double *dist=Distance, *dd=dist, distMax, vmax; Matrix H(n,n); Vector GXk(n); if (k>=0) xk=xx[k]; else xk=*v; for (i=0; i<N; i++) *(dd++)=xk.euclidianDistance(xx[i]); for (ii=0; ii<d.nLine(); ii++) { dd=dist; j=-1; distMax=-1.0; for (i=0; i<N; i++) { if (*dd>distMax) { j=i; distMax=*dd; }; dd++; } // to prevent to choose the same point once again: dist[j]=-1.0; if (distMax>2*rho) r++; pp[j].gradientHessian(xk,GXk,H); vd=LAGMAXModified(GXk,H,rho,vmax); vd+=xk; d.setLine(ii,vd); } return r; }
void CONDOR( double rhoStart, double rhoEnd, int niter, ObjectiveFunction *of, int nnode) { rhoStart=mmax(rhoStart,rhoEnd); int dim=of->dim(), info, k, t, nerror; double rho=rhoStart, delta=rhoStart, rhoNew, lambda1, normD=rhoEnd+1.0, modelStep, reduction, r, valueOF, valueFk, bound, noise; Vector d, tmp; bool improvement, forceTRStep=true, evalNeeded; initConstrainedStep(of); // pre-create the MultInd indexes to prevent multi-thread problems: cacheMultInd.get(dim,1); cacheMultInd.get(dim,2); parallelInit(nnode, dim, of); of->initData(); // points=getFirstPoints(&ValuesF, &nPtsTotal, rhoStart,of); InterPolynomial poly(2, rho, Vector::emptyVector, of->data, of); if (poly.NewtonBasis==NULL) { printf("cannot construct lagrange basis.\n"); exit(255); } //Base=poly.vBase; k=poly.kbest; valueFk=poly.valuesF[k]; fprintf(stderr,"init part 1 finished.\n"); /* InterPolynomial poly(dim,2,of); for (;;) { // find index k of the best (lowest) value of the function k=findK(ValuesF, nPtsTotal, of, points); Base=points[k].clone(); // Base=of->xStart.clone(); valueFk=ValuesF[k]; // translation: t=nPtsTotal; while (t--) points[t]-=Base; // exchange index 0 and index k (to be sure best point is inside poly): tmp=points[k]; points[k]=points[0]; points[0]=tmp; ValuesF[k]=ValuesF[0]; ValuesF[0]=valueFk; k=0; poly=InterPolynomial(2, nPtsTotal, points, ValuesF); if (poly.NewtonBasis!=NULL) break; // the construction of the first polynomial has failed // delete[] points; free(ValuesF); int kbest=findBest(of->data, of); // return 0 if startpoint is given Vector BaseStart=of->data.getLine(kbest,dim); double vBaseStart=((double**)of->data)[kbest][dim]; points=GenerateData(rho, BaseStart, vBaseStart, of, &ValuesF); nPtsTotal=n; } */ // update M: fullUpdateOfM(rho,poly.vBase,of->data,poly); fprintf(stderr,"init part 2 finished.\n"); fprintf(stderr,"init finished.\n"); // first of init all variables: parallelImprove(&poly, &k, rho, &valueFk, poly.vBase); // really start in parallel: startParallelThread(); while (true) { // fprintf(stderr,"rho=%e; fo=%e; NF=%i\n", rho,valueFk,QP_NF); while (true) { // trust region step while (true) { // poly.print(); parallelImprove(&poly, &k, rho, &valueFk, poly.vBase); niter--; if ((niter==0) ||(of->isConstrained&&checkForTermination(poly.NewtonPoints[k], poly.vBase, rhoEnd))) { poly.vBase+=poly.NewtonPoints[k]; fprintf(stderr,"rho=%e; fo=%e; NF=%i\n", rho,valueFk,of->getNFE()); of->valueBest=valueFk; of->xBest=poly.vBase; // to do : compute H and Lambda Vector vG(dim); Matrix mH(dim,dim); poly.gradientHessian(poly.NewtonPoints[k],vG,mH); of->finalize(vG,mH,FullLambda.clone()); return; } // to debug: fprintf(stderr,"Best Value Objective=%e (nfe=%i)\n", valueFk, of->getNFE()); d=ConstrainedL2NormMinimizer(poly,k,delta,&info,1000,&lambda1,poly.vBase,of); // if (d.euclidianNorm()>delta) // { // printf("Warning d to long: (%e > %e)\n", d.euclidianNorm(), delta); // } normD=mmin(d.euclidianNorm(), delta); d+=poly.NewtonPoints[k]; // next line is equivalent to reduction=valueFk-poly(d); // BUT is more precise (no rounding error) reduction=-poly.shiftedEval(d,valueFk); //if (normD<0.5*rho) { evalNeeded=true; break; } if ((normD<0.5*rho)&&(!forceTRStep)) { evalNeeded=true; break; } // IF THE MODEL REDUCTION IS SMALL, THEN WE DO NOT SAMPLE FUNCTION // AT THE NEW POINT. WE THEN WILL TRY TO IMPROVE THE MODEL. noise=0.5*mmax(of->noiseAbsolute*(1+of->noiseRelative), abs(valueFk)*of->noiseRelative); if ((reduction<noise)&&(!forceTRStep)) { evalNeeded=true; break; } forceTRStep=false; evalNeeded=false; if (quickHack) (*quickHack)(poly,k); tmp=poly.vBase+d; nerror=0; valueOF=of->eval(tmp, &nerror); of->saveValue(tmp,valueOF,nerror); if (nerror) { // evaluation failed delta*=0.5; if (normD>=2*rho) continue; break; } if (!of->isFeasible(tmp, &r)) { fprintf(stderr, "violation: %e\n",r); } // update of delta: r=(valueFk-valueOF)/reduction; if (r<=0.1) delta=0.5*normD; else if (r<0.7) delta=mmax(0.5*delta, normD); else delta=mmax(rho+ normD, mmax(1.25*normD, delta)); // powell's heuristics: if (delta<1.5*rho) delta=rho; if (valueOF<valueFk) { t=poly.findAGoodPointToReplace(-1, rho, d,&modelStep); k=t; valueFk=valueOF; improvement=true; // fprintf(stderr,"Value Objective=%e\n", valueOF); } else { t=poly.findAGoodPointToReplace(k, rho, d,&modelStep); improvement=false; // fprintf(stderr,"."); }; if (t<0) { poly.updateM(d, valueOF); break; } // If we are along constraints, it's more important to update // the polynomial with points which increase its quality. // Thus, we will skip this update to use only points coming // from checkIfValidityIsInBound if ((!of->isConstrained)||(improvement)||(reduction>0.0)||(normD<rho)) poly.replace(t, d, valueOF); if (improvement) continue; // if (modelStep>4*rho*rho) continue; if (modelStep>2*rho) continue; if (normD>=2*rho) continue; break; } // model improvement step forceTRStep=true; // fprintf(stderr,"improvement step\n"); bound=0.0; if (normD<0.5*rho) { bound=0.5*sqr(rho)*lambda1; if (poly.nUpdateOfM<10) bound=0.0; } parallelImprove(&poly, &k, rho, &valueFk, poly.vBase); // !! change d (if needed): t=poly.checkIfValidityIsInBound(d, k, bound, rho ); if (t>=0) { if (quickHack) (*quickHack)(poly,k); tmp=poly.vBase+d; nerror=0; valueOF=of->eval(tmp, &nerror); if (nerror) { Vector GXk(dim); Matrix H(dim,dim); poly.NewtonBasis[t].gradientHessian(poly.NewtonPoints[k],GXk,H); double rhot=rho,vmax; while (nerror) { rhot*=.5; d=LAGMAXModified(GXk,H,rhot,vmax); d+=poly.NewtonPoints[k]; tmp=poly.vBase+d; nerror=0; valueOF=of->eval(tmp, &nerror); of->saveValue(tmp,valueOF,nerror); } } poly.replace(t, d, valueOF); if ((valueOF<valueFk)&& (of->isFeasible(tmp))) { k=t; valueFk=valueOF; }; continue; } // the model is perfect for this value of rho: // OR // we have crossed a non_linear constraint which prevent us to advance if ((normD<=rho)||(reduction<0.0)) break; } // change rho because no improvement can now be made: if (rho<=rhoEnd) break; fprintf(stderr,"rho=%e; fo=%e; NF=%i\n", rho,valueFk,of->getNFE()); if (rho<16*rhoEnd) rhoNew=rhoEnd; else if (rho<250*rhoEnd) rhoNew=sqrt(rho*rhoEnd); else rhoNew=0.1*rho; delta=mmax(0.5*rho,rhoNew); rho=rhoNew; // update of the polynomial: translation of x[k]. // replace BASE by BASE+x[k] poly.translate(poly.NewtonPoints[k]); } parallelFinish(); Vector vG(dim); Matrix mH(dim,dim); if (evalNeeded) { tmp=poly.vBase+d; nerror=0; valueOF=of->eval(tmp,&nerror); of->saveValue(tmp,valueOF,nerror); if ((nerror)||(valueOF<valueFk)) { poly.vBase+=poly.NewtonPoints[k]; poly.gradientHessian(poly.NewtonPoints[k],vG,mH); } else { valueFk=valueOF; poly.vBase=tmp; poly.gradientHessian(d,vG,mH); } } else { poly.vBase+=poly.NewtonPoints[k]; poly.gradientHessian(poly.NewtonPoints[k],vG,mH); } // delete[] points; :not necessary: done in destructor of poly which is called automatically: fprintf(stderr,"rho=%e; fo=%e; NF=%i\n", rho,valueFk,of->getNFE()); of->valueBest=valueFk; of->xBest=poly.vBase; of->finalize(vG,mH,FullLambda.clone()); }
int InterPolynomial::checkIfValidityIsInBound(Vector ddv, unsigned k, double bound, double rho) // input: k,bound,rho // output: j,ddv { // check validity around x_k // bound is epsilon in the paper // return index of the worst point of J // if (j==-1) then everything OK : next : trust region step // else model step: replace x_j by x_k+d where d // is calculated with LAGMAX unsigned i,N=nPtsUsed, n=dim(); int j; Polynomial *pp=NewtonBasis; Vector *xx=NewtonPoints, xk=xx[k],vd; Vector Distance(N); double *dist=Distance, *dd=dist, distMax, vmax, tmp; Matrix H(n,n); Vector GXk(n); //,D(n); for (i=0; i<N; i++) *(dd++)=xk.euclidianDistance(xx[i]); while (true) { dd=dist; j=-1; distMax=2*rho; for (i=0; i<N; i++) { if (*dd>distMax) { j=i; distMax=*dd; }; dd++; } if (j<0) return -1; // to prevent to choose the same point once again: dist[j]=0; pp[j].gradientHessian(xk,GXk,H); // d=H.multiply(xk); // d.add(G); tmp=M*distMax*distMax*distMax; if (tmp*rho*(GXk.euclidianNorm()+0.5*rho*H.frobeniusNorm())>=bound) { /* vd=L2NormMinimizer(pp[j], xk, rho); vd+=xk; vmax=condorAbs(pp[j](vd)); Vector vd2=L2NormMinimizer(pp[j], xk, rho); vd2+=xk; double vmax2=condorAbs(pp[j](vd)); if (vmax<vmax2) { vmax=vmax2; vd=vd2; } */ vd=LAGMAXModified(GXk,H,rho,vmax); // tmp=vd.euclidianNorm(); vd+=xk; vmax=condorAbs(pp[j](vd)); if (tmp*vmax>=bound) break; } } if (j>=0) ddv.copyFrom(vd); return j; }