SparsePermutation.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
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());
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        VectorXi 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());
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        VectorXi 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