All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IncrementalCholeskyDecomp.cxx
Go to the documentation of this file.
2 
4 
5 #include <cmath>
6 #include <iostream>
7 
8 namespace ana
9 {
10  // --------------------------------------------------------------------------
12  {
13  // First up, expand the decomp matrix
14  for(std::vector<double>& row: fUpper) row.push_back(0); // extend each row
15  fUpper.emplace_back(fUpper.size()+1, 0); // and add one more
16  }
17 
18  // --------------------------------------------------------------------------
19  void IncrementalCholeskyDecomp::SetLastRow(const std::vector<double>& row)
20  {
21  // Implementation based on https://en.wikipedia.org/wiki/Cholesky_decomposition#Adding_and_removing_rows_and_columns
22 
23  const unsigned int N = fUpper.size();
24 
25  // S11 = L11 -- true automatically
26 
27  // S12 = L11^T \ A12
28  for(unsigned int i = 0; i+1 < N; ++i){ // which row we're solving
29  double res = row[i];
30  for(unsigned int j = 0; j < i; ++j) res -= fUpper[j][i] * fUpper[j][N-1];
31  if(res != 0) fUpper[i][N-1] = res/fUpper[i][i];
32  }
33 
34  // S22 = chol(A22 - S12T S12)
35  double dot = 0;
36  for(unsigned int i = 0; i+1 < N; ++i) dot += util::sqr(fUpper[i][N-1]);
37  fUpper[N-1][N-1] = sqrt(row[N-1] - dot);
38  }
39 
40  // --------------------------------------------------------------------------
41  void IncrementalCholeskyDecomp::SetLastRow(const std::vector<double>& bigrow,
42  const std::vector<int>& idxs)
43  {
44  std::vector<double> row;
45  row.reserve(idxs.size());
46  for(int i: idxs) row.push_back(bigrow[i]);
47  SetLastRow(row);
48  }
49 
50  // --------------------------------------------------------------------------
51  std::vector<double> IncrementalCholeskyDecomp::Solve(const std::vector<double>& b) const
52  {
53  const unsigned int N = fUpper.size();
54 
55  // Solve Ly = b
56  std::vector<double> y(N);
57 
58  for(unsigned int i = 0; i < N; ++i){ // which row we're solving
59  double res = b[i];
60  for(unsigned int j = 0; j < i; ++j) res -= fUpper[j][i] * y[j];
61  if(res != 0) y[i] = res/fUpper[i][i];
62  }
63 
64  // And now LTx = y
65  std::vector<double> x(N);
66 
67  for(int i = N-1; i >= 0; --i){
68  double res = y[i];
69  for(unsigned int j = i+1; j < N; ++j) res -= fUpper[i][j] * x[j];
70  if(res != 0) x[i] = res/fUpper[i][i];
71  }
72 
73  return x;
74  }
75 
76  // --------------------------------------------------------------------------
78  {
79  for(const std::vector<double>& row: fUpper){
80  for(double v: row) std::cout << v << "\t";
81  std::cout << std::endl;
82  }
83  }
84 }
constexpr auto dot(Vector const &a, Vector const &b)
Return cross product of two vectors.
process_name opflash particleana ie x
void Extend()
Add one row and column of zeros.
process_name opflashCryoW ana
std::vector< std::vector< double > > fUpper
T sqr(T x)
More efficient square function than pow(x,2)
Definition: MathUtil.h:23
process_name opflash particleana ie ie y
void SetLastRow(const std::vector< double > &row)
This is of course also the right-most column...
std::vector< double > Solve(const std::vector< double > &b) const
process_name largeant stream1 can override from command line with o or output physics producers generator N
BEGIN_PROLOG could also be cout