Orthogonalization.h
Go to the documentation of this file.
1 // Copyright (C) 2020 Netherlands eScience Center <f.zapata@esciencecenter.nl>
2 //
3 // This Source Code Form is subject to the terms of the Mozilla
4 // Public License v. 2.0. If a copy of the MPL was not distributed
5 // with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 
7 #ifndef SPECTRA_ORTHOGONALIZATION_H
8 #define SPECTRA_ORTHOGONALIZATION_H
9 
10 #include <Eigen/Core>
11 #include <Eigen/QR>
12 
13 namespace Spectra {
14 
20 template <typename Matrix>
21 void assert_left_cols_to_skip(Matrix& in_output, Eigen::Index left_cols_to_skip)
22 {
23  assert(in_output.cols() > left_cols_to_skip && "left_cols_to_skip is larger than columns of matrix");
24  assert(left_cols_to_skip >= 0 && "left_cols_to_skip is negative");
25 }
26 
32 template <typename Matrix>
33 Eigen::Index treat_first_col(Matrix& in_output, Eigen::Index left_cols_to_skip)
34 {
35  if (left_cols_to_skip == 0)
36  {
37  in_output.col(0).normalize();
38  left_cols_to_skip = 1;
39  }
40  return left_cols_to_skip;
41 }
42 
45 template <typename Matrix>
46 void QR_orthogonalisation(Matrix& in_output)
47 {
49  Eigen::Index nrows = in_output.rows();
50  Eigen::Index ncols = in_output.cols();
51  ncols = (std::min)(nrows, ncols);
52  InternalMatrix I = InternalMatrix::Identity(nrows, ncols);
54  in_output.leftCols(ncols).noalias() = qr.householderQ() * I;
55 }
56 
60 template <typename Matrix>
61 void MGS_orthogonalisation(Matrix& in_output, Eigen::Index left_cols_to_skip = 0)
62 {
63  assert_left_cols_to_skip(in_output, left_cols_to_skip);
64  left_cols_to_skip = treat_first_col(in_output, left_cols_to_skip);
65 
66  for (Eigen::Index k = left_cols_to_skip; k < in_output.cols(); ++k)
67  {
68  for (Eigen::Index j = 0; j < k; j++)
69  {
70  in_output.col(k) -= in_output.col(j).dot(in_output.col(k)) * in_output.col(j);
71  }
72  in_output.col(k).normalize();
73  }
74 }
75 
79 template <typename Matrix>
80 void GS_orthogonalisation(Matrix& in_output, Eigen::Index left_cols_to_skip = 0)
81 {
82  assert_left_cols_to_skip(in_output, left_cols_to_skip);
83  left_cols_to_skip = treat_first_col(in_output, left_cols_to_skip);
84 
85  for (Eigen::Index j = left_cols_to_skip; j < in_output.cols(); ++j)
86  {
87  in_output.col(j) -= in_output.leftCols(j) * (in_output.leftCols(j).transpose() * in_output.col(j));
88  in_output.col(j).normalize();
89  }
90 }
91 
98 template <typename Matrix>
99 void subspace_orthogonalisation(Matrix& in_output, Eigen::Index left_cols_to_skip)
100 {
101  assert_left_cols_to_skip(in_output, left_cols_to_skip);
102  if (left_cols_to_skip == 0)
103  {
104  return;
105  }
106 
107  Eigen::Index right_cols_to_ortho = in_output.cols() - left_cols_to_skip;
108  in_output.rightCols(right_cols_to_ortho) -= in_output.leftCols(left_cols_to_skip) *
109  (in_output.leftCols(left_cols_to_skip).transpose() * in_output.rightCols(right_cols_to_ortho));
110 }
111 
118 template <typename Matrix>
119 void JensWehner_orthogonalisation(Matrix& in_output, Eigen::Index left_cols_to_skip = 0)
120 {
121  assert_left_cols_to_skip(in_output, left_cols_to_skip);
122 
123  Eigen::Index right_cols_to_ortho = in_output.cols() - left_cols_to_skip;
124  subspace_orthogonalisation(in_output, left_cols_to_skip);
125  Eigen::Ref<Matrix> right_cols = in_output.rightCols(right_cols_to_ortho);
126  QR_orthogonalisation(right_cols);
127 }
128 
132 template <typename Matrix>
133 void twice_is_enough_orthogonalisation(Matrix& in_output, Eigen::Index left_cols_to_skip = 0)
134 {
135  JensWehner_orthogonalisation(in_output, left_cols_to_skip);
136  JensWehner_orthogonalisation(in_output, left_cols_to_skip);
137 }
138 
139 } // namespace Spectra
140 
141 #endif // SPECTRA_ORTHOGONALIZATION_H
Spectra::twice_is_enough_orthogonalisation
void twice_is_enough_orthogonalisation(Matrix &in_output, Eigen::Index left_cols_to_skip=0)
Definition: Orthogonalization.h:133
Spectra::QR_orthogonalisation
void QR_orthogonalisation(Matrix &in_output)
Definition: Orthogonalization.h:46
Spectra::treat_first_col
Eigen::Index treat_first_col(Matrix &in_output, Eigen::Index left_cols_to_skip)
Definition: Orthogonalization.h:33
Spectra::assert_left_cols_to_skip
void assert_left_cols_to_skip(Matrix &in_output, Eigen::Index left_cols_to_skip)
Definition: Orthogonalization.h:21
ceres::Matrix
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > Matrix
Definition: gtsam/3rdparty/ceres/eigen.h:42
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
I
#define I
Definition: main.h:112
Spectra::GS_orthogonalisation
void GS_orthogonalisation(Matrix &in_output, Eigen::Index left_cols_to_skip=0)
Definition: Orthogonalization.h:80
Eigen::PlainObjectBase::rows
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:143
Eigen::Ref
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:281
qr
HouseholderQR< MatrixXf > qr(A)
Spectra::JensWehner_orthogonalisation
void JensWehner_orthogonalisation(Matrix &in_output, Eigen::Index left_cols_to_skip=0)
Definition: Orthogonalization.h:119
Spectra
Definition: LOBPCGSolver.h:19
Spectra::MGS_orthogonalisation
void MGS_orthogonalisation(Matrix &in_output, Eigen::Index left_cols_to_skip=0)
Definition: Orthogonalization.h:61
min
#define min(a, b)
Definition: datatypes.h:19
Spectra::subspace_orthogonalisation
void subspace_orthogonalisation(Matrix &in_output, Eigen::Index left_cols_to_skip)
Definition: Orthogonalization.h:99
Eigen::Matrix
The matrix class, also used for vectors and row-vectors.
Definition: 3rdparty/Eigen/Eigen/src/Core/Matrix.h:178
Eigen::HouseholderQR
Householder QR decomposition of a matrix.
Definition: ForwardDeclarations.h:273
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74


gtsam
Author(s):
autogenerated on Thu Apr 10 2025 03:02:20