00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <cstdlib>
00030 #include <string>
00031
00032 #include "variables.h"
00033 #include "utils.h"
00034 #include "pager.h"
00035 #include "defun.h"
00036 #include "gripes.h"
00037 #include "quit.h"
00038 #include "unwind-prot.h"
00039
00040 #include "ov-re-sparse.h"
00041 #include "ov-cx-sparse.h"
00042 #include "ov-bool-sparse.h"
00043
00044 DEFUN (issparse, args, ,
00045 "-*- texinfo -*-\n\
00046 @deftypefn {Loadable Function} {} issparse (@var{x})\n\
00047 Return true if @var{x} is a sparse matrix.\n\
00048 @seealso{ismatrix}\n\
00049 @end deftypefn")
00050 {
00051 if (args.length() != 1)
00052 {
00053 print_usage ();
00054 return octave_value ();
00055 }
00056 else
00057 return octave_value (args(0).is_sparse_type ());
00058 }
00059
00060 DEFUN (sparse, args, ,
00061 "-*- texinfo -*-\n\
00062 @deftypefn {Loadable Function} {@var{s} =} sparse (@var{a})\n\
00063 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})\n\
00064 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})\n\
00065 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, \"unique\")\n\
00066 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{m}, @var{n})\n\
00067 Create a sparse matrix from the full matrix or row, column, value triplets.\n\
00068 If @var{a} is a full matrix, convert it to a sparse matrix representation,\n\
00069 removing all zero values in the process.\n\
00070 \n\
00071 Given the integer index vectors @var{i} and @var{j}, a 1-by-@code{nnz} vector\n\
00072 of real of complex values @var{sv}, overall dimensions @var{m} and @var{n}\n\
00073 of the sparse matrix. The argument @code{nzmax} is ignored but accepted for\n\
00074 compatibility with @sc{matlab}. If @var{m} or @var{n} are not specified\n\
00075 their values are derived from the maximum index in the vectors @var{i} and\n\
00076 @var{j} as given by @code{@var{m} = max (@var{i})},\n\
00077 @code{@var{n} = max (@var{j})}.\n\
00078 \n\
00079 @strong{Note}: if multiple values are specified with the same\n\
00080 @var{i}, @var{j} indices, the corresponding values in @var{s} will\n\
00081 be added.\n\
00082 \n\
00083 The following are all equivalent:\n\
00084 \n\
00085 @example\n\
00086 @group\n\
00087 s = sparse (i, j, s, m, n)\n\
00088 s = sparse (i, j, s, m, n, \"summation\")\n\
00089 s = sparse (i, j, s, m, n, \"sum\")\n\
00090 @end group\n\
00091 @end example\n\
00092 \n\
00093 Given the option \"unique\". if more than two values are specified for the\n\
00094 same @var{i}, @var{j} indices, the last specified value will be used.\n\
00095 \n\
00096 @code{sparse(@var{m}, @var{n})} is equivalent to\n\
00097 @code{sparse ([], [], [], @var{m}, @var{n}, 0)}\n\
00098 \n\
00099 If any of @var{sv}, @var{i} or @var{j} are scalars, they are expanded\n\
00100 to have a common size.\n\
00101 @seealso{full}\n\
00102 @end deftypefn")
00103 {
00104 octave_value retval;
00105 int nargin = args.length ();
00106
00107
00108 unwind_protect frame;
00109 frame.protect_var (Vsparse_auto_mutate);
00110 Vsparse_auto_mutate = false;
00111
00112 if (nargin == 1)
00113 {
00114 octave_value arg = args (0);
00115 if (arg.is_bool_type ())
00116 retval = arg.sparse_bool_matrix_value ();
00117 else if (arg.is_complex_type ())
00118 retval = arg.sparse_complex_matrix_value ();
00119 else if (arg.is_numeric_type ())
00120 retval = arg.sparse_matrix_value ();
00121 else
00122 gripe_wrong_type_arg ("sparse", arg);
00123 }
00124 else if (nargin == 2)
00125 {
00126 octave_idx_type m = 0, n = 0;
00127 if (args(0).is_scalar_type () && args(1).is_scalar_type ())
00128 {
00129 m = args(0).idx_type_value ();
00130 n = args(1).idx_type_value ();
00131 }
00132 else
00133 error ("sparse: dimensions M,N must be scalar");
00134
00135 if (! error_state)
00136 {
00137 if (m >= 0 && n >= 0)
00138 retval = SparseMatrix (m, n);
00139 else
00140 error ("sparse: dimensions M,N must be positive or zero");
00141 }
00142 }
00143 else if (nargin >= 3)
00144 {
00145 bool summation = true;
00146 if (nargin > 3 && args(nargin-1).is_string ())
00147 {
00148 std::string opt = args(nargin-1).string_value ();
00149 if (opt == "unique")
00150 summation = false;
00151 else if (opt == "sum" || opt == "summation")
00152 summation = true;
00153 else
00154 error ("sparse: invalid option: %s", opt.c_str ());
00155
00156 nargin -= 1;
00157 }
00158
00159 if (! error_state)
00160 {
00161 octave_idx_type m = -1, n = -1, nzmax = -1;
00162 if (nargin == 6)
00163 {
00164 nzmax = args(5).idx_type_value ();
00165 nargin --;
00166 }
00167
00168 if (nargin == 5)
00169 {
00170 if (args(3).is_scalar_type () && args(4).is_scalar_type ())
00171 {
00172 m = args(3).idx_type_value ();
00173 n = args(4).idx_type_value ();
00174 }
00175 else
00176 error ("sparse: expecting scalar dimensions");
00177
00178
00179 if (! error_state && (m < 0 || n < 0))
00180 error ("sparse: dimensions must be non-negative");
00181 }
00182 else if (nargin != 3)
00183 print_usage ();
00184
00185 if (! error_state)
00186 {
00187 idx_vector i = args(0).index_vector ();
00188 idx_vector j = args(1).index_vector ();
00189
00190 if (args(2).is_bool_type ())
00191 retval = SparseBoolMatrix (args(2).bool_array_value (), i, j,
00192 m, n, summation, nzmax);
00193 else if (args(2).is_complex_type ())
00194 retval = SparseComplexMatrix (args(2).complex_array_value (),
00195 i, j, m, n, summation, nzmax);
00196 else if (args(2).is_numeric_type ())
00197 retval = SparseMatrix (args(2).array_value (), i, j,
00198 m, n, summation, nzmax);
00199 else
00200 gripe_wrong_type_arg ("sparse", args(2));
00201 }
00202
00203 }
00204 }
00205
00206 return retval;
00207 }
00208
00209 DEFUN (spalloc, args, ,
00210 "-*- texinfo -*-\n\
00211 @deftypefn {Loadable Function} {@var{s} =} spalloc (@var{m}, @var{n}, @var{nz})\n\
00212 Create an @var{m}-by-@var{n} sparse matrix with pre-allocated space for at\n\
00213 most @var{nz} nonzero elements. This is useful for building the matrix\n\
00214 incrementally by a sequence of indexed assignments. Subsequent indexed\n\
00215 assignments will reuse the pre-allocated memory, provided they are of one of\n\
00216 the simple forms\n\
00217 \n\
00218 @itemize\n\
00219 @item @code{@var{s}(I:J) = @var{x}}\n\
00220 \n\
00221 @item @code{@var{s}(:,I:J) = @var{x}}\n\
00222 \n\
00223 @item @code{@var{s}(K:L,I:J) = @var{x}}\n\
00224 @end itemize\n\
00225 \n\
00226 @b{and} that the following conditions are met:\n\
00227 \n\
00228 @itemize\n\
00229 @item the assignment does not decrease nnz(@var{S}).\n\
00230 \n\
00231 @item after the assignment, nnz(@var{S}) does not exceed @var{nz}.\n\
00232 \n\
00233 @item no index is out of bounds.\n\
00234 @end itemize\n\
00235 \n\
00236 Partial movement of data may still occur, but in general the assignment will\n\
00237 be more memory and time-efficient under these circumstances. In particular,\n\
00238 it is possible to efficiently build a pre-allocated sparse matrix from\n\
00239 contiguous block of columns.\n\
00240 \n\
00241 The amount of pre-allocated memory for a given matrix may be queried using\n\
00242 the function @code{nzmax}.\n\
00243 @seealso{nzmax, sparse}\n\
00244 @end deftypefn")
00245 {
00246 octave_value retval;
00247 int nargin = args.length ();
00248
00249 if (nargin == 2 || nargin == 3)
00250 {
00251 octave_idx_type m = args(0).idx_type_value ();
00252 octave_idx_type n = args(1).idx_type_value ();
00253 octave_idx_type nz = 0;
00254 if (nargin == 3)
00255 nz = args(2).idx_type_value ();
00256 if (error_state)
00257 ;
00258 else if (m >= 0 && n >= 0 && nz >= 0)
00259 retval = SparseMatrix (dim_vector (m, n), nz);
00260 else
00261 error ("spalloc: M,N,NZ must be non-negative");
00262 }
00263 else
00264 print_usage ();
00265
00266 return retval;
00267 }