ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ConjugateGradient.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 // Local
11 #include "MathTools.h"
12 #include "SquareMatrix.h"
13 
14 namespace cloudViewer {
15 
17 
24 template <int N, class Scalar>
26 public:
29  memset(cg_Gn, 0, sizeof(Scalar) * N);
30  memset(cg_Hn, 0, sizeof(Scalar) * N);
31  memset(cg_u, 0, sizeof(Scalar) * N);
32  memset(cg_b, 0, sizeof(Scalar) * N);
33  }
34 
36  virtual ~ConjugateGradient() = default;
37 
40 
42  inline Scalar* b() { return cg_b; }
43 
45 
47  void initConjugateGradient(const Scalar* X0) {
48  // we init the Gn (residuals) and Hn vectors
49  // H0 = G0 = A.X0-b
50  cg_A.apply(X0, cg_Gn);
51  for (unsigned k = 0; k < N; ++k) cg_Hn[k] = (cg_Gn[k] -= cg_b[k]);
52  }
53 
55 
59  Scalar iterConjugateGradient(Scalar* Xn) {
60  // we compute Xn+1
61  cg_A.apply(cg_Hn, cg_u); // u = A.Hn
62 
63  unsigned k;
64  Scalar d = 0, e = 0, f = 0;
65  for (k = 0; k < N; ++k) {
66  d += cg_Hn[k] * cg_Gn[k]; // t^Hn.Gn
67  e += cg_Hn[k] * cg_u[k]; // t^Hn.A.Hn
68  f += cg_Gn[k] * cg_Gn[k]; // t^Gn.Gn (needed for Hn+1 - see below)
69  }
70 
71  // Xn+1 = Xn - Hn*(t^Hn.Gn)/(t^Hn.A.Hn)
72  d /= e;
73  for (k = 0; k < N; ++k) Xn[k] -= cg_Hn[k] * d;
74 
75  // we compute Gn+1
76  cg_A.apply(Xn, cg_u); // u = A.Xn+1
77  for (k = 0; k < N; ++k)
78  cg_Gn[k] = cg_u[k] - cg_b[k]; // Gn+1 =
79  // A.Xn+1-b
80 
81  // sum of square errors
82  e = cg_Gn[0] * cg_Gn[0];
83  for (k = 1; k < N; ++k) e += cg_Gn[k] * cg_Gn[k]; // t^Gn+1.Gn+1
84 
85  // we update Hn+1 for next iteration
86  d = e / f;
87  for (k = 0; k < N; ++k)
88  cg_Hn[k] =
89  cg_Gn[k] +
90  cg_Hn[k] * d; // Hn+1 = Gn+1 + Hn.(t^Gn+1.Gn+1)/(t^Gn.Gn)
91 
92  return e / N;
93  }
94 
95 protected:
97  Scalar cg_Gn[N];
98 
100 
102  Scalar cg_Hn[N];
103 
105 
107  Scalar cg_u[N];
108 
110 
112  Scalar cg_b[N];
113 
115 
118 };
119 
120 } // namespace cloudViewer
A class to perform a conjugate gradient optimization.
cloudViewer::SquareMatrixTpl< Scalar > cg_A
'A' matrix
Scalar iterConjugateGradient(Scalar *Xn)
Iterates the conjugate gradient.
cloudViewer::SquareMatrixTpl< Scalar > & A()
Returns A matrix.
virtual ~ConjugateGradient()=default
Default destructor.
void initConjugateGradient(const Scalar *X0)
Initializes the conjugate gradient.
Scalar cg_Gn[N]
Residuals vector.
ConjugateGradient()
Default constructor.
Scalar * b()
Returns b vector.
Empty class - for classification purpose only.
Definition: MathTools.h:15
Generic file read and write utility for python interface.