2 #include "linespace.hh"
6 #include "unionfind.hh"
7 #include "idealspacing.hh"
9 const Real COLFUDGE=1e-3;
11 //#define COLFUDGE 1e-3
13 Spacing_problem::contains(const PCol *w)
15 for (int i=0; i< cols.sz(); i++)
16 if (cols[i].pcol_ == w)
22 Spacing_problem::col_id(const PCol *w)const
24 for (int i=0; i< cols.sz(); i++)
25 if (cols[i].pcol_ == w)
32 Spacing_problem::OK() const
35 Union_find connected(cols.sz());
37 for (int i=0; i < ideals.sz(); i++) {
38 assert(ideals[i]->hooke > 0);
39 int l = col_id(ideals[i]->left);
40 int r = col_id(ideals[i]->right);
41 connected.connect(l,r);
43 for (int i = 0; i < cols.sz(); i++)
46 for (int i = 0; i < cols.sz(); i++) {
48 for (int j =0; j<fixed.sz(); j++)
49 c |= connected.equiv(j,i);
56 Spacing_problem::check_constraints(Vector v) const
59 // mtor << "checking solution " << v << '\n';
60 for (int i=0; i < dim; i++) {
62 if (cols[i].fixed()&& abs(cols[i].fixed_position() - v(i)) > COLFUDGE) {
68 Real mindist=cols[i-1].minright()
72 Real dif =v(i) - v(i-1)- mindist;
73 bool b = (dif > - COLFUDGE);
81 mtor << "dif= "<<dif<<" fudge= " << COLFUDGE<< " dif >fudge= "<<
84 /* fucks up for unknown reasons */
94 Spacing_problem::check_feasible() const
96 Vector sol(try_initial_solution());
97 return check_constraints(sol);
100 // generate a solution which obeys the min distances and fixed positions
102 Spacing_problem::try_initial_solution() const
106 for (int i=0; i < dim; i++) {
107 if (cols[i].fixed()) {
108 initsol(i)=cols[i].fixed_position();
110 Real mindist=cols[i-1].minright()
112 assert(mindist >= 0.0);
113 initsol(i)=initsol(i-1)+mindist;
117 // assert(initsol(i) > initsol(i-1));
124 Spacing_problem::find_initial_solution() const
126 Vector v(try_initial_solution());
127 assert(check_constraints(v));
131 // generate the matrices
133 Spacing_problem::make_matrices(Matrix &quad, Vector &lin, Real &c) const
138 for (int j=0; j < ideals.sz(); j++){
139 Idealspacing const*i=ideals[j];
140 int l = col_id(i->left);
141 int r = col_id(i->right);
143 quad(r,r) += i->hooke;
144 quad(r,l) -= i->hooke;
145 quad(l,r) -= i->hooke;
146 quad(l,l) += i->hooke;
148 lin(r) -= i->space*i->hooke;
149 lin(l) += i->space*i->hooke;
155 // put the constraints into the LP problem
157 Spacing_problem::make_constraints(Mixed_qp& lp) const
160 for (int j=0; j < dim; j++) {
161 Colinfo *c=&(cols[j]);
163 lp.add_fixed_var(j,c->fixed_position());
170 lp.add_inequality_cons(c1, cols[j-1].minright() +
177 Spacing_problem::solve() const
181 assert(check_feasible());
183 /* optimalisatiefunctie */
184 Mixed_qp lp(cols.sz());
185 make_matrices(lp.quad,lp.lin, lp.const_term);
186 make_constraints(lp);
187 Vector start=find_initial_solution();
188 Vector sol(lp.solve(start));
189 if (!check_constraints(sol)) {
190 WARN << "solution doesn't satisfy constraints.\n" ;
194 svec<Real> posns(sol);
195 posns.add(lp.eval(sol));
200 add one column to the problem.
203 Spacing_problem::add_column(const PCol *col, bool fixed, Real fixpos)
205 Colinfo c(col,(fixed)? &fixpos : 0);
210 Spacing_problem::add_ideal(const Idealspacing *i)
212 const PCol *l =i->left;
213 const PCol *r= i->right;
215 if (!contains(l) || !contains(r)) {
222 Spacing_problem::print_ideal(const Idealspacing*id)const
225 int l = col_id(id->left);
226 int r = col_id(id->right);
228 mtor << "between " << l <<","<<r<<":" ;
234 Spacing_problem::print() const
237 for (int i=0; i < cols.sz(); i++) {
238 mtor << "col " << i<<' ';
241 for (int i=0; i < ideals.sz(); i++) {
242 print_ideal(ideals[i]);
251 Colinfo::print() const
256 mtor << "fixed at " << fixed_position()<<", ";
258 mtor << "[" << minleft() << ", " << minright() << "]";
263 Colinfo::Colinfo(Colinfo const&c)
265 fixpos = (c.fixpos)?new Real(*c.fixpos):0;
270 Colinfo::Colinfo(const PCol*col_p, const Real*fixed_r_p )
272 fixpos = (fixed_r_p)? new Real(*fixed_r_p) : 0;
274 width = pcol_->width();
288 Colinfo::operator=(Colinfo const&c )
291 fixpos = (c.fixpos)?new Real(*c.fixpos):0;