sparse.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2004-2012 David Bateman
00004 Copyright (C) 1998-2004 Andy Adler
00005 Copyright (C) 2010 VZLU Prague
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
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    // Temporarily disable sparse_auto_mutate if set (it's obsolete anyway).
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines