[Pkg-octave-devel] Bug#706376: Bug#706376: Bug#706376: Bug#706376: octave: sparse matrix n*2^16

David Bateman david at bateman.eu
Sat Jun 15 15:00:14 UTC 2013


On 05/06/2013 04:24 PM, Jordi Gutiérrez Hermoso wrote:
> On 4 May 2013 20:50, Ed Meyer <eem2314 at gmail.com> wrote:
>> I think I see why numel() is getting called from trace(). isempty()
>> is called which calls is_empty() which should be virtual. Were it to
>> call the sparse version of is_empty() there would be no problem
>> because it tests the row & column dimensions instead of calling
>> numel(). So shouldn't is_empty() be virtual?
> Sure, this patches this hole. What about linear indexing, how will you
> patch that one?
>
> - Jordi G. H.
>
That a bit of a specious argument. "Because we can't solve problem B we
shouldn't solve problem A". Taking this argument to the absurd this
shouldn't work either

n = 2^16;
s = sparse (1:n,1:n,1);
t = s * s;

as t will have more elements than can be indexed with octave_idx_type.
Clear it works. So essentially you're saying that sparse matrices with
32-bit indexing and numel larger than 2^31 are useless!!

A lot of attention was made in the sparse implementation to not rely
either on linear indexing or the value of numel to avoid this issue. I'd
think that any function or operator that relies on either for sparse
matrices, or at least when it doesn't have to, is buggy.

Ed is right the is_empty method of the octave_base_value class should be
specialized for sparse matrices as in the attached changeset as it has
no need to rely on numel. Then any function that relies on isempty
should now work for sparse matrices.

David

-------------- next part --------------
# HG changeset patch
# User David Bateman <dbateman at free.fr>
# Date 1371308306 -7200
# Node ID d5c61e2aefa428e9b51d5671ff1e72e7de90a500
# Parent  1c8b6ab2c8ae71f1fdef51016472396a6665f483
Specialize is_empty method for sparse matrices

* ov-base.h (virtual bool is_empty (void) const) : Make method virtual
* ov-base-sparse.h (bool is_empty (void) const)) : Declare new method
* ov-base-sparse.cc (template <class T> bool octave_base_sparse<T>:is_empty
(void) const)) : Define new method

diff --git a/libinterp/octave-value/ov-base-sparse.cc b/libinterp/octave-value/ov-base-sparse.cc
--- a/libinterp/octave-value/ov-base-sparse.cc
+++ b/libinterp/octave-value/ov-base-sparse.cc
@@ -278,6 +278,15 @@
 
 template <class T>
 bool
+octave_base_sparse<T>::is_empty (void) const
+{
+  dim_vector dv = dims ();
+
+  return (dv.any_zero ());
+}
+
+template <class T>
+bool
 octave_base_sparse<T>::print_as_scalar (void) const
 {
   dim_vector dv = dims ();
diff --git a/libinterp/octave-value/ov-base-sparse.h b/libinterp/octave-value/ov-base-sparse.h
--- a/libinterp/octave-value/ov-base-sparse.h
+++ b/libinterp/octave-value/ov-base-sparse.h
@@ -137,6 +137,8 @@
 
   bool is_defined (void) const { return true; }
 
+  bool is_empty (void) const;
+
   bool is_constant (void) const { return true; }
 
   bool is_true (void) const;
diff --git a/libinterp/octave-value/ov-base.h b/libinterp/octave-value/ov-base.h
--- a/libinterp/octave-value/ov-base.h
+++ b/libinterp/octave-value/ov-base.h
@@ -331,7 +331,7 @@
 
   virtual bool is_defined (void) const { return false; }
 
-  bool is_empty (void) const { return numel () == 0; }
+  virtual bool is_empty (void) const { return numel () == 0; }
 
   virtual bool is_cell (void) const { return false; }
 


More information about the Pkg-octave-devel mailing list