changeset 30801:568bddf0215e

deprecate sparse_auto_mutate function and internal variable * sparse.cc (Fsparse): Don't set Vsparse_auto_mutate to false. * ov-base.h, ov-base.cc (Vsparse_auto_mutate): Deprecate variable. (Fsparse_auto_mutate): Delete function and tests. * ov-bool-sparse.h, ov-bool-sparse.cc (octave_sparse_bool_matrix::try_narrowing_conversion): Delete. * ov-re-sparse.h, ov-re-sparse.cc (octave_sparse_bool_matrix::try_narrowing_conversion): Delete. * ov-cx-sparse.cc (octave_sparse_complex_matrix::try_narrowing_conversion): Only perform complex sparse -> real sparse conversion. * scripts/deprecated/sparse_auto_mutate.m: New function. * scripts/deprecated/module.mk: Update. * sparse.txi: Remove documentation for sparse_auto_mutate.
author John W. Eaton <jwe@octave.org>
date Wed, 02 Mar 2022 15:01:30 -0500
parents 16023ccebcca
children 836104321759
files doc/interpreter/sparse.txi libinterp/corefcn/sparse.cc libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-bool-sparse.cc libinterp/octave-value/ov-bool-sparse.h libinterp/octave-value/ov-cx-sparse.cc libinterp/octave-value/ov-re-sparse.cc libinterp/octave-value/ov-re-sparse.h scripts/deprecated/module.mk scripts/deprecated/sparse_auto_mutate.m
diffstat 11 files changed, 87 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/sparse.txi	Wed Mar 02 20:31:46 2022 +0100
+++ b/doc/interpreter/sparse.txi	Wed Mar 02 15:01:30 2022 -0500
@@ -530,13 +530,6 @@
 @noindent
 returns a full matrix as can be seen.
 
-
-Additionally, if @code{sparse_auto_mutate} is true, all sparse functions
-test the amount of memory occupied by the sparse matrix to see if the
-amount of storage used is larger than the amount used by the full
-equivalent.  Therefore @code{speye (2) * 1} will return a full matrix as
-the memory used is smaller for the full version than the sparse version.
-
 As all of the mixed operators and functions between full and sparse
 matrices exist, in general this does not cause any problems.  However,
 one area where it does cause a problem is where a sparse matrix is
@@ -561,11 +554,6 @@
 always returns a sparse matrix, even if the memory used will be larger
 than its full representation.
 
-@DOCSTRING(sparse_auto_mutate)
-
-Note that the @code{sparse_auto_mutate} option is incompatible with
-@sc{matlab}, and so it is off by default.
-
 @node Mathematical Considerations
 @subsubsection Mathematical Considerations
 
--- a/libinterp/corefcn/sparse.cc	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/corefcn/sparse.cc	Wed Mar 02 15:01:30 2022 -0500
@@ -155,9 +155,6 @@
 
   octave_value retval;
 
-  // Temporarily disable sparse_auto_mutate if set (it's obsolete anyway).
-  unwind_protect_var<bool> restore_var (Vsparse_auto_mutate, false);
-
   if (nargin == 1)
     {
       octave_value arg = args(0);
--- a/libinterp/octave-value/ov-base.cc	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-base.cc	Wed Mar 02 15:01:30 2022 -0500
@@ -98,8 +98,7 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
                                      "<unknown type>", "unknown");
 
-// TRUE means to perform automatic sparse to real mutation if there
-// is memory to be saved
+// DEPRECATED in Octave 8.
 bool Vsparse_auto_mutate = false;
 
 octave_base_value *
@@ -1547,49 +1546,4 @@
   INSTALL_WIDENOP_TI (ti, octave_base_value, octave_cell, cell_conv);
 }
 
-DEFUN (sparse_auto_mutate, args, nargout,
-       doc: /* -*- texinfo -*-
-@deftypefn  {} {@var{val} =} sparse_auto_mutate ()
-@deftypefnx {} {@var{old_val} =} sparse_auto_mutate (@var{new_val})
-@deftypefnx {} {@var{old_val} =} sparse_auto_mutate (@var{new_val}, "local")
-Query or set the internal variable that controls whether Octave will
-automatically mutate sparse matrices to full matrices to save memory.
-
-For example:
-
-@example
-@group
-s = speye (3);
-sparse_auto_mutate (false);
-s(:, 1) = 1;
-typeinfo (s)
-@result{} sparse matrix
-sparse_auto_mutate (true);
-s(1, :) = 1;
-typeinfo (s)
-@result{} matrix
-@end group
-@end example
-
-When called from inside a function with the @qcode{"local"} option, the
-variable is changed locally for the function and any subroutines it calls.
-The original variable value is restored when exiting the function.
-@end deftypefn */)
-{
-  return set_internal_variable (Vsparse_auto_mutate, args, nargout,
-                                "sparse_auto_mutate");
-}
-
-/*
-%!test
-%! s = speye (3);
-%! sparse_auto_mutate (false);
-%! s(:, 1) = 1;
-%! assert (typeinfo (s), "sparse matrix");
-%! sparse_auto_mutate (true);
-%! s(1, :) = 1;
-%! assert (typeinfo (s), "matrix");
-%! sparse_auto_mutate (false);
-*/
-
 OCTAVE_NAMESPACE_END
--- a/libinterp/octave-value/ov-base.h	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-base.h	Wed Mar 02 15:01:30 2022 -0500
@@ -935,8 +935,7 @@
   octave::auto_shlib m_containing_dynamic_library;
 };
 
-// TRUE means to perform automatic sparse to real mutation if there
-// is memory to be saved
+OCTAVE_DEPRECATED (8, "Vsparse_auto_mutate is obsolete and is now always false")
 extern OCTINTERP_API bool Vsparse_auto_mutate;
 
 // Utility function to convert C++ arguments used in subsref/subsasgn into an
--- a/libinterp/octave-value/ov-bool-sparse.cc	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-bool-sparse.cc	Wed Mar 02 15:01:30 2022 -0500
@@ -73,32 +73,6 @@
                                             octave_sparse_matrix::static_type_id ());
 }
 
-octave_base_value *
-octave_sparse_bool_matrix::try_narrowing_conversion (void)
-{
-  octave_base_value *retval = nullptr;
-
-  if (Vsparse_auto_mutate)
-    {
-      // Don't use numel, since it can overflow for very large matrices
-      // Note that for the second test, this means it becomes approximative
-      // since it involves a cast to double to avoid issues of overflow
-      if (matrix.rows () == 1 && matrix.cols () == 1)
-        {
-          // Const copy of the matrix, so the right version of () operator used
-          const SparseBoolMatrix tmp (matrix);
-
-          retval = new octave_bool (tmp (0));
-        }
-      else if (matrix.cols () > 0 && matrix.rows () > 0
-               && (double (matrix.byte_size ()) > double (matrix.rows ())
-                   * double (matrix.cols ()) * sizeof (bool)))
-        retval = new octave_bool_matrix (matrix.matrix_value ());
-    }
-
-  return retval;
-}
-
 double
 octave_sparse_bool_matrix::double_value (bool) const
 {
--- a/libinterp/octave-value/ov-bool-sparse.h	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-bool-sparse.h	Wed Mar 02 15:01:30 2022 -0500
@@ -84,8 +84,6 @@
 
   type_conv_info numeric_conversion_function (void) const;
 
-  octave_base_value * try_narrowing_conversion (void);
-
   // FIXME: Adapt idx_vector to allow sparse logical indexing without overflow!
   octave::idx_vector index_vector (bool /* require_integers */ = false) const
   {
--- a/libinterp/octave-value/ov-cx-sparse.cc	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-cx-sparse.cc	Wed Mar 02 15:01:30 2022 -0500
@@ -60,49 +60,8 @@
 octave_base_value *
 octave_sparse_complex_matrix::try_narrowing_conversion (void)
 {
-  octave_base_value *retval = nullptr;
-
-  if (Vsparse_auto_mutate)
-    {
-      int nr = matrix.rows ();
-      int nc = matrix.cols ();
-
-      // Don't use numel, since it can overflow for very large matrices
-      // Note that for the tests on matrix size, they become approximative
-      // since they involves a cast to double to avoid issues of overflow
-      if (matrix.rows () == 1 && matrix.cols () == 1)
-        {
-          // Const copy of the matrix, so the right version of () operator used
-          const SparseComplexMatrix tmp (matrix);
-
-          Complex c = tmp (0, 0);
-
-          if (c.imag () == 0.0)
-            retval = new octave_scalar (c.real ());
-          else
-            retval = new octave_complex (c);
-        }
-      else if (nr == 0 || nc == 0)
-        retval = new octave_matrix (Matrix (nr, nc));
-      else if (matrix.all_elements_are_real ())
-        if (matrix.cols () > 0 && matrix.rows () > 0
-            && (double (matrix.byte_size ()) > double (matrix.rows ())
-                * double (matrix.cols ()) * sizeof (double)))
-          retval = new octave_matrix (::real (matrix.matrix_value ()));
-        else
-          retval = new octave_sparse_matrix (::real (matrix));
-      else if (matrix.cols () > 0 && matrix.rows () > 0
-               && (double (matrix.byte_size ()) > double (matrix.rows ())
-                   * double (matrix.cols ()) * sizeof (Complex)))
-        retval = new octave_complex_matrix (matrix.matrix_value ());
-    }
-  else
-    {
-      if (matrix.all_elements_are_real ())
-        retval = new octave_sparse_matrix (::real (matrix));
-    }
-
-  return retval;
+  return (matrix.all_elements_are_real ()
+          ? new octave_sparse_matrix (::real (matrix)) : nullptr);
 }
 
 double
--- a/libinterp/octave-value/ov-re-sparse.cc	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-re-sparse.cc	Wed Mar 02 15:01:30 2022 -0500
@@ -69,32 +69,6 @@
     }
 }
 
-octave_base_value *
-octave_sparse_matrix::try_narrowing_conversion (void)
-{
-  octave_base_value *retval = nullptr;
-
-  if (Vsparse_auto_mutate)
-    {
-      // Don't use numel, since it can overflow for very large matrices
-      // Note that for the second test, this means it becomes approximative
-      // since it involves a cast to double to avoid issues of overflow
-      if (matrix.rows () == 1 && matrix.cols () == 1)
-        {
-          // Const copy of the matrix, so the right version of () operator used
-          const SparseMatrix tmp (matrix);
-
-          retval = new octave_scalar (tmp (0));
-        }
-      else if (matrix.cols () > 0 && matrix.rows () > 0
-               && (double (matrix.byte_size ()) > double (matrix.rows ())
-                   * double (matrix.cols ()) * sizeof (double)))
-        retval = new octave_matrix (matrix.matrix_value ());
-    }
-
-  return retval;
-}
-
 double
 octave_sparse_matrix::double_value (bool) const
 {
--- a/libinterp/octave-value/ov-re-sparse.h	Wed Mar 02 20:31:46 2022 +0100
+++ b/libinterp/octave-value/ov-re-sparse.h	Wed Mar 02 15:01:30 2022 -0500
@@ -91,8 +91,6 @@
   octave_base_value * empty_clone (void) const
   { return new octave_sparse_matrix (); }
 
-  octave_base_value * try_narrowing_conversion (void);
-
   octave::idx_vector index_vector (bool require_integers = false) const;
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
--- a/scripts/deprecated/module.mk	Wed Mar 02 20:31:46 2022 +0100
+++ b/scripts/deprecated/module.mk	Wed Mar 02 15:01:30 2022 -0500
@@ -5,7 +5,8 @@
   %reldir%/disable_diagonal_matrix.m \
   %reldir%/disable_permutation_matrix.m \
   %reldir%/disable_range.m \
-  %reldir%/shift.m
+  %reldir%/shift.m \
+  %reldir%/sparse_auto_mutate.m
 
 %canon_reldir%dir = $(fcnfiledir)/deprecated
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/sparse_auto_mutate.m	Wed Mar 02 15:01:30 2022 -0500
@@ -0,0 +1,81 @@
+########################################################################
+##
+## Copyright (C) 2022 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn  {} {@var{val} =} sparse_auto_mutate ()
+## @deftypefnx {} {@var{old_val} =} sparse_auto_mutate (@var{new_val})
+## @deftypefnx {} {@var{old_val} =} sparse_auto_mutate (@var{new_val}, "local")
+##
+## @code{sparse_auto_mutate} is deprecated and will be removed in Octave
+## version 9.  Use @code{optimize_diagonal_matrix} instead.
+##
+## Query or set whether storing diagonal matrices in a special space-efficient
+## format is disabled.
+##
+## The default value is false.  If this option is set to true, Octave will
+## store ranges as full matrices.
+##
+## When called from inside a function with the @qcode{"local"} option, the
+## setting is changed locally for the function and any subroutines it calls.
+## The original setting is restored when exiting the function.
+## @seealso{sparse_auto_mutate, disable_permutation_matrix}
+## @end deftypefn
+
+## FIXME: DEPRECATED: Remove in version 10.
+
+function retval = sparse_auto_mutate (val, opt)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "sparse_auto_mutate is obsolete, has no effect, and will be removed from a future version of Octave\n");
+  endif
+
+  if (nargin == 0 || nargout > 0)
+    ## Always false now.
+    retval = false;
+    return;
+  endif
+
+  if (nargin == 2)
+    if (! (ischar (opt) && strcmp (opt, "local")))
+      error ('sparse_auto_mutate: second argument must be "local"');
+    endif
+    nargin = 1;
+  endif
+
+  ## Don't bother warning that "local" is invalid outside of a
+  ## function.
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  if (! islogical (val))
+    error ("sparse_auto_mutate: argument must be a logical value");
+  endif
+
+endfunction