1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2011 Kolja Brix <brix@igpm.rwth-aachen.de> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2011 Andreas Platen <andiplaten@gmx.de> 67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net> 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef KRONECKER_TENSOR_PRODUCT_H 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define KRONECKER_TENSOR_PRODUCT_H 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar, int Options, typename Index> class SparseMatrix; 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/*! 207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \brief Kronecker tensor product helper class for dense matrices 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * This class is the return value of kroneckerProduct(MatrixBase, 237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * MatrixBase). Use the function rather than construct this class 247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * directly to avoid specifying template prarameters. 257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * 267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \tparam Lhs Type of the left-hand side, a matrix expression. 277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \tparam Rhs Type of the rignt-hand side, a matrix expression. 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Lhs, typename Rhs> 307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass KroneckerProduct : public ReturnByValue<KroneckerProduct<Lhs,Rhs> > 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private: 337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef ReturnByValue<KroneckerProduct> Base; 347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename Base::Scalar Scalar; 357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename Base::Index Index; 367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public: 387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /*! \brief Constructor. */ 397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez KroneckerProduct(const Lhs& A, const Rhs& B) 407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez : m_A(A), m_B(B) 417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez {} 427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /*! \brief Evaluate the Kronecker tensor product. */ 447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<typename Dest> void evalTo(Dest& dst) const; 457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline Index rows() const { return m_A.rows() * m_B.rows(); } 477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline Index cols() const { return m_A.cols() * m_B.cols(); } 487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar coeff(Index row, Index col) const 507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return m_A.coeff(row / m_B.rows(), col / m_B.cols()) * 527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_B.coeff(row % m_B.rows(), col % m_B.cols()); 537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar coeff(Index i) const 567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STATIC_ASSERT_VECTOR_ONLY(KroneckerProduct); 587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return m_A.coeff(i / m_A.size()) * m_B.coeff(i % m_A.size()); 597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private: 627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typename Lhs::Nested m_A; 637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typename Rhs::Nested m_B; 647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/*! 677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \brief Kronecker tensor product helper class for sparse matrices 687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * 697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * If at least one of the operands is a sparse matrix expression, 707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * then this class is returned and evaluates into a sparse matrix. 717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * 727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * This class is the return value of kroneckerProduct(EigenBase, 737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * EigenBase). Use the function rather than construct this class 747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * directly to avoid specifying template prarameters. 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \tparam Lhs Type of the left-hand side, a matrix expression. 777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \tparam Rhs Type of the rignt-hand side, a matrix expression. 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Lhs, typename Rhs> 807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass KroneckerProductSparse : public EigenBase<KroneckerProductSparse<Lhs,Rhs> > 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private: 837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename internal::traits<KroneckerProductSparse>::Index Index; 847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public: 867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /*! \brief Constructor. */ 877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez KroneckerProductSparse(const Lhs& A, const Rhs& B) 887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez : m_A(A), m_B(B) 897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez {} 907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /*! \brief Evaluate the Kronecker tensor product. */ 927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<typename Dest> void evalTo(Dest& dst) const; 937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline Index rows() const { return m_A.rows() * m_B.rows(); } 957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline Index cols() const { return m_A.cols() * m_B.cols(); } 967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<typename Scalar, int Options, typename Index> 987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez operator SparseMatrix<Scalar, Options, Index>() 997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrix<Scalar, Options, Index> result; 1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez evalTo(result.derived()); 1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return result; 1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 1047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private: 1067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typename Lhs::Nested m_A; 1077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typename Rhs::Nested m_B; 1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 1097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Lhs, typename Rhs> 1117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Dest> 1127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid KroneckerProduct<Lhs,Rhs>::evalTo(Dest& dst) const 1137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const int BlockRows = Rhs::RowsAtCompileTime, 1157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez BlockCols = Rhs::ColsAtCompileTime; 1167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index Br = m_B.rows(), 1177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Bc = m_B.cols(); 1187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index i=0; i < m_A.rows(); ++i) 1197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index j=0; j < m_A.cols(); ++j) 1207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Block<Dest,BlockRows,BlockCols>(dst,i*Br,j*Bc,Br,Bc) = m_A.coeff(i,j) * m_B; 1217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} 1227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Lhs, typename Rhs> 1247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Dest> 1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid KroneckerProductSparse<Lhs,Rhs>::evalTo(Dest& dst) const 1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index Br = m_B.rows(), 1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Bc = m_B.cols(); 1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dst.resize(rows(),cols()); 1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dst.resizeNonZeros(0); 1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dst.reserve(m_A.nonZeros() * m_B.nonZeros()); 1327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index kA=0; kA < m_A.outerSize(); ++kA) 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index kB=0; kB < m_B.outerSize(); ++kB) 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (typename Lhs::InnerIterator itA(m_A,kA); itA; ++itA) 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (typename Rhs::InnerIterator itB(m_B,kB); itB; ++itB) 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index i = itA.row() * Br + itB.row(), 1427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez j = itA.col() * Bc + itB.col(); 1437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dst.insert(i,j) = itA.value() * itB.value(); 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace internal { 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename _Lhs, typename _Rhs> 1537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct traits<KroneckerProduct<_Lhs,_Rhs> > 1547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename remove_all<_Lhs>::type Lhs; 1567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename remove_all<_Rhs>::type Rhs; 1577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; 1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez enum { 1607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Rows = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret, 1617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Cols = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret, 1627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez MaxRows = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret, 1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez MaxCols = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret, 1647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez CoeffReadCost = Lhs::CoeffReadCost + Rhs::CoeffReadCost + NumTraits<Scalar>::MulCost 1657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez }; 1667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef Matrix<Scalar,Rows,Cols> ReturnType; 1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 1697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename _Lhs, typename _Rhs> 1717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct traits<KroneckerProductSparse<_Lhs,_Rhs> > 1727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef MatrixXpr XprKind; 1747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename remove_all<_Lhs>::type Lhs; 1757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename remove_all<_Rhs>::type Rhs; 1767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; 1777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, typename traits<Rhs>::StorageKind>::ret StorageKind; 1787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename promote_index_type<typename Lhs::Index, typename Rhs::Index>::type Index; 1797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez enum { 1817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez LhsFlags = Lhs::Flags, 1827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez RhsFlags = Rhs::Flags, 1837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez RowsAtCompileTime = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret, 1857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ColsAtCompileTime = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret, 1867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez MaxRowsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret, 1877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez MaxColsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret, 1887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EvalToRowMajor = (LhsFlags & RhsFlags & RowMajorBit), 1907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), 1917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Flags = ((LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) 1937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez | EvalBeforeNestingBit | EvalBeforeAssigningBit, 1947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez CoeffReadCost = Dynamic 1957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez }; 1967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace internal 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/*! 2017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \ingroup KroneckerProduct_Module 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Computes Kronecker tensor product of two dense matrices 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 2057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \warning If you want to replace a matrix by its Kronecker product 2067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * with some matrix, do \b NOT do this: 2077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \code 2087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * A = kroneckerProduct(A,B); // bug!!! caused by aliasing effect 2097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \endcode 2107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * instead, use eval() to work around this: 2117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \code 2127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * A = kroneckerProduct(A,B).eval(); 2137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \endcode 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param a Dense matrix a 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param b Dense matrix b 2177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \return Kronecker tensor product of a and b 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 2197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename A, typename B> 2207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezKroneckerProduct<A,B> kroneckerProduct(const MatrixBase<A>& a, const MatrixBase<B>& b) 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return KroneckerProduct<A, B>(a.derived(), b.derived()); 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/*! 2267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \ingroup KroneckerProduct_Module 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 2287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * Computes Kronecker tensor product of two matrices, at least one of 2297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * which is sparse 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 2317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param a Dense/sparse matrix a 2327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param b Dense/sparse matrix b 2337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \return Kronecker tensor product of a and b, stored in a sparse 2347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * matrix 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 2367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename A, typename B> 2377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezKroneckerProductSparse<A,B> kroneckerProduct(const EigenBase<A>& a, const EigenBase<B>& b) 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return KroneckerProductSparse<A,B>(a.derived(), b.derived()); 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // KRONECKER_TENSOR_PRODUCT_H 245