bool HC4Revise::backward(const Domain& y) { Domain& root=*d.top; if (root.is_empty()) throw EmptyBoxException(); switch(y.dim.type()) { case Dim::SCALAR: if (root.i().is_subset(y.i())) return true; break; case Dim::ROW_VECTOR: case Dim::COL_VECTOR: if (root.v().is_subset(y.v())) return true; break; case Dim::MATRIX: if (root.m().is_subset(y.m())) return true; break; } root &= y; if (root.is_empty()) throw EmptyBoxException(); // may throw an EmptyBoxException(). eval.f.backward<HC4Revise>(*this); return false; //std::cout << "backward:" << std::endl; f.cf.print(); }
void HC4Revise::gen1_bwd(int x, int y) { assert(dynamic_cast<const ExprGenericUnaryOp*>(&(f.node(y)))); const ExprGenericUnaryOp& e = (const ExprGenericUnaryOp&) f.node(y); e.bwd(d[y], d[x]); if (d[x].is_empty()) throw EmptyBoxException(); }
void CtcPolytopeHull::contract(IntervalVector& box) { if (!(limit_diam_box.contains(box.max_diam()))) return; // is it necessary? YES (BNE) Soplex can give false infeasible results with large numbers // cout << " box before LR " << box << endl; try { // Update the bounds the variables mylinearsolver->initBoundVar(box); //returns the number of constraints in the linearized system int cont = lr.linearization(box,mylinearsolver); if(cont<1) return; optimizer(box); // mylinearsolver->writeFile("LP.lp"); // system ("cat LP.lp"); // cout << " box after LR " << box << endl; mylinearsolver->cleanConst(); } catch(EmptyBoxException&) { box.set_empty(); // empty the box before exiting in case of EmptyBoxException mylinearsolver->cleanConst(); throw EmptyBoxException(); } }
void HC4Revise::vector_bwd(const ExprVector& v, ExprLabel** compL, const ExprLabel& y) { if (v.dim.is_vector()) { for (int i=0; i<v.length(); i++) if ((compL[i]->d->i() &= y.d->v()[i]).is_empty()) throw EmptyBoxException(); } else { if (v.row_vector()) for (int i=0; i<v.length(); i++) { if ((compL[i]->d->v()&=y.d->m().col(i)).is_empty()) throw EmptyBoxException(); } else for (int i=0; i<v.length(); i++) { if ((compL[i]->d->v()&=y.d->m().row(i)).is_empty()) throw EmptyBoxException(); } } }
void CtcInteger::contract(IntervalVector& box) { for (int i=0; i<nb_var; i++) { if (!is_int[i]) continue; proj_integer(box[i]); if (box[i].is_empty()) { box.set_empty(); throw EmptyBoxException(); } } }
void CtcInteger::contract(IntervalVector& box, const BoolMask& impact) { for (int i=0; i<nb_var; i++) { if (is_int[i] && impact[i]) { proj_integer(box[i]); if (box[i].is_empty()) { box.set_empty(); throw EmptyBoxException(); } } } }
void Optimizer::update_entailed_ctr(const IntervalVector& box) { for (int j=0; j<m; j++) { if (entailed->normalized(j)) { continue; } Interval y=sys.f[j].eval(box); if (y.lb()>0) throw EmptyBoxException(); else if (y.ub()<=0) { entailed->set_normalized_entailed(j); } } }
void CtcUnion::contract(IntervalVector& box) { IntervalVector savebox(box); IntervalVector result(IntervalVector::empty(box.size())); for (int i=0; i<list.size(); i++) { if (i>0) box=savebox; try { list[i].contract(box); result |= box; } catch(EmptyBoxException&) { } } box = result; if (box.is_empty()) throw EmptyBoxException(); } // end namespace ibex
void CtcQInterCoreF::contract(IntervalVector& box) { Array<IntervalVector> refs(list.size()); for (int i=0; i<list.size(); i++) { try { boxes[i]=box; list[i].contract(boxes[i]); } catch(EmptyBoxException&) { assert(boxes[i].is_empty()); } refs.set_ref(i,boxes[i]); } box = qinter_coref(refs,q); if (box.is_empty()) throw EmptyBoxException(); }
void CtcNotIn::contract(IntervalVector& box) { // it's simpler here to use direct computation, but // we could also have used CtCunion of two CtcFwdBwd IntervalVector savebox(box); try { HC4Revise().proj(f,d1,box); } catch (EmptyBoxException& ) {box.set_empty(); } try { HC4Revise().proj(f,d2,savebox); } catch (EmptyBoxException& ) {savebox.set_empty(); } box |= savebox; if (box.is_empty()) throw EmptyBoxException(); }
void HC4Revise::vector_bwd(int* x, int y) { assert(dynamic_cast<const ExprVector*>(&(f.node(y)))); const ExprVector& v = (const ExprVector&) f.node(y); assert(v.type()!=Dim::SCALAR); int j=0; if (v.dim.is_vector()) { for (int i=0; i<v.length(); i++) { if (v.arg(i).dim.is_vector()) { if ((d[x[i]].v() &= d[y].v().subvector(j,j+v.arg(i).dim.vec_size())).is_empty()) throw EmptyBoxException(); j+=v.arg(i).dim.vec_size(); } else { if ((d[x[i]].i() &= d[y].v()[j]).is_empty()) throw EmptyBoxException(); j++; } } assert(j==v.dim.vec_size()); } else { if (v.row_vector()) { for (int i=0; i<v.length(); i++) { if (v.arg(i).dim.is_matrix()) { if ((d[x[i]].m()&=d[y].m().submatrix(0,v.dim.nb_rows(),j,v.arg(i).dim.nb_cols())).is_empty()) throw EmptyBoxException(); j+=v.arg(i).dim.nb_cols(); } else if (v.arg(i).dim.is_vector()) { if ((d[x[i]].v()&=d[y].m().col(j)).is_empty()) throw EmptyBoxException(); j++; } } } else { for (int i=0; i<v.length(); i++) { if (v.arg(i).dim.is_matrix()) { if ((d[x[i]].m()&=d[y].m().submatrix(j,v.arg(i).dim.nb_rows(),0,v.dim.nb_cols())).is_empty()) throw EmptyBoxException(); j+=v.arg(i).dim.nb_rows(); } else if (v.arg(i).dim.is_vector()) { if ((d[x[i]].v()&=d[y].m().row(j)).is_empty()) throw EmptyBoxException(); j++; } } } } }
// called with the box without the objective void Optimizer::firstorder_contract( IntervalVector& box, const IntervalVector& init_box) { if (m==0) { // for unconstrained optimization contraction with gradient=0 if (box.is_strict_subset(init_box)) { // may throw an EmptyBoxException: if (n==1) df.backward(Interval::ZERO,box); else df.backward(IntervalVector(n,Interval::ZERO),box); } } else { PdcFirstOrder p(user_sys,init_box); p.set_entailed(entailed); if (p.test(box)==NO) throw EmptyBoxException(); } }
void CtcForAll::contract(IntervalVector& x) { assert(x.size()==nb_var); IntervalVector box(nb_var+_init.size()); IntervalVector * sub; bool mdiam; int iter =0; box.put(0, x); std::list<IntervalVector> l; l.push_back(_init); std::pair<IntervalVector,IntervalVector> cut(_init,_init); while ((!l.empty())&&(iter<_max_iter)) { cut = _bsc.bisect(l.front()); l.pop_front(); sub = &(cut.first); for (int j=1;j<=2;j++) { if (j==2) sub = &(cut.second); for(int i=0; i< _init.size(); i++) { box[i+nb_var] = (*sub)[i].mid(); } // it is enough to contract only with the middle, it is more precise and faster. try { _ctc.contract(box); } catch (EmptyBoxException& e) { x.set_empty(); throw e; } mdiam=true; for (int i=0;mdiam&&(i<_init.size()); i++) mdiam = mdiam&&((*sub)[i].diam()<= _prec); if (!mdiam) { l.push_back(*sub); iter++; } } } for(int i=0; i< nb_var; i++) x[i] &= box[i]; if (x.is_empty()) throw EmptyBoxException(); }
int LinearRelaxXTaylor::X_Linearization(const IntervalVector& savebox, int ctr, corner_point cpoint, CmpOp op, IntervalVector& G2, int id_point, int& nb_nonlinear_vars, LinearSolver& lp_solver) { IntervalVector G = G2; int n = sys.nb_var; int nonlinear_var = 0; if (id_point != 0 && linear_ctr[ctr]) return 0; // only one corner for a linear constraint /* bool* corner=NULL; if(!linear[ctr]){ // best not implemented in version 2.0 BNE if(cpoint==BEST){ corner= new bool[n]; best_corner(ctr, op, G, corner); } } */ IntervalVector box(savebox); Interval ev(0.0); Interval tot_ev(0.0); Vector row1(n); for (int j=0; j< n; j++) { //cout << "[LinearRelaxXTaylor] variable n°" << j << endl; if (sys.ctrs[ctr].f.used(j)) { if (lmode == HANSEN && !linear[ctr][j]) // get the partial derivative of ctr w.r.t. var n°j G[j]=df[ctr*n+j].eval(box); } else continue; //cout << "[LinearRelaxXTaylor] coeffs=" << G[j] << endl; if (G[j].diam() > max_diam_deriv) { // box = savebox; // [gch] where box has been modified? at the end of the loop (for Hansen computation) [bne] return 0; // To avoid problems with SoPleX } if (linear[ctr][j]) cpoint = INF_X; else if (G[j].diam() > 1e-10) nonlinear_var++; bool inf_x; /* for GREEDY heuristics :not implemented in v2 IntervalVector save; double fh_inf, fh_sup; double D; */ switch (cpoint) { /* case BEST: inf_x=corner[j]; last_rnd[j]=inf_x? 0:1; break; */ case INF_X: inf_x = true; break; case SUP_X: inf_x = false; break; case RANDOM: last_rnd[j] = rand(); inf_x = (last_rnd[j] % 2 == 0); break; case K4: if (id_point == 0) { inf_x = (rand() % 2 == 0); base_coin[j] = inf_x; } else if (nb_nonlinear_vars < 3) { if (id_point == 1) inf_x = !base_coin[j]; else return 0; } else if (G[j].diam() <= 1e-10) { inf_x = (rand() % 2 == 0); } else if (id_point == 1) { if (((double) nonlinear_var) <= (((double) nb_nonlinear_vars)/ 3.0)) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } else if (id_point == 2) { if (((double) nonlinear_var )> ((double) nb_nonlinear_vars)/ 3.0 && (double) nonlinear_var <= 2 * (double) nb_nonlinear_vars / 3.0) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } else if (id_point == 3) { if (((double) nonlinear_var) > 2 * ((double) nb_nonlinear_vars) / 3.0) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } break; case RANDOM_INV: inf_x = (last_rnd[j] % 2 != 0); break; case NEG: inf_x = (last_rnd[j] % 2 != 0); break; /* not implemented in v2.0 case GREEDY1: inf_x=((abs(Inf(G(j+1))) < abs(Sup(G(j+1))) && (op == LEQ || op== LT)) || (abs(Inf(G(j+1))) >= abs(Sup(G(j+1))) && (op == GEQ || op== GT)) )? true:false; break; case MONO: if (ctr==goal_ctr && ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || (Sup (G(j+1)) < 0 && (op == GEQ || op== GT)))) inf_x = true; else if (ctr == goal_ctr && ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || (Inf(G(j+1)) > 0 && (op == GEQ || op== GT)))) inf_x=false; else inf_x = (rand()%2==0); last_rnd[j]=inf_x? 0:1; break; case NEGMONO: if ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || (Sup (G(j+1)) < 0 && (op == GEQ || op== GT))) inf_x = false; else if ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || (Inf(G(j+1)) > 0 && (op == GEQ || op== GT))) inf_x=true; else inf_x = (rand()%2==0); last_rnd[j]=inf_x? 0:1; break; */ /* case GREEDY7: //select the coin nearest to the loup if(goal_ctr!=-1 && Dimension(Optimizer::global_optimizer())>0){ // if(j==0)cout<< Optimizer::global_optimizer()<<end; inf_x=(abs(Optimizer::global_optimizer()(j+1)-Inf(savebox(j+1))) < abs(Optimizer::global_optimizer()(j+1)-Sup(savebox(j+1))))? true:false; }else{ inf_x=(rand()%2==0); } break; */ /* case GREEDY6: save=space.box; fh_inf, fh_sup; D=Diam(savebox(j+1)); space.box=Mid(space.box); space.box(j+1)=Inf(savebox(j+1)); fh_inf=Mid(sys.ctr(ctr).eval(space)); space.box(j+1)=Sup(savebox(j+1)); fh_sup=Mid(sys.ctr(ctr).eval(space)); if (op == LEQ || op== LT) inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) > 0)? false:true; else inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true; last_rnd[j]=inf_x? 0:1; space.box=save; break; case GREEDY5: save=space.box; fh_inf, fh_sup; D=Diam(savebox(j+1)); space.box=Mid(space.box); space.box(j+1)=Inf(savebox(j+1)); fh_inf=Mid(sys.ctr(ctr).eval(space)); space.box(j+1)=Sup(savebox(j+1)); fh_sup=Mid(sys.ctr(ctr).eval(space)); if (op == LEQ || op== LT) inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) > 0)? false:true; else inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true; last_rnd[j]=inf_x? 0:1; space.box=save; break; */ default: last_rnd[j] = rand(); inf_x = (last_rnd[j] % 2 == 0); break; } // cout << " j " << j << " " << savebox[j] << G[j] << endl; box[j]=inf_x? savebox[j].lb():savebox[j].ub(); Interval a = ((inf_x && (op == LEQ || op== LT)) || (!inf_x && (op == GEQ || op== GT))) ? G[j].lb() : G[j].ub(); row1[j] = a.mid(); ev -= a*box[j]; } // cout << " ev " << ev << endl; /* used in BEST not implemented in v2.0 if(corner) delete[] corner; */ ev+= sys.ctrs[ctr].f.eval(box); if(id_point==0) nb_nonlinear_vars=nonlinear_var; for(int j=0;j<n;j++) tot_ev+=row1[j]*savebox[j]; //natural evaluation of the left side of the linear constraint bool added=false; if (op == LEQ || op == LT) { //g(xb) + a1' x1 + ... + an xn <= 0 if(tot_ev.lb()>(-ev).ub()) throw EmptyBoxException(); // the constraint is not satisfied if((-ev).ub()<tot_ev.ub()) { // otherwise the constraint is satisfied for any point in the box lp_solver.addConstraint( row1, LEQ, (-ev).ub()); added=true; } } else { if(tot_ev.ub()<(-ev).lb()) throw EmptyBoxException(); if ((-ev).lb()>tot_ev.lb()) { lp_solver.addConstraint( row1, GEQ, (-ev).lb() ); added=true; } } //box=savebox; return (added)? 1:0; }
void CtcAcid::contract(IntervalVector& box) { int nb_CID_var=cid_vars.size(); // [gch] impact.clear(); // [gch] int nbvarmax=5*nb_CID_var; // au plus 5*nbvar double *ctstat = new double[nbvarmax]; int nbinitcalls=50; // longueur du réglage int factor = 20; // détermine la période entre les débuts de 2 régalages successifs : factor*nbinitcalls int nbcall1= nbcalls% (factor*nbinitcalls); // pour savoir si on est dans une phase de réglage (nbcall1 < nbinitcalls ) IntervalVector initbox (box); if (nbcall1 < nbinitcalls) { // réglage if (nbcalls < nbinitcalls) vhandled =nb_CID_var; // premier réglage 3BCID une fois sur toutes les variables else vhandled = 2* nbcidvar; // réglages suivants : sur 2 fois le réglage précédent if (vhandled< 2) vhandled= 2; // réglage minimum à 2 for (int i =0; i< nbvarmax; i++) // initialisation du tableau des gains: ctstat[i]=0; // ctstat[i] gain moyen dû à l'appel de varcid sur la variable i } else vhandled = nbcidvar; // en dehors du réglage , on prend nbcidvar ( la valeur réglée) if (vhandled > nbvarmax) vhandled=nbvarmax; // pour rester raisonnable et dans les limites du tableau ctstat if (vhandled > 0) compute_smearorder(box); // l'ordre sur les variables est calculé avec la smearsumrel if (optim) putobjfirst(); // pour l'optim (si optim mis à true dans le constructeur, la dernière variable (objectf) est mise en premier for (int v=0; v<vhandled; v++) { int v1=v%nb_CID_var; // [gch] how can v be < nb_var?? [bne] vhandled can be between 0 and nbvarmax int v2=smearorder[v1]; impact.add(v2); var3BCID(box, v2); // appel 3BCID sur la variable v2 impact.remove(v2); if(box.is_empty()) throw EmptyBoxException(); if (nbcall1 < nbinitcalls) { // on fait des stats pour le réglage courant for (int i=0; i<initbox.size(); i++) {//cout << i << " initbox " << initbox[i].diam() << " box " << box[i].diam() << endl; if (initbox[i].diam() !=0 && box[i].diam()!= POS_INFINITY) // gain sur la ième dimension de la boîte courante après var3BCID sur la v-ième variable ctstat[v] += 1 - box[i].diam() / initbox[i].diam();} ctstat[v]=ctstat[v]/ initbox.size(); // gain moyen } initbox=box; } int nvar=0; nbcalls++; nbcall1++; // pendant la phase de réglage if (nbcall1 <= nbinitcalls) { // : on part de la dernière variable. // on s'arrête dès qu'on a trouvé une variable ayant gagné plus que ctratio, ce qui nous donne le nbre nvar de variables itéressantes. for (int v=vhandled-1 ; v>=0; v--) if (ctstat[v] > ctratio) { nvar=v+1; break; } // calcul incrémental de la moyenne du nbre de variables intéressantes nbctvar= (nbctvar * (nbcall1 - 1) + nvar ) / nbcall1; } if (nbcall1==nbinitcalls) { // fin de la phase de réglage - détermination de nbcidvar nbcidvar= (int) (nbctvar + 0.5); // - calcul incrémental de la moyenne nbtuning++; nbvarstat = (nbvarstat * (nbtuning-1) + nbcidvar) / nbtuning; } delete [] ctstat; }
void CtcPolytopeHull::optimizer(IntervalVector& box) { Interval opt(0.0); int* inf_bound = new int[nb_var]; // indicator inf_bound = 1 means the inf bound is feasible or already contracted, call to simplex useless (cf Baharev) int* sup_bound = new int[nb_var]; // indicator sup_bound = 1 means the sup bound is feasible or already contracted, call to simplex useless if (cmode==ONLY_Y) { for (int i=0; i<nb_var; i++) { // in the case of lower_bounding, only the left bound of y is contracted inf_bound[i]=1; sup_bound[i]=1; } if (goal_var>-1) inf_bound[goal_var]=0; } else { for (int i=0; i<nb_var; i++) { // in case of optimization, the right bound of y is not contracted inf_bound[i]=0; sup_bound[i]=0; } if (goal_var>-1) sup_bound[goal_var]=1; } int nexti=-1; // the next variable to be contracted int infnexti=0; // the bound to be contracted contract infnexti=0 for the lower bound, infnexti=1 for the upper bound LinearSolver::Status_Sol stat=LinearSolver::UNKNOWN; for(int ii=0; ii<(2*nb_var); ii++) { // at most 2*n calls int i= ii/2; if (nexti != -1) i=nexti; // cout << " i "<< i << " infnexti " << infnexti << " infbound " << inf_bound[i] << " supbound " << sup_bound[i] << endl; // cout << " box avant simplex " << box << endl; if (infnexti==0 && inf_bound[i]==0) // computing the left bound : minimizing x_i { inf_bound[i]=1; stat = run_simplex(box, LinearSolver::MINIMIZE, i, opt,box[i].lb()); // cout << " stat " << stat << " opt " << opt << endl; if (stat == LinearSolver::OPTIMAL) { if(opt.lb()>box[i].ub()) { throw EmptyBoxException(); } if(opt.lb() > box[i].lb()) { box[i]=Interval(opt.lb(),box[i].ub()); mylinearsolver->setBoundVar(i,box[i]); } if (!choose_next_variable(box,nexti,infnexti, inf_bound, sup_bound)) { break; } } else if (stat == LinearSolver::INFEASIBLE) { // the infeasibility is proved, the EmptyBox exception is raised throw EmptyBoxException(); } else if (stat == LinearSolver::INFEASIBLE_NOTPROVED) { // the infeasibility is found but not proved, no other call is needed break; } else if (stat == LinearSolver::UNKNOWN) { int next=-1; for (int j=0;j<nb_var;j++) { if (inf_bound[j]==0) { nexti=j; next=0; infnexti=0; break; } else if (sup_bound[j]==0) { nexti=j; next=0; infnexti=1; break; } } if (next==-1) break; } } else if (infnexti==1 && sup_bound[i]==0) { // computing the right bound : maximizing x_i sup_bound[i]=1; stat= run_simplex(box, LinearSolver::MAXIMIZE, i, opt, box[i].ub()); // cout << " stat " << stat << " opt " << opt << endl; if( stat == LinearSolver::OPTIMAL) { if(opt.ub() <box[i].lb()) { throw EmptyBoxException(); } if (opt.ub() < box[i].ub()) { box[i] =Interval( box[i].lb(), opt.ub()); mylinearsolver->setBoundVar(i,box[i]); } if (!choose_next_variable(box,nexti,infnexti, inf_bound, sup_bound)) { break; } } else if(stat == LinearSolver::INFEASIBLE) { // the infeasibility is proved, the EmptyBox exception is raised throw EmptyBoxException(); } else if (stat == LinearSolver::INFEASIBLE_NOTPROVED) { // the infeasibility is found but not proved, no other call is needed break; } else if (stat == LinearSolver::UNKNOWN) { int next=-1; for (int j=0;j<nb_var;j++) { if (inf_bound[j]==0) { nexti=j; next=0; infnexti=0; break; } else if (sup_bound[j]==0) { nexti=j; next=0; infnexti=1; break; } } if (next==-1) break; } } else break; // in case of stat==MAX_ITER we do not recall the simplex on a another variable (for efficiency reason) } delete[] inf_bound; delete[] sup_bound; }
/*********generation of the linearized system*********/ int LinearRelaxAffine2::linearization(IntervalVector & box, LinearSolver *mysolver) { Affine2 af2; Vector rowconst(sys.nb_var); Interval ev(0.0); Interval center(0.0); Interval err(0.0); CmpOp op; int cont = 0; LinearSolver::Status stat = LinearSolver::FAIL; // Create the linear relaxation of each constraint for (int ctr = 0; ctr < sys.nb_ctr; ctr++) { af2 = 0.0; ev = sys.ctrs[ctr].f.eval_affine2(box, af2); op = sys.ctrs[ctr].op; if (af2.size() == sys.nb_var) { // if the affine2 form is valid // convert the epsilon variables to the original box double tmp=0; center =0; err =0; for (int i =0; i <sys.nb_var; i++) { tmp = box[i].rad(); // if (tmp> mysolver->getEpsilon()) { rowconst[i] =af2.val(i+1) / tmp; center += rowconst[i]*box[i].mid(); err += fabs(rowconst[i])* pow(2,-50); // TODO to check // } else { // rowconst[i] = 0; // err += tmp; // } } switch (op) { case LEQ: if (0.0 == ev.lb()) throw EmptyBoxException(); case LT: { if (0.0 < ev.lb()) throw EmptyBoxException(); else if (0.0 < ev.ub()) { stat = mysolver->addConstraint(rowconst, LEQ, ((af2.err()+err) - (af2.val(0)-center)).ub()); if (stat == LinearSolver::OK) cont++; } break; } case GEQ: if (ev.ub() == 0.0) throw EmptyBoxException(); break; case GT: { if (ev.ub() < 0.0) throw EmptyBoxException(); else if (ev.lb() < 0.0) { stat = mysolver->addConstraint(rowconst, GEQ, (-(af2.err()+err) - (af2.val(0)-center)).lb()); if (stat == LinearSolver::OK) cont++; } break; } case EQ: { if (!ev.contains(0.0)) { throw EmptyBoxException(); } else { if (ev.diam()>2*mysolver->getEpsilon()) { stat = mysolver->addConstraint(rowconst, GEQ, (-(af2.err()+err) - (af2.val(0)-center)).lb()); if (stat == LinearSolver::OK) cont++; stat = mysolver->addConstraint(rowconst, LEQ, ((af2.err()+err) - (af2.val(0)-center)).ub()); if (stat == LinearSolver::OK) cont++; } } break; } } } } return cont; }
void CtcEmpty::contract(IntervalVector& box) { if (pdc.test(box)==YES) { box.set_empty(); throw EmptyBoxException(); } }
void Optimizer::contract_and_bound(Cell& c, const IntervalVector& init_box) { // cout << "box " <<c.box << endl; /*======================== contract y with y<=loup ========================*/ Interval& y=c.box[ext_sys.goal_var()]; double ymax; if (loup==POS_INFINITY) ymax=POS_INFINITY; else ymax= compute_ymax(); y &= Interval(NEG_INFINITY,ymax); if (y.is_empty()) { c.box.set_empty(); throw EmptyBoxException(); } /*================ contract x with f(x)=y and g(x)<=0 ================*/ // cout << "y=f(x) and g(x)<=0 " << endl; // cout << " x before=" << c.box << endl; // cout << " y before=" << y << endl; contract(c.box, init_box); // cout << " x after=" << c.box << endl; // cout << " y after=" << y << endl; // TODO: no more cell in argument here (just a box). Does it matter? /*====================================================================*/ /*========================= update loup =============================*/ IntervalVector tmp_box(n); read_ext_box(c.box,tmp_box); entailed = &c.get<EntailedCtr>(); update_entailed_ctr(tmp_box); update_loup(tmp_box); /*====================================================================*/ // [gch] TODO: the case (!c.box.is_bisectable()) seems redundant // with the case of a NoBisectableVariableException in // optimize(). Is update_uplo_of_epsboxes called twice in this case? // (bn] NO , the NoBisectableVariableException is raised by the bisector, // there are actually 2 different cases of a non bisected box that may cause an update // of uplo_of_epsboxes double tmp_diam =tmp_box.max_diam(); if ((tmp_diam<=prec && y.diam() <=goal_abs_prec) || !c.box.is_bisectable()) { // rem1: tmp_box and not c.box because y is handled with goal_rel_prec and goal_abs_prec // rem2: do not use a precision contractor here since it would make the box empty (and y==(-inf,-inf)!!) // rem 3 : the extended boxes with no bisectable domains should be catched for avoiding infinite bisections if (!(tmp_box.is_unbounded())) { // rem4: this case can append if the interval [1.79769e+308,inf] is in c.box. // It is only numerical degenerated case update_uplo_of_epsboxes(y.lb()); } throw EmptyBoxException(); } //gradient=0 contraction for unconstrained optimization ; //first order test for constrained optimization (useful only when there are no equations replaced by inequalities) //works with the box without the objective (tmp_box) firstorder_contract(tmp_box,init_box); // the current extended box in the cell is updated write_ext_box(tmp_box,c.box); }