/* * Locates a neighborhood for a rebalance. Uses the lower * threshold. * * Returned array format: [bottom, top_lim, count] * * NOTE: the array returned MUST be freed. */ int* find_lower_neighborhood(PMA* pma, int index){ int count; int width = 2; int prev_bot, prev_top; int bot = floor(index / width) * width; int top = bot + width; double progression = L_TRHLD / log2(pma->size); double local_thrhld = progression; count = count_in_range(pma, bot - 1, top); while (width < pma->size && (double)count / width < local_thrhld){ width *= 2; prev_bot = bot; prev_top = top; bot = floor(index / width) * width; top = bot + width; local_thrhld += progression; count += count_in_range(pma, bot - 1, prev_bot); count += count_in_range(pma, prev_top - 1, top); } return make_triple(bot, top, count); }
// Parameters initialization SensorModel::Params::Params() : m_tti_discretization(conf("tti_discretization", make_triple(0.0f, 10.0f, 0.1f))), m_tti_range(clamp(make_range(m_tti_discretization.first, m_tti_discretization.second), make_range(0.0f, 1000.0f))), m_tti_step(clamp(m_tti_discretization.third, 0.001f, m_tti_range.max())), m_belief_size(round(m_tti_range.size()/m_tti_step)) {}
// Scan through the image from the lower left corner across each row // and then up to the top right. Initially the image is sampled very // coarsely. Increment the static variables that track the progress // through the scans void GLCanvas::DrawPixel( int ray_x, int ray_y, std::vector<Triple<double, double, double> > & colors, std::vector<Triple<double, double, double> > & vertices ) { // compute the color and position of intersection Vec3f color= TraceRay(ray_x, ray_y); double r = linear_to_srgb(color.x()); double g = linear_to_srgb(color.y()); double b = linear_to_srgb(color.z()); colors.push_back(make_triple(r,g,b)); //glColor3f(r,g,b); double x = 2 * (ray_x/double(args->width)) - 1; double y = 2 * (ray_y/double(args->height)) - 1; vertices.push_back(make_triple(x,y,(double)(-1))); //glVertex3f(x,y,-1); }
/* * The back-end for find. Recursively locates a range * of values that includes the target, and returns the range. * If an exact match is found, its index is stored in the * 3rd location of the array returned (this is -1 otherwise). * * NOTE: The array returned MUST be freed. */ int* recursive_find(PMA* pma, int elem, int b_lim, int t_lim){ int index = -1; int cur; if (t_lim - b_lim <= 1){ return make_triple(b_lim, t_lim, -1); } cur = (b_lim + t_lim) / 2; cur = closest_in_range(pma, cur, b_lim, t_lim); if (pma->array[cur] == elem || cur == -1){ return make_triple(b_lim, t_lim, cur); }else if (pma->array[cur] > elem){ return recursive_find(pma, elem, b_lim, cur); } else{ return recursive_find(pma, elem, cur, t_lim); } }
void print_info_save (PrintInformation *pi) { GSList *l; gnm_conf_set_printsetup_scale_percentage (pi->scaling.type == PRINT_SCALE_PERCENTAGE); gnm_conf_set_printsetup_scale_percentage_value (pi->scaling.percentage.x); gnm_conf_set_printsetup_scale_width (pi->scaling.dim.cols); gnm_conf_set_printsetup_scale_height (pi->scaling.dim.rows); gnm_conf_set_printsetup_margin_top (pi->edge_to_below_header); gnm_conf_set_printsetup_margin_bottom (pi->edge_to_above_footer); gnm_conf_set_printsetup_preferred_unit (pi->desired_display.top); gnm_conf_set_printsetup_center_horizontally (pi->center_horizontally); gnm_conf_set_printsetup_center_vertically (pi->center_vertically); gnm_conf_set_printsetup_print_grid_lines (pi->print_grid_lines); gnm_conf_set_printsetup_print_titles (pi->print_titles); gnm_conf_set_printsetup_print_even_if_only_styles (pi->print_even_if_only_styles); gnm_conf_set_printsetup_print_black_n_white (pi->print_black_and_white); gnm_conf_set_printsetup_across_then_down (pi->print_across_then_down); gnm_conf_set_printsetup_repeat_top (pi->repeat_top); gnm_conf_set_printsetup_repeat_left (pi->repeat_left); save_formats (); l = make_triple (pi->header); gnm_conf_set_printsetup_header (l); g_slist_free (l); l = make_triple (pi->footer); gnm_conf_set_printsetup_footer (l); g_slist_free (l); gnm_conf_set_page_setup (pi->page_setup); }
// Parameter initialization RenderResultsParams::RenderResultsParams() : m_results_dir(conf<std::string>("results_dir", "")), m_results_file_name(conf<std::string>("results_file_name", "/(metlog-[[:digit:]]{8}-[[:digit:]]{6}|result)$")), m_ss_fmt(std::string(".") + ui_conf<std::string>("screen_capture_fmt", "png")), m_bump(conf("render_bump_points", true)), m_stop(conf("render_stop_points", true)), m_extr(conf("render_lrf_extrication_points", true)), m_lgmd(conf("render_lgmd_extrication_points", true)), m_bump_color(conf<int>("bump_points_color", make_triple(255, 0, 0))), m_stop_color(conf<int>("stop_points_color", make_triple(255, 165, 0))), m_extr_color(conf<int>("lrf_extrication_points_color", make_triple(0, 0, 255))), m_lgmd_color(conf<int>("lgmd_extrication_points_color", make_triple(105, 139, 105))), m_slideshow(conf("slideshow", false)), m_pause_on_dataset(conf("pause_on_dataset", false)), m_update_delay(clamp(conf("update_delay", 2500), 500, 60000)) { boost::trim(m_results_file_name) ; }
void test_RT() { typedef RT Cls; // _test_cls_regular_3( Cls() ); typedef traits::Bare_point Point; typedef traits::Weighted_point Weighted_point; typedef typename Cls::Vertex_handle Vertex_handle; typedef typename Cls::Cell_handle Cell_handle; typedef typename Cls::Facet Facet; typedef typename Cls::Edge Edge; typedef std::list<Weighted_point> list_point; typedef typename Cls::Finite_cells_iterator Finite_cells_iterator; // temporary version int n, m; int count = 0; // For dimension 0, we need to check that the point of highest weight is the // one that finally ends up in the vertex. std::cout << " test dimension 0 " << std::endl; Cls T0; T0.insert(Weighted_point( Point (0,0,0), 0) ); T0.insert(Weighted_point( Point (0,0,0), 1) ); T0.insert(Weighted_point( Point (0,0,0), -1) ); assert(T0.dimension() == 0); assert(T0.number_of_vertices() == 1); assert(T0.finite_vertices_begin()->point().weight() == 1); std::cout << " test dimension 1 " << std::endl; Cls T1; std::cout << " number of inserted points : " ; Weighted_point p[5]; for ( m=0; m<5; m++) { if ( (m%2)== 0 ) p[m] = Weighted_point( Point( 2*m,0,0 ), 2 ); else p[m] = Weighted_point( Point( -2*m+1,0,0 ), 2 ); T1.insert( p[m] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } assert( T1.is_valid() ); std::cout << std::endl << " number of vertices : " << T1.number_of_vertices() << std::endl; std::cout << " number of inserted points : " ; Weighted_point q[5]; for ( m=0; m<5; m++) { if ( (m%2)== 0 ) q[m] = Weighted_point( Point( 2*m+1,0,0 ), 5 ); else q[m] = Weighted_point( Point( -2*m+1,0,0 ), 5 ); T1.insert( q[m] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } assert( T1.is_valid() ); std::cout << std::endl << " number of vertices : " << T1.number_of_vertices() << std::endl; std::cout << " number of inserted points : " ; Weighted_point r[10]; for ( m=0; m<10; m++) { if ( (m%2)== 0 ) r[m] = Weighted_point( Point( m,0,0 ), 1 ); else r[m] = Weighted_point( Point( -m,0,0 ), 1 ); T1.insert( r[m] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } assert( T1.is_valid() ); std::cout << std::endl << " number of vertices : " << T1.number_of_vertices() << std::endl; assert( T1.dimension()==1 ); // The following is distilled from a bug report by Wulue Zhao // ([email protected]), a student of Tamal Dey. Point pt0(0,0,0); Point pt1( 1,0,0), pt2(2,0,0), pt3(3,0,0); Point pt4(-1,0,0), pt5(-2,0,0), pt6(-3,0,0); Weighted_point wp0(pt0,10.0); Weighted_point wp1(pt1,0.0), wp2(pt2,0.0), wp3(pt3,0.0); Weighted_point wp4(pt4,0.0), wp5(pt5,0.0), wp6(pt6,0.0); Cls T11; T11.insert(wp0); T11.insert(wp1); T11.insert(wp2); T11.insert(wp3); T11.insert(wp4); T11.insert(wp5); T11.insert(wp6); assert(T11.is_valid()); // And another distilled bug report from the same guy. { Point p1(-0.07, 0.04, 0.04); Point p2(0.09, 0.04, 0.04); Point p3(0.09, -0.05, 0.04); Point p4(0.05, -0.05, 0.04); Point p5(0.05, 0.0, 0.04); Point p6(-0.07, 0.0, 0.04); Point p7(-0.07, 0.04, -0.04); Point p8(0.09, 0.04, -0.04); Point p9(0.09, -0.05, -0.04); Point p10(0.05, -0.05, -0.04); Point p11(0.05, 0.0, -0.04); Point p12(-0.07, 0.0, -0.04); Weighted_point wp1(p1,0); Weighted_point wp2(p2,0); Weighted_point wp3(p3,0); Weighted_point wp4(p4,0); Weighted_point wp5(p5,0); Weighted_point wp6(p6,0); Weighted_point wp7(p7,0); Weighted_point wp8(p8,0); Weighted_point wp9(p9,0); Weighted_point wp10(p10,0); Weighted_point wp11(p11,0); Weighted_point wp12(p12,0); Weighted_point wp13(p3,0.3); // wp13 has the same coordinates with wp3 Cls T111; T111.insert(wp1); T111.insert(wp2); T111.insert(wp3); T111.insert(wp13); // it doesnot work inserting wp13 here T111.insert(wp4); T111.insert(wp5); T111.insert(wp6); T111.insert(wp7); T111.insert(wp8); T111.insert(wp9); T111.insert(wp10); T111.insert(wp11); T111.insert(wp12); assert(T111.is_valid()); } std::cout << " test dimension 2 " << std::endl; std::cout << " number of inserted points : " ; Cls T2; count = 0 ; int px=1, py=1; int qx=-1, qy=2; Weighted_point s[400]; for (m=0; m<10; m++) for (n=0; n<10; n++) { s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 1 ); T2.insert( s[m+20*n] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } for (m=10; m<20; m++) for (n=0; n<10; n++) { s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -1 ); T2.insert( s[m+20*n] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } for (m=0; m<10; m++) for (n=10; n<20; n++) { s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -2 ); T2.insert( s[m+20*n] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } for (m=10; m<20; m++) for (n=10; n<20; n++) { s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 5 ); T2.insert( s[m+20*n] ); count++; if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else std::cout << count << '\b' << '\b' << '\b' ; std::cout.flush(); } std::cout << std::endl << " number of vertices : " << T2.number_of_vertices() << std::endl; assert( T2.dimension()==2 ); assert( T2.is_valid() ); // dimension 3 std::cout << " test dimension 3" << std::endl; Cls T; list_point lp; int a, b, d; for (a=0;a!=10;a++) // for (b=0;b!=10;b++) for (b=0;b!=5;b++) // for (d=0;d!=10;d++) for (d=0;d!=5;d++) lp.push_back(Weighted_point( Point(a*b-d*a + (a-b)*10 +a , a-b+d +5*b, a*a-d*d+b), a*b-a*d) ); list_point::iterator it; count = 0 ; std::cout << " number of inserted points : " ; for (it=lp.begin(); it!=lp.end(); ++it){ count++; T.insert(*it); if (count <10) std::cout << count << '\b' ; else if (count < 100) std::cout << count << '\b' << '\b' ; else if (count < 1000) std::cout << count << '\b' << '\b' << '\b' ; else std::cout << count << std::endl; std::cout.flush(); } std::cout << std::endl; std::cout << " number of vertices : " << T.number_of_vertices() << std::endl; assert(T.is_valid()); assert(T.dimension()==3); T.clear(); std::cout << " test iterator range insert" << std::endl; T.insert (lp.begin(), lp.end()); std::cout << " number of vertices : " << T.number_of_vertices() << std::endl; assert(T.is_valid()); assert(T.dimension()==3); //test nearest_power_vertex std::cout << " test nearest_power_vertex " << std::endl; Point pp1(0.0, 0.0, 0.0); Point pp2(1.0, 0.0, 0.0); Point pp3(0.0, 1.0, 0.0); Point pp4(0.0, 0.0, 1.0); Point pp5(1.0, 1.0, 0.0); Point pp6(0.0, 1.0, 1.0); Point pp7(1.0, 0.0, 1.0); Point pp8(1.0, 1.0, 1.0); Weighted_point wpp1(pp1, 1.0); Weighted_point wpp2(pp2, 2.0); Weighted_point wpp3(pp3, 1.0); Weighted_point wpp4(pp4, 4.0); Weighted_point wpp5(pp5, 1.0); Weighted_point wpp6(pp6, 1.0); Weighted_point wpp7(pp7, 1.0); Weighted_point wpp8(pp8, 8.0); Cls T3; T3.insert(wpp1); Vertex_handle v2 = T3.insert(wpp2); assert( T3.nearest_power_vertex(Point(0.5,0.5,0.5)) == v2); T3.insert(wpp3); Vertex_handle v4 = T3.insert(wpp4); assert( T3.nearest_power_vertex(Point(0.5,0.5,0.5)) == v4); T3.insert(wpp5); T3.insert(wpp6); T3.insert(wpp7); // Avoid inserting the same point twice, now that hidden points are handled, // insert (existing_point) returns Vertex_handle(). // T3.insert(wpp8); Vertex_handle v8 = T3.insert(wpp8); Point query(0.5,0.5,0.5); assert(T3.nearest_power_vertex(query) == v8); assert(T3.nearest_power_vertex(Weighted_point(query,1.0)) == v8 ); assert(T3.nearest_power_vertex_in_cell(query ,v8->cell()) == v8); // test dual std::cout << " test dual member functions" << std::endl; Finite_cells_iterator fcit = T3.finite_cells_begin(); for( ; fcit != T3.finite_cells_end(); ++fcit) { Point cc = T3.dual(fcit); Vertex_handle ncc = T3.nearest_power_vertex(cc); assert(fcit->has_vertex(ncc)); } // test Gabriel std::cout << " test is_Gabriel " << std::endl; Point q0(0.,0.,0.); Point q1(2.,0.,0.); Point q2(0.,2.,0.); Point q3(0.,0.,2.); Weighted_point wq0(q0,0.); Weighted_point wq1(q1,0.); Weighted_point wq2(q2,0.); Weighted_point wq3(q3,0.); Weighted_point wq01(q0,2.); Cls T4; Vertex_handle v0 = T4.insert(wq0); Vertex_handle v1 = T4.insert(wq1); v2 = T4.insert(wq2); Vertex_handle v3 = T4.insert(wq3); Cell_handle c; int i,j,k,l; assert(T4.is_facet(v0,v1,v2,c,j,k,l)); i = 6 - (j+k+l); Facet f = std::make_pair(c,i); assert(T4.is_Gabriel(c,i)); assert(T4.is_Gabriel(f)); assert(T4.is_facet(v1,v2,v3,c,j,k,l)); i = 6 - (j+k+l); assert(!T4.is_Gabriel(c,i)); assert(T4.is_edge(v0,v1,c,i,j)); assert(T4.is_Gabriel(c,i,j)); Edge e = make_triple(c,i,j); assert(T4.is_Gabriel(e)); assert(T4.is_edge(v2,v3,c,i,j)); assert(T4.is_Gabriel(c,i,j)); Vertex_handle v01 = T4.insert(wq01); (void) v01; // kill warning assert(T4.is_edge(v2,v3,c,i,j)); assert(!T4.is_Gabriel(c,i,j)); Weighted_point wwq0(q0,0.); Weighted_point wwq1(q1,0.); Weighted_point wwq2(q2,0.); Weighted_point wwq3(q3,5.); Cls T5; v0 = T5.insert(wwq0); v1 = T5.insert(wwq1); v2 = T5.insert(wwq2); v3 = T5.insert(wwq3); assert(T5.nearest_power_vertex(v3->point().point()) == v3); assert(T5.nearest_power_vertex(v0->point().point()) == v3); assert(T5.is_Gabriel(v3)); assert(!T5.is_Gabriel(v0)); }
bool Disassembler::ParseSymbolTable(const list<Token *>::iterator &startiter, const list<Token *>::iterator &EndIter, SymbolList &Symbols, unsigned char Addressability, CallBackFunction) { list<Token *>::iterator TokenIter, StartIter; TokenIter = StartIter = startiter; //process one symbol at a time while(StartIter != EndIter) { //Get the symbol name if(StartIter == EndIter || (*StartIter)->TokenType != TIdentifier) { CallBack(Error, "Missing symbol name: first cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } string sSymbol = ((IDToken *)(*StartIter))->sIdentifier; TokenIter = StartIter++; //Check for possible "." which could be for a struct member. if(StartIter != EndIter && (*StartIter)->TokenType == TOperator && ((OpToken *)(*StartIter))->Operator == OpPeriod) { TokenIter = StartIter++; //Get past the member label if(StartIter != EndIter && (*StartIter)->TokenType == TIdentifier) { TokenIter = StartIter++; } else { CallBack(Error, "Missing member symbol name after struct symbol name and period: first cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } } //Get the comma if(StartIter == EndIter || (*StartIter)->TokenType != TOperator || ((OpToken *)(*StartIter))->Operator != OpComma) { CallBack(Error, "Missing comma after symbol name: first cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; //Get the symbol type SymbolEnum SymbolType = SymVoid; if(StartIter == EndIter || (*StartIter)->TokenType != (TokenEnum)TDirective || ((DirToken *)(*StartIter))->Directive != DirMacro) { if(StartIter == EndIter || (*StartIter)->TokenType != (TokenEnum)TDirective || ((DirToken *)(*StartIter))->Directive != DirExtern) { if(StartIter == EndIter || (*StartIter)->TokenType != (TokenEnum)TDirective || ((DirToken *)(*StartIter))->Directive != DirDefine) { if(StartIter == EndIter || (*StartIter)->TokenType != (TokenEnum)TData || ((DataToken *)(*StartIter))->DataType != STRUCT) { if(StartIter == EndIter || (*StartIter)->TokenType != TIdentifier || ((IDToken *)(*StartIter))->sIdentifier != "member") { if(StartIter == EndIter || (*StartIter)->TokenType != TIdentifier || ((IDToken *)(*StartIter))->sIdentifier != "label") { CallBack(Error, "Missing symbol type after symbol name: second cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } else SymbolType = SymLabel; } else SymbolType = SymMember; } else SymbolType = SymStruct; } else SymbolType = SymDefine; } else SymbolType = SymExtern; } else SymbolType = SymMacro; TokenIter = StartIter++; uint64 Address; switch(SymbolType) { case SymMacro: case SymDefine: case SymStruct: //There's nothing else for this entry. break; case SymMember: //Get the comma if(StartIter == EndIter || (*StartIter)->TokenType != TOperator || ((OpToken *)(*StartIter))->Operator != OpComma) { CallBack(Error, "Missing comma after symbol type: second cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; //Get the number if(StartIter == EndIter || (*StartIter)->TokenType != TInteger) { CallBack(Error, "Missing struct member symbol offset value: third cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; break; case SymExtern: case SymLabel: //Get the comma if(StartIter == EndIter || (*StartIter)->TokenType != TOperator || ((OpToken *)(*StartIter))->Operator != OpComma) { CallBack(Error, "Missing comma after symbol type: second cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; //Get the number if(StartIter == EndIter || (*StartIter)->TokenType != TInteger) { CallBack(Error, "Missing symbol address: third cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } Address = ((IntegerToken *)(*StartIter))->Integer; TokenIter = StartIter++; //Get the comma if(StartIter == EndIter || (*StartIter)->TokenType != TOperator || ((OpToken *)(*StartIter))->Operator != OpComma) { CallBack(Error, "Missing comma after symbol address: third cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; //Get the number if(StartIter == EndIter || (*StartIter)->TokenType != TInteger) { CallBack(Error, "Missing symbol segment-relative adddress: fourth cell in symbol table entry.", (*TokenIter)->LocationStack); return false; } TokenIter = StartIter++; if(SymbolType == SymLabel) Symbols.push_back( make_triple((*TokenIter)->LocationStack, Address << Addressability, sSymbol) ); break; } //depending on if they saved after viewing in excel, there could be a number of commas at the end. while(StartIter != EndIter && (*StartIter)->TokenType == TOperator && ((OpToken *)(*StartIter))->Operator == OpComma) TokenIter = StartIter++; } return true; }
real PseudoBoolean<real>::minimize_reduction_fixetal(vector<label>& x, int& nlabelled) const { int n = index( x.size() ); // Work with a copy of the coefficients map<triple, real> aijk = this->aijk; //map<pair, real> aij = this->aij; //map<int, real> ai = this->ai; //real constant = this->constant; // The quadratic function we are reducing to int nedges = int( aij.size() + aijk.size() + aijkl.size() + 1000 ); int nvars = int( n + aijkl.size() + aijk.size() + 1000 ); QPBO<real> qpbo(nvars, nedges, err_function_qpbo); qpbo.AddNode(n); map<int,bool> var_used; // // Step 1: reduce all positive higher-degree terms // // Go through the variables one by one and perform the // reductions of the quartic terms //for (int ind=0; ind<n; ++ind) { // // Collect all terms with positive coefficients // // containing variable i // real alpha_sum = 0; // // Holds new var // int y = -1; // 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; // // We only have to test for ind==i because of the // // order we process the indices // if (ind==i && a > 0) { // alpha_sum += a; // // Add term of degree 3 // aijk[ make_triple(j,k,l) ] += a; // // Add negative term of degree 4 // // -a*y*xj*xk*xl // if (y<0) y = qpbo.AddNode(); // int z = qpbo.AddNode(); // qpbo.AddUnaryTerm(z, 0, 3*a); // qpbo.AddPairwiseTerm(z,y, 0,0,0, -a); // qpbo.AddPairwiseTerm(z,j, 0,0,0, -a); // qpbo.AddPairwiseTerm(z,k, 0,0,0, -a); // qpbo.AddPairwiseTerm(z,l, 0,0,0, -a); // } // } // 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; // // We only have to test for ind==i because of the // // order we process the indices // if (ind==i && a > 0) { // alpha_sum += a; // // Add term of degree 2 // qpbo.AddPairwiseTerm(j,k, 0,0,0, a); // // Add negative term of degree 3 // // -a*y*xj*xk // if (y<0) y = qpbo.AddNode(); // int z = qpbo.AddNode(); // qpbo.AddUnaryTerm(z, 0, 2*a); // qpbo.AddPairwiseTerm(z,y, 0,0,0, -a); // qpbo.AddPairwiseTerm(z,j, 0,0,0, -a); // qpbo.AddPairwiseTerm(z,k, 0,0,0, -a); // } // } // if (alpha_sum > 0) { // // Add the new quadratic term // qpbo.AddPairwiseTerm(y,ind, 0,0,0, alpha_sum); // } //} // // This code should be equivalent to the commented // block above, but faster // vector<real> alpha_sum(n, 0); vector<int> y(n, -1); 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; if (a > 0) { alpha_sum[i] += a; // Add term of degree 3 aijk[ make_triple(j,k,l) ] += a; // Add negative term of degree 4 // -a*y*xj*xk*xl if (y[i]<0) y[i] = qpbo.AddNode(); int z = qpbo.AddNode(); qpbo.AddUnaryTerm(z, 0, 3*a); qpbo.AddPairwiseTerm(z,y[i], 0,0,0, -a); qpbo.AddPairwiseTerm(z,j, 0,0,0, -a); qpbo.AddPairwiseTerm(z,k, 0,0,0, -a); qpbo.AddPairwiseTerm(z,l, 0,0,0, -a); } var_used[i] = true; var_used[j] = true; var_used[k] = true; var_used[l] = 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; if (a > 0) { alpha_sum[i] += a; // Add term of degree 2 qpbo.AddPairwiseTerm(j,k, 0,0,0, a); //aij[ make_pair(j,k) ] += a; // Add negative term of degree 3 // -a*y*xj*xk if (y[i]<0) y[i] = qpbo.AddNode(); /*int z = qpbo.AddNode(); qpbo.AddUnaryTerm(z, 0, 2*a); qpbo.AddPairwiseTerm(z,y[i], 0,0,0, -a); qpbo.AddPairwiseTerm(z,j, 0,0,0, -a); qpbo.AddPairwiseTerm(z,k, 0,0,0, -a);*/ aijk[ make_triple(y[i],j,k) ] += -a; } var_used[i] = true; var_used[j] = true; var_used[k] = true; } // No need to continue with the lower degree terms //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; // if (a > 0) { // alpha_sum[i] += a; // // Add term of degree 1 // ai[ j ] += a; // // Add negative term of degree 2 // // -a*y*xj // if (y[i]<0) y[i] = qpbo.AddNode(); // aij[ make_pair(y[i],j) ] += -a; // // Now remove this term // a = 0; // } //} //for (auto itr=ai.begin(); itr != ai.end(); ++itr) { // int i =itr->first; // real& a = itr->second; // if (a > 0) { // alpha_sum[i] += a; // // Add term of degree 0 // constant += a; // // Add negative term of degree 1 // // -a*y*xj // if (y[i]<0) y[i] = qpbo.AddNode(); // ai[ y[i] ] += -a; // // Now remove this term // a = 0; // } //} for (int i=0;i<n;++i) { if (alpha_sum[i] > 0) { // Add the new quadratic term qpbo.AddPairwiseTerm(y[i],i, 0,0,0, alpha_sum[i]); } } // // Done with reducing all positive higher-degree terms // // Add all negative quartic terms for (auto itr=aijkl.begin(); itr != aijkl.end(); ++itr) { real a = itr->second; if (a < 0) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); int l = get_l(itr->first); int z = qpbo.AddNode(); qpbo.AddUnaryTerm(z, 0, -3*a); qpbo.AddPairwiseTerm(z,i, 0,0,0, a); qpbo.AddPairwiseTerm(z,j, 0,0,0, a); qpbo.AddPairwiseTerm(z,k, 0,0,0, a); qpbo.AddPairwiseTerm(z,l, 0,0,0, a); } } // Add all negative cubic terms for (auto itr=aijk.begin(); itr != aijk.end(); ++itr) { real a = itr->second; if (a < 0) { int i = get_i(itr->first); int j = get_j(itr->first); int k = get_k(itr->first); int z = qpbo.AddNode(); qpbo.AddUnaryTerm(z, 0, -2*a); qpbo.AddPairwiseTerm(z,i, 0,0,0, a); qpbo.AddPairwiseTerm(z,j, 0,0,0, a); qpbo.AddPairwiseTerm(z,k, 0,0,0, a); } } // Add all quadratic terms for (auto itr=aij.begin(); itr != aij.end(); ++itr) { real a = itr->second; int i = get_i(itr->first); int j = get_j(itr->first); qpbo.AddPairwiseTerm(i,j, 0,0,0, a); var_used[i] = true; var_used[j] = true; } // Add all linear terms for (auto itr=ai.begin(); itr != ai.end(); ++itr) { real a = itr->second; int i = itr->first; qpbo.AddUnaryTerm(i, 0, a); var_used[i] = true; } qpbo.MergeParallelEdges(); qpbo.Solve(); qpbo.ComputeWeakPersistencies(); nlabelled = 0; for (int i=0; i<n; ++i) { if (var_used[i] || x.at(i)<0) { x[i] = qpbo.GetLabel(i); } if (x[i] >= 0) { nlabelled++; } } real energy = constant + qpbo.ComputeTwiceLowerBound()/2; return energy; }