# HG changeset patch # User dbateman # Date 1188978825 0 # Node ID 3c64128e621c3dec0f1c2008f305ce45f7b8372b # Parent d63339cbb2050b9ccd841442b7d721df0b5101dd [project @ 2007-09-05 07:52:48 by dbateman] diff --git a/doc/ChangeLog b/doc/ChangeLog --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2007-09-05 David Bateman + + * interpreter/container.txi: Document struct2cell. + * interpreter/stats.txi: Document mode. + * interpreter/eval.txi: Document run. + 2007-09-01 David Bateman * interpreter/Makefile.in: Remove stray character from diff --git a/doc/interpreter/container.txi b/doc/interpreter/container.txi --- a/doc/interpreter/container.txi +++ b/doc/interpreter/container.txi @@ -200,6 +200,7 @@ * Structure Arrays:: * Creating Structures:: * Manipulating Structures:: +* Processing Data in Structures:: @end menu @node Structure Arrays @@ -395,9 +396,22 @@ @DOCSTRING(getfield) -@DOCSTRING(struct2cell) +@DOCSTRING(substruct) + +@node Processing Data in Structures +@subsection Processing Data in Structures -@DOCSTRING(substruct) +The simpliest way to process data in a structure is within a @code{for} +loop or othe means of iterating over the fields. A similar effect can be +achieved with the @code{structfun} function, where a user defined +function is applied to eacg field of the structure. + +@DOCSTRING(structfun) + +Alternatively, to process the data in a strcuture, the structure might +be converted to another type of container before being treated. + +@DOCSTRING(struct2cell) @node Cell Arrays @section Cell Arrays diff --git a/doc/interpreter/eval.txi b/doc/interpreter/eval.txi --- a/doc/interpreter/eval.txi +++ b/doc/interpreter/eval.txi @@ -75,6 +75,11 @@ @DOCSTRING(feval) +A similar function @code{run} exists for calling user script files, that +are not necessarily on the user path + +@DOCSTRING(run) + @node Evaluation in a Different Context @section Evaluation in a Different Context diff --git a/doc/interpreter/stats.txi b/doc/interpreter/stats.txi --- a/doc/interpreter/stats.txi +++ b/doc/interpreter/stats.txi @@ -52,6 +52,8 @@ @DOCSTRING(var) +@DOCSTRING(mode) + @DOCSTRING(cov) @DOCSTRING(cor) diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,12 @@ +2007-09-05 David Bateman + + * general/structfun.m: New function. + * general/Makefile.in (SOURCES): Add it to sources. + * miscellaneous/run.m: New function. + * miscellaneous/Makefile.in (SOURCES): Add it to sources. + * statistics/base/mode.m: New function. + * statistics/base//Makefile.in (SOURCES): Add it to sources. + 2007-09-05 John W. Eaton * miscellaneous/orderfields.m: Use numel instead of length. diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in --- a/scripts/general/Makefile.in +++ b/scripts/general/Makefile.in @@ -30,7 +30,7 @@ nargchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \ polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \ repmat.m rot90.m rotdim.m shift.m shiftdim.m sortrows.m \ - sph2cart.m strerror.m sub2ind.m trapz.m tril.m triu.m + sph2cart.m strerror.m structfun.m sub2ind.m trapz.m tril.m triu.m DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES)) diff --git a/scripts/general/structfun.m b/scripts/general/structfun.m new file mode 100644 --- /dev/null +++ b/scripts/general/structfun.m @@ -0,0 +1,87 @@ +## Copyright (C) 2007 David Bateman +## +## 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 2, 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, write to the Free +## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301, USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {} structfun (@var{func}, @var{s}) +## @deftypefnx {Function File} {[@var{a}, @var{b}] =} structfun (@dots{}) +## @deftypefnx {Function File} {} structfun (@dots{}, 'ErrorHandler', @var{errfunc}) +## @deftypefnx {Function File} {} structfun (@dots{}, 'UniformOutput', @var{val}) +## +## Evaluate the function named @var{name} on the fields of the structure +## @var{s}. The fields of @var{s} are passed the the function @var{func} +## individually. +## +## @code{structfun} accepts an arbitrary function @var{func} in the form of +## an inline function, function handle, or the name of a function (in a +## character string). In the case of a character string argument, the +## function must accept a single argument named @var{x}, and it must return +## a string value. If the function returns more than one argument, they are +## returned as separate output variables. +## +## If the param 'UniformOutput' is set to true (the default), then the function +## must return either a single element which will be concatenated into the +## return value. If 'UniformOutput is false, the outputs placed in a structure +## with the same fieldnames as the input structure. +## +## @example +## @group +## s.name1 = "John Smith"; +## s.name2 = "Jill Jones"; +## structfun (@{x@} regexp (x, '(\w+)$', 'matches')@{1@}, s, +## 'UniformOutput', false) +## @end group +## @end example +## +## Given the parameter 'ErrorHandler', then @var{errfunc} defines a function to +## call in case @var{func} generates an error. The form of the function is +## +## @example +## function [@dots{}] = errfunc (@var{se}, @dots{}) +## @end example +## +## where there is an additional input argument to @var{errfunc} relative to +## @var{func}, given by @var{se}. This is a structure with the elements +## 'identifier', 'message' and 'index', giving respectively the error +## identifier, the error message, and the index into the input arguments +## of the element that caused the error. +## @seealso{cellfun, arrayfun} +## @end deftypefn + +function varargout = structfun (fun, s, varargin); + if (nargin < 2) + print_usage (); + endif + + varargout = cell (max ([nargout, 1]), 1); + [varargout{:}] = cellfun (fun, struct2cell (s), varargin {:}); + + if (iscell (varargout{1})) + [varargout{:}] = cell2struct (varargout{1}, fieldnames(s), 1); + endif +endfunction + + +%!test +%! s.name1 = "John Smith"; +%! s.name2 = "Jill Jones"; +%! l.name1 = "Smith"; +%! l.name2 = "Jones"; +%! o = structfun (@(x) regexp (x, '(\w+)$', 'matches'){1}, s, +%! 'UniformOutput', false); +%! assert (o, l); diff --git a/scripts/miscellaneous/Makefile.in b/scripts/miscellaneous/Makefile.in --- a/scripts/miscellaneous/Makefile.in +++ b/scripts/miscellaneous/Makefile.in @@ -27,7 +27,7 @@ inputname.m ispc.m isunix.m license.m list_primes.m ls.m \ ls_command.m menu.m mex.m mexext.m mkoctfile.m movefile.m \ news.m orderfields.m pack.m paren.m parseparams.m \ - semicolon.m setfield.m single.m substruct.m tar.m \ + run.m semicolon.m setfield.m single.m substruct.m tar.m \ tempdir.m tempname.m texas_lotto.m unix.m unpack.m untar.m \ unzip.m ver.m version.m warning_ids.m xor.m zip.m diff --git a/scripts/miscellaneous/run.m b/scripts/miscellaneous/run.m new file mode 100644 --- /dev/null +++ b/scripts/miscellaneous/run.m @@ -0,0 +1,56 @@ +## Copyright (C) 2007 David Bateman +## +## 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 2, 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, write to the Free +## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301, USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {} run (@var{f}) +## @deftypefnx {Command} {} run @var{f} +## Run scripts in the current workspace that are not necessarily on the +## path. If @var{f} is the script to run, including its path, then @code{run} +## change the directory to the directory where @var{f} is found. @code{run} +## then executes the script, and returns to the original directory. +## @seealso{system} +## @end deftypefn + +## PKG_ADD: mark_as_commnd run + +function run (s) + [d, f, ext] = fileparts (s); + if (! isempty (d)) + if (exist (d, "dir")) + wd = pwd (); + unwind_protect + cd (d); + if (! exist (s, "file") || ! strcmp (ext, ".m")) + error ("run: file must exist and be a valid Octave script file"); + endif + evalin ("caller", [f, ";"], "rethrow (lasterror ())"); + unwind_protect_cleanup + cd (wd); + end_unwind_protect + else + error ("run: the path %s doesn't exist", d); + endif + else + if (exist (script, "file")) + evalin ("caller", [script, ";"], "rethrow (lasterror ())"); + else + error ("run: %s not found", s); + endif + endif +endfunction diff --git a/scripts/statistics/base/Makefile.in b/scripts/statistics/base/Makefile.in --- a/scripts/statistics/base/Makefile.in +++ b/scripts/statistics/base/Makefile.in @@ -22,7 +22,7 @@ SOURCES = center.m cloglog.m cor.m corrcoef.m cov.m cut.m gls.m \ iqr.m kendall.m kurtosis.m logit.m mahalanobis.m mean.m meansq.m \ - median.m moment.m ols.m ppplot.m probit.m qqplot.m range.m \ + median.m mode.m moment.m ols.m ppplot.m probit.m qqplot.m range.m \ ranks.m run_count.m skewness.m spearman.m statistics.m std.m \ studentize.m table.m values.m var.m diff --git a/scripts/statistics/base/mode.m b/scripts/statistics/base/mode.m new file mode 100644 --- /dev/null +++ b/scripts/statistics/base/mode.m @@ -0,0 +1,111 @@ +## Copyright (C) 2007 David Bateman +## +## 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 2, 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, write to the Free +## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301, USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@var{x}, @var{dim}) +## Count the most frequently appearing value. @code{mode} counts the +## frequency along the first non-singleton dimension and if two or more +## values have te same frequency returns the smallest of the two in +## @var{m}. The dimension along which to count can be specified by the +## @var{dim} parameter. +## +## The variable @var{f} counts the frequency of each of the most frequently +## occuring ellements. The cell array @var{c} contains all of the elements +## with the maximum frequency . +## @end deftypefn + +function [m, f, c] = mode (x, dim) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + nd = ndims (x); + sz = size (x); + + if (nargin != 2) + ## Find the first non-singleton dimension. + dim = 1; + while (dim < nd + 1 && sz(dim) == 1) + dim = dim + 1; + endwhile + if (dim > nd) + dim = 1; + endif + else + if (! (isscalar (dim) && dim == round (dim)) + && dim > 0 + && dim < (nd + 1)) + error ("mode: dim must be an integer and valid dimension"); + endif + endif + + sz2 = sz; + sz2 (dim) = 1; + sz3 = ones (1, nd); + sz3 (dim) = sz (dim); + + if (dim != 1) + perm = [1 : nd]; + perm(1) = dim; + perm(dim) = 1; + endif + + xs = sort (x, dim); + t = cat (dim, true (sz2), diff (xs, 1, dim) != 0); + if (issparse (x)) + t2 = sparse (sz(1), sz(2)); + else + t2 = zeros (size (t)); + endif + + if (dim != 1) + t2 (permute (t != 0, perm)) = diff ([find(permute (t, perm)); prod(sz)+1]); + f = max (ipermute (t2, perm), [], dim); + xs = permute (xs, perm); + else + t2 (t) = diff ([find(t); prod(sz)+1]); + f = max (t2, [], dim); + endif + + c = cell (sz2); + m = zeros (sz2); + for i = 1 : prod (sz2) + c {i} = xs (t2 (:, i) == f(i), i); + m (i) = c{i}(1); + endfor +endfunction + +%!test +%! [m, f, c] = mode (toeplitz (1:5)); +%! assert (m, [1,2,2,2,1]); +%! assert (f, [1,2,2,2,1]); +%! assert (c, {[1;2;3;4;5],[2],[2;3],[2],[1;2;3;4;5]}); +%!test +%! [m, f, c] = mode (toeplitz (1:5), 2); +%! assert (m, [1;2;2;2;1]); +%! assert (f, [1;2;2;2;1]); +%! assert (c, {[1;2;3;4;5];[2];[2;3];[2];[1;2;3;4;5]}); +%!test +%! a = sprandn (32, 32, 0.05); +%! [m, f, c] = mode (a); +%! [m2, f2, c2] = mode (full (a)); +%! assert (m, m2); +%! assert (f, f2); +%! assert (c, c2); diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,23 @@ +2007-09-05 David Bateman + + * DLD-FUNCTIONS/sort.cc (mx_sort_sparse, mx_sort_sparse_indexed): + New template classes for sparse sort functions. + (Fsort): Use them. + * ov.h (octave_value (const Sparse&, const MatrixType&), + octave_value (const Sparse&, const MatrixType&)): New + constructors. + * ov.cc (octave_value::octave_value (const Sparse&, + const MatrixType&), octave_value::octave_value (const + Sparse&, const MatrixType&)): Define them. + * ov-re-sparse.h (octave_sparse_matrix (const MSparse&, + const MatrixType&), octave_sparse_matrix (const Sparse&), + octave_sparse_matrix (const Sparse&, const MatrixType&)): + New constructors. + * ov-cx-sparse.h (octave_sparse_complex_matrix (const MSparse&, + const MatrixType&), octave_sparse_complex_matrix (const + Sparse&), octave_sparse_complex_matrix (const + Sparse&, const MatrixType&)): ditto. + 2007-09-04 Gabriele Pannocchia * DLD-FUNCTIONS/__qp__.cc (qp): Use Wact(j) == i - n_eq when diff --git a/src/DLD-FUNCTIONS/sort.cc b/src/DLD-FUNCTIONS/sort.cc --- a/src/DLD-FUNCTIONS/sort.cc +++ b/src/DLD-FUNCTIONS/sort.cc @@ -236,6 +236,188 @@ return retval; } +template +static octave_value +mx_sort_sparse (Sparse &m, int dim, sortmode mode = UNDEFINED) +{ + octave_value retval; + + octave_idx_type nr = m.rows (); + octave_idx_type nc = m.columns (); + + if (m.length () < 1) + return Sparse (nr, nc); + + if (dim > 0) + { + m = m.transpose (); + nr = m.rows (); + nc = m.columns (); + } + + octave_sort sort; + + if (mode == ASCENDING) + sort.set_compare (ascending_compare); + else if (mode == DESCENDING) + sort.set_compare (descending_compare); + + T *v = m.data (); + octave_idx_type *cidx = m.cidx (); + octave_idx_type *ridx = m.ridx (); + + for (octave_idx_type j = 0; j < nc; j++) + { + octave_idx_type ns = cidx [j + 1] - cidx [j]; + sort.sort (v, ns); + + octave_idx_type i; + if (mode == ASCENDING) + { + for (i = 0; i < ns; i++) + if (ascending_compare (static_cast (0), v [i])) + break; + } + else + { + for (i = 0; i < ns; i++) + if (descending_compare (static_cast (0), v [i])) + break; + } + for (octave_idx_type k = 0; k < i; k++) + ridx [k] = k; + for (octave_idx_type k = i; k < ns; k++) + ridx [k] = k - ns + nr; + + v += ns; + ridx += ns; + } + + if (dim > 0) + m = m.transpose (); + + retval = m; + + return retval; +} + +template +static octave_value_list +mx_sort_sparse_indexed (Sparse &m, int dim, sortmode mode = UNDEFINED) +{ + octave_value_list retval; + + octave_idx_type nr = m.rows (); + octave_idx_type nc = m.columns (); + + if (m.length () < 1) + { + retval (1) = NDArray (dim_vector (nr, nc)); + retval (0) = octave_value (SparseMatrix (nr, nc)); + return retval; + } + + if (dim > 0) + { + m = m.transpose (); + nr = m.rows (); + nc = m.columns (); + } + + octave_sort *> indexed_sort; + + if (mode == ASCENDING) + indexed_sort.set_compare (ascending_compare); + else if (mode == DESCENDING) + indexed_sort.set_compare (descending_compare); + + T *v = m.data (); + octave_idx_type *cidx = m.cidx (); + octave_idx_type *ridx = m.ridx (); + + OCTAVE_LOCAL_BUFFER (vec_index *, vi, nr); + OCTAVE_LOCAL_BUFFER (vec_index, vix, nr); + + for (octave_idx_type i = 0; i < nr; i++) + vi[i] = &vix[i]; + + Matrix idx (nr, nc); + + for (octave_idx_type j = 0; j < nc; j++) + { + octave_idx_type ns = cidx [j + 1] - cidx [j]; + octave_idx_type offset = j * nr; + + if (ns == 0) + { + for (octave_idx_type k = 0; k < nr; k++) + idx (offset + k) = k + 1; + } + else + { + for (octave_idx_type i = 0; i < ns; i++) + { + vi[i]->vec = v[i]; + vi[i]->indx = ridx[i] + 1; + } + + indexed_sort.sort (vi, ns); + + octave_idx_type i; + if (mode == ASCENDING) + { + for (i = 0; i < ns; i++) + if (ascending_compare (static_cast (0), vi [i] -> vec)) + break; + } + else + { + for (i = 0; i < ns; i++) + if (descending_compare (static_cast (0), vi [i] -> vec)) + break; + } + + octave_idx_type ii = 0; + octave_idx_type jj = i; + for (octave_idx_type k = 0; k < nr; k++) + { + if (ii < ns && ridx[ii] == k) + ii++; + else + idx (offset + jj++) = k + 1; + } + + for (octave_idx_type k = 0; k < i; k++) + { + v [k] = vi [k] -> vec; + idx (k + offset) = vi [k] -> indx; + ridx [k] = k; + } + + for (octave_idx_type k = i; k < ns; k++) + { + v [k] = vi [k] -> vec; + idx (k - ns + nr + offset) = vi [k] -> indx; + ridx [k] = k - ns + nr; + } + + v += ns; + ridx += ns; + } + } + + if (dim > 0) + { + m = m.transpose (); + idx = idx.transpose (); + } + + retval (1) = idx; + retval(0) = octave_value (m); + + return retval; +} + // If we have IEEE 754 data format, then we can use the trick of // casting doubles as unsigned eight byte integers, and with a little // bit of magic we can automatically sort the NaN's correctly. @@ -602,6 +784,14 @@ #endif #endif +#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL) +static octave_value_list +mx_sort_sparse (Sparse &m, int dim, sortmode mode); + +static octave_value_list +mx_sort_sparse_indexed (Sparse &m, int dim, sortmode mode); +#endif + // std::abs(Inf) returns NaN!! static inline double xabs (const Complex& x) @@ -611,6 +801,36 @@ template <> bool +ascending_compare (Complex a, Complex b) +{ + return (xisnan (b) || (xabs (a) < xabs (b)) || ((xabs (a) == xabs (b)) + && (arg (a) < arg (b)))); +} + +bool +operator < (const Complex a, const Complex b) +{ + return (xisnan (b) || (xabs (a) < xabs (b)) || ((xabs (a) == xabs (b)) + && (arg (a) < arg (b)))); +} + +template <> +bool +descending_compare (Complex a, Complex b) +{ + return (xisnan (a) || (xabs (a) > xabs (b)) || ((xabs (a) == xabs (b)) + && (arg (a) > arg (b)))); +} + +bool +operator > (const Complex a, const Complex b) +{ + return (xisnan (a) || (xabs (a) > xabs (b)) || ((xabs (a) == xabs (b)) + && (arg (a) > arg (b)))); +} + +template <> +bool ascending_compare (vec_index *a, vec_index *b) { return (xisnan (b->vec) @@ -629,12 +849,22 @@ && (arg (a->vec) > arg (b->vec)))); } +template class octave_sort; template class vec_index; template class octave_sort *>; #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL) static octave_value_list +mx_sort (ArrayN &m, int dim, sortmode mode); + +static octave_value_list mx_sort_indexed (ArrayN &m, int dim, sortmode mode); + +static octave_value_list +mx_sort_sparse (Sparse &m, int dim, sortmode mode); + +static octave_value_list +mx_sort_sparse_indexed (Sparse &m, int dim, sortmode mode); #endif template class octave_sort; @@ -821,31 +1051,63 @@ if (arg.is_real_type ()) { - NDArray m = arg.array_value (); - - if (! error_state) + if (arg.is_sparse_type ()) { -#ifdef HAVE_IEEE754_DATA_FORMAT - // As operator > gives the right result, can special case here - if (! return_idx && smode == ASCENDING) - retval = mx_sort (m, dim); - else -#endif + SparseMatrix m = arg.sparse_matrix_value (); + + if (! error_state) { if (return_idx) - retval = mx_sort_indexed (m, dim, smode); + retval = mx_sort_sparse_indexed (m, dim, smode); else - retval = mx_sort (m, dim, smode); + retval = mx_sort_sparse (m, dim, smode); + } + } + else + { + NDArray m = arg.array_value (); + + if (! error_state) + { +#ifdef HAVE_IEEE754_DATA_FORMAT + // As operator > gives the right result, can special case here + if (! return_idx && smode == ASCENDING) + retval = mx_sort (m, dim); + else +#endif + { + if (return_idx) + retval = mx_sort_indexed (m, dim, smode); + else + retval = mx_sort (m, dim, smode); + } } } } else if (arg.is_complex_type ()) { - ComplexNDArray cm = arg.complex_array_value (); + if (arg.is_sparse_type ()) + { + SparseComplexMatrix cm = arg.sparse_complex_matrix_value (); - // Don't have unindexed version as no ">" operator - if (! error_state) - retval = mx_sort_indexed (cm, dim, smode); + if (! error_state) + { + if (return_idx) + retval = mx_sort_sparse_indexed (cm, dim, smode); + else + retval = mx_sort_sparse (cm, dim, smode); + } + } + else + { + ComplexNDArray cm = arg.complex_array_value (); + + if (! error_state) + { + // The indexed version seems to be slightly faster + retval = mx_sort_indexed (cm, dim, smode); + } + } } else if (arg.is_string ()) { diff --git a/src/ov-cx-sparse.h b/src/ov-cx-sparse.h --- a/src/ov-cx-sparse.h +++ b/src/ov-cx-sparse.h @@ -73,6 +73,17 @@ octave_sparse_complex_matrix (const MSparse& m) : octave_base_sparse (m) { } + octave_sparse_complex_matrix (const MSparse& m, + const MatrixType &t) + : octave_base_sparse (m, t) { } + + octave_sparse_complex_matrix (const Sparse& m, + const MatrixType &t) + : octave_base_sparse (SparseComplexMatrix (m), t) { } + + octave_sparse_complex_matrix (const Sparse& m) + : octave_base_sparse (SparseComplexMatrix (m)) { } + octave_sparse_complex_matrix (const octave_sparse_complex_matrix& cm) : octave_base_sparse (cm) { } diff --git a/src/ov-re-sparse.h b/src/ov-re-sparse.h --- a/src/ov-re-sparse.h +++ b/src/ov-re-sparse.h @@ -73,6 +73,15 @@ octave_sparse_matrix (const MSparse& m) : octave_base_sparse (m) { } + octave_sparse_matrix (const MSparse& m, const MatrixType& t) + : octave_base_sparse (m, t) { } + + octave_sparse_matrix (const Sparse& m) + : octave_base_sparse (SparseMatrix (m)) { } + + octave_sparse_matrix (const Sparse& m, const MatrixType& t) + : octave_base_sparse (SparseMatrix (m), t) { } + octave_sparse_matrix (const octave_sparse_matrix& m) : octave_base_sparse (m) { } diff --git a/src/ov.cc b/src/ov.cc --- a/src/ov.cc +++ b/src/ov.cc @@ -534,12 +534,24 @@ maybe_mutate (); } +octave_value::octave_value (const Sparse& m, const MatrixType &t) + : rep (new octave_sparse_matrix (m, t)) +{ + maybe_mutate (); +} + octave_value::octave_value (const SparseComplexMatrix& m, const MatrixType &t) : rep (new octave_sparse_complex_matrix (m, t)) { maybe_mutate (); } +octave_value::octave_value (const Sparse& m, const MatrixType &t) + : rep (new octave_sparse_complex_matrix (m, t)) +{ + maybe_mutate (); +} + octave_value::octave_value (const SparseBoolMatrix& bm, const MatrixType &t) : rep (new octave_sparse_bool_matrix (bm, t)) { diff --git a/src/ov.h b/src/ov.h --- a/src/ov.h +++ b/src/ov.h @@ -192,8 +192,10 @@ octave_value (const ArrayN& chnda, bool is_string = false, char type = '"'); octave_value (const SparseMatrix& m, const MatrixType& t = MatrixType ()); + octave_value (const Sparse& m, const MatrixType& t = MatrixType ()); octave_value (const SparseComplexMatrix& m, const MatrixType& t = MatrixType ()); + octave_value (const Sparse& m, const MatrixType& t = MatrixType ()); octave_value (const SparseBoolMatrix& bm, const MatrixType& t = MatrixType ()); octave_value (const octave_int8& i);