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
00033 template<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {};
00034 template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N >
00035 : ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::type> > >
00036 {};
00037
00038
00039 template<typename Lhs, typename Rhs>
00040 struct ProductReturnType<Lhs,Rhs,DiagonalProduct>
00041 {
00042 typedef typename ei_nested_diagonal<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
00043 typedef typename ei_nested_diagonal<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
00044
00045 typedef Product<LhsNested, RhsNested, DiagonalProduct> Type;
00046 };
00047
00048 template<typename LhsNested, typename RhsNested>
00049 struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
00050 {
00051
00052 typedef typename ei_cleantype<LhsNested>::type _LhsNested;
00053 typedef typename ei_cleantype<RhsNested>::type _RhsNested;
00054 typedef typename _LhsNested::Scalar Scalar;
00055
00056 enum {
00057 LhsFlags = _LhsNested::Flags,
00058 RhsFlags = _RhsNested::Flags,
00059 RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
00060 ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
00061 MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
00062 MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
00063
00064 LhsIsDiagonal = (_LhsNested::Flags&Diagonal)==Diagonal,
00065 RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal,
00066
00067 CanVectorizeRhs = (!RhsIsDiagonal) && (RhsFlags & RowMajorBit) && (RhsFlags & PacketAccessBit)
00068 && (ColsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
00069
00070 CanVectorizeLhs = (!LhsIsDiagonal) && (!(LhsFlags & RowMajorBit)) && (LhsFlags & PacketAccessBit)
00071 && (RowsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
00072
00073 RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit),
00074
00075 Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
00076 | (((CanVectorizeLhs&&RhsIsDiagonal) || (CanVectorizeRhs&&LhsIsDiagonal)) ? PacketAccessBit : 0),
00077
00078 CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost
00079 };
00080 };
00081
00082 template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNested, DiagonalProduct> : ei_no_assignment_operator,
00083 public MatrixBase<Product<LhsNested, RhsNested, DiagonalProduct> >
00084 {
00085 typedef typename ei_traits<Product>::_LhsNested _LhsNested;
00086 typedef typename ei_traits<Product>::_RhsNested _RhsNested;
00087
00088 enum {
00089 RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal
00090 };
00091
00092 public:
00093
00094 EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
00095
00096 template<typename Lhs, typename Rhs>
00097 inline Product(const Lhs& lhs, const Rhs& rhs)
00098 : m_lhs(lhs), m_rhs(rhs)
00099 {
00100 ei_assert(lhs.cols() == rhs.rows());
00101 }
00102
00103 inline int rows() const { return m_lhs.rows(); }
00104 inline int cols() const { return m_rhs.cols(); }
00105
00106 const Scalar coeff(int row, int col) const
00107 {
00108 const int unique = RhsIsDiagonal ? col : row;
00109 return m_lhs.coeff(row, unique) * m_rhs.coeff(unique, col);
00110 }
00111
00112 template<int LoadMode>
00113 const PacketScalar packet(int row, int col) const
00114 {
00115 if (RhsIsDiagonal)
00116 {
00117 return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col)));
00118 }
00119 else
00120 {
00121 return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col));
00122 }
00123 }
00124
00125 protected:
00126 const LhsNested m_lhs;
00127 const RhsNested m_rhs;
00128 };
00129
00130 #endif // EIGEN_DIAGONALPRODUCT_H