void CtcFirstOrderTest::contract(IntervalVector& box, ContractContext& context) { if(box.size() == 2) { return; } BxpNodeData* node_data = (BxpNodeData*) context.prop[BxpNodeData::id]; if(node_data == nullptr) { ibex_error("CtcFirstOrderTest: BxpNodeData must be set"); } vector<IntervalVector> gradients; for (int i = 0; i < system_.normal_constraints_.size() - 1; ++i) { if (!system_.normal_constraints_[i].isSatisfied(box)) { gradients.push_back(system_.normal_constraints_[i].gradient(box)); } } for (int i = 0; i < system_.sic_constraints_.size(); ++i) { if (!system_.sic_constraints_[i].isSatisfied(box, node_data->sic_constraints_caches[i])) { gradients.push_back(system_.sic_constraints_[i].gradient(box, node_data->sic_constraints_caches[i])); } } // Without the goal variable IntervalMatrix matrix(nb_var - 1, gradients.size() + 1); matrix.set_col(0, system_.goal_function_->gradient(box.subvector(0, nb_var - 2))); for (int i = 0; i < gradients.size(); ++i) { matrix.set_col(i + 1, gradients[i].subvector(0, nb_var - 2)); } bool testfailed = true; if (matrix.nb_cols() == 1) { if (matrix.col(0).contains(Vector::zeros(nb_var - 2))) { testfailed = false; } } else { int* pr = new int[matrix.nb_rows()]; int* pc = new int[matrix.nb_cols()]; IntervalMatrix LU(matrix.nb_rows(), matrix.nb_cols()); testfailed = true; try { interval_LU(matrix, LU, pr, pc); } catch(SingularMatrixException&) { testfailed = false; } delete[] pr; delete[] pc; } if(testfailed) { box.set_empty(); } }
BoolInterval PdcFirstOrder::test(const IntervalVector& box) { BoolInterval res; int n=sys.nb_var; // by default, all the constraints are activated int M=sys.nb_ctr; // count the number of active constraints // in the original system for (int j=0; j<sys.nb_ctr; j++) { if (e && e->original(j)) M--; } if (M>n) { return MAYBE; } // cannot be full rank int j2=0; IntervalMatrix* J=new IntervalMatrix(M+1,n); // +1 because we add the gradient of f sys.goal->gradient(box,J->row(j2++)); for (int j=0; j<sys.nb_ctr; j++) { if (e && e->original(j)) { continue; } sys.f_ctrs[j].gradient(box,J->row(j2++)); } int N=sys.nb_var; // final number of variables // check the active bouding constraints for (int i=0; i<sys.nb_var; i++) { // if the ith bounding constraint is active // we will remove the ith column in the matrix J2 if (!box[i].is_interior_subset(init_box[i])) { if (box[i].is_superset(init_box[i])) { delete J; return MAYBE; // cannot be full rank } else { N--; } } } IntervalMatrix* J2=J; if (N==n) J2=J; // useless to build J a second time. else if (M+1>N) { // cannot be full rank delete J; return MAYBE; } else { J2 = new IntervalMatrix(M+1,N); int i2=0; for (int i=0; i<sys.nb_var; i++) { if (box[i].is_interior_subset(init_box[i])) J2->set_col(i2++,J->col(i)); } delete J; assert(i2==N); } // check for invertibility int *p=new int[M+1]; // will not be used int *q=new int[n]; // will not be used IntervalMatrix LU(M+1,N); // will not be used try { // note: seems worse with complete pivoting interval_LU(*J2, LU, p, q); //, q); // the matrix is rank M+1 res = NO; } catch(SingularMatrixException&) { res = MAYBE; } delete J2; delete [] p; delete [] q; return res; }
void CtcKhunTucker::contract(IntervalVector& box) { if (df==NULL) return; // if (sys.nb_ctr==0) { // if (box.is_strict_interior_subset(sys.box)) { // // for unconstrained optimization we benefit from a cheap // // contraction with gradient=0, before running Newton. // // if (nb_var==1) // df->backward(Interval::ZERO,box); // else // df->backward(IntervalVector(nb_var,Interval::ZERO),box); // } // } // // if (box.is_empty()) return; //if (box.max_diam()>1e-1) return; // do we need a threshold? // ========================================================================================= BitSet active=sys.active_ctrs(box); FncKhunTucker fjf(sys,df,dg,box,BitSet::all(sys.nb_ctr)); //active); // we consider that Newton will not succeed if there are more // than n active constraints. if ((fjf.eq.empty() && fjf.nb_mult > sys.nb_var+1) || (!fjf.eq.empty() && fjf.nb_mult > sys.nb_var)) { //cout << fjf.nb_mult << endl; too_many_active++; return; } IntervalVector lambda=fjf.multiplier_domain(); IntervalVector old_lambda(lambda); int *pr; int *pc=new int[fjf.nb_mult]; IntervalMatrix A(fjf.eq.empty() ? sys.nb_var+1 : sys.nb_var, fjf.nb_mult); if (fjf.eq.empty()) { A.put(0,0, fjf.gradients(box)); A.put(sys.nb_var, 0, Vector::ones(fjf.nb_mult), true); // normalization equation pr = new int[sys.nb_var+1]; // selected rows } else { A = fjf.gradients(box); pr = new int[sys.nb_var]; // selected rows } IntervalMatrix LU(A); bool preprocess_success=false; try { IntervalMatrix A2(fjf.nb_mult, fjf.nb_mult); // if (A.nb_rows()>A.nb_cols()) { //cout << "A=" << A << endl; interval_LU(A,LU,pr,pc); lu_OK++; //cout << "LU success\n"; // } else // cout << "bypass LU\n"; Vector b2=Vector::zeros(fjf.nb_mult); for (int i=0; i<fjf.nb_mult; i++) { A2.set_row(i, A.row(pr[i])); if (pr[i]==sys.nb_var) // right-hand side of normalization is 1 b2[i]=1; } //cout << "\n\nA2=" << A2 << endl; precond(A2); //cout << "precond success\n"; precond_OK++; gauss_seidel(A2,b2,lambda); double maxdiam=0; for (int i=0; i<A.nb_rows(); i++) { double d=A.row(i).max_diam(); if (d>maxdiam) maxdiam=d; } if (old_lambda.rel_distance(lambda)>0.1 //&& maxdiam<10 && lambda[1].lb()>0 ) { preprocess_success=true; } if (lambda.is_empty()) { box.set_empty(); return; } } catch(SingularMatrixException&) { } delete[] pr; delete[] pc; if (!preprocess_success) return; CtcNewton newton(fjf,1); IntervalVector full_box = cart_prod(box, lambda); // ========================================================================================= // CtcNewton newton(fjc.f,1); // // IntervalVector full_box = cart_prod(box, IntervalVector(fjc.M+fjc.R+fjc.K+1,Interval(0,1))); // // full_box.put(fjc.n+fjc.M+fjc.R+1,IntervalVector(fjc.K,Interval::ZERO)); // ========================================================================================= IntervalVector save(full_box); newton.contract(full_box); if (full_box.is_empty()) { if (preprocess_success) newton_OK_preproc_OK++; else newton_OK_preproc_KO++; box.set_empty(); } else { if (save.subvector(0,sys.nb_var-1)!=full_box.subvector(0,sys.nb_var-1)) { if (preprocess_success) newton_OK_preproc_OK++; else newton_OK_preproc_KO++; box = full_box.subvector(0,sys.nb_var-1); } else { if (preprocess_success) { newton_KO_preproc_OK++; } else newton_KO_preproc_KO++; } } // ========================================================================================= }