1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_DIAGONALPRODUCT_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_DIAGONALPRODUCT_H 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename DiagonalType, int ProductOrder> 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : traits<MatrixType> 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar; 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime = MatrixType::RowsAtCompileTime, 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColsAtCompileTime = MatrixType::ColsAtCompileTime, 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor, 297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) 307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)), 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath _SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value, 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME currently we need same types, but in the future the next rule should be the one 337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), 347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), 357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename DiagonalType, int ProductOrder> 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass DiagonalProduct : internal::no_assignment_operator, 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef MatrixBase<DiagonalProduct> Base; 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct) 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal) 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_matrix(matrix), m_diagonal(diagonal) 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols())); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } 597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col); 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const 677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez enum { 697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor 707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez }; 717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); 727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<int LoadMode> 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col; 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional< 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type()); 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<int LoadMode> 877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const 887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez enum { 907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor 917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez }; 927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return packet<LoadMode>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); 937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<int LoadMode> 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::pmul(m_matrix.template packet<LoadMode>(row, col), 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id))); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<int LoadMode> 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime, 1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned) 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::pmul(m_matrix.template packet<LoadMode>(row, col), 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id)); 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename MatrixType::Nested m_matrix; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename DiagonalType::Nested m_diagonal; 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename DiagonalDerived> 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight> 1237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezMatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), a_diagonal.derived()); 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_DIAGONALPRODUCT_H 131