Eigen  5.0.1
 
Loading...
Searching...
No Matches
SelfAdjointView.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_SELFADJOINTMATRIX_H
12#define EIGEN_SELFADJOINTMATRIX_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
34
35namespace internal {
36
37template <typename MatrixType, unsigned int UpLo>
38struct traits<SelfAdjointView<MatrixType, UpLo>> : traits<MatrixType> {
39 using MatrixTypeNested = typename ref_selector<MatrixType>::non_const_type;
40 using MatrixTypeNestedCleaned = remove_all_t<MatrixTypeNested>;
41 using ExpressionType = MatrixType;
42 using FullMatrixType = typename MatrixType::PlainObject;
43 enum {
44 Mode = UpLo | SelfAdjoint,
45 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
46 Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits | FlagsLvalueBit) &
47 (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved
48 };
49};
50
51} // namespace internal
52
53template <typename MatrixType_, unsigned int UpLo>
54class SelfAdjointView : public TriangularBase<SelfAdjointView<MatrixType_, UpLo> > {
55 public:
56 EIGEN_STATIC_ASSERT(UpLo == Lower || UpLo == Upper, SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY)
57
58 using MatrixType = MatrixType_;
59 using Base = TriangularBase<SelfAdjointView>;
60 using MatrixTypeNested = typename internal::traits<SelfAdjointView>::MatrixTypeNested;
61 using MatrixTypeNestedCleaned = typename internal::traits<SelfAdjointView>::MatrixTypeNestedCleaned;
62 using NestedExpression = MatrixTypeNestedCleaned;
63
65 using Scalar = typename internal::traits<SelfAdjointView>::Scalar;
67 using RealScalar = typename NumTraits<Scalar>::Real;
68 using StorageIndex = typename MatrixType::StorageIndex;
69
70 enum {
71 Mode = internal::traits<SelfAdjointView>::Mode,
72 Flags = internal::traits<SelfAdjointView>::Flags,
73 TransposeMode = ((int(Mode) & int(Upper)) ? Lower : 0) | ((int(Mode) & int(Lower)) ? Upper : 0)
74 };
75 using PlainObject = typename MatrixType::PlainObject;
76
77 EIGEN_DEVICE_FUNC explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) {}
78 using Base::operator*;
79 EIGEN_DEFAULT_COPY_CONSTRUCTOR(SelfAdjointView)
80
81
82 template <typename OtherDerived>
83 EIGEN_DEVICE_FUNC SelfAdjointView& operator=(const MatrixBase<OtherDerived>& other) {
84 m_matrix.template triangularView<UpLo>() = other;
85 return *this;
86 }
87
89 template <typename OtherDerived>
90 EIGEN_DEVICE_FUNC SelfAdjointView& operator=(const TriangularBase<OtherDerived>& other) {
91 other.evalToLazy(m_matrix);
92 return *this;
93 }
94
95 EIGEN_DEVICE_FUNC SelfAdjointView& operator=(const SelfAdjointView& other) {
96 return *this = static_cast<const Base&>(other);
97 }
98
100 template <typename OtherDerived>
101 EIGEN_DEVICE_FUNC SelfAdjointView& operator+=(const DenseBase<OtherDerived>& other) {
102 m_matrix.template triangularView<UpLo>() += other;
103 return *this;
104 }
105
107 template <typename OtherDerived>
108 EIGEN_DEVICE_FUNC SelfAdjointView& operator-=(const DenseBase<OtherDerived>& other) {
109 m_matrix.template triangularView<UpLo>() -= other;
110 return *this;
111 }
112
114 EIGEN_DEVICE_FUNC SelfAdjointView& operator*=(const Scalar& other) {
115 eigen_assert(numext::imag(other) == typename NumTraits<Scalar>::Real(0) &&
116 "SelfAdjointView in-place scaling requires a real scalar; "
117 "scaling only the stored triangle by a non-real scalar would "
118 "leave conj(other) on the unstored half.");
119 m_matrix.template triangularView<UpLo>() *= other;
120 return *this;
121 }
122
124 EIGEN_DEVICE_FUNC SelfAdjointView& operator/=(const Scalar& other) {
125 eigen_assert(numext::imag(other) == typename NumTraits<Scalar>::Real(0) &&
126 "SelfAdjointView in-place division requires a real scalar; "
127 "dividing only the stored triangle by a non-real scalar would "
128 "leave conj(other) on the unstored half.");
129 m_matrix.template triangularView<UpLo>() /= other;
130 return *this;
131 }
132
134 EIGEN_DEVICE_FUNC constexpr const MatrixTypeNestedCleaned& _expression() const noexcept { return m_matrix; }
135
136 EIGEN_DEVICE_FUNC constexpr const MatrixTypeNestedCleaned& nestedExpression() const noexcept { return m_matrix; }
137 EIGEN_DEVICE_FUNC constexpr MatrixTypeNestedCleaned& nestedExpression() noexcept { return m_matrix; }
138
139 EIGEN_DEVICE_FUNC const SelfAdjointView<
140 const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(MatrixType, Scalar, internal::scalar_product_op), UpLo>
141 operator*(const Scalar& s) const {
142 return (nestedExpression() * s).template selfadjointView<UpLo>();
143 }
144
145 friend EIGEN_DEVICE_FUNC const SelfAdjointView<
146 const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar, MatrixType, internal::scalar_product_op), UpLo>
147 operator*(const Scalar& s, const SelfAdjointView& mat) {
148 return (s * mat.nestedExpression()).template selfadjointView<UpLo>();
149 }
150
161 template <typename DerivedU, typename DerivedV>
162 EIGEN_DEVICE_FUNC SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v,
163 const Scalar& alpha = Scalar(1));
164
175 template <typename DerivedU>
176 EIGEN_DEVICE_FUNC SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
177
189 template <unsigned int TriMode>
190 EIGEN_DEVICE_FUNC
191 std::conditional_t<(TriMode & (Upper | Lower)) == (UpLo & (Upper | Lower)), TriangularView<MatrixType, TriMode>,
194 std::conditional_t<(TriMode & (Upper | Lower)) == (UpLo & (Upper | Lower)), MatrixType&,
195 typename MatrixType::ConstTransposeReturnType>
196 tmp1(m_matrix);
197 std::conditional_t<(TriMode & (Upper | Lower)) == (UpLo & (Upper | Lower)), MatrixType&,
198 typename MatrixType::AdjointReturnType>
199 tmp2(tmp1);
200 return std::conditional_t<(TriMode & (Upper | Lower)) == (UpLo & (Upper | Lower)),
203 }
204
210 EIGEN_DEVICE_FUNC typename MatrixType::ConstDiagonalReturnType diagonal() const {
211 return typename MatrixType::ConstDiagonalReturnType(m_matrix);
212 }
213
219 EIGEN_DEVICE_FUNC RealScalar l1Norm() const { return internal::selfadjoint_l1_norm<UpLo>(m_matrix); }
220
222
226
228
231
232 EIGEN_DEVICE_FUNC EigenvaluesReturnType eigenvalues() const;
233 EIGEN_DEVICE_FUNC RealScalar operatorNorm() const;
234
235 protected:
236 MatrixTypeNested m_matrix;
237};
238
239// selfadjoint to dense matrix
240
241namespace internal {
242
243// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
244// in the future selfadjoint-ness should be defined by the expression traits
245// such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to
246// make it work)
247template <typename MatrixType, unsigned int Mode>
248struct evaluator_traits<SelfAdjointView<MatrixType, Mode> > {
249 using Kind = typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind;
250 using Shape = SelfAdjointShape;
251};
252
253template <int UpLo, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor,
254 int Version>
255class triangular_dense_assignment_kernel<UpLo, SelfAdjoint, SetOpposite, DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor,
256 Version>
257 : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> {
258 protected:
259 using Base = generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>;
260 using DstXprType = typename Base::DstXprType;
261 using SrcXprType = typename Base::SrcXprType;
262 using Base::m_dst;
263 using Base::m_functor;
264 using Base::m_src;
265
266 public:
267 using DstEvaluatorType = typename Base::DstEvaluatorType;
268 using SrcEvaluatorType = typename Base::SrcEvaluatorType;
269 using Scalar = typename Base::Scalar;
270 using AssignmentTraits = typename Base::AssignmentTraits;
271
272 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType& dst, const SrcEvaluatorType& src,
273 const Functor& func, DstXprType& dstExpr)
274 : Base(dst, src, func, dstExpr) {}
275
276 EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col) {
277 eigen_internal_assert(row != col);
278 Scalar tmp = m_src.coeff(row, col);
279 m_functor.assignCoeff(m_dst.coeffRef(row, col), tmp);
280 m_functor.assignCoeff(m_dst.coeffRef(col, row), numext::conj(tmp));
281 }
282
283 // Override to ensure the SelfAdjoint assignCoeff (which mirrors conjugates) is called,
284 // not the base class version (which is a plain copy).
285 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeffByOuterInner(Index outer, Index inner) {
286 Index row = Base::rowIndexByOuterInner(outer, inner);
287 Index col = Base::colIndexByOuterInner(outer, inner);
288 assignCoeff(row, col);
289 }
290
291 EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id) { Base::assignCoeff(id, id); }
292
293 EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index, Index) { eigen_internal_assert(false && "should never be called"); }
294};
295
296} // end namespace internal
297
298/***************************************************************************
299 * Implementation of MatrixBase methods
300 ***************************************************************************/
301
303template <typename Derived>
304template <unsigned int UpLo>
305EIGEN_DEVICE_FUNC constexpr typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
306MatrixBase<Derived>::selfadjointView() const {
307 return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
308}
309
320template <typename Derived>
321template <unsigned int UpLo>
322EIGEN_DEVICE_FUNC constexpr typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
323MatrixBase<Derived>::selfadjointView() {
324 return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
325}
326
327} // end namespace Eigen
328
329#endif // EIGEN_SELFADJOINTMATRIX_H
Bunch-Kaufman factorization of a symmetric / Hermitian indefinite matrix.
Definition BunchKaufman.h:75
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:45
Robust Cholesky decomposition of a matrix with pivoting.
Definition LDLT.h:67
Standard Cholesky decomposition (LL^T) of a matrix and associated features.
Definition LLT.h:85
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Expression of a selfadjoint matrix from a triangular part of a dense matrix.
Definition SelfAdjointView.h:54
RealScalar operatorNorm() const
Computes the L2 operator norm.
Definition MatrixBaseEigenvalues.h:136
BunchKaufman< PlainObject, UpLo > bunchKaufman() const
Definition BunchKaufman.h:1108
std::conditional_t<(TriMode &(Upper|Lower))==(UpLo &(Upper|Lower)), TriangularView< MatrixType, TriMode >, TriangularView< typename MatrixType::AdjointReturnType, TriMode > > triangularView() const
Definition SelfAdjointView.h:193
SelfAdjointView & operator+=(const DenseBase< OtherDerived > &other)
Definition SelfAdjointView.h:101
SelfAdjointView & rankUpdate(const MatrixBase< DerivedU > &u, const MatrixBase< DerivedV > &v, const Scalar &alpha=Scalar(1))
LDLT< PlainObject, UpLo > ldlt() const
Definition LDLT.h:750
typename internal::traits< SelfAdjointView >::Scalar Scalar
Definition SelfAdjointView.h:65
LLT< PlainObject, UpLo > llt() const
Definition LLT.h:672
SelfAdjointView & operator/=(const Scalar &other)
Definition SelfAdjointView.h:124
typename NumTraits< Scalar >::Real RealScalar
Definition SelfAdjointView.h:67
SelfAdjointView & operator=(const MatrixBase< OtherDerived > &other)
Definition SelfAdjointView.h:83
Matrix< RealScalar, internal::traits< MatrixType >::ColsAtCompileTime, 1 > EigenvaluesReturnType
Definition SelfAdjointView.h:230
SelfAdjointView & operator=(const TriangularBase< OtherDerived > &other)
Definition SelfAdjointView.h:90
SelfAdjointView & operator*=(const Scalar &other)
Definition SelfAdjointView.h:114
SelfAdjointView & rankUpdate(const MatrixBase< DerivedU > &u, const Scalar &alpha=Scalar(1))
MatrixType::ConstDiagonalReturnType diagonal() const
Definition SelfAdjointView.h:210
RealScalar l1Norm() const
Definition SelfAdjointView.h:219
EigenvaluesReturnType eigenvalues() const
Computes the eigenvalues of a matrix.
Definition MatrixBaseEigenvalues.h:84
SelfAdjointView & operator-=(const DenseBase< OtherDerived > &other)
Definition SelfAdjointView.h:108
void evalToLazy(MatrixBase< DenseDerived > &other) const
Definition TriangularMatrix.h:1077
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:426
@ SelfAdjoint
Definition Constants.h:228
@ Lower
Definition Constants.h:212
@ Upper
Definition Constants.h:214
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int LinearAccessBit
Definition Constants.h:134
constexpr unsigned int LvalueBit
Definition Constants.h:149