PLaSK library
Loading...
Searching...
No Matches
jama_cholesky.h
Go to the documentation of this file.
1#ifndef JAMA_CHOLESKY_H
2#define JAMA_CHOLESKY_H
3
4#include "../tnt/tnt_array1d.h"
5#include "../tnt/tnt_array2d.h"
6
7#include <math.h>
8/* needed for sqrt() below. */
9
10namespace JAMA
11{
12
13using namespace TNT;
14
48template <class Real>
50{
51 Array2D<Real> L_; // lower triangular factor
52 int isspd; // 1 if matrix to be factored was SPD
53
54public:
55
56 Cholesky();
57 Cholesky(const Array2D<Real> &A);
58 Array2D<Real> getL() const;
61 int is_spd() const;
62
63};
64
65template <class Real>
66Cholesky<Real>::Cholesky() : L_(0,0), isspd(0) {}
67
72template <class Real>
74{
75 return isspd;
76}
77
81template <class Real>
83{
84 return L_;
85}
86
93template <class Real>
95{
96
97
98 int m = A.dim1();
99 int n = A.dim2();
100
101 isspd = (m == n);
102
103 if (m != n)
104 {
105 L_ = Array2D<Real>(0,0);
106 return;
107 }
108
109 L_ = Array2D<Real>(n,n);
110
111
112 // Main loop.
113 for (int j = 0; j < n; j++)
114 {
115 double d = 0.0;
116 for (int k = 0; k < j; k++)
117 {
118 Real s = 0.0;
119 for (int i = 0; i < k; i++)
120 {
121 s += L_[k][i]*L_[j][i];
122 }
123 L_[j][k] = s = (A[j][k] - s)/L_[k][k];
124 d = d + s*s;
125 isspd = isspd && (A[k][j] == A[j][k]);
126 }
127 d = A[j][j] - d;
128 isspd = isspd && (d > 0.0);
129 L_[j][j] = sqrt(d > 0.0 ? d : 0.0);
130 for (int k = j+1; k < n; k++)
131 {
132 L_[j][k] = 0.0;
133 }
134 }
135}
136
147template <class Real>
149{
150 int n = L_.dim1();
151 if (b.dim1() != n)
152 return Array1D<Real>();
153
154
155 Array1D<Real> x = b.copy();
156
157
158 // Solve L*y = b;
159 for (int k = 0; k < n; k++)
160 {
161 for (int i = 0; i < k; i++)
162 x[k] -= x[i]*L_[k][i];
163 x[k] /= L_[k][k];
164
165 }
166
167 // Solve L'*X = Y;
168 for (int k = n-1; k >= 0; k--)
169 {
170 for (int i = k+1; i < n; i++)
171 x[k] -= x[i]*L_[i][k];
172 x[k] /= L_[k][k];
173 }
174
175 return x;
176}
177
178
189template <class Real>
191{
192 int n = L_.dim1();
193 if (B.dim1() != n)
194 return Array2D<Real>();
195
196
197 Array2D<Real> X = B.copy();
198 int nx = B.dim2();
199
200// Cleve's original code
201#if 0
202 // Solve L*Y = B;
203 for (int k = 0; k < n; k++) {
204 for (int i = k+1; i < n; i++) {
205 for (int j = 0; j < nx; j++) {
206 X[i][j] -= X[k][j]*L_[k][i];
207 }
208 }
209 for (int j = 0; j < nx; j++) {
210 X[k][j] /= L_[k][k];
211 }
212 }
213
214 // Solve L'*X = Y;
215 for (int k = n-1; k >= 0; k--) {
216 for (int j = 0; j < nx; j++) {
217 X[k][j] /= L_[k][k];
218 }
219 for (int i = 0; i < k; i++) {
220 for (int j = 0; j < nx; j++) {
221 X[i][j] -= X[k][j]*L_[k][i];
222 }
223 }
224 }
225#endif
226
227
228 // Solve L*y = b;
229 for (int j=0; j< nx; j++)
230 {
231 for (int k = 0; k < n; k++)
232 {
233 for (int i = 0; i < k; i++)
234 X[k][j] -= X[i][j]*L_[k][i];
235 X[k][j] /= L_[k][k];
236 }
237 }
238
239 // Solve L'*X = Y;
240 for (int j=0; j<nx; j++)
241 {
242 for (int k = n-1; k >= 0; k--)
243 {
244 for (int i = k+1; i < n; i++)
245 X[k][j] -= X[i][j]*L_[i][k];
246 X[k][j] /= L_[k][k];
247 }
248 }
249
250
251
252 return X;
253}
254
255
256}
257// namespace JAMA
258
259#endif
260// JAMA_CHOLESKY_H