1function Problem = ssget (matrix, ss_index)
2%SSGET loads a matrix from the SuiteSparse Matrix Collection.
3%   (formerly called the University of Florida Sparse Matrix Collection).
4%
5%   Problem = ssget(matrix) loads a matrix from the SuiteSparse Matrix
6%   Collection, specified as either a unique ID number (1 to the # of matrices
7%   in the collection) or as a string (the full name of the matrix).  With no
8%   input parameters, index=ssget returns an index of matrices in the
9%   collection.  A local copy of the matrix is saved.  If no input or output
10%   arguments are provided, the index is printed.  With a 2nd parameter
11%   (Problem = ssget (matrix, index)), the index file is not loaded.  This is
12%   faster if you are loading lots of matrices.
13%
14%   Examples:
15%       index = ssget ;                     % loads index
16%       index = ssget ('refresh') ;         % forces download of new index
17%       index = ssget ('update') ;          % same as 'refresh'
18%
19%       Problem = ssget (6)                 % 4 ways of loading the same Problem
20%       Problem = ssget ('HB/arc130')
21%       Problem = ssget (6, index)
22%       Problem = ssget ('HB/arc130', index)
23%
24%   See also ssgrep, ssweb, ssget_example, ssget_defaults, websave.
25
26% Copyright 2009-2019, Timothy A. Davis, http://www.suitesparse.com
27
28%-------------------------------------------------------------------------------
29% get the parameter settings
30%-------------------------------------------------------------------------------
31
32params = ssget_defaults ;
33
34% The ss_index.mat file is used by ssget only, not by ssgui.java.
35indexfile = [ params.topdir 'files' filesep 'ss_index.mat' ] ;
36indexurl  = [ params.topurl '/files/ss_index.mat' ] ;
37
38% The ssstats.csv file is used by the ssgui.java program.  It is also used by
39% the sskinds.m function, which reads the file to find the problem kind for
40% each matrix in the collection.
41statfile = [ params.topdir 'files' filesep 'ssstats.csv' ] ;
42staturl  = [ params.topurl '/files/ssstats.csv' ] ;
43
44%-------------------------------------------------------------------------------
45% get the index file (download a new one if necessary)
46%-------------------------------------------------------------------------------
47
48refresh = 0 ;
49if nargin == 0
50    % if the user passed in a zero or no argument at all, return the index file
51    matrix = 0 ;
52else
53    % ssget ('refresh') downloads the latest index file from the web
54    if (ischar (matrix))
55        if (strcmp (matrix, 'refresh') || strcmp (matrix, 'update'))
56            matrix = 0 ;
57            refresh = 1 ;
58        end
59    end
60end
61
62if (~refresh)
63    try
64        % load the existing index file
65        if (nargin < 2)
66            load (indexfile) ;
67        end
68        % see if the index file is old; if so, download a fresh copy
69        fileinfo = dir (indexfile) ;
70        refresh = (fileinfo.datenum + params.refresh < now) ;
71    catch
72        % oops, no index file, or a refresh is due.  download it.
73        refresh = 1 ;
74    end
75end
76
77err = '' ;      % to catch a download error, if any
78
79if (refresh)
80    % a new ss_index.mat file to get access to new matrices (if any)
81    try
82        % fprintf ('Downloading latest index to the collection.\n') ;
83
84        % get a new ss_index.mat file
85        tmp = tempname ;                        % download to a temp file first
86        old = [ params.topdir 'files' filesep 'ss_index_old.mat' ] ;
87        websave (tmp, indexurl) ;               % download the latest index file
88        try
89            movefile (indexfile, old, 'f') ;    % keep a backup of the old index
90        catch
91            % backup failed, continue anyway
92        end
93        movefile ([tmp '.mat'], indexfile, 'f');% move the new index into place
94
95        % get a new ssstats.csv file
96        tmp = tempname ;                        % download to a temp file first
97        old = [ params.topdir 'files' filesep 'ssstats_old.csv' ] ;
98        websave (tmp, staturl) ;                % download the latest stats file
99        try
100            movefile (statfile, old, 'f') ;     % keep a backup of the old stats
101        catch
102            % backup failed, continue anyway
103        end
104        movefile ([tmp '.csv'], statfile, 'f') ;% move the new index into place
105
106    catch me
107        err = me.message ;
108    end
109    load (indexfile) ;
110end
111
112%-------------------------------------------------------------------------------
113% return the index file if requested
114%-------------------------------------------------------------------------------
115
116if (matrix == 0)
117    if (nargout == 0)
118        % no output arguments have been passed, so print the index file
119        fprintf ('\nSuiteSparse Matrix Collection\n') ;
120        fprintf ('(formerly called the Univ of Florida Sparse Matrix Collection)\n') ;
121        fprintf ('index:  last revised %s\n', ss_index.LastRevisionDate) ;
122        fprintf ('\nLegend:\n') ;
123        fprintf ('(p,n)sym:  symmetry of the pattern and values\n') ;
124        fprintf ('           (0 = unsymmetric, 1 = symmetric, - = not computed)\n') ;
125        fprintf ('type:      real\n') ;
126        fprintf ('           complex\n') ;
127        fprintf ('           binary:  all entries are 0 or 1\n') ;
128        nmat = length (ss_index.nrows) ;
129        for j = 1:nmat
130            if (mod (j, 25) == 1)
131                fprintf ('\n') ;
132                fprintf ('ID   Group/Name                nrows-by-  ncols  nonzeros  (p,n)sym  type\n') ;
133            end
134            s = sprintf ('%s/%s', ss_index.Group {j}, ss_index.Name {j}) ;
135            fprintf ('%4d %-30s %7d-by-%7d %9d ', ...
136            j, s, ss_index.nrows (j), ss_index.ncols (j), ss_index.nnz (j)) ;
137            psym = ss_index.pattern_symmetry (j) ;
138            nsym = ss_index.numerical_symmetry (j) ;
139            if (psym < 0)
140                fprintf ('  -  ') ;
141            else
142                fprintf (' %4.2f', psym) ;
143            end
144            if (nsym < 0)
145                fprintf ('  -  ') ;
146            else
147                fprintf (' %4.2f', nsym) ;
148            end
149            if (ss_index.isBinary (j))
150                fprintf (' binary\n') ;
151            elseif (~ss_index.isReal (j))
152                fprintf (' complex\n') ;
153            else
154                fprintf (' real\n') ;
155            end
156        end
157    else
158        Problem = ss_index ;
159    end
160
161    if (~isempty (err))
162        fprintf ('\nssget: unable to download latest index; using old one.\n') ;
163        disp (err) ;
164    end
165    return ;
166end
167
168%-------------------------------------------------------------------------------
169% determine if the matrix parameter is a matrix index or name
170%-------------------------------------------------------------------------------
171
172[group, matname, id] = ssget_lookup (matrix, ss_index) ;
173
174if (id == 0)
175    error ('invalid matrix') ;
176end
177
178%-------------------------------------------------------------------------------
179% download the matrix (if needed) and load it into MATLAB
180
181grpdir =  [ params.topdir 'mat' filesep group ] ;
182matfile = [ grpdir filesep matname '.mat' ] ;
183maturl =  [ params.topurl '/mat/' group '/' matname '.mat' ] ;
184
185if (~exist (grpdir, 'dir'))
186    mkdir (grpdir) ;                        % create the Group directory
187end
188
189if (~exist (matfile, 'file'))
190    fprintf ('downloading %s\n', maturl) ;
191    fprintf ('to %s\n', matfile) ;
192    tmp = tempname ;                        % download to a temp file first
193    websave (tmp, maturl) ;
194    movefile ([tmp '.mat'], matfile, 'f') ; % move the new matrix into place
195end
196
197load (matfile) ;
198
199