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_SELFADJOINT_PRODUCT_H
00026 #define EIGEN_SELFADJOINT_PRODUCT_H
00027
00028
00029
00030
00031
00032
00033
00034 template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>
00035 struct selfadjoint_rank1_update;
00036
00037 template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
00038 struct selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRhs>
00039 {
00040 static void run(Index size, Scalar* mat, Index stride, const Scalar* vec, Scalar alpha)
00041 {
00042 internal::conj_if<ConjRhs> cj;
00043 typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;
00044 typedef typename internal::conditional<ConjLhs,typename OtherMap::ConjugateReturnType,const OtherMap&>::type ConjRhsType;
00045 for (Index i=0; i<size; ++i)
00046 {
00047 Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+(UpLo==Lower ? i : 0), (UpLo==Lower ? size-i : (i+1)))
00048 += (alpha * cj(vec[i])) * ConjRhsType(OtherMap(vec+(UpLo==Lower ? i : 0),UpLo==Lower ? size-i : (i+1)));
00049 }
00050 }
00051 };
00052
00053 template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
00054 struct selfadjoint_rank1_update<Scalar,Index,RowMajor,UpLo,ConjLhs,ConjRhs>
00055 {
00056 static void run(Index size, Scalar* mat, Index stride, const Scalar* vec, Scalar alpha)
00057 {
00058 selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo==Lower?Upper:Lower,ConjRhs,ConjLhs>::run(size,mat,stride,vec,alpha);
00059 }
00060 };
00061
00062 template<typename MatrixType, typename OtherType, int UpLo, bool OtherIsVector = OtherType::IsVectorAtCompileTime>
00063 struct selfadjoint_product_selector;
00064
00065 template<typename MatrixType, typename OtherType, int UpLo>
00066 struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
00067 {
00068 static void run(MatrixType& mat, const OtherType& other, typename MatrixType::Scalar alpha)
00069 {
00070 typedef typename MatrixType::Scalar Scalar;
00071 typedef typename MatrixType::Index Index;
00072 typedef internal::blas_traits<OtherType> OtherBlasTraits;
00073 typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType;
00074 typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType;
00075 const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived());
00076
00077 Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived());
00078
00079 enum {
00080 StorageOrder = (internal::traits<MatrixType>::Flags&RowMajorBit) ? RowMajor : ColMajor,
00081 UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1
00082 };
00083 internal::gemv_static_vector_if<Scalar,OtherType::SizeAtCompileTime,OtherType::MaxSizeAtCompileTime,!UseOtherDirectly> static_other;
00084
00085 bool freeOtherPtr = false;
00086 Scalar* actualOtherPtr;
00087 if(UseOtherDirectly)
00088 actualOtherPtr = const_cast<Scalar*>(actualOther.data());
00089 else
00090 {
00091 if((actualOtherPtr=static_other.data())==0)
00092 {
00093 freeOtherPtr = true;
00094 actualOtherPtr = ei_aligned_stack_new(Scalar,other.size());
00095 }
00096 Map<typename _ActualOtherType::PlainObject>(actualOtherPtr, actualOther.size()) = actualOther;
00097 }
00098
00099 selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
00100 OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
00101 (!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
00102 ::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualAlpha);
00103
00104 if((!UseOtherDirectly) && freeOtherPtr) ei_aligned_stack_delete(Scalar, actualOtherPtr, other.size());
00105 }
00106 };
00107
00108 template<typename MatrixType, typename OtherType, int UpLo>
00109 struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
00110 {
00111 static void run(MatrixType& mat, const OtherType& other, typename MatrixType::Scalar alpha)
00112 {
00113 typedef typename MatrixType::Scalar Scalar;
00114 typedef typename MatrixType::Index Index;
00115 typedef internal::blas_traits<OtherType> OtherBlasTraits;
00116 typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType;
00117 typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType;
00118 const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived());
00119
00120 Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived());
00121
00122 enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
00123
00124 internal::general_matrix_matrix_triangular_product<Index,
00125 Scalar, _ActualOtherType::Flags&RowMajorBit ? RowMajor : ColMajor, OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
00126 Scalar, _ActualOtherType::Flags&RowMajorBit ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex,
00127 MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor, UpLo>
00128 ::run(mat.cols(), actualOther.cols(),
00129 &actualOther.coeffRef(0,0), actualOther.outerStride(), &actualOther.coeffRef(0,0), actualOther.outerStride(),
00130 mat.data(), mat.outerStride(), actualAlpha);
00131 }
00132 };
00133
00134
00135
00136 template<typename MatrixType, unsigned int UpLo>
00137 template<typename DerivedU>
00138 SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
00139 ::rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha)
00140 {
00141 selfadjoint_product_selector<MatrixType,DerivedU,UpLo>::run(_expression().const_cast_derived(), u.derived(), alpha);
00142
00143 return *this;
00144 }
00145
00146 #endif // EIGEN_SELFADJOINT_PRODUCT_H