# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1314747366 18000 # Node ID b646413c3d0e6660c37706f7282f92f180366bca # Parent 50db905c3cf17532fdd2fd7094a6ff324daa71e4 Make operators do smarter sparse conversions on permutation matrices. * Sparse.cc (Sparse::Sparse): New templated ctor, plus two instantiations. * Sparse.h (Sparse): Declare new ctor. * MSparse.h (MSparse): Give this class a PermMatrix ctor. * boolSparse.h (BoolSparseMatrix): Ditto. * dSparse.cc: Refactor PermMatrix ctor, moved into common parent class. * dSparse.h (SparseMatrix): Ditto. * op-pm-sm.cc: Declare and install smarter permutation matrix operators. * ov-perm.cc (octave_perm_matrix): Declare new virtual function override. * ov-perm.cc (sparse_bool_matrix_value): Override this virtual function. diff -r 50db905c3cf1 -r b646413c3d0e liboctave/MSparse.h --- a/liboctave/MSparse.h Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/MSparse.h Tue Aug 30 18:36:06 2011 -0500 @@ -65,6 +65,8 @@ explicit MSparse (octave_idx_type r, octave_idx_type c, T val) : Sparse (r, c, val) { } + explicit MSparse (const PermMatrix& a) : Sparse(a) { } + MSparse (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : Sparse (r, c, num_nz) { } ~MSparse (void) { } diff -r 50db905c3cf1 -r b646413c3d0e liboctave/Sparse.cc --- a/liboctave/Sparse.cc Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/Sparse.cc Tue Aug 30 18:36:06 2011 -0500 @@ -50,6 +50,38 @@ #include "oct-spparms.h" #include "mx-inlines.cc" +#include "PermMatrix.h" + +template +Sparse::Sparse (const PermMatrix& a) + : rep (new typename Sparse::SparseRep (a.rows (), a.cols (), a.rows ())), + dimensions (dim_vector (a.rows (), a.cols())) +{ + octave_idx_type n = a.rows (); + for (octave_idx_type i = 0; i <= n; i++) + cidx (i) = i; + + const Array pv = a.pvec (); + + if (a.is_row_perm ()) + { + for (octave_idx_type i = 0; i < n; i++) + ridx (pv (i)) = i; + } + else + { + for (octave_idx_type i = 0; i < n; i++) + ridx (i) = pv (i); + } + + for (octave_idx_type i = 0; i < n; i++) + data (i) = 1.0; +} + +// SparseMatrix and SparseBoolMatrix both need this ctor +template Sparse::Sparse (const PermMatrix& a); +template Sparse::Sparse (const PermMatrix& a); + template T& Sparse::SparseRep::elem (octave_idx_type _r, octave_idx_type _c) diff -r 50db905c3cf1 -r b646413c3d0e liboctave/Sparse.h --- a/liboctave/Sparse.h Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/Sparse.h Tue Aug 30 18:36:06 2011 -0500 @@ -41,6 +41,7 @@ #include "oct-mem.h" class idx_vector; +class PermMatrix; // Two dimensional sparse class. Handles the reference counting for // all the derived classes. @@ -195,6 +196,10 @@ : rep (new typename Sparse::SparseRep (nr, nc, nz)), dimensions (dim_vector (nr, nc)) { } + // Both SparseMatrix and SparseBoolMatrix need this ctor, and this + // is their only common ancestor. + explicit Sparse (const PermMatrix& a); + // Type conversion case. Preserves capacity (). template Sparse (const Sparse& a) diff -r 50db905c3cf1 -r b646413c3d0e liboctave/boolSparse.h --- a/liboctave/boolSparse.h Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/boolSparse.h Tue Aug 30 18:36:06 2011 -0500 @@ -57,6 +57,8 @@ explicit SparseBoolMatrix (const boolNDArray& a) : Sparse (a) { } + explicit SparseBoolMatrix (const PermMatrix& a) : Sparse (a) { }; + SparseBoolMatrix (const Array& a, const idx_vector& r, const idx_vector& c, octave_idx_type nr = -1, octave_idx_type nc = -1, bool sum_terms = true, diff -r 50db905c3cf1 -r b646413c3d0e liboctave/dSparse.cc --- a/liboctave/dSparse.cc Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/dSparse.cc Tue Aug 30 18:36:06 2011 -0500 @@ -180,29 +180,6 @@ cidx(i) = j; } -SparseMatrix::SparseMatrix (const PermMatrix& a) - : MSparse (a.rows (), a.cols (), a.rows ()) -{ - octave_idx_type n = a.rows (); - for (octave_idx_type i = 0; i <= n; i++) - cidx (i) = i; - const Array pv = a.pvec (); - - if (a.is_row_perm ()) - { - for (octave_idx_type i = 0; i < n; i++) - ridx (pv (i)) = i; - } - else - { - for (octave_idx_type i = 0; i < n; i++) - ridx (i) = pv (i); - } - - for (octave_idx_type i = 0; i < n; i++) - data (i) = 1.0; -} - bool SparseMatrix::operator == (const SparseMatrix& a) const { diff -r 50db905c3cf1 -r b646413c3d0e liboctave/dSparse.h --- a/liboctave/dSparse.h Tue Aug 30 14:37:25 2011 -0400 +++ b/liboctave/dSparse.h Tue Aug 30 18:36:06 2011 -0500 @@ -82,7 +82,7 @@ explicit SparseMatrix (const DiagMatrix& a); - explicit SparseMatrix (const PermMatrix& a); + explicit SparseMatrix (const PermMatrix& a) : MSparse(a) { } SparseMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : MSparse (r, c, num_nz) { } diff -r 50db905c3cf1 -r b646413c3d0e src/OPERATORS/op-pm-sm.cc --- a/src/OPERATORS/op-pm-sm.cc Tue Aug 30 14:37:25 2011 -0400 +++ b/src/OPERATORS/op-pm-sm.cc Tue Aug 30 18:36:06 2011 -0500 @@ -32,6 +32,49 @@ #include "ov-perm.h" #include "ov-re-sparse.h" +#include "ov-bool-sparse.h" + +// Unary permutation ops, some cast to sparse + +//Avoid casting to a full matrix +DEFUNOP_OP (uplus, perm_matrix, /* no-op */) + +// Not calling standard CAST_UNOP_ARG for these next two because a +// dynamic_cast would fail. +DEFUNOP (not, perm_matrix) +{ + // Obviously negation of a permutation matrix destroys sparsity + return octave_value ( ! a.bool_array_value ()); +} + +DEFUNOP (uminus, perm_matrix) +{ + return octave_value ( - a.sparse_matrix_value ()); +} + +// Most other logical operations cast to SparseBoolMatrix +DEFBINOP (eq_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return v1.sparse_bool_matrix_value () == v2.sparse_bool_matrix_value (); +} +DEFBINOP (ne_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return v1.sparse_bool_matrix_value () != v2.sparse_bool_matrix_value (); +} +DEFBINOP (el_and_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return mx_el_and(v1.sparse_bool_matrix_value (), + v2.sparse_bool_matrix_value ()); +} +DEFBINOP (el_or_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return mx_el_or(v1.sparse_bool_matrix_value (), + v2.sparse_bool_matrix_value ()); +} // permutation matrix by sparse matrix ops @@ -86,6 +129,11 @@ void install_pm_sm_ops (void) { + INSTALL_UNOP (op_not, octave_perm_matrix, not); + INSTALL_UNOP (op_uplus, octave_perm_matrix, uplus); + INSTALL_UNOP (op_uminus, octave_perm_matrix, uminus); + + INSTALL_BINOP (op_mul, octave_perm_matrix, octave_sparse_matrix, mul_pm_sm); INSTALL_BINOP (op_ldiv, octave_perm_matrix, octave_sparse_matrix, @@ -94,4 +142,9 @@ mul_sm_pm); INSTALL_BINOP (op_div, octave_sparse_matrix, octave_perm_matrix, div_sm_pm); + + INSTALL_BINOP (op_eq, octave_perm_matrix, octave_perm_matrix, eq_pm); + INSTALL_BINOP (op_ne, octave_perm_matrix, octave_perm_matrix, ne_pm); + INSTALL_BINOP (op_el_and, octave_perm_matrix, octave_perm_matrix, el_and_pm); + INSTALL_BINOP (op_el_or, octave_perm_matrix, octave_perm_matrix, el_or_pm); } diff -r 50db905c3cf1 -r b646413c3d0e src/ov-perm.cc --- a/src/ov-perm.cc Tue Aug 30 14:37:25 2011 -0400 +++ b/src/ov-perm.cc Tue Aug 30 18:36:06 2011 -0500 @@ -217,6 +217,12 @@ return SparseMatrix (matrix); } +SparseBoolMatrix +octave_perm_matrix::sparse_bool_matrix_value (bool) const +{ + return SparseBoolMatrix (matrix); +} + SparseComplexMatrix octave_perm_matrix::sparse_complex_matrix_value (bool) const { diff -r 50db905c3cf1 -r b646413c3d0e src/ov-perm.h --- a/src/ov-perm.h Tue Aug 30 14:37:25 2011 -0400 +++ b/src/ov-perm.h Tue Aug 30 18:36:06 2011 -0500 @@ -160,6 +160,8 @@ SparseMatrix sparse_matrix_value (bool = false) const; + SparseBoolMatrix sparse_bool_matrix_value (bool = false) const; + SparseComplexMatrix sparse_complex_matrix_value (bool = false) const; int8NDArray