1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SPARSE_PERMUTATION_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSE_PERMUTATION_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file implements sparse * permutation products 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename PermutationType, typename MatrixType, int Side, bool Transposed> 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<permut_sparsematrix_product_retval<PermutationType, MatrixType, Side, Transposed> > 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixTypeNestedCleaned::Scalar Scalar; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixTypeNestedCleaned::Index Index; 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::conditional<MoveOuter, 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrix<Scalar,SrcStorageOrder,Index>, 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,Index> >::type ReturnType; 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename PermutationType, typename MatrixType, int Side, bool Transposed> 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct permut_sparsematrix_product_retval 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : public ReturnByValue<permut_sparsematrix_product_retval<PermutationType, MatrixType, Side, Transposed> > 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixTypeNestedCleaned::Scalar Scalar; 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixTypeNestedCleaned::Index Index; 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath permut_sparsematrix_product_retval(const PermutationType& perm, const MatrixType& matrix) 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_permutation(perm), m_matrix(matrix) 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath {} 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline int rows() const { return m_matrix.rows(); } 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline int cols() const { return m_matrix.cols(); } 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Dest> inline void evalTo(Dest& dst) const 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(MoveOuter) 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrix<Scalar,SrcStorageOrder,Index> tmp(m_matrix.rows(), m_matrix.cols()); 607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix<Index,Dynamic,1> sizes(m_matrix.outerSize()); 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_matrix.outerSize(); ++j) 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index jp = m_permutation.indices().coeff(j); 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath sizes[((Side==OnTheLeft) ^ Transposed) ? jp : j] = m_matrix.innerVector(((Side==OnTheRight) ^ Transposed) ? jp : j).size(); 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp.reserve(sizes); 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_matrix.outerSize(); ++j) 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index jp = m_permutation.indices().coeff(j); 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index jsrc = ((Side==OnTheRight) ^ Transposed) ? jp : j; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index jdst = ((Side==OnTheLeft) ^ Transposed) ? jp : j; 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,jsrc); it; ++it) 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp.insertByOuterInner(jdst,it.index()) = it.value(); 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst = tmp; 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,Index> tmp(m_matrix.rows(), m_matrix.cols()); 807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix<Index,Dynamic,1> sizes(tmp.outerSize()); 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath sizes.setZero(); 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath PermutationMatrix<Dynamic,Dynamic,Index> perm; 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if((Side==OnTheLeft) ^ Transposed) 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath perm = m_permutation; 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath perm = m_permutation.transpose(); 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_matrix.outerSize(); ++j) 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,j); it; ++it) 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath sizes[perm.indices().coeff(it.index())]++; 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp.reserve(sizes); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_matrix.outerSize(); ++j) 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(typename MatrixTypeNestedCleaned::InnerIterator it(m_matrix,j); it; ++it) 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp.insertByOuterInner(perm.indices().coeff(it.index()),j) = it.value(); 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst = tmp; 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const PermutationType& m_permutation; 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename MatrixType::Nested m_matrix; 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the matrix with the permutation applied to the columns 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseDerived, typename PermDerived> 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false> 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathoperator*(const SparseMatrixBase<SparseDerived>& matrix, const PermutationBase<PermDerived>& perm) 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false>(perm, matrix.derived()); 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the matrix with the permutation applied to the rows 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseDerived, typename PermDerived> 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false> 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathoperator*( const PermutationBase<PermDerived>& perm, const SparseMatrixBase<SparseDerived>& matrix) 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false>(perm, matrix.derived()); 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the matrix with the inverse permutation applied to the columns. 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseDerived, typename PermDerived> 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true> 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathoperator*(const SparseMatrixBase<SparseDerived>& matrix, const Transpose<PermutationBase<PermDerived> >& tperm) 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true>(tperm.nestedPermutation(), matrix.derived()); 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the matrix with the inverse permutation applied to the rows. 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseDerived, typename PermDerived> 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true> 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathoperator*(const Transpose<PermutationBase<PermDerived> >& tperm, const SparseMatrixBase<SparseDerived>& matrix) 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true>(tperm.nestedPermutation(), matrix.derived()); 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H 149