static long coordinates_intersect(long src, long dst, long i) { long res,res2; if(get_j(src)==i) { //test both get_upj(src) and get_uj(src) if(get_j(dst)==i) { //test both get_upj(dst) and get_uj(dst) if((res=get_upj(src))==get_upj(dst) && (res2=get_uj(src))==get_uj(dst)) //The problem with determinism here is that we need to make a //choice dependent on the coordinate we want to change, which //is not this one. #ifdef DETERMINISTIC //WARNING. IF THE RETURN VALUE IS TO BE USED, YOU MUST CHOOSE //RES OR RES2 WHERE THIS FUNCTION IS CALLED, BECAUSE PARAM_N //IS AN INVALID COORDINATE VALUE. return param_n; #else return (rand()%2)?res:res2; #endif #ifdef DEBUG //this next case does not occur, given the canonical labeling //where get_uj(src) < get_upj(src) and get_uj(dst) < //get_upj(dst). We throw an exception if it does if((res=get_upj(src))==get_uj(dst) && (res2=get_uj(src))==get_upj(dst)) { printf("unexpected behaviour in coordinates_intersect\n"); exit(-1); } #endif if((res=get_upj(src))==get_upj(dst)) return res; if((res=get_upj(src))==get_uj(dst)) return res; if((res=get_uj(src))==get_uj(dst)) return res; if((res=get_uj(src))==get_upj(dst)) return res; else return -1; } else if(((res=label[dst][i])==get_upj(src)) || (label[dst][i]==get_uj(src))) return res; else return -1; } else if(get_j(dst)==i) { if(((res=label[src][i])==get_upj(dst)) || (label[src][i]==get_uj(dst))) return res; else return -1; } if((res=label[src][i]) == label[dst][i]) return res; else return -1; }
void Puissance4::hasP4_sens(int i, int j, int *sens, bool *stop){ if((not stop[0]) && i > -1 && j > -1 && i<getNbLignes() && j<getNbColonnes()){ if(not HAS_PION(i, j)|| GET_CASE(i, j)->getPion()->getJoueur() != get_j()){ *stop = true; } else { (*sens)++; } } }
REAL d_dem::getMeanValue(REAL x_from, REAL x_to, REAL y_from, REAL y_to) const { size_t i_from, i_to; size_t j_from, j_to; i_from = get_i(x_from); i_from = MAX(0, i_from); i_to = get_i(x_to); i_to = MIN(i_to, getCountX()-1); j_from = get_j(y_from); j_from = MAX(0, j_from); j_to = get_j(y_to); j_to = MIN(j_to, getCountY()-1); size_t NN = getCountX(); size_t i,j; size_t cnt = 0; REAL sum_value = 0; REAL value; for (j = j_from; j <= j_to; j++) { for (i = i_from; i <= i_to; i++) { size_t pos = i + j*NN; value = (*coeff)(pos); if (value == this->undef_value) continue; sum_value += value; cnt++; }; }; if (cnt == 0) return this->undef_value; REAL res = sum_value/REAL(cnt); return res; };
int main() { extern int i; /* extern optional for funtions: */ int get_j(void); printf("i == %d\n", ++i); printf("j == %d\n", get_j()); return 0; }
/*-----------------------------------------------------------------------------* | Bit2_map_col_major | Purpose: maps the given function onto every element of the given Bit2 | in col major order | Arguments: a pointer to the 2D bit array, a pointer to a void apply | function, the closure as a void * | Returns: - | Fail cases: | - the pointer to the 2D bit array is null | - the pointer to the apply function is null *-----------------------------------------------------------------------------*/ void Bit2_map_col_major(Bit2_T bit2, void apply(int i, int j, Bit2_T bit2, int value, void *cl), void *cl) { assert(bit2 != NULL); assert(apply != NULL); int index; int i; int j; for (index = 0; index < Bit_length(bit2->bitmap); index++) { i = get_i(index, Bit2_height(bit2)); j = get_j(index, Bit2_height(bit2)); apply(i, j, bit2, Bit2_get(bit2, i, j), cl); } }
/*-----------------------------------------------------------------------------* | UArray2_map_col_major | Purpose: maps the given function onto every element of the given | UArray2 in col major order | Arguments: a pointer to the 2D array, a pointer to a void apply | function, the closure as a void * | Returns: - | Fail cases: | - the pointer to the 2D array is null | - the pointer to the apply function is null *-----------------------------------------------------------------------------*/ void UArray2_map_col_major(UArray2_T uarray2, void apply(int i, int j, UArray2_T uarray2, void *value, void *cl), void *cl) { assert(uarray2 != NULL); assert(apply != NULL); int index; int i; int j; for (index = 0; index < UArray_length(uarray2->uarray); index ++) { i = get_i(index, UArray2_height(uarray2)); j = get_j(index, UArray2_height(uarray2)); apply(i, j, uarray2, UArray2_at(uarray2, i, j), cl); }; }
static long get_uj(long server) { return label[server][get_j(server)]; }
static long route_full(long src, long dst) { long next_node,tmp,tmp2,this_node,exit_switch,i; //for each dimension i, if the coordinates differ, then ammend them. //if i is not next_nodej and next_node and dst do not differ at //next_nodej then we need to leave next_node via the intersection of //next_node and dst at these coordinates; otherwise, we choose //arbitrarily, but (try to do it) in a way that balances the usage //of the links in the network. Finally, settle into dstj coordinate //if necessary. next_node=src; for(i=0; i<param_k; i++) { if(coordinates_intersect(src,dst,i)==-1) { if(get_j(next_node)!=i) { //we are changing on dimension i, but if next_node and dst do //not differ at dimension get_j(next_node) (different from i), //then we may need to exit get_j(next_node) via a specific //switch. otherwise pick one arbitrarily. if((exit_switch= coordinates_intersect(next_node,dst,get_j(next_node)))==-1 || exit_switch==param_n) { //THIS DEALS WITH THE param_n return value //coordinates_intersect #ifdef DEBUG if(src!=next_node) { printf("Expected next_node=src in this case\n"); exit(-1); } #endif #ifdef DETERMINISTIC exit_switch=make_det(src,dst)?get_uj(next_node):get_upj(next_node); #else exit_switch=(rand()%2)?get_uj(next_node):get_upj(next_node); #endif } //having chosen an exit switch, we append this switch to the path if((next_node = append_to_path( next_node, (exit_switch==get_uj(next_node))?0:1 ) ) == -1 ) { empty_path(&path,&path_tail); return -1; } //next_node is now a switch and we need to get to the server //on dimension i. } else { //we are changing on dimension get_j(next_node), so the //exit switch is arbitrary, since these dimensions differ. #ifdef DEBUG if(src!=next_node) { printf("Expected next_node=src in this case\n"); exit(-1); } #endif #ifdef DETERMINISTIC if((next_node = append_to_path(next_node, (( make_det(src,dst) )?0:1)))==-1) #else if((next_node = append_to_path(next_node,rand()%2))==-1) #endif { empty_path(&path,&path_tail); return -1; } } //next_node is a switch here if((next_node = append_to_path( next_node, get_port_to_server( next_node, i, (get_j(dst)==i)? #ifdef DETERMINISTIC (make_det(src,dst)? get_uj(dst) : get_upj(dst)) #else ((rand()%2)? get_uj(dst) : get_upj(dst)) #endif : label[dst][i] ) ))==-1) { empty_path(&path,&path_tail); return -1; } } #ifdef DEBUG if(coordinates_intersect(next_node,dst,i)==-1) { empty_path(&path,&path_tail); return -1; } #endif } // Settling step. if(next_node==dst) return 1; //next_node and dst at same switch this_node=next_node; if(((next_node = network[this_node].port[tmp=0].neighbour.node) == network[dst].port[tmp2=1].neighbour.node ) || (network[this_node].port[0].neighbour.node == network[dst].port[tmp2=0].neighbour.node ) || ((next_node = network[this_node].port[tmp=1].neighbour.node) == network[dst].port[tmp2=1].neighbour.node ) || (network[this_node].port[1].neighbour.node) == network[dst].port[tmp2=0].neighbour.node ) { if( ((next_node=append_to_path(this_node,tmp))==-1) || ((next_node= append_to_path(next_node, network[dst].port[tmp2].neighbour.port))==-1) ) { empty_path(&path,&path_tail); return -1; } return 1; } else return 1; }
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; }
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; }