function obj=rsparse(varargin)
%RSPARSE - Creates a sparse array object that is a subclass of MATLAB's native
%sparse data type, but which is robust against certain bugs and errors
%(present as of R2009b).
%
% S=rsparse(varargin)
%
%The I/O syntax and options for rsparse() are identical to that of sparse().
%
%Where sparse() would return a double sparse matrix, rsparse() will return a matrix
%of class RobustSparseDouble, a class defined in this package. Similarly, wherever
%sparse() would return a logical sparse matrix, rsparse() will return a matrix of
%user-defined class RobustSparseLogical.
%
%%%%%%%%%%
%EXAMPLE 1: Indexing robustness - this utilizes the sparse-sub-access
% package by Bruno Luong.
%
%
% >> A=sparse(100000,100000,1), %native MATLAB sparse matrix
%
%
% A =
%
% (100000,100000) 1
%
%
% >> B=rsparse(A), %convert to robust type
%
% B=
%
% (100000,100000) 1
%
%
%
% >> whos A B
%
% Name Size Bytes Class Attributes
%
% A 100000x100000 400016 double sparse
% B 100000x100000 400072 RobustSparseDouble
%
%
%
% >> A(logical(A))=2, %Wrong result due to indexing bug
%
% A =
%
% (65408,14101) 2
% (100000,100000) 1
%
%
%
% >> B(logical(B))=2, %RIGHT!!!
%
% B=
%
% (100000,100000) 2
%
%
%
%%%%%%%%%%
%EXAMPLE 2: Robustness to mixed data type operations.
%
%For some reason, MATLAB decides to issue an error when a mathematical operation
%involving sparse and non-double numeric data is attempted:
%
% A=speye(3);
% x=single([1;2;3]);
%
% >> y=A*x, %ANNOYING....
%
% ??? Error using ==> mtimes
% Sparse single arrays are not supported.
%
%
%The RobustSparse types, however, will silently pre-convert the foreign data
%to doubles:
%
% B=rsparse(A);
%
% >>y=B*x, %BETTER!!!
%
% y =
%
% 1
% 2
% 3
%
%%%%%%%%%%%%%%%%%%%%%%%
%
%I'm hoping that TMW will fix these problems soon, rendering this package
%obsolete. Once they do, simply replace the code in rsparse.m with
%the following, and calls to rsparse() will become equivalent to calls to
%sparse().
%
%function S=rsparse(varargin)
%
% S=sparse(varargin{:});
%
%end
%
%
%CAUTIONARY NOTES:
%
%(1) Because this package uses various M-coded wrappers for built-in sparse
%routines, there is obviously some compromise in speed.
%
%(2) I've overloaded all math operators (+ , - , .* , >=, <=, etc...) and some
%common functions like sum(), inv(), spfun(), etc... to return
%RobustSparse data types, where they would otherwise return ordinary sparse types.
%For obvious reasons, however, I cannot do this
%for all functions out there capable of returning a sparse matrix
%(e.g., triu, tril, sin, cos, etc ... ), nor can I keep
%up with TMW's releases of new functions.
%
%Therefore, you should bear in mind that B=triu(rsparse(A)) and similar
%will return an ordinary native sparse data type, B,
%with all of its vulnerabilities. You should take care to post-convert
%such results to robust type, via B=rsparse(B). Or, you can add overloaded
%methods as you see fit, mimicking the others in RobustSparseDouble.m and
%RobustSparseLogical.m
%
%
%See also rspeye, rsprand, rsprandn, rsprandsym
%
% by Matt Jacobson
%
% Copyright, Xoran Technologies, Inc. 2009
%
data=sparse(varargin{:});
if isa(data,'double')
obj=RobustSparseDouble(data); return
elseif isa(data,'logical')
obj=RobustSparseLogical(data); return
end