summaryrefslogtreecommitdiff
path: root/src/qlp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/qlp.cc')
-rw-r--r--src/qlp.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/qlp.cc b/src/qlp.cc
new file mode 100644
index 0000000000..3dd8e4227e
--- /dev/null
+++ b/src/qlp.cc
@@ -0,0 +1,147 @@
+#include "debug.hh"
+#include "const.hh"
+#include "qlp.hh"
+#include "choleski.hh"
+
+void
+Mixed_qp::add_equality_cons(Vector , double )
+{
+ assert(false);
+}
+
+void
+Mixed_qp::add_fixed_var(int i, Real r)
+{
+ eq_cons.add(i);
+ eq_consrhs.add(r);
+}
+
+void
+Ineq_constrained_qp::add_inequality_cons(Vector c, double r)
+{
+ cons.add(c);
+ consrhs.add(r);
+}
+
+Ineq_constrained_qp::Ineq_constrained_qp(int novars):
+ quad(novars),
+ lin(novars)
+{
+}
+
+void
+Ineq_constrained_qp::OK() const
+{
+#ifndef NDEBUG
+ assert(cons.sz() == consrhs.sz());
+ Matrix Qdif= quad - quad.transposed();
+ assert(Qdif.norm()/quad.norm() < EPS);
+#endif
+}
+
+
+Real
+Ineq_constrained_qp::eval (Vector v)
+{
+ return v * quad * v + lin * v + const_term;
+}
+/*
+ eliminate appropriate variables, until we have a Ineq_constrained_qp
+ then solve that.
+
+ PRE
+ cons should be ascending
+ */
+Vector
+Mixed_qp::solve(Vector start) const
+{
+ print();
+ Ineq_constrained_qp pure(*this);
+
+ for (int i= eq_cons.sz()-1; i>=0; i--) {
+ pure.eliminate_var(eq_cons[i], eq_consrhs[i]);
+ start.del(eq_cons[i]);
+ }
+ Vector sol = pure.solve(start);
+ for (int i= 0; i < eq_cons.sz(); i++) {
+ sol.insert( eq_consrhs[i],eq_cons[i]);
+ }
+ return sol;
+}
+
+/*
+ assume x(idx) == value, and adjust constraints, lin and quad accordingly
+ */
+void
+Ineq_constrained_qp::eliminate_var(int idx, Real value)
+{
+ Vector row(quad.row(idx));
+ row*= value;
+
+ quad.delete_row(idx);
+
+ quad.delete_column(idx);
+
+ lin.del(idx);
+ row.del(idx);
+ lin +=row ;
+
+ for (int i=0; i < cons.sz(); i++) {
+ consrhs[i] -= cons[i](idx) *value;
+ cons[i].del(idx);
+ }
+}
+
+
+
+
+Mixed_qp::Mixed_qp(int n)
+ : Ineq_constrained_qp(n)
+{
+}
+
+void
+Mixed_qp::OK() const
+{
+#ifndef NDEBUG
+ Ineq_constrained_qp::OK();
+ assert(eq_consrhs.sz() == eq_cons.sz());
+#endif
+}
+void
+Ineq_constrained_qp::print() const
+{
+#ifndef NPRINT
+ mtor << "Quad " << quad;
+ mtor << "lin " << lin <<"\n";
+ for (int i=0; i < cons.sz(); i++) {
+ mtor << "constraint["<<i<<"]: " << cons[i] << " >= " << consrhs[i];
+ mtor << "\n";
+ }
+#endif
+}
+void
+Mixed_qp::print() const
+{
+#ifndef NPRINT
+ Ineq_constrained_qp::print();
+ for (int i=0; i < eq_cons.sz(); i++) {
+ mtor << "eq cons "<<i<<": x["<<eq_cons[i]<<"] == " << eq_consrhs[i]<<"\n";
+ }
+#endif
+}
+
+
+void
+Ineq_constrained_qp::assert_solution(Vector sol) const
+{
+ svec<int> binding;
+ for (int i=0; i < cons.sz(); i++) {
+ Real R=cons[i] * sol- consrhs[i];
+ assert(R> -EPS);
+ if (R < EPS)
+ binding.add(i);
+ }
+ // KKT check...
+ // todo
+}