summaryrefslogtreecommitdiff
path: root/lily/qlp.cc
blob: 6625b68babdf7140258b8f8f851c524e5016aa89 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
  qlp.cc -- implement Mixed_qp

  source file of the GNU LilyPond music typesetter

  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
*/

#include "debug.hh"
#include "qlp.hh"

void
Mixed_qp::add_equality_cons (Vector , double)
{
    assert (false);
}

void
Mixed_qp::add_fixed_var (int i, Real r)
{
    eq_cons.push (i);
    eq_consrhs.push (r);
}


/**
    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 
{
    if (!dim())
	return Vector (0);
    
    print();
    Ineq_constrained_qp pure (*this);
    
    for  (int i= eq_cons.size()-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.size(); i++) {
	sol.insert (eq_consrhs[i],eq_cons[i]);
    }
    return sol;
}


void
Ineq_constrained_qp::assert_solution (Vector sol) const
{
    Array<int> binding;
    for (int i=0; i < cons.size(); i++) {
	Real R=cons[i] * sol- consrhs[i];
	assert (R> -EPS);
	if (R < EPS)
	    binding.push (i);
    }
    // KKT check...
    // todo
}

void
Ineq_constrained_qp::print() const
{
#ifndef NPRINT
    DOUT << "Quad " << quad;
    DOUT << "lin " << lin <<"\n"
	<< "const " << const_term<<"\n";
    for (int i=0; i < cons.size(); i++) {
	DOUT << "constraint["<<i<<"]: " << cons[i] << " >= " << consrhs[i];
	DOUT << "\n";
    }
#endif
}

Mixed_qp::Mixed_qp (int n)
    : Ineq_constrained_qp (n)
{
}

void
Mixed_qp::OK() const
{
#ifndef NDEBUG
    Ineq_constrained_qp::OK();
    assert (eq_consrhs.size() == eq_cons.size ());
#endif    
}

void
Mixed_qp::print() const
{
#ifndef NPRINT
    Ineq_constrained_qp::print();
    for (int i=0; i < eq_cons.size(); i++) {
	DOUT << "eq cons "<<i<<": x["<<eq_cons[i]<<"] == " << eq_consrhs[i]<<"\n";
    }
#endif
}