44#define __NOTNAN(p) (p)==(p)
48 double ai=
scale/v->scale;
49 double bi=v->offset/v->scale;
52 AD+=wi*ai*v->desiredPosition;
72 COLA_ASSERT(__NOTNAN(
posn));
105 COLA_ASSERT(__NOTNAN(
posn));
106#ifdef LIBVPSC_LOGGING
107 ofstream f(LOGFILE,ios::app);
108 f <<
", posn=" <<
posn << endl;
128 std::vector<Constraint*> *cs=
in?&(v->in):&(v->out);
129 for (
Cit j=cs->begin();j!=cs->end();++j) {
132 if ( ((
c->left->block !=
this) &&
in) ||
133 ((
c->right->block !=
this) && !
in) )
141#ifdef LIBVPSC_LOGGING
142 ofstream f(LOGFILE,ios::app);
143 f<<
" merging on: "<<*
c<<
",c->left->offset="<<
c->left->offset<<
",c->right->offset="<<
c->right->offset<<endl;
145 double dist =
c->right->offset -
c->left->offset -
c->gap;
148 if (l->
vars->size() < r->
vars->size()) {
154#ifdef LIBVPSC_LOGGING
155 f<<
" merged block="<<*mergeBlock<<endl;
167#ifdef LIBVPSC_LOGGING
168 ofstream f(LOGFILE,ios::app);
169 f<<
" merging: "<<*b<<
"dist="<<dist<<endl;
174 for(
Vit i=b->
vars->begin();i!=b->
vars->end();++i) {
181#ifdef LIBVPSC_LOGGING
184 f<<
" v["<<v->id<<
"]: d="<<v->desiredPosition
185 <<
" a="<<v->scale<<
" o="<<v->offset
193 COLA_ASSERT(__NOTNAN(
posn));
198#ifdef LIBVPSC_LOGGING
199 ofstream f(LOGFILE,ios::app);
200 f<<
" merging constraint heaps... "<<endl;
206#ifdef LIBVPSC_LOGGING
207 f<<
" merged heap: "<<*
in<<endl;
217 std::vector<Constraint*> outOfDate;
218 while (!
in->isEmpty()) {
220 Block *lb=v->left->block;
221 Block *rb=v->right->block;
223#ifdef LIBVPSC_LOGGING
224 ofstream f(LOGFILE,ios::app);
225 f<<
" checking constraint ... "<<*v;
226 f<<
" timestamps: left="<<lb->
timeStamp<<
" right="<<rb->
timeStamp<<
" constraint="<<v->timeStamp<<endl;
230#ifdef LIBVPSC_LOGGING
232 f<<
" violated internal constraint found! "<<*v<<endl;
233 f<<
" lb="<<*lb<<endl;
234 f<<
" rb="<<*rb<<endl;
238#ifdef LIBVPSC_LOGGING
239 f<<
" ... skipping internal constraint"<<endl;
241 }
else if(v->timeStamp < lb->
timeStamp) {
244 outOfDate.push_back(v);
245#ifdef LIBVPSC_LOGGING
246 f<<
" reinserting out of date (reinsert later)"<<endl;
252 for(
Cit i=outOfDate.begin();i!=outOfDate.end();++i) {
265 if(
out->isEmpty())
return nullptr;
267 while (v->left->block == v->right->block) {
269 if(
out->isEmpty())
return nullptr;
276#ifdef LIBVPSC_LOGGING
277 ofstream f(LOGFILE,ios::app);
278 f<<
"deleteMinInConstraint... "<<endl;
279 f<<
" result: "<<*
in<<endl;
286 return c->left->block==
this &&
c->active && last!=
c->left;
289 return c->right->
block==
this &&
c->active && last!=
c->right;
299 double dfdv=v->dfdv();
300 for(
Cit it=v->out.begin();it!=v->out.end();++it) {
304 dfdv+=
c->lm*
c->left->scale;
305 if(!
c->equality&&(min_lm==
nullptr||
c->
lm<min_lm->
lm)) min_lm=
c;
308 for(
Cit it=v->in.begin();it!=v->in.end();++it) {
312 dfdv-=
c->lm*
c->right->scale;
313 if(!
c->equality&&(min_lm==
nullptr||
c->
lm<min_lm->
lm)) min_lm=
c;
316 return dfdv/v->scale;
319 double dfdv = v->dfdv();
320 for(
Cit it = v->out.begin(); it != v->out.end(); ++it) {
324 dfdv +=
c->lm *
c->left->scale;
327 for(
Cit it=v->in.begin();it!=v->in.end();++it) {
331 dfdv -=
c->lm *
c->right->scale;
334 return dfdv/v->scale;
351 bool desperation=
false
354 for(
Cit it(v->in.begin());it!=v->in.end();++it) {
357#ifdef LIBVPSC_LOGGING
358 ofstream f(LOGFILE,ios::app);
359 f<<
" left split path: "<<*
c<<endl;
362 if(desperation&&!
c->equality) m=
c;
366 if(desperation && !
c->equality && (!m||
c->
lm<m->
lm)) {
374 for(
Cit it(v->out.begin());it!=v->out.end();++it) {
377#ifdef LIBVPSC_LOGGING
378 ofstream f(LOGFILE,ios::app);
379 f<<
" right split path: "<<*
c<<endl;
382 if(!
c->equality) m=
c;
386 if(!
c->equality && (!m||
c->
lm<m->
lm))
445 for(
Cit it=v->out.begin();it!=v->out.end();++it) {
452 for(
Cit it=v->in.begin();it!=v->in.end();++it) {
461 for(
Cit it=v->out.begin();it!=v->out.end();++it) {
464#ifdef LIBVPSC_LOGGING
465 ofstream f(LOGFILE,ios::app);
471 for(
Cit it=v->in.begin();it!=v->in.end();++it) {
474#ifdef LIBVPSC_LOGGING
475 ofstream f(LOGFILE,ios::app);
490#ifdef LIBVPSC_LOGGING
491 ofstream f(LOGFILE,ios::app);
492 f<<
" langrangians: "<<endl;
503 if(min_lm==
nullptr) {
507 if(min_lm==
nullptr) {
509 fprintf(stderr,
"Couldn't find split point!\n");
515 COLA_ASSERT(min_lm!=
nullptr);
524 for (
Cit c=v->in.begin();
c!=v->in.end();++
c) {
528 for (
Cit c=v->out.begin();
c!=v->out.end();++
c) {
538 if(u==v)
return true;
561 if(u==v)
return true;
573 if(u==v)
return true;
592#ifdef LIBVPSC_LOGGING
593 ofstream f(LOGFILE,ios::app);
594 f<<
" need to split between: "<<*vl<<
" and "<<*vr<<endl;
597#ifdef LIBVPSC_LOGGING
598 f<<
" going to split on: "<<*
c<<endl;
629 double diff = (*v)->position() - (*v)->desiredPosition;
630 c += (*v)->weight * diff * diff;
634std::ostream& operator <<(std::ostream &os,
const Block& b)
636 os<<
"Block(posn="<<b.
posn<<
"):";
PairNode< T > * insert(const T &x)
Insert item x into the priority queue, maintaining heap order.
void setUpConstraintHeap(PairingHeap< Constraint *, CompareConstraints > *&h, bool in)
void populateSplitBlock(Block *b, Variable *v, Variable const *u)
bool canFollowRight(Constraint const *c, Variable const *last) const
PairingHeap< Constraint *, CompareConstraints > * in
void merge(Block *b, Constraint *c, double dist)
double compute_dfdv(Variable *const v, Variable *const u)
Block(Blocks *blocks, Variable *const v=nullptr)
Constraint * splitBetween(Variable *vl, Variable *vr, Block *&lb, Block *&rb)
Constraint * findMinLMBetween(Variable *const lv, Variable *const rv)
void setUpOutConstraints()
void reset_active_lm(Variable *const v, Variable *const u)
bool isActiveDirectedPathBetween(Variable const *u, Variable const *v) const
bool canFollowLeft(Constraint const *c, Variable const *last) const
void deleteMinInConstraint()
void split(Block *&l, Block *&r, Constraint *c)
Constraint * findMinOutConstraint()
void updateWeightedPosition()
void addVariable(Variable *v)
bool getActiveDirectedPathBetween(Constraints &path, Variable const *u, Variable const *v) const
Constraint * findMinInConstraint()
void deleteMinOutConstraint()
std::vector< Constraint * > Constraints
bool getActivePathBetween(Constraints &path, Variable const *u, Variable const *v, Variable const *w) const
bool split_path(Variable *, Variable *const, Variable *const, Constraint *&min_lm, bool desperation)
Constraints::iterator Cit
Constraints::const_iterator Cit_const
void list_active(Variable *const v, Variable *const u)
void setUpInConstraints()
PairingHeap< Constraint *, CompareConstraints > * out
A constraint determines a minimum or exact spacing required between two Variable objects.
A variable is comprised of an ideal position, final position and a weight.
libvpsc: Variable Placement with Separation Constraints quadratic program solver library.
void addVariable(Variable *const v)
std::vector< Constraint * > path