Another set of UI messages fixes and tweaks! No functional changes.
[blender.git] / extern / Eigen3 / Eigen / src / Core / products / SelfadjointRank2Update.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 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H
26 #define EIGEN_SELFADJOINTRANK2UPTADE_H
27
28 namespace internal {
29
30 /* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu'
31  * It corresponds to the Level2 syr2 BLAS routine
32  */
33
34 template<typename Scalar, typename Index, typename UType, typename VType, int UpLo>
35 struct selfadjoint_rank2_update_selector;
36
37 template<typename Scalar, typename Index, typename UType, typename VType>
38 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
39 {
40   static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
41   {
42     const Index size = u.size();
43     for (Index i=0; i<size; ++i)
44     {
45       Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
46                         (conj(alpha)  * conj(u.coeff(i))) * v.tail(size-i)
47                       + (alpha * conj(v.coeff(i))) * u.tail(size-i);
48     }
49   }
50 };
51
52 template<typename Scalar, typename Index, typename UType, typename VType>
53 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
54 {
55   static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
56   {
57     const Index size = u.size();
58     for (Index i=0; i<size; ++i)
59       Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
60                         (conj(alpha)  * conj(u.coeff(i))) * v.head(i+1)
61                       + (alpha * conj(v.coeff(i))) * u.head(i+1);
62   }
63 };
64
65 template<bool Cond, typename T> struct conj_expr_if
66   : conditional<!Cond, const T&,
67       CwiseUnaryOp<scalar_conjugate_op<typename traits<T>::Scalar>,T> > {};
68
69 } // end namespace internal
70
71 template<typename MatrixType, unsigned int UpLo>
72 template<typename DerivedU, typename DerivedV>
73 SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
74 ::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha)
75 {
76   typedef internal::blas_traits<DerivedU> UBlasTraits;
77   typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
78   typedef typename internal::remove_all<ActualUType>::type _ActualUType;
79   const ActualUType actualU = UBlasTraits::extract(u.derived());
80
81   typedef internal::blas_traits<DerivedV> VBlasTraits;
82   typedef typename VBlasTraits::DirectLinearAccessType ActualVType;
83   typedef typename internal::remove_all<ActualVType>::type _ActualVType;
84   const ActualVType actualV = VBlasTraits::extract(v.derived());
85
86   // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and
87   // vice versa, and take the complex conjugate of all coefficients and vector entries.
88
89   enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
90   Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
91                              * internal::conj(VBlasTraits::extractScalarFactor(v.derived()));
92   if (IsRowMajor)
93     actualAlpha = internal::conj(actualAlpha);
94
95   internal::selfadjoint_rank2_update_selector<Scalar, Index,
96     typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type,
97     typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ VBlasTraits::NeedToConjugate,_ActualVType>::type>::type,
98     (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)>
99     ::run(_expression().const_cast_derived().data(),_expression().outerStride(),actualU,actualV,actualAlpha);
100
101   return *this;
102 }
103
104 #endif // EIGEN_SELFADJOINTRANK2UPTADE_H