std::vector<T> Selector::select(const std::vector<T> &v) const { assert(v.size() == nvars_possible()); if (include_all_ || nvars() == nvars_possible()) return v; std::vector<T> ans; ans.reserve(nvars()); for (uint i = 0; i < nvars(); ++i) { ans.push_back(v[indx(i)]); } return ans; }
std::vector<T> Selector::select(const std::vector<T> &v) const{ assert(v.size()==nvars_possible()); std::vector<T> ans; ans.reserve(nvars()); for(uint i=0; i<nvars_possible(); ++i) if(inc(i)) ans.push_back(v[i]); return ans;}
T Selector::sub_select(const T &x, const Selector &rhs) const { assert(rhs.nvars() <= this->nvars()); assert(this->covers(rhs)); Selector tmp(nvars(), false); for (uint i = 0; i < rhs.nvars(); ++i) { tmp.add(INDX(rhs.indx(i))); } return tmp.select(x); }
real PseudoBoolean<real>::minimize_reduction_M(vector<label>& x, int& nlabelled) const { // // Compute a large enough value for M // real M = 0; for (auto itr=aijkl.begin(); itr != aijkl.end(); ++itr) { real a = itr->second; M += abs(a); } for (auto itr=aijk.begin(); itr != aijk.end(); ++itr) { real a = itr->second; M += abs(a); } for (auto itr=aij.begin(); itr != aij.end(); ++itr) { real a = itr->second; M += abs(a); } for (auto itr=ai.begin(); itr != ai.end(); ++itr) { real a = itr->second; M += abs(a); } // Copy of the polynomial. Will contain the reduced polynomial PseudoBoolean<real> pb = *this; // Number of variables (will be increased int n = nvars(); int norg = n; // // Reduce the degree-4 terms // double M2 = M; for (auto itr=pb.aijkl.begin(); itr != pb.aijkl.end(); ++itr) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); int l = get_l(itr->first); real a = itr->second; // a*xi*xj*xk*xl will be converted to // a*xi*xj*z + M( xk*xl - 2*xk*z - 2*xl*z + 3*z ) int z = n++; pb.add_monomial(i,j,z, a); pb.add_monomial(k,l,M); pb.add_monomial(k,z, -2*M); pb.add_monomial(l,z, -2*M); pb.add_monomial(z, 3*M); M2 += a + 4*M; } // Remove all degree-4 terms. pb.aijkl.clear(); // // Reduce the degree-3 terms // for (auto itr=pb.aijk.begin(); itr != pb.aijk.end(); ++itr) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); real a = itr->second; // a*xi*xj*xk will be converted to // a*xi*z + M( xj*xk -2*xj*z -2*xk*z + 3*z ) int z = n++; pb.add_monomial(i,z, a); pb.add_monomial(j,k,M2); pb.add_monomial(j,z, -2*M2); pb.add_monomial(k,z, -2*M2); pb.add_monomial(z, 3*M2); } // Remove all degree-3 terms. pb.aijk.clear(); // // Minimize the reduced polynomial // vector<label> xtmp(n,-1); real bound = pb.minimize(xtmp, HOCR); nlabelled = 0; for (int i=0;i<norg;++i) { x.at(i) = xtmp[i]; if (x[i] >= 0) { nlabelled++; } } return bound; }
real PseudoBoolean<real>::minimize_reduction(vector<label>& x, int& nlabelled) const { index nVars = index( x.size() ); // Here it is important that all indices appear as pairs // in aij or ai ASSERT_STR( nvars() <= nVars , "x too small"); PBF<real, 4> hocr; map<int,bool> var_used; for (auto itr=ai.begin(); itr != ai.end(); ++itr) { int i = itr->first; real a = itr->second; hocr.AddUnaryTerm(i, 0, a); var_used[i] = true; } for (auto itr=aij.begin(); itr != aij.end(); ++itr) { int i = get_i(itr->first); int j = get_j(itr->first); real a = itr->second; hocr.AddPairwiseTerm(i,j, 0,0,0, a); var_used[i] = true; var_used[j] = true; } for (auto itr=aijk.begin(); itr != aijk.end(); ++itr) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); real a = itr->second; int ind[] = {i,j,k}; real E[8] = {0,0,0,0, 0,0,0,0}; E[7] = a; hocr.AddHigherTerm(3, ind, E); var_used[i] = true; var_used[j] = true; var_used[k] = true; } for (auto itr=aijkl.begin(); itr != aijkl.end(); ++itr) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); int l = get_l(itr->first); real a = itr->second; int ind[] = {i,j,k,l}; real E[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; E[15] = a; hocr.AddHigherTerm(4, ind, E); var_used[i] = true; var_used[j] = true; var_used[k] = true; var_used[l] = true; } index nOptimizedVars = hocr.maxID() + 1; PBF<real,2> qpbf; hocr.toQuadratic(qpbf); hocr.clear(); QPBO<real> qpbo(nVars, qpbf.size(), err_function_qpbo); convert(qpbo, qpbf); qpbo.MergeParallelEdges(); qpbo.Solve(); qpbo.ComputeWeakPersistencies(); nlabelled = 0; for (int i=0; i < nOptimizedVars; ++i) { if (var_used[i] || x.at(i)<0) { x[i] = qpbo.GetLabel(i); } if (x[i] >= 0) { nlabelled++; } } // These variables were not part of the minimization ASSERT(nVars >= nOptimizedVars); nlabelled += nVars - nOptimizedVars; real energy = constant + qpbo.ComputeTwiceLowerBound()/2; //double energy = eval(x); //Only when x is fully labelled return energy; }