00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef KRONECKER_TENSOR_PRODUCT_H
00013 #define KRONECKER_TENSOR_PRODUCT_H
00014
00015
00016 namespace Eigen {
00017
00018 namespace internal {
00019
00027 template<typename Derived_A, typename Derived_B, typename Derived_AB>
00028 void kroneckerProduct_full(const Derived_A& A, const Derived_B& B, Derived_AB & AB)
00029 {
00030 const unsigned int Ar = A.rows(),
00031 Ac = A.cols(),
00032 Br = B.rows(),
00033 Bc = B.cols();
00034 for (unsigned int i=0; i<Ar; ++i)
00035 for (unsigned int j=0; j<Ac; ++j)
00036 AB.block(i*Br,j*Bc,Br,Bc) = A(i,j)*B;
00037 }
00038
00039
00047 template<typename Derived_A, typename Derived_B, typename Derived_AB>
00048 void kroneckerProduct_sparse(const Derived_A &A, const Derived_B &B, Derived_AB &AB)
00049 {
00050 const unsigned int Ar = A.rows(),
00051 Ac = A.cols(),
00052 Br = B.rows(),
00053 Bc = B.cols();
00054 AB.resize(Ar*Br,Ac*Bc);
00055 AB.resizeNonZeros(0);
00056 AB.reserve(A.nonZeros()*B.nonZeros());
00057
00058 for (int kA=0; kA<A.outerSize(); ++kA)
00059 {
00060 for (int kB=0; kB<B.outerSize(); ++kB)
00061 {
00062 for (typename Derived_A::InnerIterator itA(A,kA); itA; ++itA)
00063 {
00064 for (typename Derived_B::InnerIterator itB(B,kB); itB; ++itB)
00065 {
00066 const unsigned int iA = itA.row(),
00067 jA = itA.col(),
00068 iB = itB.row(),
00069 jB = itB.col(),
00070 i = iA*Br + iB,
00071 j = jA*Bc + jB;
00072 AB.insert(i,j) = itA.value() * itB.value();
00073 }
00074 }
00075 }
00076 }
00077 }
00078
00079 }
00080
00081
00082
00090 template<typename A,typename B,typename CScalar,int CRows,int CCols, int COptions, int CMaxRows, int CMaxCols>
00091 void kroneckerProduct(const MatrixBase<A>& a, const MatrixBase<B>& b, Matrix<CScalar,CRows,CCols,COptions,CMaxRows,CMaxCols>& c)
00092 {
00093 c.resize(a.rows()*b.rows(),a.cols()*b.cols());
00094 internal::kroneckerProduct_full(a.derived(), b.derived(), c);
00095 }
00096
00109 template<typename A,typename B,typename C>
00110 void kroneckerProduct(const MatrixBase<A>& a, const MatrixBase<B>& b, MatrixBase<C> const & c_)
00111 {
00112 MatrixBase<C>& c = const_cast<MatrixBase<C>& >(c_);
00113 internal::kroneckerProduct_full(a.derived(), b.derived(), c.derived());
00114 }
00115
00123 template<typename A,typename B,typename C>
00124 void kroneckerProduct(const MatrixBase<A>& a, const SparseMatrixBase<B>& b, SparseMatrixBase<C>& c)
00125 {
00126 internal::kroneckerProduct_sparse(a.derived(), b.derived(), c.derived());
00127 }
00128
00136 template<typename A,typename B,typename C>
00137 void kroneckerProduct(const SparseMatrixBase<A>& a, const MatrixBase<B>& b, SparseMatrixBase<C>& c)
00138 {
00139 internal::kroneckerProduct_sparse(a.derived(), b.derived(), c.derived());
00140 }
00141
00149 template<typename A,typename B,typename C>
00150 void kroneckerProduct(const SparseMatrixBase<A>& a, const SparseMatrixBase<B>& b, SparseMatrixBase<C>& c)
00151 {
00152 internal::kroneckerProduct_sparse(a.derived(), b.derived(), c.derived());
00153 }
00154
00155 }
00156
00157 #endif // KRONECKER_TENSOR_PRODUCT_H