Mercurial > hg > octave-lojdl
changeset 10325:8b3cfc1288e2
implement lazy index conversions
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 16 Feb 2010 15:28:53 +0100 |
parents | 7673850d6adf |
children | ade59ae10e80 |
files | src/ChangeLog src/Makefile.am src/ls-hdf5.cc src/ov-lazy-idx.cc src/ov-lazy-idx.h src/ov.cc src/ov.h |
diffstat | 7 files changed, 413 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2010-02-16 Jaroslav Hajek <highegg@gmail.com> + + * ov-lazy-idx.h: New source. + * ov-lazy-idx.cc: New source. + * ov.cc (install_types): Register lazy_index here. + (octave_value::octave_value (const idx_vector&)): Use lazy + construction if possible, under control of an optional flag. + (octave_value::clone): Implement. + * ls-hdf5.cc (save_hdf5): Avoid saving lazy indices. + 2010-02-15 Jaroslav Hajek <highegg@gmail.com> * ov-fcn-handle.h (octave_fcn_handle::print_as_scalar): New method
--- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,6 +165,7 @@ ov-flt-cx-mat.h \ ov-flt-re-diag.h \ ov-flt-re-mat.h \ + ov-lazy-idx.h \ ov-mex-fcn.h \ ov-null-mat.h \ ov-perm.h \ @@ -337,6 +338,7 @@ ov-flt-cx-mat.cc \ ov-flt-re-diag.cc \ ov-flt-re-mat.cc \ + ov-lazy-idx.cc \ ov-mex-fcn.cc \ ov-null-mat.cc \ ov-perm.cc \
--- a/src/ls-hdf5.cc +++ b/src/ls-hdf5.cc @@ -67,6 +67,7 @@ #include "variables.h" #include "version.h" #include "dMatrix.h" +#include "ov-lazy-idx.h" #include "ls-utils.h" #include "ls-hdf5.h" @@ -753,7 +754,8 @@ // FIXME: diagonal & permutation matrices currently don't know how to save // themselves, so we convert them first to normal matrices using A = A(:,:). // This is a temporary hack. - if (val.is_diag_matrix () || val.is_perm_matrix ()) + if (val.is_diag_matrix () || val.is_perm_matrix () + || val.type_id () == octave_lazy_index::static_type_id ()) val = val.full_value (); std::string t = val.type_name();
new file mode 100644 --- /dev/null +++ b/src/ov-lazy-idx.cc @@ -0,0 +1,115 @@ + +/* + +Copyright (C) 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 "ov-lazy-idx.h" +#include "ops.h" +#include "ov-scalar.h" +#include "ls-oct-ascii.h" +#include "ls-oct-binary.h" + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_lazy_index, "lazy_index", "double"); + +static octave_base_value * +default_numeric_conversion_function (const octave_base_value& a) +{ + CAST_CONV_ARG (const octave_lazy_index&); + + return v.full_value ().clone (); +} + +octave_base_value::type_conv_info +octave_lazy_index::numeric_conversion_function (void) const +{ + return octave_base_value::type_conv_info (default_numeric_conversion_function, + octave_matrix::static_type_id ()); +} + +octave_base_value * +octave_lazy_index::try_narrowing_conversion (void) +{ + octave_base_value *retval = 0; + + switch (index.length (0)) + { + case 1: + retval = new octave_scalar (static_cast<double> (index(0) + 1)); + break; + + case 0: + retval = new octave_matrix (NDArray (index.orig_dimensions ())); + break; + + default: + break; + } + + return retval; +} + +static const std::string value_save_tag ("index_value"); + +bool octave_lazy_index::save_ascii (std::ostream& os) +{ + return save_ascii_data (os, make_value (), value_save_tag, false, 0); +} + +bool octave_lazy_index::load_ascii (std::istream& is) +{ + bool dummy; + + std::string nm = read_ascii_data (is, std::string (), dummy, value, 0); + + if (nm != value_save_tag) + error ("lazy_index: corrupted data on load"); + else + index = value.index_vector (); + + return ! error_state; +} + + +bool octave_lazy_index::save_binary (std::ostream& os, bool& save_as_floats) +{ + return save_binary_data (os, make_value (), value_save_tag, false, 0, save_as_floats); +} + +bool octave_lazy_index::load_binary (std::istream& is, bool swap, + oct_mach_info::float_format fmt) +{ + bool dummy; + std::string doc; + + std::string nm = read_binary_data (is, swap, fmt, std::string (), + dummy, value, doc); + + if (nm != value_save_tag) + error ("lazy_index: corrupted data on load"); + else + index = value.index_vector (); + + return ! error_state; +}
new file mode 100644 --- /dev/null +++ b/src/ov-lazy-idx.h @@ -0,0 +1,263 @@ +/* + +Copyright (C) 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/>. + +*/ + +#if !defined (octave_lazy_idx_h) +#define octave_lazy_idx_h 1 + +#include "ov-re-mat.h" + +// Lazy indices that stay in idx_vector form until the conversion to NDArray is +// actually needed. + +class +OCTINTERP_API +octave_lazy_index : public octave_base_value +{ +public: + + octave_lazy_index (void) + : octave_base_value () { } + + octave_lazy_index (const idx_vector& idx) + : octave_base_value (), index (idx) { } + + octave_lazy_index (const octave_lazy_index& i) + : octave_base_value (), index (i.index), value (i.value) { } + + ~octave_lazy_index (void) { } + + octave_base_value *clone (void) const { return new octave_lazy_index (*this); } + octave_base_value *empty_clone (void) const { return new octave_matrix (); } + + type_conv_info numeric_conversion_function (void) const; + + octave_base_value *try_narrowing_conversion (void); + + size_t byte_size (void) const { return numel () * sizeof (octave_idx_type); } + + // FIXME: should avoid conversion. + octave_value squeeze (void) const { return make_value ().squeeze (); } + + octave_value full_value (void) const { return make_value (); } + + idx_vector index_vector (void) const + { return index; } + + builtin_type_t builtin_type (void) const { return btyp_double; } + + bool is_real_matrix (void) const { return true; } + + bool is_real_type (void) const { return true; } + + bool is_double_type (void) const { return true; } + + bool is_float_type (void) const { return true; } + + octave_value subsref (const std::string& type, + const std::list<octave_value_list>& idx) + { return make_value ().subsref (type, idx); } + + octave_value_list subsref (const std::string& type, + const std::list<octave_value_list>& idx, int) + { return subsref (type, idx); } + + octave_value subsasgn (const std::string& type, + const std::list<octave_value_list>& idx, + const octave_value& rhs) + { return make_value ().subsasgn (type, idx, rhs); } + + octave_value do_index_op (const octave_value_list& idx, + bool resize_ok = false) + { return make_value ().do_index_op (idx, resize_ok); } + + dim_vector dims (void) const { return index.orig_dimensions (); } + + octave_idx_type numel (void) const { return index.length (0); } + + octave_idx_type nnz (void) const { return numel (); } + + // FIXME: should avoid conversion. + octave_value reshape (const dim_vector& new_dims) const + { return make_value ().reshape (new_dims); } + + octave_value permute (const Array<int>& vec, bool inv = false) const + { return make_value ().permute (vec, inv); } + + octave_value resize (const dim_vector& dv, bool fill = false) const + { return make_value ().resize (dv, fill); } + + octave_value all (int dim = 0) const { return make_value ().all (dim); } + octave_value any (int dim = 0) const { return make_value ().any (dim); } + + MatrixType matrix_type (void) const { return make_value ().matrix_type (); } + MatrixType matrix_type (const MatrixType& _typ) const + { return make_value ().matrix_type (_typ); } + + // FIXME: should avoid conversion. + sortmode is_sorted (sortmode mode = UNSORTED) const + { return make_value ().is_sorted (mode); } + + Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const + { return make_value ().sort_rows_idx (mode); } + + sortmode is_sorted_rows (sortmode mode = UNSORTED) const + { return make_value ().is_sorted_rows (mode); } + + bool is_matrix_type (void) const { return true; } + + bool is_numeric_type (void) const { return true; } + + bool is_defined (void) const { return true; } + + bool is_constant (void) const { return true; } + + bool is_true (void) const + { return make_value ().is_true (); } + + bool print_as_scalar (void) const + { return make_value ().print_as_scalar (); } + + void print (std::ostream& os, bool pr_as_read_syntax = false) const + { make_value ().print (os, pr_as_read_syntax); } + + void print_info (std::ostream& os, const std::string& prefix) const + { make_value ().print_info (os, prefix); } + +#define FORWARD_VALUE_QUERY(TYPE,NAME) \ + TYPE \ + NAME (void) const { return make_value ().NAME (); } + + FORWARD_VALUE_QUERY (int8NDArray, int8_array_value) + FORWARD_VALUE_QUERY (int16NDArray, int16_array_value) + FORWARD_VALUE_QUERY (int32NDArray, int32_array_value) + FORWARD_VALUE_QUERY (int64NDArray, int64_array_value) + FORWARD_VALUE_QUERY (uint8NDArray, uint8_array_value) + FORWARD_VALUE_QUERY (uint16NDArray, uint16_array_value) + FORWARD_VALUE_QUERY (uint32NDArray, uint32_array_value) + FORWARD_VALUE_QUERY (uint64NDArray, uint64_array_value) + +#define FORWARD_VALUE_QUERY1(TYPE,NAME) \ + TYPE \ + NAME (bool flag = false) const { return make_value ().NAME (flag); } + + FORWARD_VALUE_QUERY1 (double, double_value) + + FORWARD_VALUE_QUERY1 (float, float_value) + + FORWARD_VALUE_QUERY1 (double, scalar_value) + + FORWARD_VALUE_QUERY1 (Matrix, matrix_value) + + FORWARD_VALUE_QUERY1 (FloatMatrix, float_matrix_value) + + FORWARD_VALUE_QUERY1 (Complex, complex_value) + + FORWARD_VALUE_QUERY1 (FloatComplex, float_complex_value) + + FORWARD_VALUE_QUERY1 (ComplexMatrix, complex_matrix_value) + + FORWARD_VALUE_QUERY1 (FloatComplexMatrix, float_complex_matrix_value) + + FORWARD_VALUE_QUERY1 (ComplexNDArray, complex_array_value) + + FORWARD_VALUE_QUERY1 (FloatComplexNDArray, float_complex_array_value) + + FORWARD_VALUE_QUERY1 (boolNDArray, bool_array_value) + + FORWARD_VALUE_QUERY1 (charNDArray, char_array_value) + + FORWARD_VALUE_QUERY1 (NDArray, array_value) + + FORWARD_VALUE_QUERY1 (FloatNDArray, float_array_value) + + FORWARD_VALUE_QUERY1 (SparseMatrix, sparse_matrix_value) + + FORWARD_VALUE_QUERY1 (SparseComplexMatrix, sparse_complex_matrix_value) + + octave_value diag (octave_idx_type k = 0) const + { return make_value ().diag (k); } + + octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const + { return make_value ().sort (dim, mode); } + + octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0, + sortmode mode = ASCENDING) const + { return make_value ().sort (sidx, dim, mode); } + + octave_value convert_to_str_internal (bool pad, bool force, char type) const + { return make_value ().convert_to_str_internal (pad, force, type); } + + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const + { return make_value ().print_raw (os, pr_as_read_syntax); } + + bool save_ascii (std::ostream& os); + + bool load_ascii (std::istream& is); + + bool save_binary (std::ostream& os, bool& save_as_floats); + + bool load_binary (std::istream& is, bool swap, + oct_mach_info::float_format fmt); + + // HDF5 functions not defined. + + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { return make_value ().write (os, block_size, output_type, skip, flt_fmt); } + + // Unsafe. This function exists to support the MEX interface. + // You should not use it anywhere else. + void *mex_get_data (void) const + { return make_value ().mex_get_data (); } + + mxArray *as_mxArray (void) const + { return make_value ().as_mxArray (); } + + octave_value map (unary_mapper_t umap) const + { return make_value ().map (umap); } + +private: + const octave_value& make_value (void) const + { + if (value.is_undefined ()) + value = octave_value (index, false); + + return value; + } + + octave_value& make_value (void) + { + if (value.is_undefined ()) + value = octave_value (index, false); + + return value; + } + + idx_vector index; + mutable octave_value value; + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +#endif +
--- a/src/ov.cc +++ b/src/ov.cc @@ -74,6 +74,7 @@ #include "ov-fcn-inline.h" #include "ov-typeinfo.h" #include "ov-null-mat.h" +#include "ov-lazy-idx.h" #include "defun.h" #include "error.h" @@ -1044,7 +1045,7 @@ maybe_mutate (); } -octave_value::octave_value (const idx_vector& idx) +octave_value::octave_value (const idx_vector& idx, bool lazy) : rep () { double scalar; @@ -1053,6 +1054,21 @@ boolNDArray mask; idx_vector::idx_class_type idx_class; + if (lazy) + { + // Only make lazy indices out of ranges and index vectors. + switch (idx.idx_class ()) + { + case idx_vector::class_range: + case idx_vector::class_vector: + rep = new octave_lazy_index (idx); + maybe_mutate (); + return; + default: + break; + } + } + idx.unconvert (idx_class, scalar, range, array, mask); switch (idx_class) @@ -1135,8 +1151,7 @@ octave_base_value * octave_value::clone (void) const { - panic_impossible (); - return 0; + return rep->clone (); } void @@ -2653,6 +2668,7 @@ octave_null_matrix::register_type (); octave_null_str::register_type (); octave_null_sq_str::register_type (); + octave_lazy_index::register_type (); } #if 0
--- a/src/ov.h +++ b/src/ov.h @@ -271,7 +271,7 @@ octave_value (const Array<octave_idx_type>& inda, bool zero_based = false, bool cache_index = false); octave_value (const Array<std::string>& cellstr); - octave_value (const idx_vector& idx); + octave_value (const idx_vector& idx, bool lazy = true); octave_value (double base, double limit, double inc); octave_value (const Range& r); octave_value (const Octave_map& m);