SelfadjointRank2Update.h
Go to the documentation of this file.
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 
10 #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H
11 #define EIGEN_SELFADJOINTRANK2UPTADE_H
12 
13 #include "../InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 /* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu'
20  * It corresponds to the Level2 syr2 BLAS routine
21  */
22 
23 template<typename Scalar, typename Index, typename UType, typename VType, int UpLo>
24 struct selfadjoint_rank2_update_selector;
25 
26 template<typename Scalar, typename Index, typename UType, typename VType>
27 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
28 {
29  static EIGEN_DEVICE_FUNC
30  void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
31  {
32  const Index size = u.size();
33  for (Index i=0; i<size; ++i)
34  {
35  Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
36  (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.tail(size-i)
37  + (alpha * numext::conj(v.coeff(i))) * u.tail(size-i);
38  }
39  }
40 };
41 
42 template<typename Scalar, typename Index, typename UType, typename VType>
43 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
44 {
45  static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
46  {
47  const Index size = u.size();
48  for (Index i=0; i<size; ++i)
49  Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
50  (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.head(i+1)
51  + (alpha * numext::conj(v.coeff(i))) * u.head(i+1);
52  }
53 };
54 
55 template<bool Cond, typename T>
56 using conj_expr_if = std::conditional<!Cond, const T&, CwiseUnaryOp<scalar_conjugate_op<typename traits<T>::Scalar>,T>>;
57 
58 } // end namespace internal
59 
60 template<typename MatrixType, unsigned int UpLo>
61 template<typename DerivedU, typename DerivedV>
64 {
65  typedef internal::blas_traits<DerivedU> UBlasTraits;
66  typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
67  typedef internal::remove_all_t<ActualUType> ActualUType_;
68  internal::add_const_on_value_type_t<ActualUType> actualU = UBlasTraits::extract(u.derived());
69 
70  typedef internal::blas_traits<DerivedV> VBlasTraits;
71  typedef typename VBlasTraits::DirectLinearAccessType ActualVType;
72  typedef internal::remove_all_t<ActualVType> ActualVType_;
73  internal::add_const_on_value_type_t<ActualVType> actualV = VBlasTraits::extract(v.derived());
74 
75  // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and
76  // vice versa, and take the complex conjugate of all coefficients and vector entries.
77 
78  enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
79  Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
80  * numext::conj(VBlasTraits::extractScalarFactor(v.derived()));
81  if (IsRowMajor)
82  actualAlpha = numext::conj(actualAlpha);
83 
84  typedef internal::remove_all_t<typename internal::conj_expr_if<int(IsRowMajor) ^ int(UBlasTraits::NeedToConjugate), ActualUType_>::type> UType;
85  typedef internal::remove_all_t<typename internal::conj_expr_if<int(IsRowMajor) ^ int(VBlasTraits::NeedToConjugate), ActualVType_>::type> VType;
86  internal::selfadjoint_rank2_update_selector<Scalar, Index, UType, VType,
87  (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)>
88  ::run(_expression().const_cast_derived().data(),_expression().outerStride(),UType(actualU),VType(actualV),actualAlpha);
89 
90  return *this;
91 }
92 
93 } // end namespace Eigen
94 
95 #endif // EIGEN_SELFADJOINTRANK2UPTADE_H
Array< int, Dynamic, 1 > v
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
Expression of a selfadjoint matrix from a triangular part of a dense matrix.
SelfAdjointView & rankUpdate(const MatrixBase< DerivedU > &u, const MatrixBase< DerivedV > &v, const Scalar &alpha=Scalar(1))
internal::traits< SelfAdjointView >::Scalar Scalar
The type of coefficients in this matrix.
@ Lower
Definition: Constants.h:211
@ Upper
Definition: Constants.h:213
const unsigned int RowMajorBit
Definition: Constants.h:68
typename remove_all< T >::type remove_all_t
Definition: Meta.h:119
std::conditional<!Cond, const T &, CwiseUnaryOp< scalar_conjugate_op< typename traits< T >::Scalar >, T > > conj_expr_if
typename add_const_on_value_type< T >::type add_const_on_value_type_t
Definition: Meta.h:176
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)