Eigen  5.0.1
 
Loading...
Searching...
No Matches
GeneralizedSelfAdjointEigenSolver.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
13#define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
14
15#include "./Tridiagonalization.h"
16
17// IWYU pragma: private
18#include "./InternalHeaderCheck.h"
19
20namespace Eigen {
21
51template <typename MatrixType_>
54
55 public:
56 using MatrixType = MatrixType_;
57
65 GeneralizedSelfAdjointEigenSolver() : Base(), m_cholB(), m_matC() {}
66
79 explicit GeneralizedSelfAdjointEigenSolver(Index size) : Base(size), m_cholB(size), m_matC(size, size) {}
80
108 template <typename InputTypeA, typename InputTypeB>
110 int options = ComputeEigenvectors | Ax_lBx)
111 : Base(matA.cols()) {
112 compute(matA.derived(), matB.derived(), options);
113 }
114
129 template <typename InputTypeA, typename InputTypeB, bool IsRef = internal::is_ref<MatrixType>::value,
130 std::enable_if_t<IsRef, int> = 0>
132 int options = ComputeEigenvectors | Ax_lBx)
133 : Base(matA, typename Base::BindStorageTag()), m_cholB(matB.derived()), m_matC(matA.derived()) {
134 // Complete the upper triangle from the referenced lower one.
135 m_matC = m_matC.template selfadjointView<Lower>();
136 computeInPlace(options);
137 }
138
181 template <typename InputTypeA, typename InputTypeB>
183 int options = ComputeEigenvectors | Ax_lBx);
184
185 protected:
186 // Reused across compute() calls so that a solver constructed with its size,
187 // or computed with once, does not allocate again.
188 LLT<MatrixType> m_cholB;
189 MatrixType m_matC;
190
191 private:
192 GeneralizedSelfAdjointEigenSolver& computeInPlace(int options);
193};
194
195template <typename MatrixType>
196template <typename InputTypeA, typename InputTypeB>
198 const EigenBase<InputTypeA>& matA, const EigenBase<InputTypeB>& matB, int options) {
199 eigen_assert(matA.cols() == matA.rows() && matB.rows() == matA.rows() && matB.cols() == matB.rows());
200
201 // Compute the cholesky decomposition of matB = L L' = U'U
202 m_cholB.compute(matB.derived());
203 m_matC = matA.derived().template selfadjointView<Lower>();
204 return computeInPlace(options);
205}
206
209template <typename MatrixType>
210GeneralizedSelfAdjointEigenSolver<MatrixType>& GeneralizedSelfAdjointEigenSolver<MatrixType>::computeInPlace(
211 int options) {
212 eigen_assert(m_matC.cols() == m_matC.rows() && m_cholB.rows() == m_matC.rows());
213 eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
214 ((options & GenEigMask) == 0 || (options & GenEigMask) == Ax_lBx || (options & GenEigMask) == ABx_lx ||
215 (options & GenEigMask) == BAx_lx) &&
216 "invalid option parameter");
217
218 bool computeEigVecs = ((options & EigVecMask) == 0) || ((options & EigVecMask) == ComputeEigenvectors);
219
220 int type = (options & GenEigMask);
221 if (type == 0) type = Ax_lBx;
222
223 // In the inplace decomposition the eigenvector storage is the matrix A itself, i.e. m_matC: the products of the
224 // ABx_lx and BAx_lx forms, which cannot run in place, then go through a temporary instead.
225 const bool eivecIsMatC = internal::is_same_dense(Base::m_eivec, m_matC);
226
227 if (type == Ax_lBx) {
228 // compute C = inv(L) A inv(L')
229 m_cholB.matrixL().template solveInPlace<OnTheLeft>(m_matC);
230 m_cholB.matrixU().template solveInPlace<OnTheRight>(m_matC);
231
232 Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);
233
234 // transform back the eigen vectors: evecs = inv(U) * evecs
235 if (computeEigVecs) m_cholB.matrixU().solveInPlace(Base::m_eivec);
236 } else if (type == ABx_lx) {
237 // compute C = L' A L, using Base::m_eivec for the intermediate product: Base::compute()
238 // overwrites it before reading it.
239 if (eivecIsMatC) {
240 typename Base::PlainMatrixType tmp = m_matC * m_cholB.matrixL();
241 m_matC.noalias() = m_cholB.matrixU() * tmp;
242 } else {
243 Base::m_eivec.noalias() = m_matC * m_cholB.matrixL();
244 m_matC.noalias() = m_cholB.matrixU() * Base::m_eivec;
245 }
246
247 Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);
248
249 // transform back the eigen vectors: evecs = inv(U) * evecs
250 if (computeEigVecs) m_cholB.matrixU().solveInPlace(Base::m_eivec);
251 } else if (type == BAx_lx) {
252 // compute C = L' A L
253 if (eivecIsMatC) {
254 typename Base::PlainMatrixType tmp = m_matC * m_cholB.matrixL();
255 m_matC.noalias() = m_cholB.matrixU() * tmp;
256 } else {
257 Base::m_eivec.noalias() = m_matC * m_cholB.matrixL();
258 m_matC.noalias() = m_cholB.matrixU() * Base::m_eivec;
259 }
260
261 Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);
262
263 // transform back the eigen vectors: evecs = L * evecs, using m_matC as the
264 // intermediate: Base::compute() has consumed it.
265 if (computeEigVecs) {
266 if (eivecIsMatC) {
267 Base::m_eivec = m_cholB.matrixL() * Base::m_eivec;
268 } else {
269 m_matC.noalias() = m_cholB.matrixL() * Base::m_eivec;
270 Base::m_eivec = m_matC;
271 }
272 }
273 }
274
275 // The reduction above is only valid for a positive definite B.
276 if (m_cholB.info() != Success) Base::m_info = NumericalIssue;
277
278 return *this;
279}
280
281} // end namespace Eigen
282
283#endif // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
Computes eigenvalues and eigenvectors of the generalized selfadjoint eigen problem.
Definition GeneralizedSelfAdjointEigenSolver.h:52
GeneralizedSelfAdjointEigenSolver()
Default constructor for fixed-size matrices.
Definition GeneralizedSelfAdjointEigenSolver.h:65
GeneralizedSelfAdjointEigenSolver(Index size)
Constructor, pre-allocates memory for dynamic-size matrices.
Definition GeneralizedSelfAdjointEigenSolver.h:79
GeneralizedSelfAdjointEigenSolver(const EigenBase< InputTypeA > &matA, const EigenBase< InputTypeB > &matB, int options=ComputeEigenvectors|Ax_lBx)
Constructor; computes generalized eigendecomposition of given matrix pencil.
Definition GeneralizedSelfAdjointEigenSolver.h:109
GeneralizedSelfAdjointEigenSolver & compute(const EigenBase< InputTypeA > &matA, const EigenBase< InputTypeB > &matB, int options=ComputeEigenvectors|Ax_lBx)
Computes generalized eigendecomposition of given matrix pencil.
GeneralizedSelfAdjointEigenSolver(EigenBase< InputTypeA > &matA, EigenBase< InputTypeB > &matB, int options=ComputeEigenvectors|Ax_lBx)
Constructor for inplace decomposition .
Definition GeneralizedSelfAdjointEigenSolver.h:131
Standard Cholesky decomposition (LL^T) of a matrix and associated features.
Definition LLT.h:85
SelfAdjointEigenSolver()
Default constructor for fixed-size matrices.
Definition SelfAdjointEigenSolver.h:140
Eigen::Index Index
Definition SelfAdjointEigenSolver.h:95
@ NumericalIssue
Definition Constants.h:459
@ Success
Definition Constants.h:457
@ Ax_lBx
Definition Constants.h:411
@ ComputeEigenvectors
Definition Constants.h:406
@ BAx_lx
Definition Constants.h:417
@ ABx_lx
Definition Constants.h:414
@ EigenvaluesOnly
Definition Constants.h:403
Definition EigenBase.h:34
constexpr Index cols() const noexcept
Definition EigenBase.h:62
constexpr Derived & derived()
Definition EigenBase.h:50
constexpr Index rows() const noexcept
Definition EigenBase.h:60