File indexing completed on 2025-02-22 10:34:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_SPARSE_PERMUTATION_H
0011 #define EIGEN_SPARSE_PERMUTATION_H
0012
0013
0014
0015 namespace Eigen {
0016
0017 namespace internal {
0018
0019 template<typename ExpressionType, int Side, bool Transposed>
0020 struct permutation_matrix_product<ExpressionType, Side, Transposed, SparseShape>
0021 {
0022 typedef typename nested_eval<ExpressionType, 1>::type MatrixType;
0023 typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
0024
0025 typedef typename MatrixTypeCleaned::Scalar Scalar;
0026 typedef typename MatrixTypeCleaned::StorageIndex StorageIndex;
0027
0028 enum {
0029 SrcStorageOrder = MatrixTypeCleaned::Flags&RowMajorBit ? RowMajor : ColMajor,
0030 MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight
0031 };
0032
0033 typedef typename internal::conditional<MoveOuter,
0034 SparseMatrix<Scalar,SrcStorageOrder,StorageIndex>,
0035 SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,StorageIndex> >::type ReturnType;
0036
0037 template<typename Dest,typename PermutationType>
0038 static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
0039 {
0040 MatrixType mat(xpr);
0041 if(MoveOuter)
0042 {
0043 SparseMatrix<Scalar,SrcStorageOrder,StorageIndex> tmp(mat.rows(), mat.cols());
0044 Matrix<StorageIndex,Dynamic,1> sizes(mat.outerSize());
0045 for(Index j=0; j<mat.outerSize(); ++j)
0046 {
0047 Index jp = perm.indices().coeff(j);
0048 sizes[((Side==OnTheLeft) ^ Transposed) ? jp : j] = StorageIndex(mat.innerVector(((Side==OnTheRight) ^ Transposed) ? jp : j).nonZeros());
0049 }
0050 tmp.reserve(sizes);
0051 for(Index j=0; j<mat.outerSize(); ++j)
0052 {
0053 Index jp = perm.indices().coeff(j);
0054 Index jsrc = ((Side==OnTheRight) ^ Transposed) ? jp : j;
0055 Index jdst = ((Side==OnTheLeft) ^ Transposed) ? jp : j;
0056 for(typename MatrixTypeCleaned::InnerIterator it(mat,jsrc); it; ++it)
0057 tmp.insertByOuterInner(jdst,it.index()) = it.value();
0058 }
0059 dst = tmp;
0060 }
0061 else
0062 {
0063 SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,StorageIndex> tmp(mat.rows(), mat.cols());
0064 Matrix<StorageIndex,Dynamic,1> sizes(tmp.outerSize());
0065 sizes.setZero();
0066 PermutationMatrix<Dynamic,Dynamic,StorageIndex> perm_cpy;
0067 if((Side==OnTheLeft) ^ Transposed)
0068 perm_cpy = perm;
0069 else
0070 perm_cpy = perm.transpose();
0071
0072 for(Index j=0; j<mat.outerSize(); ++j)
0073 for(typename MatrixTypeCleaned::InnerIterator it(mat,j); it; ++it)
0074 sizes[perm_cpy.indices().coeff(it.index())]++;
0075 tmp.reserve(sizes);
0076 for(Index j=0; j<mat.outerSize(); ++j)
0077 for(typename MatrixTypeCleaned::InnerIterator it(mat,j); it; ++it)
0078 tmp.insertByOuterInner(perm_cpy.indices().coeff(it.index()),j) = it.value();
0079 dst = tmp;
0080 }
0081 }
0082 };
0083
0084 }
0085
0086 namespace internal {
0087
0088 template <int ProductTag> struct product_promote_storage_type<Sparse, PermutationStorage, ProductTag> { typedef Sparse ret; };
0089 template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Sparse, ProductTag> { typedef Sparse ret; };
0090
0091
0092
0093
0094
0095 template<typename Lhs, typename Rhs, int ProductTag>
0096 struct product_evaluator<Product<Lhs, Rhs, AliasFreeProduct>, ProductTag, PermutationShape, SparseShape>
0097 : public evaluator<typename permutation_matrix_product<Rhs,OnTheLeft,false,SparseShape>::ReturnType>
0098 {
0099 typedef Product<Lhs, Rhs, AliasFreeProduct> XprType;
0100 typedef typename permutation_matrix_product<Rhs,OnTheLeft,false,SparseShape>::ReturnType PlainObject;
0101 typedef evaluator<PlainObject> Base;
0102
0103 enum {
0104 Flags = Base::Flags | EvalBeforeNestingBit
0105 };
0106
0107 explicit product_evaluator(const XprType& xpr)
0108 : m_result(xpr.rows(), xpr.cols())
0109 {
0110 ::new (static_cast<Base*>(this)) Base(m_result);
0111 generic_product_impl<Lhs, Rhs, PermutationShape, SparseShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs());
0112 }
0113
0114 protected:
0115 PlainObject m_result;
0116 };
0117
0118 template<typename Lhs, typename Rhs, int ProductTag>
0119 struct product_evaluator<Product<Lhs, Rhs, AliasFreeProduct>, ProductTag, SparseShape, PermutationShape >
0120 : public evaluator<typename permutation_matrix_product<Lhs,OnTheRight,false,SparseShape>::ReturnType>
0121 {
0122 typedef Product<Lhs, Rhs, AliasFreeProduct> XprType;
0123 typedef typename permutation_matrix_product<Lhs,OnTheRight,false,SparseShape>::ReturnType PlainObject;
0124 typedef evaluator<PlainObject> Base;
0125
0126 enum {
0127 Flags = Base::Flags | EvalBeforeNestingBit
0128 };
0129
0130 explicit product_evaluator(const XprType& xpr)
0131 : m_result(xpr.rows(), xpr.cols())
0132 {
0133 ::new (static_cast<Base*>(this)) Base(m_result);
0134 generic_product_impl<Lhs, Rhs, SparseShape, PermutationShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs());
0135 }
0136
0137 protected:
0138 PlainObject m_result;
0139 };
0140
0141 }
0142
0143
0144
0145 template<typename SparseDerived, typename PermDerived>
0146 inline const Product<SparseDerived, PermDerived, AliasFreeProduct>
0147 operator*(const SparseMatrixBase<SparseDerived>& matrix, const PermutationBase<PermDerived>& perm)
0148 { return Product<SparseDerived, PermDerived, AliasFreeProduct>(matrix.derived(), perm.derived()); }
0149
0150
0151
0152 template<typename SparseDerived, typename PermDerived>
0153 inline const Product<PermDerived, SparseDerived, AliasFreeProduct>
0154 operator*( const PermutationBase<PermDerived>& perm, const SparseMatrixBase<SparseDerived>& matrix)
0155 { return Product<PermDerived, SparseDerived, AliasFreeProduct>(perm.derived(), matrix.derived()); }
0156
0157
0158
0159
0160 template<typename SparseDerived, typename PermutationType>
0161 inline const Product<SparseDerived, Inverse<PermutationType>, AliasFreeProduct>
0162 operator*(const SparseMatrixBase<SparseDerived>& matrix, const InverseImpl<PermutationType, PermutationStorage>& tperm)
0163 {
0164 return Product<SparseDerived, Inverse<PermutationType>, AliasFreeProduct>(matrix.derived(), tperm.derived());
0165 }
0166
0167
0168
0169 template<typename SparseDerived, typename PermutationType>
0170 inline const Product<Inverse<PermutationType>, SparseDerived, AliasFreeProduct>
0171 operator*(const InverseImpl<PermutationType,PermutationStorage>& tperm, const SparseMatrixBase<SparseDerived>& matrix)
0172 {
0173 return Product<Inverse<PermutationType>, SparseDerived, AliasFreeProduct>(tperm.derived(), matrix.derived());
0174 }
0175
0176 }
0177
0178 #endif