Mercurial > octave-nkf
diff src/octave-value/ov-base.cc @ 15057:46b19589b593
maint: Partition src/ directory with more code in subdirs.
Create new octave-value dir for ov* code.
Create new parse-tre dir for pt* code.
Move OPERATORS and TEMPLATE-INST directories to lowercase names
* octave-value/module.mk: Hook code in octave-value dir into build system.
* octave-value/ov-base-diag.cc,
octave-value/ov-base-diag.h, octave-value/ov-base-int.cc,
octave-value/ov-base-int.h, octave-value/ov-base-mat.cc,
octave-value/ov-base-mat.h, octave-value/ov-base-scalar.cc,
octave-value/ov-base-scalar.h, octave-value/ov-base-sparse.cc,
octave-value/ov-base-sparse.h, octave-value/ov-base.cc, octave-value/ov-base.h,
octave-value/ov-bool-mat.cc, octave-value/ov-bool-mat.h,
octave-value/ov-bool-sparse.cc, octave-value/ov-bool-sparse.h,
octave-value/ov-bool.cc, octave-value/ov-bool.h, octave-value/ov-builtin.cc,
octave-value/ov-builtin.h, octave-value/ov-cell.cc, octave-value/ov-cell.h,
octave-value/ov-ch-mat.cc, octave-value/ov-ch-mat.h, octave-value/ov-class.cc,
octave-value/ov-class.h, octave-value/ov-colon.cc, octave-value/ov-colon.h,
octave-value/ov-complex.cc, octave-value/ov-complex.h,
octave-value/ov-cs-list.cc, octave-value/ov-cs-list.h,
octave-value/ov-cx-diag.cc, octave-value/ov-cx-diag.h,
octave-value/ov-cx-mat.cc, octave-value/ov-cx-mat.h,
octave-value/ov-cx-sparse.cc, octave-value/ov-cx-sparse.h,
octave-value/ov-dld-fcn.cc, octave-value/ov-dld-fcn.h,
octave-value/ov-fcn-handle.cc, octave-value/ov-fcn-handle.h,
octave-value/ov-fcn-inline.cc, octave-value/ov-fcn-inline.h,
octave-value/ov-fcn.cc, octave-value/ov-fcn.h, octave-value/ov-float.cc,
octave-value/ov-float.h, octave-value/ov-flt-complex.cc,
octave-value/ov-flt-complex.h, octave-value/ov-flt-cx-diag.cc,
octave-value/ov-flt-cx-diag.h, octave-value/ov-flt-cx-mat.cc,
octave-value/ov-flt-cx-mat.h, octave-value/ov-flt-re-diag.cc,
octave-value/ov-flt-re-diag.h, octave-value/ov-flt-re-mat.cc,
octave-value/ov-flt-re-mat.h, octave-value/ov-int-traits.h,
octave-value/ov-int16.cc, octave-value/ov-int16.h, octave-value/ov-int32.cc,
octave-value/ov-int32.h, octave-value/ov-int64.cc, octave-value/ov-int64.h,
octave-value/ov-int8.cc, octave-value/ov-int8.h, octave-value/ov-intx.h,
octave-value/ov-lazy-idx.cc, octave-value/ov-lazy-idx.h,
octave-value/ov-mex-fcn.cc, octave-value/ov-mex-fcn.h,
octave-value/ov-null-mat.cc, octave-value/ov-null-mat.h,
octave-value/ov-oncleanup.cc, octave-value/ov-oncleanup.h,
octave-value/ov-perm.cc, octave-value/ov-perm.h, octave-value/ov-range.cc,
octave-value/ov-range.h, octave-value/ov-re-diag.cc, octave-value/ov-re-diag.h,
octave-value/ov-re-mat.cc, octave-value/ov-re-mat.h,
octave-value/ov-re-sparse.cc, octave-value/ov-re-sparse.h,
octave-value/ov-scalar.cc, octave-value/ov-scalar.h,
octave-value/ov-str-mat.cc, octave-value/ov-str-mat.h,
octave-value/ov-struct.cc, octave-value/ov-struct.h,
octave-value/ov-type-conv.h, octave-value/ov-typeinfo.cc,
octave-value/ov-typeinfo.h, octave-value/ov-uint16.cc,
octave-value/ov-uint16.h, octave-value/ov-uint32.cc, octave-value/ov-uint32.h,
octave-value/ov-uint64.cc, octave-value/ov-uint64.h, octave-value/ov-uint8.cc,
octave-value/ov-uint8.h, octave-value/ov-usr-fcn.cc, octave-value/ov-usr-fcn.h,
octave-value/ov.cc, octave-value/ov.h: Moved from src/ dir to octave-value dir.
* operators/module.mk, operators/op-b-b.cc, operators/op-b-bm.cc,
operators/op-b-sbm.cc, operators/op-bm-b.cc, operators/op-bm-bm.cc,
operators/op-bm-sbm.cc, operators/op-cdm-cdm.cc, operators/op-cdm-cm.cc,
operators/op-cdm-cs.cc, operators/op-cdm-dm.cc, operators/op-cdm-m.cc,
operators/op-cdm-s.cc, operators/op-cell.cc, operators/op-chm.cc,
operators/op-class.cc, operators/op-cm-cdm.cc, operators/op-cm-cm.cc,
operators/op-cm-cs.cc, operators/op-cm-dm.cc, operators/op-cm-m.cc,
operators/op-cm-pm.cc, operators/op-cm-s.cc, operators/op-cm-scm.cc,
operators/op-cm-sm.cc, operators/op-cs-cm.cc, operators/op-cs-cs.cc,
operators/op-cs-m.cc, operators/op-cs-s.cc, operators/op-cs-scm.cc,
operators/op-cs-sm.cc, operators/op-dm-cdm.cc, operators/op-dm-cm.cc,
operators/op-dm-cs.cc, operators/op-dm-dm.cc, operators/op-dm-m.cc,
operators/op-dm-s.cc, operators/op-dm-scm.cc, operators/op-dm-sm.cc,
operators/op-dm-template.cc, operators/op-dms-template.cc,
operators/op-double-conv.cc, operators/op-fcdm-fcdm.cc,
operators/op-fcdm-fcm.cc, operators/op-fcdm-fcs.cc, operators/op-fcdm-fdm.cc,
operators/op-fcdm-fm.cc, operators/op-fcdm-fs.cc, operators/op-fcm-fcdm.cc,
operators/op-fcm-fcm.cc, operators/op-fcm-fcs.cc, operators/op-fcm-fdm.cc,
operators/op-fcm-fm.cc, operators/op-fcm-fs.cc, operators/op-fcm-pm.cc,
operators/op-fcn.cc, operators/op-fcs-fcm.cc, operators/op-fcs-fcs.cc,
operators/op-fcs-fm.cc, operators/op-fcs-fs.cc, operators/op-fdm-fcdm.cc,
operators/op-fdm-fcm.cc, operators/op-fdm-fcs.cc, operators/op-fdm-fdm.cc,
operators/op-fdm-fm.cc, operators/op-fdm-fs.cc, operators/op-float-conv.cc,
operators/op-fm-fcdm.cc, operators/op-fm-fcm.cc, operators/op-fm-fcs.cc,
operators/op-fm-fdm.cc, operators/op-fm-fm.cc, operators/op-fm-fs.cc,
operators/op-fm-pm.cc, operators/op-fs-fcm.cc, operators/op-fs-fcs.cc,
operators/op-fs-fm.cc, operators/op-fs-fs.cc, operators/op-i16-i16.cc,
operators/op-i32-i32.cc, operators/op-i64-i64.cc, operators/op-i8-i8.cc,
operators/op-int-concat.cc, operators/op-int-conv.cc, operators/op-int.h,
operators/op-m-cdm.cc, operators/op-m-cm.cc, operators/op-m-cs.cc,
operators/op-m-dm.cc, operators/op-m-m.cc, operators/op-m-pm.cc,
operators/op-m-s.cc, operators/op-m-scm.cc, operators/op-m-sm.cc,
operators/op-pm-cm.cc, operators/op-pm-fcm.cc, operators/op-pm-fm.cc,
operators/op-pm-m.cc, operators/op-pm-pm.cc, operators/op-pm-scm.cc,
operators/op-pm-sm.cc, operators/op-pm-template.cc, operators/op-range.cc,
operators/op-s-cm.cc, operators/op-s-cs.cc, operators/op-s-m.cc,
operators/op-s-s.cc, operators/op-s-scm.cc, operators/op-s-sm.cc,
operators/op-sbm-b.cc, operators/op-sbm-bm.cc, operators/op-sbm-sbm.cc,
operators/op-scm-cm.cc, operators/op-scm-cs.cc, operators/op-scm-m.cc,
operators/op-scm-s.cc, operators/op-scm-scm.cc, operators/op-scm-sm.cc,
operators/op-sm-cm.cc, operators/op-sm-cs.cc, operators/op-sm-m.cc,
operators/op-sm-s.cc, operators/op-sm-scm.cc, operators/op-sm-sm.cc,
operators/op-str-m.cc, operators/op-str-s.cc, operators/op-str-str.cc,
operators/op-struct.cc, operators/op-ui16-ui16.cc, operators/op-ui32-ui32.cc,
operators/op-ui64-ui64.cc, operators/op-ui8-ui8.cc: Moved from OPERATORS/
dir to operators/ directory.
* mkops: Correctly print comment in generated file ops.cc that it is made by
mkops. Change sed expression for OPERATORS/ to operators/.
* parse-tree/module.mk: Hook code in parse-tree dir into build system.
* parse-tree/pt-all.h, parse-tree/pt-arg-list.cc, parse-tree/pt-arg-list.h,
parse-tree/pt-assign.cc, parse-tree/pt-assign.h, parse-tree/pt-binop.cc,
parse-tree/pt-binop.h, parse-tree/pt-bp.cc, parse-tree/pt-bp.h,
parse-tree/pt-cbinop.cc, parse-tree/pt-cbinop.h, parse-tree/pt-cell.cc,
parse-tree/pt-cell.h, parse-tree/pt-check.cc, parse-tree/pt-check.h,
parse-tree/pt-cmd.cc, parse-tree/pt-cmd.h, parse-tree/pt-colon.cc,
parse-tree/pt-colon.h, parse-tree/pt-const.cc, parse-tree/pt-const.h,
parse-tree/pt-decl.cc, parse-tree/pt-decl.h, parse-tree/pt-eval.cc,
parse-tree/pt-eval.h, parse-tree/pt-except.cc, parse-tree/pt-except.h,
parse-tree/pt-exp.cc, parse-tree/pt-exp.h, parse-tree/pt-fcn-handle.cc,
parse-tree/pt-fcn-handle.h, parse-tree/pt-id.cc, parse-tree/pt-id.h,
parse-tree/pt-idx.cc, parse-tree/pt-idx.h, parse-tree/pt-jump.cc,
parse-tree/pt-jump.h, parse-tree/pt-loop.cc, parse-tree/pt-loop.h,
parse-tree/pt-mat.cc, parse-tree/pt-mat.h, parse-tree/pt-misc.cc,
parse-tree/pt-misc.h, parse-tree/pt-pr-code.cc, parse-tree/pt-pr-code.h,
parse-tree/pt-select.cc, parse-tree/pt-select.h, parse-tree/pt-stmt.cc,
parse-tree/pt-stmt.h, parse-tree/pt-unop.cc, parse-tree/pt-unop.h,
parse-tree/pt-walk.h, parse-tree/pt.cc, parse-tree/pt.h:
Moved from src/ dir to parse-tree dir.
* template-inst/Array-jit.cc, template-inst/Array-os.cc,
template-inst/Array-sym.cc, template-inst/Array-tc.cc, template-inst/module.mk:
Moved from TEMPLATE-INST dir to template-inst/ directory.
* src/Makefile.am: Add new directories to build system.
* corefcn/module.mk: Use COREFCN_SRC with all capitals to indicate it is not an
Automake special target.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 30 Jul 2012 15:29:19 -0700 |
parents | src/ov-base.cc@460a3c6d8bf1 |
children | 62a35ae7d6a2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/octave-value/ov-base.cc Mon Jul 30 15:29:19 2012 -0700 @@ -0,0 +1,1579 @@ +/* + +Copyright (C) 1996-2012 John W. Eaton +Copyright (C) 2009-2010 VZLU Prague + +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 +<http://www.gnu.org/licenses/>. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <climits> + +#include <iostream> + +#include "lo-ieee.h" +#include "lo-mappers.h" + +#include "defun.h" +#include "gripes.h" +#include "oct-map.h" +#include "oct-obj.h" +#include "oct-lvalue.h" +#include "oct-stream.h" +#include "ops.h" +#include "ov-base.h" +#include "ov-cell.h" +#include "ov-ch-mat.h" +#include "ov-complex.h" +#include "ov-cx-mat.h" +#include "ov-range.h" +#include "ov-re-mat.h" +#include "ov-scalar.h" +#include "ov-str-mat.h" +#include "ov-fcn-handle.h" +#include "parse.h" +#include "pr-output.h" +#include "utils.h" +#include "variables.h" + +builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y) +{ + builtin_type_t retval = btyp_unknown; + + if (x == btyp_bool) + x = btyp_double; + if (y == btyp_bool) + y = btyp_double; + + if (x <= btyp_float_complex && y <= btyp_float_complex) + retval = static_cast<builtin_type_t> (x | y); + else if (x <= btyp_uint64 && y <= btyp_float) + retval = x; + else if (x <= btyp_float && y <= btyp_uint64) + retval = y; + else if ((x >= btyp_int8 && x <= btyp_int64 + && y >= btyp_int8 && y <= btyp_int64) + || (x >= btyp_uint8 && x <= btyp_uint64 + && y >= btyp_uint8 && y <= btyp_uint64)) + retval = (x > y) ? x : y; + + return retval; +} + +std::string btyp_class_name[btyp_num_types] = +{ + "double", "single", "double", "single", + "int8", "int16", "int32", "int64", + "uint8", "uint16", "uint32", "uint64", + "logical", "char", + "struct", "cell", "function_handle" +}; + +string_vector +get_builtin_classes (void) +{ + static string_vector retval; + + if (retval.is_empty ()) + { + int n = btyp_num_types - 2; + retval = string_vector (n); + int j = 0; + for (int i = 0; i < btyp_num_types; i++) + { + builtin_type_t ityp = static_cast<builtin_type_t> (i); + if (ityp != btyp_complex && ityp != btyp_float_complex) + retval(j++) = btyp_class_name[i]; + } + } + + return retval; +} + +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 +bool Vsparse_auto_mutate = false; + +octave_base_value * +octave_base_value::empty_clone (void) const +{ + return resize (dim_vector ()).clone (); +} + +octave_value +octave_base_value::squeeze (void) const +{ + std::string nm = type_name (); + error ("squeeze: invalid operation for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value +octave_base_value::full_value (void) const +{ + gripe_wrong_type_arg ("full: invalid operation for %s type", type_name ()); + return octave_value (); +} + +Matrix +octave_base_value::size (void) +{ + const dim_vector dv = dims (); + Matrix mdv (1, dv.length ()); + for (octave_idx_type i = 0; i < dv.length (); i++) + mdv(i) = dv(i); + return mdv; +} + +octave_idx_type +octave_base_value::numel (const octave_value_list& idx) +{ + return dims_to_numel (dims (), idx); +} + +octave_value +octave_base_value::subsref (const std::string&, + const std::list<octave_value_list>&) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value_list +octave_base_value::subsref (const std::string&, + const std::list<octave_value_list>&, int) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value +octave_base_value::subsref (const std::string& type, + const std::list<octave_value_list>& idx, + bool /* auto_add */) +{ + // This way we may get a more meaningful error message. + return subsref (type, idx); +} + +octave_value_list +octave_base_value::subsref (const std::string& type, + const std::list<octave_value_list>& idx, + int nargout, + const std::list<octave_lvalue> *) +{ + // Fall back to call without passing lvalue list. + return subsref (type, idx, nargout); +} + +octave_value +octave_base_value::do_index_op (const octave_value_list&, bool) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value_list +octave_base_value::do_multi_index_op (int, const octave_value_list&) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value_list +octave_base_value::do_multi_index_op (int nargout, const octave_value_list& idx, + const std::list<octave_lvalue> *) +{ + // Fall back. + return do_multi_index_op (nargout, idx); +} + +idx_vector +octave_base_value::index_vector (void) const +{ + std::string nm = type_name (); + error ("%s type invalid as index value", nm.c_str ()); + return idx_vector (); +} + +octave_value +octave_base_value::subsasgn (const std::string& type, + const std::list<octave_value_list>& idx, + const octave_value& rhs) +{ + octave_value retval; + + if (is_defined ()) + { + if (is_numeric_type ()) + { + switch (type[0]) + { + case '(': + { + if (type.length () == 1) + retval = numeric_assign (type, idx, rhs); + else if (is_empty ()) + { + // Allow conversion of empty matrix to some other + // type in cases like + // + // x = []; x(i).f = rhs + + octave_value tmp = octave_value::empty_conv (type, rhs); + + retval = tmp.subsasgn (type, idx, rhs); + } + else + { + std::string nm = type_name (); + error ("in indexed assignment of %s, last rhs index must be ()", + nm.c_str ()); + } + } + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + } + else + { + std::string nm = type_name (); + error ("can't perform indexed assignment for %s type", nm.c_str ()); + } + } + else + { + // Create new object of appropriate type for given index and rhs + // types and then call undef_subsasgn for that object. + + octave_value tmp = octave_value::empty_conv (type, rhs); + + retval = tmp.undef_subsasgn (type, idx, rhs); + } + + return retval; +} + +octave_value +octave_base_value::undef_subsasgn (const std::string& type, + const std::list<octave_value_list>& idx, + const octave_value& rhs) +{ + // In most cases, undef_subsasgn is handled the sams as subsasgn. One + // exception is octave_class objects. + + return subsasgn (type, idx, rhs); +} + +octave_idx_type +octave_base_value::nnz (void) const +{ + gripe_wrong_type_arg ("octave_base_value::nnz ()", type_name ()); + return -1; +} + +octave_idx_type +octave_base_value::nzmax (void) const +{ + return numel (); +} + +octave_idx_type +octave_base_value::nfields (void) const +{ + gripe_wrong_type_arg ("octave_base_value::nfields ()", type_name ()); + return -1; +} + +octave_value +octave_base_value::reshape (const dim_vector&) const +{ + gripe_wrong_type_arg ("octave_base_value::reshape ()", type_name ()); + return octave_value (); +} + +octave_value +octave_base_value::permute (const Array<int>&, bool) const +{ + gripe_wrong_type_arg ("octave_base_value::permute ()", type_name ()); + return octave_value (); +} + +octave_value +octave_base_value::resize (const dim_vector&, bool) const +{ + gripe_wrong_type_arg ("octave_base_value::resize ()", type_name ()); + return octave_value (); +} + +MatrixType +octave_base_value::matrix_type (void) const +{ + gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ()); + return MatrixType (); +} + +MatrixType +octave_base_value::matrix_type (const MatrixType&) const +{ + gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ()); + return MatrixType (); +} + +octave_value +octave_base_value::all (int) const +{ + return 0.0; +} + +octave_value +octave_base_value::any (int) const +{ + return 0.0; +} + +octave_value +octave_base_value::convert_to_str (bool pad, bool force, char type) const +{ + octave_value retval = convert_to_str_internal (pad, force, type); + + if (! force && is_numeric_type ()) + gripe_implicit_conversion ("Octave:num-to-str", + type_name (), retval.type_name ()); + + return retval; +} + +octave_value +octave_base_value::convert_to_str_internal (bool, bool, char) const +{ + gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()", + type_name ()); + return octave_value (); +} + +void +octave_base_value::convert_to_row_or_column_vector (void) +{ + gripe_wrong_type_arg + ("octave_base_value::convert_to_row_or_column_vector ()", + type_name ()); +} + +void +octave_base_value::print (std::ostream&, bool) const +{ + gripe_wrong_type_arg ("octave_base_value::print ()", type_name ()); +} + +void +octave_base_value::print_raw (std::ostream&, bool) const +{ + gripe_wrong_type_arg ("octave_base_value::print_raw ()", type_name ()); +} + +bool +octave_base_value::print_name_tag (std::ostream& os, const std::string& name) const +{ + bool retval = false; + + indent (os); + + if (print_as_scalar ()) + os << name << " = "; + else + { + os << name << " ="; + newline (os); + if (! Vcompact_format) + newline (os); + + retval = true; + } + + return retval; +} + +void +octave_base_value::print_with_name (std::ostream& output_buf, + const std::string& name, + bool print_padding) +{ + bool pad_after = print_name_tag (output_buf, name); + + print (output_buf); + + if (print_padding && pad_after && ! Vcompact_format) + newline (output_buf); +} + +void +octave_base_value::print_info (std::ostream& os, + const std::string& /* prefix */) const +{ + os << "no info for type: " << type_name () << "\n"; +} + +#define INT_CONV_METHOD(T, F, MIN_LIMIT, MAX_LIMIT) \ + T \ + octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \ + { \ + T retval = 0; \ + \ + double d = double_value (frc_str_conv); \ + \ + if (! error_state) \ + { \ + if (require_int && D_NINT (d) != d) \ + error_with_cfn ("conversion of %g to " #T " value failed", d); \ + else if (d < MIN_LIMIT) \ + retval = MIN_LIMIT; \ + else if (d > MAX_LIMIT) \ + retval = MAX_LIMIT; \ + else \ + retval = static_cast<T> (::fix (d)); \ + } \ + else \ + gripe_wrong_type_arg ("octave_base_value::" #F "_value ()", \ + type_name ()); \ + \ + return retval; \ + } + +INT_CONV_METHOD (short int, short, SHRT_MIN, SHRT_MAX) +INT_CONV_METHOD (unsigned short int, ushort, 0, USHRT_MAX) + +INT_CONV_METHOD (int, int, INT_MIN, INT_MAX) +INT_CONV_METHOD (unsigned int, uint, 0, UINT_MAX) + +INT_CONV_METHOD (long int, long, LONG_MIN, LONG_MAX) +INT_CONV_METHOD (unsigned long int, ulong, 0, ULONG_MAX) + +int +octave_base_value::nint_value (bool frc_str_conv) const +{ + int retval = 0; + + double d = double_value (frc_str_conv); + + if (! error_state) + { + if (xisnan (d)) + { + error ("conversion of NaN to integer value failed"); + return retval; + } + + retval = static_cast<int> (::fix (d)); + } + else + gripe_wrong_type_arg ("octave_base_value::nint_value ()", type_name ()); + + return retval; +} + +double +octave_base_value::double_value (bool) const +{ + double retval = lo_ieee_nan_value (); + gripe_wrong_type_arg ("octave_base_value::double_value ()", type_name ()); + return retval; +} + +float +octave_base_value::float_value (bool) const +{ + float retval = lo_ieee_float_nan_value (); + gripe_wrong_type_arg ("octave_base_value::float_value ()", type_name ()); + return retval; +} + +Cell +octave_base_value::cell_value () const +{ + Cell retval; + gripe_wrong_type_arg ("octave_base_value::cell_value()", type_name ()); + return retval; +} + +Matrix +octave_base_value::matrix_value (bool) const +{ + Matrix retval; + gripe_wrong_type_arg ("octave_base_value::matrix_value()", type_name ()); + return retval; +} + +FloatMatrix +octave_base_value::float_matrix_value (bool) const +{ + FloatMatrix retval; + gripe_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ()); + return retval; +} + +NDArray +octave_base_value::array_value (bool) const +{ + FloatNDArray retval; + gripe_wrong_type_arg ("octave_base_value::array_value()", type_name ()); + return retval; +} + +FloatNDArray +octave_base_value::float_array_value (bool) const +{ + FloatNDArray retval; + gripe_wrong_type_arg ("octave_base_value::float_array_value()", type_name ()); + return retval; +} + +Complex +octave_base_value::complex_value (bool) const +{ + double tmp = lo_ieee_nan_value (); + Complex retval (tmp, tmp); + gripe_wrong_type_arg ("octave_base_value::complex_value()", type_name ()); + return retval; +} + +FloatComplex +octave_base_value::float_complex_value (bool) const +{ + float tmp = lo_ieee_float_nan_value (); + FloatComplex retval (tmp, tmp); + gripe_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ()); + return retval; +} + +ComplexMatrix +octave_base_value::complex_matrix_value (bool) const +{ + ComplexMatrix retval; + gripe_wrong_type_arg ("octave_base_value::complex_matrix_value()", + type_name ()); + return retval; +} + +FloatComplexMatrix +octave_base_value::float_complex_matrix_value (bool) const +{ + FloatComplexMatrix retval; + gripe_wrong_type_arg ("octave_base_value::float_complex_matrix_value()", + type_name ()); + return retval; +} + +ComplexNDArray +octave_base_value::complex_array_value (bool) const +{ + ComplexNDArray retval; + gripe_wrong_type_arg ("octave_base_value::complex_array_value()", + type_name ()); + return retval; +} + +FloatComplexNDArray +octave_base_value::float_complex_array_value (bool) const +{ + FloatComplexNDArray retval; + gripe_wrong_type_arg ("octave_base_value::float_complex_array_value()", + type_name ()); + return retval; +} + +bool +octave_base_value::bool_value (bool) const +{ + bool retval = false; + gripe_wrong_type_arg ("octave_base_value::bool_value()", type_name ()); + return retval; +} + +boolMatrix +octave_base_value::bool_matrix_value (bool) const +{ + boolMatrix retval; + gripe_wrong_type_arg ("octave_base_value::bool_matrix_value()", + type_name ()); + return retval; +} + +boolNDArray +octave_base_value::bool_array_value (bool) const +{ + boolNDArray retval; + gripe_wrong_type_arg ("octave_base_value::bool_array_value()", + type_name ()); + return retval; +} + +charMatrix +octave_base_value::char_matrix_value (bool force) const +{ + charMatrix retval; + + octave_value tmp = convert_to_str (false, force); + + if (! error_state) + retval = tmp.char_matrix_value (); + + return retval; +} + +charNDArray +octave_base_value::char_array_value (bool) const +{ + charNDArray retval; + gripe_wrong_type_arg ("octave_base_value::char_array_value()", + type_name ()); + return retval; +} + +SparseMatrix +octave_base_value::sparse_matrix_value (bool) const +{ + SparseMatrix retval; + gripe_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ()); + return retval; +} + +SparseComplexMatrix +octave_base_value::sparse_complex_matrix_value (bool) const +{ + SparseComplexMatrix retval; + gripe_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()", type_name ()); + return retval; +} + +SparseBoolMatrix +octave_base_value::sparse_bool_matrix_value (bool) const +{ + SparseBoolMatrix retval; + gripe_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()", type_name ()); + return retval; +} + +DiagMatrix +octave_base_value::diag_matrix_value (bool) const +{ + DiagMatrix retval; + gripe_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ()); + return retval; +} + +FloatDiagMatrix +octave_base_value::float_diag_matrix_value (bool) const +{ + FloatDiagMatrix retval; + gripe_wrong_type_arg ("octave_base_value::float_diag_matrix_value()", type_name ()); + return retval; +} + +ComplexDiagMatrix +octave_base_value::complex_diag_matrix_value (bool) const +{ + ComplexDiagMatrix retval; + gripe_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()", type_name ()); + return retval; +} + +FloatComplexDiagMatrix +octave_base_value::float_complex_diag_matrix_value (bool) const +{ + FloatComplexDiagMatrix retval; + gripe_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()", type_name ()); + return retval; +} + +PermMatrix +octave_base_value::perm_matrix_value (void) const +{ + PermMatrix retval; + gripe_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ()); + return retval; +} + +octave_int8 +octave_base_value::int8_scalar_value (void) const +{ + octave_int8 retval; + gripe_wrong_type_arg ("octave_base_value::int8_scalar_value()", + type_name ()); + return retval; +} + +octave_int16 +octave_base_value::int16_scalar_value (void) const +{ + octave_int16 retval; + gripe_wrong_type_arg ("octave_base_value::int16_scalar_value()", + type_name ()); + return retval; +} + +octave_int32 +octave_base_value::int32_scalar_value (void) const +{ + octave_int32 retval; + gripe_wrong_type_arg ("octave_base_value::int32_scalar_value()", + type_name ()); + return retval; +} + +octave_int64 +octave_base_value::int64_scalar_value (void) const +{ + octave_int64 retval; + gripe_wrong_type_arg ("octave_base_value::int64_scalar_value()", + type_name ()); + return retval; +} + +octave_uint8 +octave_base_value::uint8_scalar_value (void) const +{ + octave_uint8 retval; + gripe_wrong_type_arg ("octave_base_value::uint8_scalar_value()", + type_name ()); + return retval; +} + +octave_uint16 +octave_base_value::uint16_scalar_value (void) const +{ + octave_uint16 retval; + gripe_wrong_type_arg ("octave_base_value::uint16_scalar_value()", + type_name ()); + return retval; +} + +octave_uint32 +octave_base_value::uint32_scalar_value (void) const +{ + octave_uint32 retval; + gripe_wrong_type_arg ("octave_base_value::uint32_scalar_value()", + type_name ()); + return retval; +} + +octave_uint64 +octave_base_value::uint64_scalar_value (void) const +{ + octave_uint64 retval; + gripe_wrong_type_arg ("octave_base_value::uint64_scalar_value()", + type_name ()); + return retval; +} + +int8NDArray +octave_base_value::int8_array_value (void) const +{ + int8NDArray retval; + gripe_wrong_type_arg ("octave_base_value::int8_array_value()", + type_name ()); + return retval; +} + +int16NDArray +octave_base_value::int16_array_value (void) const +{ + int16NDArray retval; + gripe_wrong_type_arg ("octave_base_value::int16_array_value()", + type_name ()); + return retval; +} + +int32NDArray +octave_base_value::int32_array_value (void) const +{ + int32NDArray retval; + gripe_wrong_type_arg ("octave_base_value::int32_array_value()", + type_name ()); + return retval; +} + +int64NDArray +octave_base_value::int64_array_value (void) const +{ + int64NDArray retval; + gripe_wrong_type_arg ("octave_base_value::int64_array_value()", + type_name ()); + return retval; +} + +uint8NDArray +octave_base_value::uint8_array_value (void) const +{ + uint8NDArray retval; + gripe_wrong_type_arg ("octave_base_value::uint8_array_value()", + type_name ()); + return retval; +} + +uint16NDArray +octave_base_value::uint16_array_value (void) const +{ + uint16NDArray retval; + gripe_wrong_type_arg ("octave_base_value::uint16_array_value()", + type_name ()); + return retval; +} + +uint32NDArray +octave_base_value::uint32_array_value (void) const +{ + uint32NDArray retval; + gripe_wrong_type_arg ("octave_base_value::uint32_array_value()", + type_name ()); + return retval; +} + +uint64NDArray +octave_base_value::uint64_array_value (void) const +{ + uint64NDArray retval; + gripe_wrong_type_arg ("octave_base_value::uint64_array_value()", + type_name ()); + return retval; +} + +string_vector +octave_base_value::all_strings (bool pad) const +{ + string_vector retval; + + octave_value tmp = convert_to_str (pad, true); + + if (! error_state) + retval = tmp.all_strings (); + + return retval; +} + +std::string +octave_base_value::string_value (bool force) const +{ + std::string retval; + + octave_value tmp = convert_to_str (force); + + if (! error_state) + retval = tmp.string_value (); + + return retval; +} + +Array<std::string> +octave_base_value::cellstr_value (void) const +{ + Array<std::string> retval; + gripe_wrong_type_arg ("octave_base_value::cellstry_value()", + type_name ()); + return retval; +} + +Range +octave_base_value::range_value (void) const +{ + Range retval; + gripe_wrong_type_arg ("octave_base_value::range_value()", type_name ()); + return retval; +} + +octave_map +octave_base_value::map_value (void) const +{ + octave_map retval; + gripe_wrong_type_arg ("octave_base_value::map_value()", type_name ()); + return retval; +} + +octave_scalar_map +octave_base_value::scalar_map_value (void) const +{ + octave_map tmp = map_value (); + + if (tmp.numel () == 1) + return tmp.checkelem (0); + else + { + if (! error_state) + error ("invalid conversion of multi-dimensional struct to scalar struct"); + + return octave_scalar_map (); + } +} + +string_vector +octave_base_value::map_keys (void) const +{ + string_vector retval; + gripe_wrong_type_arg ("octave_base_value::map_keys()", type_name ()); + return retval; +} + +size_t +octave_base_value::nparents (void) const +{ + size_t retval = 0; + gripe_wrong_type_arg ("octave_base_value::nparents()", type_name ()); + return retval; +} + +std::list<std::string> +octave_base_value::parent_class_name_list (void) const +{ + std::list<std::string> retval; + gripe_wrong_type_arg ("octave_base_value::parent_class_name_list()", + type_name ()); + return retval; +} + +string_vector +octave_base_value::parent_class_names (void) const +{ + string_vector retval; + gripe_wrong_type_arg ("octave_base_value::parent_class_names()", + type_name ()); + return retval; +} + +octave_function * +octave_base_value::function_value (bool silent) +{ + octave_function *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::function_value()", + type_name ()); + return retval; +} + +octave_user_function * +octave_base_value::user_function_value (bool silent) +{ + octave_user_function *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::user_function_value()", + type_name ()); + return retval; +} + +octave_user_script * +octave_base_value::user_script_value (bool silent) +{ + octave_user_script *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::user_script_value()", + type_name ()); + return retval; +} + +octave_user_code * +octave_base_value::user_code_value (bool silent) +{ + octave_user_code *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::user_code_value()", + type_name ()); + return retval; +} + +octave_fcn_handle * +octave_base_value::fcn_handle_value (bool silent) +{ + octave_fcn_handle *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::fcn_handle_value()", + type_name ()); + return retval; +} + +octave_fcn_inline * +octave_base_value::fcn_inline_value (bool silent) +{ + octave_fcn_inline *retval = 0; + + if (! silent) + gripe_wrong_type_arg ("octave_base_value::fcn_inline_value()", + type_name ()); + return retval; +} + +octave_value_list +octave_base_value::list_value (void) const +{ + octave_value_list retval; + gripe_wrong_type_arg ("octave_base_value::list_value()", type_name ()); + return retval; +} + +bool +octave_base_value::save_ascii (std::ostream&) +{ + gripe_wrong_type_arg ("octave_base_value::save_ascii()", type_name ()); + return false; +} + +bool +octave_base_value::load_ascii (std::istream&) +{ + gripe_wrong_type_arg ("octave_base_value::load_ascii()", type_name ()); + return false; +} + +bool +octave_base_value::save_binary (std::ostream&, bool&) +{ + gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ()); + return false; +} + +bool +octave_base_value::load_binary (std::istream&, bool, + oct_mach_info::float_format) +{ + gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ()); + return false; +} + +#if defined (HAVE_HDF5) + +bool +octave_base_value::save_hdf5 (hid_t, const char *, bool) +{ + gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ()); + + return false; +} + +bool +octave_base_value::load_hdf5 (hid_t, const char *) +{ + gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ()); + + return false; +} + +#endif + +int +octave_base_value::write (octave_stream&, int, oct_data_conv::data_type, + int, oct_mach_info::float_format) const +{ + gripe_wrong_type_arg ("octave_base_value::write()", type_name ()); + + return false; +} + +mxArray * +octave_base_value::as_mxArray (void) const +{ + return 0; +} + +octave_value +octave_base_value::diag (octave_idx_type) const +{ + gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ()); + + return octave_value (); +} + +octave_value +octave_base_value::diag (octave_idx_type, octave_idx_type) const +{ + gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ()); + + return octave_value (); +} + +octave_value +octave_base_value::sort (octave_idx_type, sortmode) const +{ + gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ()); + + return octave_value (); +} + +octave_value +octave_base_value::sort (Array<octave_idx_type> &, + octave_idx_type, sortmode) const +{ + gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ()); + + return octave_value (); +} + +sortmode +octave_base_value::is_sorted (sortmode) const +{ + gripe_wrong_type_arg ("octave_base_value::is_sorted ()", type_name ()); + + return UNSORTED; +} + +Array<octave_idx_type> +octave_base_value::sort_rows_idx (sortmode) const +{ + gripe_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ()); + + return Array<octave_idx_type> (); +} + +sortmode +octave_base_value::is_sorted_rows (sortmode) const +{ + gripe_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ()); + + return UNSORTED; +} + + +const char * +octave_base_value::get_umap_name (unary_mapper_t umap) +{ + static const char *names[num_unary_mappers] = + { + "abs", + "acos", + "acosh", + "angle", + "arg", + "asin", + "asinh", + "atan", + "atanh", + "cbrt", + "ceil", + "conj", + "cos", + "cosh", + "erf", + "erfinv", + "erfcinv", + "erfc", + "exp", + "expm1", + "finite", + "fix", + "floor", + "gamma", + "imag", + "isinf", + "isna", + "isnan", + "lgamma", + "log", + "log2", + "log10", + "log1p", + "real", + "round", + "roundb", + "signum", + "sin", + "sinh", + "sqrt", + "tan", + "tanh", + "isalnum", + "isalpha", + "isascii", + "iscntrl", + "isdigit", + "isgraph", + "islower", + "isprint", + "ispunct", + "isspace", + "isupper", + "isxdigit", + "toascii", + "tolower", + "toupper" + }; + + if (umap < 0 || umap >= num_unary_mappers) + return "unknown"; + else + return names[umap]; +} + +octave_value +octave_base_value::map (unary_mapper_t umap) const +{ + error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ()); + return octave_value (); +} + +void +octave_base_value::lock (void) +{ + gripe_wrong_type_arg ("octave_base_value::lock ()", type_name ()); +} + +void +octave_base_value::unlock (void) +{ + gripe_wrong_type_arg ("octave_base_value::unlock ()", type_name ()); +} + +void +octave_base_value::dump (std::ostream& os) const +{ + dim_vector dv = this->dims (); + + os << "class: " << this->class_name () + << " type: " << this->type_name () + << " dims: " << dv.str (); +} + +static void +gripe_indexed_assignment (const std::string& tn1, const std::string& tn2) +{ + error ("assignment of `%s' to indexed `%s' not implemented", + tn2.c_str (), tn1.c_str ()); +} + +static void +gripe_assign_conversion_failed (const std::string& tn1, + const std::string& tn2) +{ + error ("type conversion for assignment of `%s' to indexed `%s' failed", + tn2.c_str (), tn1.c_str ()); +} + +static void +gripe_no_conversion (const std::string& on, const std::string& tn1, + const std::string& tn2) +{ + error ("operator %s: no conversion for assignment of `%s' to indexed `%s'", + on.c_str (), tn2.c_str (), tn1.c_str ()); +} + +octave_value +octave_base_value::numeric_assign (const std::string& type, + const std::list<octave_value_list>& idx, + const octave_value& rhs) +{ + octave_value retval; + + if (idx.front ().empty ()) + { + error ("missing index in indexed assignment"); + return retval; + } + + int t_lhs = type_id (); + int t_rhs = rhs.type_id (); + + octave_value_typeinfo::assign_op_fcn f + = octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq, + t_lhs, t_rhs); + + bool done = false; + + if (f) + { + f (*this, idx.front (), rhs.get_rep ()); + + done = (! error_state); + } + + if (done) + { + count++; + retval = octave_value (this); + } + else + { + int t_result + = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs); + + if (t_result >= 0) + { + octave_base_value::type_conv_fcn cf + = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result); + + if (cf) + { + octave_base_value *tmp = cf (*this); + + if (tmp) + { + octave_value val (tmp); + + retval = val.subsasgn (type, idx, rhs); + + done = (! error_state); + } + else + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + } + else + gripe_indexed_assignment (type_name (), rhs.type_name ()); + } + + if (! (done || error_state)) + { + octave_value tmp_rhs; + + octave_base_value::type_conv_info cf_rhs + = rhs.numeric_conversion_function (); + + octave_base_value::type_conv_info cf_this + = numeric_conversion_function (); + + // Try biased (one-sided) conversions first. + if (cf_rhs.type_id () >= 0 + && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq, + t_lhs, cf_rhs.type_id ()) + || octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, + cf_rhs.type_id ()) >= 0)) + cf_this = 0; + else if (cf_this.type_id () >= 0 + && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq, + cf_this.type_id (), t_rhs) + || octave_value_typeinfo::lookup_pref_assign_conv (cf_this.type_id (), + t_rhs) >= 0)) + cf_rhs = 0; + + if (cf_rhs) + { + octave_base_value *tmp = cf_rhs (rhs.get_rep ()); + + if (tmp) + tmp_rhs = octave_value (tmp); + else + { + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + return octave_value (); + } + } + else + tmp_rhs = rhs; + + count++; + octave_value tmp_lhs = octave_value (this); + + if (cf_this) + { + octave_base_value *tmp = cf_this (*this); + + if (tmp) + tmp_lhs = octave_value (tmp); + else + { + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + return octave_value (); + } + } + + if (cf_this || cf_rhs) + { + retval = tmp_lhs.subsasgn (type, idx, tmp_rhs); + + done = (! error_state); + } + else + gripe_no_conversion (octave_value::assign_op_as_string (octave_value::op_asn_eq), + type_name (), rhs.type_name ()); + } + } + + // The assignment may have converted to a type that is wider than + // necessary. + + retval.maybe_mutate (); + + return retval; +} + +// Current indentation. +int octave_base_value::curr_print_indent_level = 0; + +// TRUE means we are at the beginning of a line. +bool octave_base_value::beginning_of_line = true; + +// Each print() function should call this before printing anything. +// +// This doesn't need to be fast, but isn't there a better way? + +void +octave_base_value::indent (std::ostream& os) const +{ + assert (curr_print_indent_level >= 0); + + if (beginning_of_line) + { + // FIXME -- do we need this? + // os << prefix; + + for (int i = 0; i < curr_print_indent_level; i++) + os << " "; + + beginning_of_line = false; + } +} + +// All print() functions should use this to print new lines. + +void +octave_base_value::newline (std::ostream& os) const +{ + os << "\n"; + + beginning_of_line = true; +} + +// For ressetting print state. + +void +octave_base_value::reset (void) const +{ + beginning_of_line = true; + curr_print_indent_level = 0; +} + + +octave_value +octave_base_value::fast_elem_extract (octave_idx_type) const +{ + return octave_value (); +} + +bool +octave_base_value::fast_elem_insert (octave_idx_type, const octave_value&) +{ + return false; +} + +bool +octave_base_value::fast_elem_insert_self (void *, builtin_type_t) const +{ + return false; +} + +CONVDECLX (matrix_conv) +{ + return new octave_matrix (); +} + +CONVDECLX (complex_matrix_conv) +{ + return new octave_complex_matrix (); +} + +CONVDECLX (string_conv) +{ + return new octave_char_matrix_str (); +} + +CONVDECLX (cell_conv) +{ + return new octave_cell (); +} + +void +install_base_type_conversions (void) +{ + INSTALL_ASSIGNCONV (octave_base_value, octave_scalar, octave_matrix); + INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_matrix); + INSTALL_ASSIGNCONV (octave_base_value, octave_complex, octave_complex_matrix); + INSTALL_ASSIGNCONV (octave_base_value, octave_complex_matrix, octave_complex_matrix); + INSTALL_ASSIGNCONV (octave_base_value, octave_range, octave_matrix); + INSTALL_ASSIGNCONV (octave_base_value, octave_char_matrix_str, octave_char_matrix_str); + INSTALL_ASSIGNCONV (octave_base_value, octave_cell, octave_cell); + + INSTALL_WIDENOP (octave_base_value, octave_matrix, matrix_conv); + INSTALL_WIDENOP (octave_base_value, octave_complex_matrix, complex_matrix_conv); + INSTALL_WIDENOP (octave_base_value, octave_char_matrix_str, string_conv); + INSTALL_WIDENOP (octave_base_value, octave_cell, cell_conv); +} + +DEFUN (sparse_auto_mutate, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} sparse_auto_mutate ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} sparse_auto_mutate (@var{new_val}, \"local\")\n\ +Query or set the internal variable that controls whether Octave will\n\ +automatically mutate sparse matrices to full matrices to save memory.\n\ +For example:\n\ +\n\ +@example\n\ +@group\n\ +s = speye (3);\n\ +sparse_auto_mutate (false);\n\ +s(:, 1) = 1;\n\ +typeinfo (s)\n\ +@result{} sparse matrix\n\ +sparse_auto_mutate (true);\n\ +s(1, :) = 1;\n\ +typeinfo (s)\n\ +@result{} matrix\n\ +@end group\n\ +@end example\n\ +\n\ +When called from inside a function with the \"local\" option, the variable is\n\ +changed locally for the function and any subroutines it calls. The original\n\ +variable value is restored when exiting the function.\n\ +@end deftypefn") +{ + return SET_INTERNAL_VARIABLE (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); +*/