changeset 13030:b646413c3d0e

Make operators do smarter sparse conversions on permutation matrices. * Sparse.cc (Sparse<T>::Sparse): New templated ctor, plus two instantiations. * Sparse.h (Sparse<T>): 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.
author Jordi Gutiérrez Hermoso <jordigh@gmail.com>
date Tue, 30 Aug 2011 18:36:06 -0500
parents 50db905c3cf1
children 7d4429c82212
files liboctave/MSparse.h liboctave/Sparse.cc liboctave/Sparse.h liboctave/boolSparse.h liboctave/dSparse.cc liboctave/dSparse.h src/OPERATORS/op-pm-sm.cc src/ov-perm.cc src/ov-perm.h
diffstat 9 files changed, 103 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- 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<T> (r, c, val) { }
 
+  explicit MSparse (const PermMatrix& a) : Sparse<T>(a) { }
+
   MSparse (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : Sparse<T> (r, c, num_nz) { }
 
   ~MSparse (void) { }
--- 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 <class T>
+Sparse<T>::Sparse (const PermMatrix& a)
+  : rep (new typename Sparse<T>::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<octave_idx_type> 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<double>::Sparse (const PermMatrix& a);
+template Sparse<bool>::Sparse (const PermMatrix& a);
+
 template <class T>
 T&
 Sparse<T>::SparseRep::elem (octave_idx_type _r, octave_idx_type _c)
--- 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<T>::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 <class U>
   Sparse (const Sparse<U>& a)
--- 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<bool> (a) { }
 
+  explicit SparseBoolMatrix (const PermMatrix& a) : Sparse<bool> (a) { };
+
   SparseBoolMatrix (const Array<bool>& a, const idx_vector& r,
                     const idx_vector& c, octave_idx_type nr = -1,
                     octave_idx_type nc = -1, bool sum_terms = true,
--- 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<double> (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<octave_idx_type> 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
 {
--- 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<double>(a) { }
 
   SparseMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : MSparse<double> (r, c, num_nz) { }
 
--- 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);
 }
--- 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
 {
--- 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