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
00026 #ifndef EIGEN_DIAGONALPRODUCT_H
00027 #define EIGEN_DIAGONALPRODUCT_H
00028
00029 namespace internal {
00030 template<typename MatrixType, typename DiagonalType, int ProductOrder>
00031 struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
00032 : traits<MatrixType>
00033 {
00034 typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
00035 enum {
00036 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00037 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
00038 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00039 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00040
00041 _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
00042 _PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
00043 ||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)),
00044 _SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
00045
00046
00047 _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))),
00048
00049 Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),
00050 CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
00051 };
00052 };
00053 }
00054
00055 template<typename MatrixType, typename DiagonalType, int ProductOrder>
00056 class DiagonalProduct : internal::no_assignment_operator,
00057 public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
00058 {
00059 public:
00060
00061 typedef MatrixBase<DiagonalProduct> Base;
00062 EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
00063
00064 inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
00065 : m_matrix(matrix), m_diagonal(diagonal)
00066 {
00067 eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
00068 }
00069
00070 inline Index rows() const { return m_matrix.rows(); }
00071 inline Index cols() const { return m_matrix.cols(); }
00072
00073 const Scalar coeff(Index row, Index col) const
00074 {
00075 return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
00076 }
00077
00078 template<int LoadMode>
00079 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00080 {
00081 enum {
00082 StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
00083 };
00084 const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
00085
00086 return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
00087 ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
00088 ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
00089 }
00090
00091 protected:
00092 template<int LoadMode>
00093 EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const
00094 {
00095 return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
00096 internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id)));
00097 }
00098
00099 template<int LoadMode>
00100 EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const
00101 {
00102 enum {
00103 InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
00104 DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned
00105 };
00106 return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
00107 m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
00108 }
00109
00110 const typename MatrixType::Nested m_matrix;
00111 const typename DiagonalType::Nested m_diagonal;
00112 };
00113
00116 template<typename Derived>
00117 template<typename DiagonalDerived>
00118 inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
00119 MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &diagonal) const
00120 {
00121 return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), diagonal.derived());
00122 }
00123
00126 template<typename DiagonalDerived>
00127 template<typename MatrixDerived>
00128 inline const DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>
00129 DiagonalBase<DiagonalDerived>::operator*(const MatrixBase<MatrixDerived> &matrix) const
00130 {
00131 return DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>(matrix.derived(), derived());
00132 }
00133
00134
00135 #endif // EIGEN_DIAGONALPRODUCT_H