CEDRIC  Revision_backup-2009-02
Cholesky.h
Go to the documentation of this file.
1 #ifndef REDUKT_CHOLESKY_H
2 #define REDUKT_CHOLESKY_H
3 
4 #include "math.h" // for sqrt()
5 
6 #include <boost/numeric/ublas/matrix.hpp> // replacement for TNT::Array2D
7 #include <boost/numeric/ublas/vector.hpp> // replacement for TNT::Array1D
8 
9 namespace ublas = boost::numeric::ublas;
10 
44 template<class ValueType>
45 class Cholesky
46 {
47  typedef ublas::matrix<ValueType> Matrix;
48  typedef ublas::vector<ValueType> Vector;
49 
50  Matrix L_; // lower triangular factor
51  int isspd; // 1 if matrix to be factored was SPD
52 
53 public:
54 
55  //~ Cholesky();
56  Cholesky(const Matrix &A);
57 
61  Matrix getL() const { return L_; }
62 
63 
74  Vector solve( const Vector &b )
75  {
76  int n = L_.dim1();
77  if (b.dim1() != n)
78  return Vector();
79 
80 
81  Vector x = b;
82 
83 
84  // Solve L*y = b;
85  for (int k = 0; k < n; k++)
86  {
87  for (int i = 0; i < k; i++)
88  x[k] -= x[i]*L_(k,i);
89  x[k] /= L_(k,k);
90 
91  }
92 
93  // Solve L'*X = Y;
94  for (int k = n-1; k >= 0; k--)
95  {
96  for (int i = k+1; i < n; i++)
97  x[k] -= x[i]*L_(i,k);
98  x[k] /= L_(k,k);
99  }
100 
101  return x;
102  }
103 
104 
115  Matrix solve(const Matrix &B)
116  {
117  int n = L_.dim1();
118  if (B.dim1() != n)
119  return Matrix();
120 
121 
122  Matrix X = B;
123  int nx = B.size2();
124 
125  // Solve L*y = b;
126  for (int j=0; j< nx; j++)
127  {
128  for (int k = 0; k < n; k++)
129  {
130  for (int i = 0; i < k; i++)
131  X(k,j) -= X(i,j)*L_(k,i);
132  X(k,j) /= L_(k,k);
133  }
134  }
135 
136  // Solve L'*X = Y;
137  for (int j=0; j<nx; j++)
138  {
139  for (int k = n-1; k >= 0; k--)
140  {
141  for (int i = k+1; i < n; i++)
142  X(k,j) -= X(i,j)*L_(i,k);
143  X(k,j) /= L_(k,k);
144  }
145  }
146 
147  return X;
148  }
149 
154  int is_spd() const { return isspd; }
155 
156 };
157 
158 //~ template <class ValueType>
159 //~ Cholesky<ValueType>::Cholesky() : L_(0,0), isspd(0) {}
160 
161 
168 template <class ValueType>
169 Cholesky<ValueType>::Cholesky( const ublas::matrix<ValueType> &A )
170 {
171  int m = A.size1();
172  int n = A.size2();
173 
174  isspd = (m == n);
175 
176  if (m != n)
177  {
178  L_ = Matrix(0,0);
179  return;
180  }
181 
182  L_ = Matrix(n,n);
183 
184 
185  // Main loop.
186  for (int j = 0; j < n; j++)
187  {
188  ValueType d(0.0);
189  for (int k = 0; k < j; k++)
190  {
191  ValueType s(0.0);
192  for (int i = 0; i < k; i++)
193  {
194  s += L_(k,i)*L_(j,i);
195  }
196  L_(j,k) = s = (A(j,k) - s)/L_(k,k);
197  d = d + s*s;
198  isspd = isspd && (A(k,j) == A(j,k));
199  }
200  d = A(j,j) - d;
201  isspd = isspd && (d > 0.0);
202  L_(j,j) = sqrt(d > 0.0 ? d : 0.0);
203  for (int k = j+1; k < n; k++)
204  {
205  L_(j,k) = 0.0;
206  }
207  }
208 }
209 
210 #endif
Definition: Cholesky.h:45
Vector solve(const Vector &b)
Definition: Cholesky.h:74
Matrix solve(const Matrix &B)
Definition: Cholesky.h:115
Cholesky(const Matrix &A)
Definition: Cholesky.h:169
int is_spd() const
Definition: Cholesky.h:154
Matrix getL() const
Definition: Cholesky.h:61