DiagonalProduct.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
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     // FIXME currently we need same types, but in the future the next rule should be the one
00046     //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))),
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


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:02