00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H
00026 #define EIGEN_SELFADJOINTRANK2UPTADE_H
00027
00028 namespace internal {
00029
00030
00031
00032
00033
00034 template<typename Scalar, typename Index, typename UType, typename VType, int UpLo>
00035 struct selfadjoint_rank2_update_selector;
00036
00037 template<typename Scalar, typename Index, typename UType, typename VType>
00038 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
00039 {
00040 static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
00041 {
00042 const Index size = u.size();
00043 for (Index i=0; i<size; ++i)
00044 {
00045 Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
00046 (conj(alpha) * conj(u.coeff(i))) * v.tail(size-i)
00047 + (alpha * conj(v.coeff(i))) * u.tail(size-i);
00048 }
00049 }
00050 };
00051
00052 template<typename Scalar, typename Index, typename UType, typename VType>
00053 struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
00054 {
00055 static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
00056 {
00057 const Index size = u.size();
00058 for (Index i=0; i<size; ++i)
00059 Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
00060 (conj(alpha) * conj(u.coeff(i))) * v.head(i+1)
00061 + (alpha * conj(v.coeff(i))) * u.head(i+1);
00062 }
00063 };
00064
00065 template<bool Cond, typename T> struct conj_expr_if
00066 : conditional<!Cond, const T&,
00067 CwiseUnaryOp<scalar_conjugate_op<typename traits<T>::Scalar>,T> > {};
00068
00069 }
00070
00071 template<typename MatrixType, unsigned int UpLo>
00072 template<typename DerivedU, typename DerivedV>
00073 SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
00074 ::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha)
00075 {
00076 typedef internal::blas_traits<DerivedU> UBlasTraits;
00077 typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
00078 typedef typename internal::remove_all<ActualUType>::type _ActualUType;
00079 const ActualUType actualU = UBlasTraits::extract(u.derived());
00080
00081 typedef internal::blas_traits<DerivedV> VBlasTraits;
00082 typedef typename VBlasTraits::DirectLinearAccessType ActualVType;
00083 typedef typename internal::remove_all<ActualVType>::type _ActualVType;
00084 const ActualVType actualV = VBlasTraits::extract(v.derived());
00085
00086
00087
00088
00089 enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
00090 Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
00091 * internal::conj(VBlasTraits::extractScalarFactor(v.derived()));
00092 if (IsRowMajor)
00093 actualAlpha = internal::conj(actualAlpha);
00094
00095 internal::selfadjoint_rank2_update_selector<Scalar, Index,
00096 typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type,
00097 typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ VBlasTraits::NeedToConjugate,_ActualVType>::type>::type,
00098 (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)>
00099 ::run(_expression().const_cast_derived().data(),_expression().outerStride(),actualU,actualV,actualAlpha);
00100
00101 return *this;
00102 }
00103
00104 #endif // EIGEN_SELFADJOINTRANK2UPTADE_H