lilypond-1.3.12
[lilypond.git] / lily / qlpsolve.cc
blob3d64b3779289b4ccd58d559e1caa7375784483e9
1 /*
2 qlpsolve.cc -- implement Active_constraints, Inactive_iter
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 TODO:
9 try fixed point arithmetic, to speed up lily.
12 #include "ineq-constrained-qp.hh"
13 #include "qlpsolve.hh"
14 #include "debug.hh"
15 #include "choleski.hh"
17 const Real TOL=1e-1; // roughly 1/30 mm
19 String
20 Active_constraints::status() const
22 String s ("Active|Inactive [");
23 for (int i=0; i< active.size(); i++)
25 s += to_str (active[i]) + " ";
28 s+="| ";
29 for (int i=0; i< inactive.size(); i++)
31 s += to_str (inactive[i]) + " ";
33 s+="]";
35 return s;
38 void
39 Active_constraints::OK()
41 #ifndef NDEBUG
42 H.OK();
43 A.OK();
44 assert (active.size() +inactive.size () == opt->cons_.size ());
45 assert (H.dim() == opt->dim ());
46 assert (active.size() == A.rows ());
47 Array<int> allcons;
49 for (int i=0; i < opt->cons_.size(); i++)
50 allcons.push (0);
51 for (int i=0; i < active.size(); i++)
53 int j = active[i];
54 allcons[j]++;
56 for (int i=0; i < inactive.size(); i++)
58 int j = inactive[i];
59 allcons[j]++;
61 for (int i=0; i < allcons.size(); i++)
62 assert (allcons[i] == 1);
63 #endif
66 Vector
67 Active_constraints::get_lagrange (Vector gradient)
69 return (A*gradient);
72 void
73 Active_constraints::add_constraint (int k)
75 // add indices
76 int cidx=inactive[k];
78 Vector a (opt->cons_[cidx]);
79 // update of matrices
80 Vector Ha = H*a;
81 Real aHa = a*Ha;
82 Vector addrow (Ha.dim());
83 bool degenerate = (abs (aHa) < EPS);
85 if (degenerate)
87 warning (String ("Active_constraints::add ():")
88 + _("degenerate constraints"));
89 DOUT << "Ha = " << Ha.str () << '\n';
91 a != 0, so if Ha = O(EPS), then
92 Ha * aH / aHa = O(EPS^2/EPS)
94 if H*a == 0, the constraints are dependent.
96 degenerate_count_i_ ++;
98 if (!degenerate)
100 active.push (cidx);
101 inactive.swap (k,inactive.size()-1);
102 inactive.pop();
104 H -= Matrix (Ha/aHa , Ha);
106 addrow=Ha;
107 addrow /= aHa;
108 A -= Matrix (A*a, addrow);
109 A.insert_row (addrow,A.rows());
113 void
114 Active_constraints::drop_constraint (int k)
116 int q=active.size()-1;
119 Vector a (A.row (q));
120 if (a.norm() > EPS)
122 // drop indices
123 inactive.push (active[k]);
124 active.swap (k,q);
125 A.swap_rows (k,q);
126 active.pop();
130 Real aqa = a*opt->quad_*a;
131 Matrix aaq (a,a/aqa);
132 H += aaq;
133 A -= A*opt->quad_*aaq;
135 A.delete_row (q);
136 }else {
137 degenerate_count_i_ ++;
138 warning (String ("Active_constraints::drop ():")
139 + _("degenerate constraints"));
144 Active_constraints::Active_constraints (Ineq_constrained_qp const *op)
145 : A(0,op->dim()),
146 H(op->dim()),
147 opt (op)
149 for (int i=0; i < op->cons_.size(); i++)
150 inactive.push (i);
151 Choleski_decomposition chol (op->quad_);
154 ugh.
156 H=chol.inverse();
157 OK();
159 degenerate_count_i_ = 0;
162 /** Find the optimum which is in the planes generated by the active
163 constraints.
165 Vector
166 Active_constraints::find_active_optimum (Vector g)
168 return H*g;