lilypond-1.5.2
[lilypond.git] / flower / choleski.cc
blobae40c456130acf49f31ed43cf43784930deeb756
1 /*
2 choleski.cc -- implement Choleski_decomposition
4 source file of the Flower Library
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "choleski.hh"
10 const Real EPS = 1e-7; // so sue me. Hard coded
12 // for testing new Matrix_storage.
13 //#define PARANOID
15 void
16 Choleski_decomposition::full_matrix_solve (Vector &out, Vector const &rhs) const
18 int n= rhs.dim();
19 assert (n == L.dim());
20 Vector y;
21 y.set_dim (n);
22 out.set_dim (n);
24 // forward substitution
25 for (int i=0; i < n; i++)
27 Real sum (0.0);
28 for (int j=0; j < i; j++)
29 sum += y (j) * L(i,j);
30 y (i) = (rhs (i) - sum)/L(i,i);
33 for (int i=0; i < n; i++)
34 y (i) /= D(i);
36 // backward subst
37 Vector &x (out); // using input as return val.
38 for (int i=n-1; i >= 0; i--)
40 Real sum (0.0);
41 for (int j=i+1; j < n; j++)
42 sum += L(j,i)*x (j);
43 x (i) = (y (i) - sum)/L(i,i);
47 void
48 Choleski_decomposition::band_matrix_solve (Vector &out, Vector const &rhs) const
50 int n= rhs.dim();
51 int b = L.band_i();
52 assert (n == L.dim());
54 out.set_dim (n);
56 Vector y;
57 y.set_dim (n);
59 // forward substitution
60 for (int i=0; i < n; i++)
62 Real sum (0.0);
63 for (int j= 0 >? i - b; j < i; j++)
64 sum += y (j) * L(i,j);
65 y (i) = (rhs (i) - sum)/L(i,i);
67 for (int i=0; i < n; i++)
68 y (i) /= D(i);
70 // backward subst
71 Vector &x (out); // using input as return val.
72 for (int i=n-1; i >= 0; i--)
74 Real sum (0.0);
75 for (int j=i+1; j <= i + b&&j < n ; j++)
76 sum += L(j,i)*x (j);
77 x (i) = (y (i) - sum)/L(i,i);
81 void
82 Choleski_decomposition::solve (Vector &x, Vector const &rhs) const
84 if (band_b_)
86 band_matrix_solve (x,rhs);
88 else
89 full_matrix_solve (x,rhs);
92 Vector
93 Choleski_decomposition::solve (Vector rhs) const
95 Vector r;
96 solve (r, rhs);
97 return r;
100 void
101 Choleski_decomposition::full_matrix_decompose (Matrix const & P)
104 int n = P.dim();
105 L.unit();
106 for (int k= 0; k < n; k++)
108 for (int j = 0; j < k; j++)
110 Real sum (0.0);
111 for (int l=0; l < j; l++)
112 sum += L(k,l)*L(j,l)*D(l);
113 L(k,j) = (P(k,j) - sum)/D(j);
115 Real sum=0.0;
117 for (int l=0; l < k; l++)
118 sum += sqr (L(k,l))*D(l);
119 Real d = P(k,k) - sum;
120 D(k) = d;
125 void
126 Choleski_decomposition::band_matrix_decompose (Matrix const &P)
128 int n = P.dim();
129 int b = P.band_i();
130 L.unit();
132 for (int i= 0; i < n; i++)
134 for (int j = 0 >? i - b; j < i; j++)
136 Real sum (0.0);
137 for (int l=0 >? i - b; l < j; l++)
138 sum += L(i,l)*L(j,l)*D(l);
139 L(i,j) = (P(i,j) - sum)/D(j);
141 Real sum=0.0;
143 for (int l=0 >? i - b; l < i; l++)
144 sum += sqr (L(i,l))*D(l);
145 Real d = P(i,i) - sum;
146 D(i) = d;
148 L.set_band();
149 band_b_ = true;
156 Standard matrix algorithm.
159 Choleski_decomposition::Choleski_decomposition (Matrix const & P)
160 : L(P.dim()), D(P.dim ())
162 #ifdef PARANOID
163 assert ((P-P.transposed()).norm ()/P.norm () < EPS);
164 #endif
165 band_b_ = false;
167 int b = P.calc_band_i ();
169 if (b <= P.dim ()/2)
170 band_matrix_decompose (P);
171 else
172 full_matrix_decompose (P);
174 #ifdef PARANOID
175 assert ((original()-P).norm () / P.norm () < EPS);
176 #endif
179 Matrix
180 Choleski_decomposition::original() const
182 Matrix T(L.dim());
183 T.set_diag (D);
184 return L*T*L.transposed();
187 Matrix
188 Choleski_decomposition::inverse() const
190 int n=L.dim();
191 Matrix invm (n);
192 Vector e_i (n);
193 Vector inv (n);
194 for (int i = 0; i < n; i++)
196 e_i.set_unit (i);
197 solve (inv, e_i);
198 for (int j = 0 ; j<n; j++)
199 invm (i,j) = inv (j);
202 #ifdef PARANOID
203 Matrix I1(n), I2(original());
204 I1.unit();
205 assert ((I1-I2*invm).norm()/I2.norm () < EPS);
206 #endif
208 return invm;