1 /* 2 * bsptree.cpp 3 * 4 * Created on: Feb 5, 2011 5 * Author: anders 6 */ 7 8 #include "linalg.h" 9 #include "bsptree.h" 10 #include "lp.h" 11 #include "matrix.h" 12 #include "log.h" 13 buildHyperplanes()14 void BSPTree::buildHyperplanes() 15 { 16 set<IntegerVector> temp; 17 IntegerVector v; 18 for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();i++) 19 { 20 i->assignEquation(v); 21 temp.insert(v); 22 } 23 hyperplanes=vector<IntegerVector>(temp.size()); 24 int I=0; 25 for(set<IntegerVector>::const_iterator i=temp.begin();i!=temp.end();i++,I++) 26 hyperplanes[I]=*i; 27 } 28 29 /* Figure out what the right assumptions are. These seem not to be right: 30 * A is assumed to be full-dimensional. 31 * B is assumed to be of codimension 1 with known facets and implied equations. 32 */ isIntersectionOfCodimensionOne(PolyhedralCone const & A,BSPTree::SmallCone const & B)33 static bool isIntersectionOfCodimensionOne(PolyhedralCone const &A, BSPTree::SmallCone const &B) 34 { 35 36 IntegerVectorList strictInequalities=A.getHalfSpaces(); 37 IntegerVectorList strictInequalities2=B.getHalfSpaces(); 38 for(IntegerVectorList::const_iterator i=strictInequalities2.begin();i!=strictInequalities2.end();i++)strictInequalities.push_back(*i); 39 if(B.getEquations().size()!=1) 40 { 41 assert(0); //debug<<B; 42 } 43 assert(B.getEquations().size()==1); 44 strictInequalities.push_front(B.getEquations().front()); 45 IntegerVector ei(strictInequalities.size());ei[0]=1; 46 // bool originalReturnValue=hasInteriorPoint(strictInequalities, false, &ei); 47 48 49 ////////////////// 50 IntegerVectorList inequalities; 51 IntegerVectorList::const_iterator i=strictInequalities.begin();i++; 52 for(;i!=strictInequalities.end();i++) 53 inequalities.push_back(concatenation(-IntegerVector::standardVector(1,0),*i)); 54 IntegerVectorList equations; 55 equations.push_back(concatenation(IntegerVector(1),strictInequalities.front())); 56 bool fastReturnValue=hasHomogeneousSolution(A.ambientDimension()+1,inequalities,equations); 57 58 // assert(originalReturnValue==fastReturnValue); 59 ///////////////// 60 return fastReturnValue; 61 62 // return originalReturnValue; 63 } isInClosedHalfSpace(BSPTree::SmallCone const & A,IntegerVector const & normal)64 static bool isInClosedHalfSpace(BSPTree::SmallCone const &A, IntegerVector const &normal) 65 { 66 //WE ALSO NEED TO CHECK LINEALITYSPACE! 67 IntegerVectorList temp2=A.generatorsOfLinealitySpace(); 68 for(IntegerVectorList::const_iterator i=temp2.begin();i!=temp2.end();i++) 69 if(dotLong(normal,*i)!=0)return false; 70 71 72 73 IntegerVectorList temp=A.extremeRays(); 74 for(IntegerVectorList::const_iterator i=temp.begin();i!=temp.end();i++) 75 if(dotLong(normal,*i)<0)return false; 76 return true; 77 } 78 79 80 class ProgressPrinter 81 { 82 public: 83 static int depth; 84 static char s[16]; 85 static int timeToPrint; 86 public: ProgressPrinter()87 ProgressPrinter() 88 { 89 if(depth>0 && depth<17)s[depth-1]++; 90 depth++; 91 if(depth<17)s[depth-1]=0; 92 93 timeToPrint++; 94 if(depth<16) 95 // if(!(timeToPrint&1)) 96 { 97 log1 debug<<"Progress:"; 98 log1 for(int i=0;(i<depth-1)&&(i<16);i++) 99 debug<<((s[i]-1)?"1":"0"); 100 log1 debug<<"\n"; 101 } 102 } ~ProgressPrinter()103 ~ProgressPrinter() 104 { 105 depth--; 106 } 107 }; 108 int ProgressPrinter::depth; 109 char ProgressPrinter::s[16]; 110 int ProgressPrinter::timeToPrint; 111 heuristic1(PolyhedralCone const & region,vector<int> const & active)112 IntegerVector BSPTree::heuristic1(PolyhedralCone const ®ion, vector<int> const &active) 113 { 114 int index=active[rand()%active.size()]; 115 assert(theCones[index].getEquations().size()==1); 116 IntegerVector normal=theCones[index].getEquations().front(); 117 118 { 119 map<IntegerVector,int> M; 120 for(vector<int>::const_iterator i=active.begin();i!=active.end();i++) 121 { 122 M[theCones[*i].getEquations().front()]++; 123 } 124 int highScore=0; 125 IntegerVector const *p=0; 126 for(map<IntegerVector,int>::const_iterator i=M.begin();i!=M.end();i++) 127 { 128 if(highScore<i->second) 129 { 130 highScore=i->second; 131 p=&(i->first); 132 } 133 } 134 normal=*p; 135 } 136 return normal; 137 } 138 heuristic2(PolyhedralCone const & region,vector<int> const & active)139 IntegerVector BSPTree::heuristic2(PolyhedralCone const ®ion, vector<int> const &active) 140 { 141 if(active.size()<1000)return heuristic1(region,active); 142 143 int bestScore=1000; 144 IntegerVector bestNormal=theCones[active[0]].getEquations().front(); 145 146 for(int i=0;i<100;i++) 147 { 148 int index=active[rand()%active.size()]; 149 int inPlane=0; 150 int right=0; 151 int left=0; 152 153 IntegerVector normal=theCones[index].getEquations().front(); 154 155 IntegerVectorList temp;temp.push_back(normal); 156 IntegerVectorList empty; 157 PolyhedralCone rightRegion=intersection(region,PolyhedralCone(temp,empty)); 158 PolyhedralCone leftRegion=intersection(region,PolyhedralCone(temp,empty).negated()); 159 PolyhedralCone hyperPlane=intersection(region,PolyhedralCone(empty,temp)); 160 161 162 for(int j=0;j<100;j++) 163 { 164 // int r= 165 int rindex=active[rand()%active.size()]; 166 if(dependent(normal,theCones[rindex].getEquations().front()))inPlane++; 167 else 168 { 169 if(isIntersectionOfCodimensionOne(leftRegion,theCones[rindex]))left++; 170 if(isIntersectionOfCodimensionOne(rightRegion,theCones[rindex]))right++; 171 } 172 } 173 int score=left+right; 174 175 debug<<inPlane<<" "<<left<<" "<<right<<" "<<left+right<<"\n"; 176 177 if(score<bestScore) 178 { 179 bestScore=score; 180 bestNormal=normal; 181 } 182 } 183 return bestNormal; 184 // return heuristic1(region,active); 185 } 186 187 buildTree(PolyhedralCone const & region,vector<int> const & active)188 BSPTree::Node *BSPTree::buildTree(PolyhedralCone const ®ion, vector<int> const &active) 189 { 190 ProgressPrinter PP; 191 // depth++; 192 // debug<<"Size:"<<(int)active.size()<<"\n"; 193 if(active.size()==0)return 0; 194 195 IntegerVector normal=heuristic1(region,active); 196 197 vector<int> conesInHyperplane; 198 vector<int> conesLeft; 199 vector<int> conesRight; 200 IntegerVectorList temp;temp.push_back(normal); 201 IntegerVectorList empty; 202 PolyhedralCone rightRegion=intersection(region,PolyhedralCone(temp,empty)); 203 PolyhedralCone leftRegion=intersection(region,PolyhedralCone(temp,empty).negated()); 204 PolyhedralCone hyperPlane=intersection(region,PolyhedralCone(empty,temp)); 205 int counter=0; 206 for(vector<int>::const_iterator i=active.begin();i!=active.end();i++) 207 { 208 counter++; 209 log1 if(!(counter&(4096*4-1)))debug<<counter<<"\n"; 210 /* 211 * Cases: 212 * The intersection of the cone with the relative interior of the left region is of codimension 1 213 * The intersection of the cone with the relative interior of the right region is of codimension 1 214 * None of these are the case, then the cone is contained in the chosen hyperplane, and should be added to the node. 215 */ 216 217 // PolyhedralCone iHyperplane=intersection(theCones[*i],hyperPlane); 218 // iHyperplane.findImpliedEquations(); 219 // if(iHyperplane.dimension()==n-1) 220 if(dependent(normal,theCones[*i].getEquations().front())) 221 conesInHyperplane.push_back(*i); 222 else 223 { 224 bool A=isInClosedHalfSpace(theCones[*i],-normal); 225 bool B=isInClosedHalfSpace(theCones[*i],normal); 226 // if(isInClosedHalfSpace(theCones[*i],-normal)||!isInClosedHalfSpace(theCones[*i],normal)) 227 if(A||!B) 228 if(isIntersectionOfCodimensionOne(leftRegion,theCones[*i])) 229 conesLeft.push_back(*i); 230 // if(isInClosedHalfSpace(theCones[*i],normal)||!isInClosedHalfSpace(theCones[*i],-normal)) 231 if(B||!A) 232 if(isIntersectionOfCodimensionOne(rightRegion,theCones[*i])) 233 conesRight.push_back(*i); 234 } 235 } 236 if(PP.depth<10+15)debug<<PP.depth<<":"<<(int)conesInHyperplane.size()<<" "<<(int)conesLeft.size()<<" "<<(int)conesRight.size()<<"\n"; 237 return new Node( 238 buildTree(leftRegion,conesLeft), 239 buildTree(rightRegion,conesRight), 240 normal,conesInHyperplane); 241 } BSPTree(int n_,vector<BSPTree::SmallCone> const & theCones_,PolyhedralCone const * restrictingCone,bool doBuild)242 BSPTree::BSPTree(int n_, vector<BSPTree::SmallCone> const &theCones_, PolyhedralCone const *restrictingCone, bool doBuild): 243 theCones(theCones_), 244 n(n_), 245 hasBeenBuilt(false) 246 { 247 buildHyperplanes(); 248 vector<int> active(theCones.size()); 249 for(int i=0;i<active.size();i++)active[i]=i; 250 if(doBuild) 251 { 252 if(restrictingCone) 253 root=buildTree(*restrictingCone,active); 254 else 255 root=buildTree(PolyhedralCone(n),active); 256 hasBeenBuilt=true; 257 } 258 else 259 root=0; 260 } isOnRightHandSide(IntegerVectorList const & omega,IntegerVector const & normal)261 bool BSPTree::isOnRightHandSide(IntegerVectorList const &omega, IntegerVector const &normal) 262 { 263 for(IntegerVectorList::const_iterator i=omega.begin();i!=omega.end();i++) 264 { 265 if(dotLong(*i,normal)>0)return true; 266 if(dotLong(*i,normal)<0)return false; 267 } 268 for(int i=0;i<normal.size();i++) 269 { 270 if(normal[i]>0)return true; 271 if(normal[i]<0)return false; 272 } 273 assert(0); 274 return true; 275 } glue(PolyhedralCone A,PolyhedralCone B,IntegerVector const & normal)276 PolyhedralCone BSPTree::glue(PolyhedralCone A, PolyhedralCone B, IntegerVector const &normal) 277 { 278 A.findFacets(); 279 B.findFacets(); 280 IntegerVectorList inequalitiesA=A.getHalfSpaces(); 281 IntegerVectorList inequalitiesB=B.getHalfSpaces(); 282 set<IntegerVector> inequalities; 283 for(IntegerVectorList::const_iterator i=inequalitiesA.begin();i!=inequalitiesA.end();i++) 284 if(!dependent(*i,normal))inequalities.insert(normalized(*i)); 285 for(IntegerVectorList::const_iterator i=inequalitiesB.begin();i!=inequalitiesB.end();i++) 286 if(!dependent(*i,normal))inequalities.insert(normalized(*i)); 287 IntegerVectorList empty; 288 IntegerVectorList inequalities2;for(set<IntegerVector>::const_iterator i=inequalities.begin();i!=inequalities.end();i++)inequalities2.push_back(*i); 289 PolyhedralCone ret(inequalities2,empty,normal.size(),PCP_facetsKnown|PCP_impliedEquationsKnown); 290 return ret; 291 // ret.canonicalize(); 292 293 #if 0 294 //Assumes that A and B are full dimensional. 295 A.canonicalize(); 296 B.canonicalize(); 297 /* debug<<"Gluing:\n"; 298 debug<<normal<<"\n"; 299 debug<<A; 300 debug<<B; 301 */ 302 /* { 303 PolyhedralCone in=intersection(A,B); 304 IntegerVector v=in.getRelativeInteriorPoint(); 305 PolyhedralCone FA=A.faceContaining(v); 306 PolyhedralCone FB=B.faceContaining(v); 307 308 FA.canonicalize(); 309 FB.canonicalize(); 310 debug<<"FA"<<FA; 311 debug<<"FB"<<FB; 312 assert(!(FA<FB)); 313 assert(!(FB<FA)); 314 } 315 */ 316 317 318 IntegerVectorList inequalitiesA=A.getHalfSpaces(); 319 IntegerVectorList inequalitiesB=B.getHalfSpaces(); 320 IntegerVectorList inequalities; 321 for(IntegerVectorList::const_iterator i=inequalitiesA.begin();i!=inequalitiesA.end();i++) 322 if(!dependent(*i,normal))inequalities.push_back(*i); 323 for(IntegerVectorList::const_iterator i=inequalitiesB.begin();i!=inequalitiesB.end();i++) 324 if(!dependent(*i,normal))inequalities.push_back(*i); 325 326 //debug<<inequalities; 327 IntegerVectorList empty; 328 PolyhedralCone ret(inequalities,empty,normal.size()); 329 ret.canonicalize(); 330 //debug<<"RET"<<ret; 331 /* 332 { 333 IntegerVectorList generatorsA=A.extremeRays(); 334 IntegerVectorList generatorsB=B.extremeRays(); 335 IntegerVectorList generatorsAL=A.generatorsOfLinealitySpace(); 336 IntegerVectorList generatorsBL=B.generatorsOfLinealitySpace(); 337 for(IntegerVectorList::const_iterator i=generatorsB.begin();i!=generatorsB.end();i++)generatorsA.push_back(*i); 338 for(IntegerVectorList::const_iterator i=generatorsBL.begin();i!=generatorsBL.end();i++)generatorsAL.push_back(*i); 339 PolyhedralCone ret2=PolyhedralCone::givenByRays(generatorsA,generatorsAL,A.ambientDimension()); 340 ret2.canonicalize(); 341 debug<<"RET2"<<ret2; 342 assert(ret.contains(ret2)); 343 assert(ret2.contains(ret)); 344 assert(!(ret2<ret)); 345 assert(!(ret<ret2)); 346 // return ret2; 347 // assert(ret==ret2); 348 }*/ 349 return ret; 350 #endif 351 } 352 regionRek(PolyhedralCone const & C,IntegerVectorList const & omega,const Node * tree) const353 PolyhedralCone BSPTree::regionRek(PolyhedralCone const &C, IntegerVectorList const &omega, const Node *tree)const 354 { 355 if(tree==0)return C; 356 IntegerVectorList empty; 357 IntegerVectorList temp;temp.push_back(tree->normal); 358 PolyhedralCone hyperPlane(empty,temp); 359 PolyhedralCone rightHalfSpace(temp,empty);//HERE 360 PolyhedralCone leftHalfSpace=rightHalfSpace.negated(); 361 int sideWeAreOn=isOnRightHandSide(omega,tree->normal); 362 IntegerVectorList tempIneq=C.getHalfSpaces();tempIneq.push_back(sideWeAreOn?tree->normal:-tree->normal); 363 PolyhedralCone tempIntersection(tempIneq,empty,n,PCP_impliedEquationsKnown); 364 // PolyhedralCone A=regionRek(intersection(C,sideWeAreOn?rightHalfSpace:leftHalfSpace),omega,tree->leftRight[sideWeAreOn]); 365 PolyhedralCone A=regionRek(tempIntersection,omega,tree->leftRight[sideWeAreOn]); 366 367 bool isANormal=false; 368 A.findFacets(); 369 IntegerVectorList normals=A.getHalfSpaces(); 370 for(IntegerVectorList::const_iterator i=normals.begin();i!=normals.end();i++) 371 if(dependent(tree->normal,*i)){isANormal=true;break;} 372 if(!isANormal)return A; 373 374 375 PolyhedralCone iA(normals,temp,n,PCP_impliedEquationsKnown); 376 // PolyhedralCone iA=intersection(A,hyperPlane); 377 // iA.findImpliedEquations(); 378 379 380 // if(iA.dimension()==n-1) 381 { 382 IntegerVector v=iA.getRelativeInteriorPoint(); 383 bool isContained=false; 384 for(vector<int>::const_iterator i=tree->conesInHyperplane.begin();i!=tree->conesInHyperplane.end();i++) 385 if(theCones[*i].contains(v)){isContained=true;break;} 386 if(!isContained) 387 { 388 IntegerVectorList omega2; 389 omega2.push_back(v);omega2.push_back(sideWeAreOn?-(tree->normal):tree->normal);//HERE 390 IntegerVectorList tempIneq2=C.getHalfSpaces();tempIneq2.push_back(sideWeAreOn?-tree->normal:tree->normal); 391 PolyhedralCone tempIntersection2(tempIneq2,empty,n,PCP_impliedEquationsKnown); 392 PolyhedralCone B=regionRek(tempIntersection2,omega2,tree->leftRight[1-sideWeAreOn]); 393 // PolyhedralCone B=regionRek(intersection(C,sideWeAreOn?leftHalfSpace:rightHalfSpace),omega2,tree->leftRight[1-sideWeAreOn]); 394 return glue(A,B,tree->normal); 395 } 396 } 397 return A; 398 } region(IntegerVectorList const & omega) const399 PolyhedralCone BSPTree::region(IntegerVectorList const &omega)const 400 { 401 assert(hasBeenBuilt); 402 PolyhedralCone C=PolyhedralCone(n); 403 return regionRek(C,omega,root); 404 } printRek(Node const * p)405 void BSPTree::printRek(Node const *p) 406 { 407 if(p) 408 { 409 debug<<p->normal; 410 debug<<"["; 411 printRek(p->leftRight[1]); 412 debug<<":"; 413 printRek(p->leftRight[0]); 414 debug<<"]\n"; 415 } 416 417 } print() const418 void BSPTree::print()const 419 { 420 printRek(root); 421 } numberOfRegionsRek(Node const * v) const422 int BSPTree::numberOfRegionsRek(Node const *v)const 423 { 424 if(v==0)return 1; 425 return numberOfRegionsRek(v->leftRight[0])+numberOfRegionsRek(v->leftRight[1]); 426 } numberOfRegions() const427 int BSPTree::numberOfRegions()const 428 { 429 return numberOfRegionsRek(root); 430 } 431 isPerturbedDotProductPositive(IntegerVector const & p,IntegerVector const & ineq)432 static bool isPerturbedDotProductPositive(IntegerVector const &p, IntegerVector const &ineq) 433 { 434 if(dotLong(p,ineq)>0)return true; 435 if(dotLong(p,ineq)<0)return false; 436 for(int i=0;i<p.size();i++) 437 { 438 if(ineq[i]>0)return true; 439 if(ineq[i]<0)return false; 440 } 441 assert(ineq.isZero()); 442 return false; 443 } 444 445 /** 446 * Given vectors u,p and hyperplanes h1 h2, decide if the ray going from u to a lex perturbed p intersects h1 before h2. 447 */ before(IntegerVector const & u,IntegerVector const & p,IntegerVector const & h1,IntegerVector const & h2)448 static bool before(IntegerVector const &u, IntegerVector const &p, IntegerVector const &h1, IntegerVector const &h2) 449 { 450 /* 451 * The ray is (after scaling) parameterized as follows 452 * v(t)=tu+b+eps*e_1+...+eps^n*e_n 453 * where t goes from infinity through 0 to minus infinity. 454 * 455 * The times for intersection are 456 * t_i=(hi*b+eps*hi_1+...+eps^n*hi_n)/(-u*hi) 457 * WLOG we assume that u*hi>0 458 * 459 * Hence we check if 460 * (h1*b+eps*h1_1+...+eps^n*h1_n)*(u*h2) < (h2*b+eps*h2_1+...+eps^n*h2_n)*(u*h1) 461 */ 462 /* int64 uh1=dotLong(u,h1); 463 int64 uh2=dotLong(u,h2); 464 int64 ph1=dotLong(p,h1); 465 int64 ph2=dotLong(p,h2); 466 */ 467 int64 uh1,uh2,ph1,ph2; 468 dotLong4(u,p,h1,h2,uh1,uh2,ph1,ph2); 469 bool flag=(uh1<0)^(uh2<0); 470 /* if(uh1<0) 471 { 472 uh1=-uh1; 473 h1=-h1; 474 } 475 if(uh2<0) 476 { 477 uh2=-uh2; 478 h2=-h2; 479 } 480 if(dotLong(h1,p)*uh2>dotLong(h2,p)*uh1)return false^flag; 481 if(dotLong(h1,p)*uh2<dotLong(h2,p)*uh1)return true^flag; 482 */ 483 if(ph1*uh2>ph2*uh1)return false^flag; 484 if(ph1*uh2<ph2*uh1)return true^flag; 485 for(int i=0;i<u.size();i++) 486 { 487 if(h1[i]*uh2>h2[i]*uh1)return false^flag; 488 if(h1[i]*uh2<h2[i]*uh1)return true^flag; 489 } 490 if(flag)assert((h1+h2).isZero()); 491 else assert((h1-h2).isZero()); 492 return false; 493 } 494 495 /** 496 * Checks if the given vector is in the complement of the stored cones. 497 */ isInComplement(IntegerVector const & v) const498 bool BSPTree::isInComplement(IntegerVector const &v)const 499 { 500 for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();i++) 501 if(i->contains(v))return false; 502 return true; 503 } 504 505 /** 506 * Returns random vector in complement. 507 */ randomVectorInComplement() const508 IntegerVector BSPTree::randomVectorInComplement()const 509 { 510 while(1) 511 { 512 IntegerVector ret=randomIntegerVector(n,100); 513 514 if(isInComplement(ret))return ret; 515 } 516 return IntegerVector(); 517 } 518 519 520 /** 521 * Given a vector u and a vector n, such that none of the stored cones contain u+epsilon n for epsilon>0 sufficient small, 522 * find a vector ret in the span of u and n such that the open line segment between u and ret does intersect any of the 523 * stored cones. 524 */ perturbationToVectorInComplement(IntegerVector const & u,IntegerVector const & normal) const525 IntegerVector BSPTree::perturbationToVectorInComplement(IntegerVector const &u, IntegerVector const &normal)const 526 { 527 /* if(theCones.size()==0)return u+normals; 528 vector<SmallCone>::const_iterator best=theCones.end(); 529 for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();i++) 530 { 531 IntegerVector equation=i->getEquation().front(); 532 if(dotLong(equation,u)==0)continue; 533 534 } 535 536 */ 537 //Fix this later 538 539 bool found=false; 540 IntegerVector const *current=0; 541 for(vector<IntegerVector>::const_iterator i=hyperplanes.begin();i!=hyperplanes.end();i++) 542 { 543 if(dotLong(*i,u)){ 544 current=&*i; 545 found=true; 546 } 547 } 548 if(!found) 549 { 550 return normal; 551 } 552 for(vector<IntegerVector>::const_iterator i=hyperplanes.begin();i!=hyperplanes.end();i++) 553 if(dotLong(*i,u)) 554 if(before(u, normal, *i, *current))current=&*i; 555 556 int s=1; 557 int64 ud=dotLong(*current,u); 558 IntegerVector ret=u+normal; 559 for(int i=0;i<30;i++) 560 { 561 if(ud<0 && dotLong(*current,ret)<0)return ret; 562 if(ud>0 && dotLong(*current,ret)>0)return ret; 563 s*=2; 564 ret+=s*u; 565 } 566 assert(0); 567 return 100*u+normal; 568 } 569 570 571 /** 572 * Given a subset of the stored cones, a vector u in the complement and a point p, find the first codimension one intersecting 573 * the ray starting at u and passing through a lex perturbation of p. 574 */ firstIntersectionNormal(IntegerVector const & u,IntegerVector const & p,vector<SmallCone>::const_iterator i) const575 IntegerVector BSPTree::firstIntersectionNormal(IntegerVector const &u, IntegerVector const &p, vector<SmallCone>::const_iterator i)const 576 { 577 IntegerVector ret; 578 bool found=false; 579 IntegerVector equation; 580 // for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();i++) 581 for(;i!=theCones.end();i++) 582 { 583 584 i->assignEquation(equation); 585 // IntegerVectorList equations=i->getEquations(); 586 // assert(equations.size()==1); 587 // IntegerVector equation=equations.front(); 588 // check if equation is better that current 589 if(dotLong(equation,u)) 590 if(!found || before(u,p,equation,ret)) 591 { 592 bool doIntersect=true; 593 int doint=i->doIntersectNonPerturbed(u,p); 594 if(doint==2)goto noTestNeeded; 595 if(doint==0)continue; 596 //check if ray intersects cone 597 { 598 IntegerVectorList inequalities=i->getHalfSpaces(); 599 for(IntegerVectorList::const_iterator j=inequalities.begin();j!=inequalities.end();j++) 600 { 601 int64 ju=dotLong(*j,u); 602 603 604 if( (ju==0)&& !isPerturbedDotProductPositive(p,*j)|| 605 (ju>0)&&before(u,p,*j,equation)|| 606 (ju<0)&&before(u,p,equation,*j)) 607 { 608 doIntersect=false; 609 break; 610 } 611 } 612 } 613 noTestNeeded: 614 if(doIntersect) 615 { 616 /* if(ret.size()) 617 for(int k=0;k<12;k++) 618 { 619 IntegerVector temp=k*p+(10-k)*u; 620 D((int)dotLong(ret,temp)); 621 D((int)dotLong(equation,temp)); 622 }*/ 623 ret=equation; 624 found=true; 625 } 626 } 627 } 628 assert(found); 629 return ret; 630 } 631 632 633 /** 634 * Given a vector u not contained in any of the stored cones find the closure of the connected component of the complement 635 * of the stored cones containing u. 636 */ regionFast(IntegerVector const & u) const637 PolyhedralCone BSPTree::regionFast(IntegerVector const &u)const 638 { 639 if(0) { 640 static int abort; 641 if(!abort)D(abort); 642 abort++; 643 if(abort>1000)assert(0); 644 } 645 assert(u.size()==n); 646 PolyhedralCone ret=(n); 647 IntegerVectorList ineq; 648 IntegerVectorList ineqNeg; 649 for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();) 650 { 651 bool skip=false; 652 #if 0 653 IntegerVectorList gen;i->appendGeneratorsOfLinealitySpace(gen); 654 IntegerVectorList rays;i->appendExtremeRays(rays); 655 // IntegerVectorList ineq=ret.getHalfSpaces(); 656 for(IntegerVectorList::const_iterator j=ineq.begin();j!=ineq.end();j++) 657 { 658 bool isCert=true; 659 for(IntegerVectorList::const_iterator i=gen.begin();i!=gen.end();i++) 660 if(dotLong(*i,*j)!=0){isCert=false;goto leave;} 661 for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) 662 if(dotLong(*i,*j)>0){isCert=false;goto leave;} 663 leave: 664 if(isCert){skip=true;break;} 665 } 666 #else 667 for(IntegerVectorList::const_iterator j=ineqNeg.begin();j!=ineqNeg.end();j++) 668 { 669 if(i->doesSatisfyInequalityExpensive(*j)){skip=true;break;} 670 } 671 #endif 672 // D(skip); 673 674 if(!skip && isIntersectionOfCodimensionOne(ret,*i)) 675 { 676 PolyhedralCone B=intersection(ret,PolyhedralCone(i->getHalfSpaces(),i->getEquations(),n)); 677 IntegerVector p=B.getRelativeInteriorPoint(); 678 IntegerVector w=firstIntersectionNormal(u,p,i); 679 if(dotLong(w,u)<0)w=-w; 680 IntegerVectorList temp;temp.push_back(w); 681 ret=intersection(ret,PolyhedralCone(temp,IntegerVectorList(),n)); 682 ineq.push_back(w); 683 ineqNeg.push_back(-w); 684 assert(ret.contains(u)); 685 } 686 else 687 i++; 688 } 689 return ret; 690 } 691 multiplicity(IntegerVector const & v,IntegerVector const & normal) const692 int BSPTree::multiplicity(IntegerVector const &v, IntegerVector const &normal)const 693 { 694 int ret=0; 695 IntegerVectorList temp;temp.push_back(normal); 696 IntegerMatrix t=rowsToIntegerMatrix(temp); 697 FieldMatrix M=integerMatrixToFieldMatrix(t,Q); 698 IntegerVectorList l=fieldMatrixToIntegerMatrixPrimitive(M.reduceAndComputeKernel()).getRows(); 699 l.push_front(v); 700 for(vector<SmallCone>::const_iterator i=theCones.begin();i!=theCones.end();i++) 701 if(i->contains(v)) 702 { 703 ret+=i->multiplicity(); 704 } 705 706 return ret; 707 } 708