GiSTpenalty * MTentry::Penalty(const GiSTentry &newEntry, MTpenalty *minPenalty) const // in this case we can avoid to compute some distances by using some stored information: // minPenalty (the minimum penalty achieved so far), // newEntry.key->distance (the distance of the entry from the parent of this entry, stored in the SearchMinPenalty method), // and maxradius. { double retval; assert(newEntry.IsA()==MTENTRY_CLASS); const MTentry& e=(const MTentry &)newEntry; double dist; // printf("Distance between %s & %s=%f\n", object().name, e.object().name, dist); // return area enlargement switch(TB_FUNCTION) { case MIN_R_INCR: { if(((MTkey *)newEntry.Key())->distance>0) { // in this case is possible to prune some entries using triangular inequality double distPen=fabs(((MTkey *)newEntry.Key())->distance-Key()->distance)-maxradius(); MTpenalty *tmpPen; if(distPen>=0) tmpPen=new MTpenalty(distPen, 0); else tmpPen=new MTpenalty(distPen+maxradius()-maxDist(), 0); if((minPenalty!=NULL)&&!((*tmpPen)<(*minPenalty))) { delete tmpPen; return new MTpenalty(MAXDOUBLE, 0); // ... and we avoid to compute this distance } delete tmpPen; } dist=object().distance(e.object())+e.maxradius(); // compute the distance retval=dist-maxradius(); if(retval<0) retval=-maxDist()+dist; // if the entry can fit in (more than) a node without enlarging its radius, we assign it to its nearest node break; } case MIN_OVERLAP: { retval=0; dist=object().distance(e.object())+e.maxradius(); for (int i=0; i<Node()->NumEntries(); i++) { // compute total overlap for this node const MTentry& sibling=(const MTentry &)*(*(Node()))[i].Ptr(); double cost=sibling.maxradius()+dist-object().distance(sibling.object()); retval+=MAX(cost, 0); } break; } } // cout << "Penalty for " << newEntry << " in " << this << " = " << retval << " (distance = " << dist << ")" << endl; return new MTpenalty(retval, dist); }
void MTnode::InvalidateEntry(BOOL isNew) { GiSTpath path=Path(); if(path.Level()>1) { MTnode *parent=((MT *)Tree())->ParentNode((MTnode *)this), *gparent=((MT *)Tree())->ParentNode(parent); int i; for(i=0; i<parent->NumEntries(); i++) { // search the entry between the parent's children MTentry *e=(MTentry *)((*parent)[i].Ptr()); if(e->Ptr()==path.Page()) { if(isNew) e->Key()->distance=-maxDist(); // else e->Key()->distance=-e->Key()->distance; e->Key()->splitted=TRUE; break; } } path.MakeParent(); for(i=0; i<gparent->NumEntries(); i++) { // search the parent entry between the grandparent's children MTentry *e=(MTentry *)((*gparent)[i].Ptr()); if(e->Ptr()==path.Page()) { e->setmaxradius(-1); break; } } ((MT *)Tree())->WriteNode(parent); // write parent node (in inconsistent state) ((MT *)Tree())->WriteNode(gparent); // write gparent node (to invalidate the parent's entry) delete parent; delete gparent; } }
GiSTpenalty * MTentry::Penalty(const GiSTentry &newEntry) const { double retval; assert(newEntry.IsA()==MTENTRY_CLASS); const MTentry& e=(const MTentry &)newEntry; double dist=object().distance(e.object())+e.maxradius(); // printf("Distance between %s & %s=%f\n", object().name, e.object().name, dist); // return area enlargement switch(TB_FUNCTION) { case MIN_R_INCR: { retval=dist-maxradius(); if(retval<0) retval=-maxDist()+dist; // if the entry can fit in (more than) a node without enlarging its radius, we assign it to its nearest node break; } case MIN_OVERLAP: { retval=0; for (int i=0; i<Node()->NumEntries(); i++) { // compute total overlap for this node const MTentry& sibling=(const MTentry &)*(*(Node()))[i].Ptr(); double cost=sibling.maxradius()+dist-object().distance(sibling.object()); retval+=MAX(cost, 0); } break; } } // cout << "Penalty for " << newEntry << " in " << this << " = " << retval << " (distance = " << dist << ")" << endl; return new MTpenalty(retval, dist); }
void CmSaliencyGC::GetGU(vecD& gc, vecD &d, double sigmaDist, double dominate) { if (d.size() == 0){ d.resize(_NUM); #pragma omp parallel for for (int i = 0; i < _NUM; i++) SpatialVar(_PixelSalCi1f[i], d[i]); } Mat_<double> clrDist; clrDist = Mat_<double>::zeros(_NUM, _NUM); vector<Vec3f> gmmClrs(_NUM); cvtColor(_gmmClrs, gmmClrs, CV_BGR2Lab); vecD maxDist(_NUM); for (int i = 0; i < _NUM; i++) for (int j = 0; j < i; j++){ double dCrnt = vecDist(gmmClrs[i], gmmClrs[j]); clrDist(i, j) = clrDist(j, i) = dCrnt; maxDist[i] = max(maxDist[i], dCrnt); maxDist[j] = max(maxDist[j], dCrnt); } for (int i = 0; i < _NUM; i++) { gc[i] = 0; for (int j = 0; j < _NUM; j++) gc[i] += _gmmW[j] * clrDist(i, j) / maxDist[i]; //min(clrDist(i, j), dominate); } for (int i = 0; i < _NUM; i++) _gu[i] = _gu[i] * exp(-9.0 * sqr(d[i])); // normalize(_gu, _gu, 0, 1, CV_MINMAX); }
double MTnode::distance(int i) const { MTentry *e=(MTentry *)((*this)[i].Ptr()); // if(e->Key()->distance>=0) cout << "Distance between " << obj << " & " << e->object() << " = " << e->Key()->distance << endl; // else cout << "Computing distance between " << obj << " & " << e->object() << "..." << endl; return (e->Key()->distance<0)? ((e->Key()->distance>-maxDist())? -e->Key()->distance: obj->distance(e->object())): e->Key()->distance; }
double MTcursor::Bound() const { if(queue.IsEmpty()) if(results.IsEmpty()) return maxDist(); else return(results.First()->maxradius()); else if(results.IsEmpty()) return(queue.First()->Bound()); else return MIN(queue.First()->Bound(), results.First()->maxradius()); }
uint maxDist(State *s){ uint mm = 0; for(uint i = 0; i < s->go.nSpans; ++i){ State *t = s->go.span[i].to; if(t){ uint m = 1; if(!t->link) m += maxDist(t); if(m > mm) mm = m; } } return mm; }
void calcDepth(State *head){ State *t; for(State *s = head; s; s = s->next){ if(s->link == s){ for(uint i = 0; i < s->go.nSpans; ++i){ t = s->go.span[i].to; if(t && t->link == s) goto inSCC; } s->link = NULL; } else { inSCC: s->depth = maxDist(s); } } }
GiSTentry * MTnode::Union() const { GiSTpath path=((MTnode *)this)->Path(); MTentry *u=new MTentry; Object *o=NULL; u->InitKey(); if(obj==NULL) { // retrieve the node's object MTentry *e=Entry(); ((MTnode *)this)->obj=(o=new Object(e->object())); delete e; } if(path.Level()>1) { // if we aren't in the root... MTnode *parent=((MT *)Tree())->ParentNode((MTnode *)this); MTentry *e=Entry(); if(e!=NULL) { // copy the entry u->Key()->distance=e->Key()->distance; if(e->Key()->splitted) u->Key()->recomp=TRUE; delete e; } if(u->Key()->distance<0) { // compute the distance from the parent MTentry *fe=parent->Entry(); if(u->Key()->distance==-maxDist()) u->Key()->distance=obj->distance(fe->object()); u->Key()->recomp=TRUE; delete fe; } delete parent; } u->setobject(*obj); u->setmaxradius(0); u->setminradius(MAXDOUBLE); mMRadius(u); // compute the radii if(o!=NULL) delete o; ((MTnode *)this)->obj=NULL; return u; }
void MTnode::InvalidateEntries() { for(int i=0; i<NumEntries(); i++) ((MTentry *)((*this)[i].Ptr()))->Key()->distance=-maxDist(); }
void MTnode::Split(MTnode *node, int *leftvec, int *rightvec, int *leftdeletes, int *rightdeletes) { int i; *rightdeletes=0; *leftdeletes=0; // cout << "Now splitting between:\n"; // cout << obj << " & " << node->obj << endl; switch(SPLIT_FUNCTION) { case G_HYPERPL: { int numentries=NumEntries(); double *rightdistances=new double[numentries], *leftdistances=new double[numentries]; for(i=0; i<numentries; i++) { leftdistances[i]=distance(i); rightdistances[i]=node->distance(i); } while((*rightdeletes<numentries*MIN_UTIL)&&(*leftdeletes<numentries*MIN_UTIL)) { // balance entries up to minimum utilization (assigning to each node its remaining nearest entry) i=FindMin(leftdistances, numentries); ((MTentry *)(*this)[i].Ptr())->Key()->distance=leftdistances[i]; ((MTentry *)(*node)[i].Ptr())->Key()->distance=rightdistances[i]; // cout << (*this)[i].Ptr() << " (" << leftdistances[i] << ", " << rightdistances[i] << ") to the left\n"; rightvec[(*rightdeletes)++]=i; rightdistances[i]=MAXDOUBLE; leftdistances[i]=MAXDOUBLE; i=FindMin(rightdistances, numentries); if(i>=0) { ((MTentry *)(*node)[i].Ptr())->Key()->distance=rightdistances[i]; ((MTentry *)(*this)[i].Ptr())->Key()->distance=leftdistances[i]; // cout << (*node)[i].Ptr() << " (" << leftdistances[i] << ", " << rightdistances[i] << ") to the right\n"; leftvec[(*leftdeletes)++]=i; rightdistances[i]=MAXDOUBLE; leftdistances[i]=MAXDOUBLE; } } for(i=0; i<numentries; i++) { // then perform the hyperplane split (assigning each entry to its nearest node) if(rightdistances[i]==MAXDOUBLE) continue; // ((MTentry *)(*this)[i].Ptr())->Key()->distance=distance(i)+((MTentry *)(*this)[i].Ptr())->maxradius(); // ((MTentry *)(*node)[i].Ptr())->Key()->distance=node->distance(i)+((MTentry *)(*node)[i].Ptr())->maxradius(); ((MTentry *)(*this)[i].Ptr())->Key()->distance=leftdistances[i]; ((MTentry *)(*node)[i].Ptr())->Key()->distance=rightdistances[i]; if (((MTentry *)(*this)[i].Ptr())->Key()->distance<((MTentry *)(*node)[i].Ptr())->Key()->distance) { // cout << (*this)[i].Ptr() << " (" << ((MTentry *)(*this)[i].Ptr())->Key()->distance << ", " << ((MTentry *)(*node)[i].Ptr())->Key()->distance << ") to the left\n"; rightvec[(*rightdeletes)++]=i; } else { // cout << (*node)[i].Ptr() << " (" << ((MTentry *)(*this)[i].Ptr())->Key()->distance << ", " << ((MTentry *)(*node)[i].Ptr())->Key()->distance << ") to the right\n"; leftvec[(*leftdeletes)++]=i; } } delete []rightdistances; delete []leftdistances; break; } case BAL_G_HYPERPL: { int numentries=NumEntries(), j; for(i=0; i<NumEntries(); i++) { // assign the parents' entries if(obj==&((MTentry *)((*this)[i].Ptr()))->object()) { // cout << (*this)[i].Ptr() << " to the left\n"; ((MTentry *)(*this)[i].Ptr())->Key()->distance=0; rightvec[(*rightdeletes)++]=i; } if(node->obj==&((MTentry *)((*node)[i].Ptr()))->object()) { // cout << (*node)[i].Ptr() << " to the right\n"; ((MTentry *)(*node)[i].Ptr())->Key()->distance=0; leftvec[(*leftdeletes)++]=i; } } for(i=0; (*rightdeletes<(numentries+1)/2)&&(*leftdeletes<(numentries+1)/2); i++) { // perform the hyperplane split up to a node utilization of the 50% if((obj!=&((MTentry *)((*this)[i].Ptr()))->object())&&(node->obj!=&((MTentry *)((*node)[i].Ptr()))->object())) { // the parents' entries were already assigned ((MTentry *)(*this)[i].Ptr())->Key()->distance=distance(i); ((MTentry *)(*node)[i].Ptr())->Key()->distance=node->distance(i); if (((MTentry *)(*this)[i].Ptr())->Key()->distance<((MTentry *)(*node)[i].Ptr())->Key()->distance) { // cout << (*this)[i].Ptr() << " (" << ((MTentry *)(*this)[i].Ptr())->Key()->distance << ", " << ((MTentry *)(*node)[i].Ptr())->Key()->distance << ") to the left\n"; rightvec[(*rightdeletes)++]=i; } else { // cout << (*node)[i].Ptr() << " (" << ((MTentry *)(*this)[i].Ptr())->Key()->distance << ", " << ((MTentry *)(*node)[i].Ptr())->Key()->distance << ") to the right\n"; leftvec[(*leftdeletes)++]=i; } } } // then balance the remaining entries for(j=*rightdeletes; j<numentries/2; j++, i++) if((obj!=&((MTentry *)((*this)[i].Ptr()))->object())&&(node->obj!=&((MTentry *)((*node)[i].Ptr()))->object())) { // the parents' entries were already assigned ((MTentry *)(*this)[i].Ptr())->Key()->distance=distance(i); ((MTentry *)(*node)[i].Ptr())->Key()->distance=-maxDist(); // cout << (*this)[i].Ptr() << " (" << ((MTentry *)(*this)[i].Ptr())->Key()->distance << ") to the left\n"; rightvec[(*rightdeletes)++]=i; } else j--; for(j=*leftdeletes; j<numentries/2; j++, i++) if((obj!=&((MTentry *)((*this)[i].Ptr()))->object())&&(node->obj!=&((MTentry *)((*node)[i].Ptr()))->object())) { // the parents' entries were already assigned ((MTentry *)(*node)[i].Ptr())->Key()->distance=node->distance(i); ((MTentry *)(*this)[i].Ptr())->Key()->distance=-maxDist(); // cout << (*node)[i].Ptr() << " (" << ((MTentry *)(*node)[i].Ptr())->Key()->distance << ") to the right\n"; leftvec[(*leftdeletes)++]=i; } else j--; break; } case BALANCED: { // assign iteratively to each node its remaining nearest entry int numentries=NumEntries(); double *rightdistances=new double[numentries], *leftdistances=new double[numentries]; for(i=0; i<numentries; i++) { leftdistances[i]=distance(i); rightdistances[i]=node->distance(i); } while((*rightdeletes<(numentries+1)/2)&&(*leftdeletes<(numentries+1)/2)) { i=FindMin(leftdistances, numentries); ((MTentry *)(*this)[i].Ptr())->Key()->distance=leftdistances[i]; ((MTentry *)(*node)[i].Ptr())->Key()->distance=rightdistances[i]; // cout << (*this)[i].Ptr() << " (" << leftdistances[i] << ", " << rightdistances[i] << ") to the left\n"; rightvec[(*rightdeletes)++]=i; rightdistances[i]=MAXDOUBLE; leftdistances[i]=MAXDOUBLE; i=FindMin(rightdistances, numentries); if(i>=0) { ((MTentry *)(*node)[i].Ptr())->Key()->distance=rightdistances[i]; ((MTentry *)(*this)[i].Ptr())->Key()->distance=leftdistances[i]; // cout << (*node)[i].Ptr() << " (" << leftdistances[i] << ", " << rightdistances[i] << ") to the right\n"; leftvec[(*leftdeletes)++]=i; rightdistances[i]=MAXDOUBLE; leftdistances[i]=MAXDOUBLE; } } delete []rightdistances; delete []leftdistances; break; } } }
MTnode * MTnode::PromotePart() { MTnode *newnode; switch(PROMOTE_PART_FUNCTION) { case RANDOM: { // complexity: constant int i, j; // pick two *different* random entries // cout << "Random promotion: "; i=PickRandom(0, NumEntries()); do j=PickRandom(0, NumEntries()); while (j==i); if(((MTentry *)(*this)[j].Ptr())->Key()->distance==0) { int k=i; i=j; j=k; // if we chose the parent entry, put it in the left node } // cout << "Entries " << (*this)[i].Ptr() << " & " << (*this)[j].Ptr() << " chosen.\n"; newnode=(MTnode *)NCopy(); // re-assign the nodes' object newnode->obj=&((MTentry *)((*newnode)[j].Ptr()))->object(); obj=&((MTentry *)((*this)[i].Ptr()))->object(); if(((MTentry *)(*this)[i].Ptr())->Key()->distance>0) { // if the parent object wasn't confirmed, invalidate also the parent InvalidateEntry(TRUE); InvalidateEntries(); } else InvalidateEntry(FALSE); // else, invalidate only the node's radii break; } case CONFIRMED: { // complexity: determined by the confirmed promotion algorithm int i; BOOL isRoot=TRUE; // cout << "Confirmed promotion: "; // for(i=0; (i<NumEntries())&&(isRoot); i++) isRoot=(((MTentry *)((*this)[i].Ptr()))->Key()->distance==-MAXDIST); isRoot=(((MTentry *)((*this)[0].Ptr()))->Key()->distance==-maxDist()); // we have ordered entries if(isRoot) { // if we're splitting the root we have to use a policy that doesn't use stored distances PROMOTE_PART_FUNCTION=SECONDARY_PART_FUNCTION; newnode=PromotePart(); PROMOTE_PART_FUNCTION=CONFIRMED; } else { int index=-1; for(i=0; (i<NumEntries())&&(index<0); i++) if(((MTentry *)((*this)[i].Ptr()))->Key()->distance==0) index=i; obj=&((MTentry *)((*this)[index].Ptr()))->object(); // now choose the right node parent newnode=PromoteVote(); } InvalidateEntry(FALSE); break; } case MAX_UB_DIST: { // complexity: constant double maxdist=-1, maxdist2; int i, maxcand1, maxcand2; BOOL isRoot=TRUE; // cout << "Largest max dist promotion:\n"; // for(i=0; (i<NumEntries())&&(isRoot); i++) isRoot=(((MTentry *)((*this)[i].Ptr()))->Key()->distance==-MAXDIST); isRoot=(((MTentry *)((*this)[0].Ptr()))->Key()->distance==-maxDist()); // we have ordered entries if(isRoot) { // if we're splitting the root we have to use a policy that doesn't use stored distances PROMOTE_PART_FUNCTION=SECONDARY_PART_FUNCTION; newnode=PromotePart(); PROMOTE_PART_FUNCTION=CONFIRMED; } else if(Tree()->IsOrdered()) { // if the tree is ordered we can choose the last two elements maxcand1=NumEntries()-1; maxcand2=NumEntries()-2; } // the following code should be unreachable else // otherwise we have to search the two objects which are farthest from the parent for (i=0; i<NumEntries(); i++) { MTentry *e=(MTentry *)((*this)[i].Ptr()); if (e->Key()->distance>maxdist) { maxdist2=maxdist; maxdist=e->Key()->distance; maxcand2=maxcand1; maxcand1=i; } else if (e->Key()->distance>maxdist2) { maxdist2=e->Key()->distance; maxcand2=i; } } // cout << "Entries " << (*this)[maxcand1].Ptr() << " & " << (*this)[maxcand2].Ptr() << " chosen.\n"; // for sure the parent isn't confirmed (unless we have a binary tree...) obj=&((MTentry *)((*this)[maxcand1].Ptr()))->object(); InvalidateEntry(TRUE); InvalidateEntries(); newnode=(MTnode *)NCopy(); newnode->obj=&((MTentry *)((*newnode)[maxcand2].Ptr()))->object(); break; } case SAMPLING: { // complexity: O(kn) distance computations // cout << "Sampling: "; int *vec=PickCandidates(), i, j, min1, min2, bestld, bestrd, *bestlv=new int[NumEntries()], *bestrv=new int[NumEntries()]; double minvalue=MAXDOUBLE, sec_minvalue=MAXDOUBLE, **distances=new double*[MIN(NUM_CANDIDATES, NumEntries())]; // distance matrix // initialize distance matrix for(i=0; i<MIN(NUM_CANDIDATES, NumEntries()); i++) { distances[i]=new double[NumEntries()]; for(j=0; j<NumEntries(); j++) distances[i][j]=-maxDist(); } for(i=0; i<MIN(NUM_CANDIDATES, NumEntries()); i++) if(((MTentry *)((*this)[vec[i]].Ptr()))->Key()->distance==0) { for(j=0; j<NumEntries(); j++) distances[i][j]=((MTentry *)((*this)[j].Ptr()))->Key()->distance; break; } for(i=0; i<MIN(NUM_CANDIDATES, NumEntries()); i++) distances[i][vec[i]]=0; // find the candidates with minimum radius for(i=1; i<MIN(NUM_CANDIDATES, NumEntries()); i++) for (j=0; j<i; j++) { MTentry *e1=new MTentry, *e2=new MTentry; MTnode *node1=(MTnode *)NCopy(), *node2=(MTnode *)NCopy(); double value, sec_value; int leftdeletes, rightdeletes, *leftvec=new int[NumEntries()], *rightvec=new int[NumEntries()], k; for(k=0; k<NumEntries(); k++) { ((MTentry *)((*node1)[k].Ptr()))->Key()->distance=distances[i][k]; ((MTentry *)((*node2)[k].Ptr()))->Key()->distance=distances[j][k]; } node1->obj=&((MTentry *)((*this)[vec[i]].Ptr()))->object(); node2->obj=&((MTentry *)((*this)[vec[j]].Ptr()))->object(); // perform the split node1->Split(node2, leftvec, rightvec, &leftdeletes, &rightdeletes); for(k=0; k<NumEntries(); k++) { distances[i][k]=((MTentry *)((*node1)[k].Ptr()))->Key()->distance; distances[j][k]=((MTentry *)((*node2)[k].Ptr()))->Key()->distance; } // given the deletion vectors, do bulk deletes node1->DeleteBulk(leftvec, leftdeletes); node2->DeleteBulk(rightvec, rightdeletes); e1->InitKey(); e2->InitKey(); e1->setobject(*node1->obj); e2->setobject(*node2->obj); e1->setmaxradius(0); e2->setmaxradius(0); e1->setminradius(MAXDOUBLE); e2->setminradius(MAXDOUBLE); // compute the radii node1->mMRadius(e1); node2->mMRadius(e2); // check the result value=MAX(e1->maxradius(), e2->maxradius()); // this is minMAX_RADII sec_value=MIN(e1->maxradius(), e2->maxradius()); if((value<minvalue)||((value==minvalue)&&(sec_value<sec_minvalue))) { int index; minvalue=value; sec_minvalue=sec_value; bestld=leftdeletes; bestrd=rightdeletes; for(index=0; index<leftdeletes; index++) bestlv[index]=leftvec[index]; for(index=0; index<rightdeletes; index++) bestrv[index]=rightvec[index]; min1=i; min2=j; } // be tidy delete []leftvec; delete []rightvec; delete node1; delete node2; delete e1; delete e2; } // cout << "Entries " << (*this)[vec[min1]].Ptr() << " & " << (*this)[vec[min2]].Ptr() << " chosen.\n"; if(((MTentry *)(*this)[vec[min2]].Ptr())->Key()->distance>0) newnode=(MTnode *)NCopy(); else newnode=(MTnode *)Copy(); newnode->obj=&((MTentry *)((*newnode)[vec[min2]].Ptr()))->object(); obj=&((MTentry *)((*this)[vec[min1]].Ptr()))->object(); if(((MTentry *)(*this)[vec[min1]].Ptr())->Key()->distance>0) { // if the parent object wasn't confirmed, invalidate also the parent InvalidateEntry(TRUE); InvalidateEntries(); } else InvalidateEntry(FALSE); // else, invalidate only the node's radii for(i=0; i<NumEntries(); i++) { ((MTentry *)((*this)[i].Ptr()))->Key()->distance=distances[min1][i]; ((MTentry *)((*newnode)[i].Ptr()))->Key()->distance=distances[min2][i]; } delete []bestlv; delete []bestrv; for(i=0; i<MIN(NUM_CANDIDATES, NumEntries()); i++) delete []distances[i]; delete []distances; break; } case MIN_RAD: case MIN_OVERLAPS: { // complexity: O(n^2) distance computations int min1, min2, i, j, bestld, bestrd, *bestlv=new int[NumEntries()], *bestrv=new int[NumEntries()]; double minvalue=MAXDOUBLE, sec_minvalue=MAXDOUBLE, **distances=new double *[NumEntries()]; // distance matrix // initialize distance matrix for(i=0; i<NumEntries(); i++) { distances[i]=new double[NumEntries()]; for(j=0; j<NumEntries(); j++) distances[i][j]=-maxDist(); } for(i=0; i<NumEntries(); i++) if(((MTentry *)((*this)[i].Ptr()))->Key()->distance==0) { for(j=0; j<NumEntries(); j++) { distances[i][j]=((MTentry *)((*this)[j].Ptr()))->Key()->distance; distances[j][i]=distances[i][j]; } break; } for(i=0; i<NumEntries(); i++) distances[i][i]=0; // if(PROMOTE_PART_FUNCTION==MIN_RADII) cout << "Min radii promotion: "; // else cout << "Min overlaps promotion: "; for (i=1; i<NumEntries(); i++) for (j=0; j<i; j++) { MTentry *e1=new MTentry, *e2=new MTentry; MTnode *node1=(MTnode *)NCopy(), *node2=(MTnode *)NCopy(); double value, sec_value; int leftdeletes, rightdeletes, *leftvec=new int[NumEntries()], *rightvec=new int[NumEntries()], k; for(k=0; k<NumEntries(); k++) { ((MTentry *)((*node1)[k].Ptr()))->Key()->distance=distances[i][k]; ((MTentry *)((*node2)[k].Ptr()))->Key()->distance=distances[j][k]; } node1->obj=&((MTentry *)((*this)[i].Ptr()))->object(); node2->obj=&((MTentry *)((*this)[j].Ptr()))->object(); // perform the split node1->Split(node2, leftvec, rightvec, &leftdeletes, &rightdeletes); for(k=0; k<NumEntries(); k++) { distances[i][k]=((MTentry *)((*node1)[k].Ptr()))->Key()->distance; distances[j][k]=((MTentry *)((*node2)[k].Ptr()))->Key()->distance; distances[k][i]=distances[i][k]; distances[k][j]=distances[j][k]; } // given the deletion vectors, do bulk deletes node1->DeleteBulk(leftvec, leftdeletes); node2->DeleteBulk(rightvec, rightdeletes); e1->InitKey(); e2->InitKey(); e1->setobject(*node1->obj); e2->setobject(*node2->obj); e1->setmaxradius(0); e2->setmaxradius(0); e1->setminradius(MAXDOUBLE); e2->setminradius(MAXDOUBLE); // compute the radii node1->mMRadius(e1); node2->mMRadius(e2); // check the result if(PROMOTE_PART_FUNCTION==MIN_RAD) { value=MAX(e1->maxradius(), e2->maxradius()); // this is minMAX_RADII sec_value=MIN(e1->maxradius(), e2->maxradius()); } else value=e1->maxradius()+e2->maxradius()-distances[i][j]; if((value<minvalue)||((value==minvalue)&&(sec_value<sec_minvalue))) { int index; minvalue=value; sec_minvalue=sec_value; bestld=leftdeletes; bestrd=rightdeletes; for(index=0; index<leftdeletes; index++) bestlv[index]=leftvec[index]; for(index=0; index<rightdeletes; index++) bestrv[index]=rightvec[index]; min1=i; min2=j; } // be tidy delete []leftvec; delete []rightvec; delete node1; delete node2; delete e1; delete e2; } // cout << "Entries " << (*this)[min1].Ptr() << " & " << (*this)[min2].Ptr() << " chosen.\n"; if(((MTentry *)(*this)[min2].Ptr())->Key()->distance>0) newnode=(MTnode *)NCopy(); else newnode=(MTnode *)Copy(); newnode->obj=&((MTentry *)((*newnode)[min2].Ptr()))->object(); obj=&((MTentry *)((*this)[min1].Ptr()))->object(); if(((MTentry *)(*this)[min1].Ptr())->Key()->distance>0) { // if the parent object wasn't confirmed, invalidate also the parent InvalidateEntry(TRUE); InvalidateEntries(); } else InvalidateEntry(FALSE); // else, invalidate only the node's radii for(i=0; i<NumEntries(); i++) { ((MTentry *)((*this)[i].Ptr()))->Key()->distance=distances[min1][i]; ((MTentry *)((*newnode)[i].Ptr()))->Key()->distance=distances[min2][i]; } delete bestlv; delete bestrv; for(i=0; i<NumEntries(); i++) delete []distances[i]; delete []distances; break; } } return newnode; }
uint DFA::emit(SubString &name, uint label, ostream &o){ State *s; uint i, j; findSCCs(); head->link = head; head->depth = maxDist(head); uint nRules = 0; for(s = head; s; s = s->next) if(s->rule && s->rule->accept >= nRules) nRules = s->rule->accept + 1; uint nSaves = 0; uint *saves = new uint[nRules]; memset(saves, ~0, (nRules)*sizeof(*saves)); uint nMarks = 0; for(s = head; s; s = s->next){ RuleOp *ignore = NULL; if(s->rule){ for(i = 0; i < s->go.nSpans; ++i) if(s->go.span[i].to && !s->go.span[i].to->rule){ delete s->action; if(saves[s->rule->accept] == ~0) saves[s->rule->accept] = nSaves++; new Save(s, saves[s->rule->accept]); continue; } ignore = s->rule; } } State **rules = new State*[nRules]; memset(rules, 0, (nRules)*sizeof(*rules)); State *accept = NULL; for(s = head; s; s = s->next){ State *ow; if(!s->rule){ ow = accept; } else { if(!rules[s->rule->accept]){ State *n = new State; new Rule(n, s->rule); rules[s->rule->accept] = n; addState(&s->next, n); } ow = rules[s->rule->accept]; } for(i = 0; i < s->go.nSpans; ++i) if(!s->go.span[i].to){ if(!ow){ ow = accept = new State; new Accept(accept, nRules, saves, rules); addState(&s->next, accept); } s->go.span[i].to = ow; } } for(s = head; s; s = s->next) if(s->link){ split(s); s = s->next; } Span *span = new Span[ubChar - lbChar]; for(s = head; s; s = s->next){ if(!s->link){ for(i = 0; i < s->go.nSpans; ++i){ State *to = s->go.span[i].to; if(to && to->link && to->depth == 1){ to = to->go.span[0].to; uint nSpans = merge(span, s, to); if(nSpans < s->go.nSpans){ delete s->go.span; s->go.nSpans = nSpans; s->go.span = new Span[nSpans]; memcpy(s->go.span, span, nSpans*sizeof(Span)); } break; } } } } delete span; delete head->action; new Enter(head, name); for(s = head; s; s = s->next) s->label = label++; o << "\tgoto " << name << ";\n"; for(s = head; s; s = s->next){ s->emit(o); s->genGoto(o); } delete saves; delete rules; return label; }
static bool bruteMinT(skiatest::Reporter* reporter, const SkDQuad& quad1, const SkDQuad& quad2, TRange* lowerRange, TRange* upperRange) { double maxRadius = SkTMin(maxDist(quad1), maxDist(quad2)); double maxQuads = SkTMax(maxQuad(quad1), maxQuad(quad2)); double r = maxRadius / 2; double rStep = r / 2; SkDPoint best1 = {SK_ScalarInfinity, SK_ScalarInfinity}; SkDPoint best2 = {SK_ScalarInfinity, SK_ScalarInfinity}; int bestCCW = -1; double bestR = maxRadius; upperRange->tMin = 0; lowerRange->tMin = 1; do { do { // find upper bounds of single result TRange tRange; bool stepUp = orderTRange(reporter, quad1, quad2, r, &tRange); if (stepUp) { SkDPoint pt1 = quad1.ptAtT(tRange.t1); if (equalPoints(pt1, best1, maxQuads)) { break; } best1 = pt1; SkDPoint pt2 = quad2.ptAtT(tRange.t2); if (equalPoints(pt2, best2, maxQuads)) { break; } best2 = pt2; if (gPathOpsAngleIdeasVerbose) { SkDebugf("u bestCCW=%d ccw=%d bestMin=%1.9g:%1.9g r=%1.9g tMin=%1.9g\n", bestCCW, tRange.ccw, lowerRange->tMin, upperRange->tMin, r, tRange.tMin); } if (bestCCW >= 0 && bestCCW != (int) tRange.ccw) { if (tRange.tMin < upperRange->tMin) { upperRange->tMin = 0; } else { stepUp = false; } } if (upperRange->tMin < tRange.tMin) { bestCCW = tRange.ccw; bestR = r; *upperRange = tRange; } if (lowerRange->tMin > tRange.tMin) { *lowerRange = tRange; } } r += stepUp ? rStep : -rStep; rStep /= 2; } while (rStep > FLT_EPSILON); if (bestCCW < 0) { REPORTER_ASSERT(reporter, bestR < maxRadius); return false; } double lastHighR = bestR; r = bestR / 2; rStep = r / 2; do { // find lower bounds of single result TRange tRange; bool success = orderTRange(reporter, quad1, quad2, r, &tRange); if (success) { if (gPathOpsAngleIdeasVerbose) { SkDebugf("l bestCCW=%d ccw=%d bestMin=%1.9g:%1.9g r=%1.9g tMin=%1.9g\n", bestCCW, tRange.ccw, lowerRange->tMin, upperRange->tMin, r, tRange.tMin); } if (bestCCW != (int) tRange.ccw || upperRange->tMin < tRange.tMin) { bestCCW = tRange.ccw; *upperRange = tRange; bestR = lastHighR; break; // need to establish a new upper bounds } SkDPoint pt1 = quad1.ptAtT(tRange.t1); SkDPoint pt2 = quad2.ptAtT(tRange.t2); if (equalPoints(pt1, best1, maxQuads)) { goto breakOut; } best1 = pt1; if (equalPoints(pt2, best2, maxQuads)) { goto breakOut; } best2 = pt2; if (equalPoints(pt1, pt2, maxQuads)) { success = false; } else { if (upperRange->tMin < tRange.tMin) { *upperRange = tRange; } if (lowerRange->tMin > tRange.tMin) { *lowerRange = tRange; } } lastHighR = SkTMin(r, lastHighR); } r += success ? -rStep : rStep; rStep /= 2; } while (rStep > FLT_EPSILON); } while (rStep > FLT_EPSILON); breakOut: if (gPathOpsAngleIdeasVerbose) { SkDebugf("l a2-a1==%1.9g\n", lowerRange->a2 - lowerRange->a1); } return true; }
void naive(double *data, double *distvec, int *nrow, int *ncol, double *vcovi, int *ntr, int *l2, int *l1names, int *valid, double *validvar, double *validlb, double *validub, int *verbose, double *pairdist, int *ismahal, int *result, int *p) { /* */ /* set up distances */ /* */ unsigned n = choose(*nrow, 2), i; double *vec=Calloc(n, double), *vec2=Calloc(n, double); /* Compute distances between all units */ if(*ismahal==1) { vec = allmahal(ncol, nrow, n, data, vcovi, vec); } else { /* put in user-supplied distances if mahalanobis distances are not wanted */ for(i=1; i<n; i++) { vec[i] = distvec[i]; } } for(i=1; i<n; i++) { vec2[i] = vec[i]; } /* Set some distances to INF to avoid unwanted matches if valid.var is set or if level.two=TRUE (return original distances otherwise) */ vec = cleanUp(*l2, l1names, *valid, validvar, *validlb, *validub, n, vec); unsigned unitlist[*nrow], unit, k, matches[*ntr], mm, mn[*ntr], check=0, j=0; for(unit=0; unit<*nrow; unit++) { if(unitlist[unit] != 1) { matches[0] = unit+1; if(*l2 == 1) /* if level.two=TRUE, eliminate subunits within the same level two unit */ { for(i=0; i<n; i++) { if(levelTwoCheck(i, unit+1, l1names)==1) { vec[i] = HUGE_VAL; if(l1names[myrow(i)-1]==l1names[unit]) { unitlist[myrow(i)-1] = 1; } else { unitlist[mycol(i)-1] = 1; } } } } for(k=0; k<(*ntr-1); k++) { /* find minimum distance */ mn[k] = findMin2(vec, *nrow, unit+1); /* record row and column */ mm = mycol(mn[k]); if(mm==matches[0]) { matches[k+1] = myrow(mn[k]); } else { matches[k+1] = mm; } unitlist[matches[k+1]-1] = 1; if(vec[mn[k]] == HUGE_VAL && check==0) { check = k+1; } /* inf out things not to be reused */ vec[mn[k]] = HUGE_VAL; if(*l2 == 1) /* if level.two=TRUE, eliminate subunits within the same level two unit */ { for(i=0; i<n; i++) { if(levelTwoCheck(i, matches[k+1], l1names)==1) { vec[i] = HUGE_VAL; if(l1names[myrow(i)-1]==l1names[matches[k+1]-1]) { unitlist[myrow(i)-1] = 1; } else { unitlist[mycol(i)-1] = 1; } } } } } pairdist[j] = maxDist(vec2, matches, *ntr); /* get rid of used units */ for(i=0; i<*ntr; i++) { vec = eliminate(matches[i],vec, *nrow); } /* record matches for the R output */ if(check > 0) { for(i=check; i<*ntr; i++) { matches[i] = 0; } } check = 0; for(i=0; i<*ntr; i++) { result[j*(*ntr) + i] = matches[i]; } /* reset matches to zero for next iteration */ for(i=0; i<*ntr; i++) { matches[i] = 0; } j++; } } }