function UFpage (matrix, index, figures) %UFpage: create web page for a matrix in UF Sparse Matrix Collection % % Usage: % UFpage (matrix, index, figures) % % matrix: id or name of matrix to create the web page for. % index: the UF index, from UFget. % figures: 1 if the figures are to be created, 0 otherwise % % Example: % % UFpage (267) % UFpage ('HB/west0479') % % See also UFget, cspy, UFgplot, UFint. % This function assumes that the mat/, MM/, and RB/ directories all reside in % the same parent directory, given by the download directory specified by % UFget_defaults. % Copyright 2006, Timothy A. Davis %------------------------------------------------------------------------------- % get inputs %------------------------------------------------------------------------------- if (nargin < 2) index = UFget ; end if (nargin < 3) figures = 1 ; end %------------------------------------------------------------------------------- % get the Problem and its contents %------------------------------------------------------------------------------- Problem = UFget (matrix,index) ; disp (Problem) ; fullname = Problem.name ; s = strfind (fullname, '/') ; grp = fullname (1:s-1) ; name = fullname (s+1:end) ; id = Problem.id ; % create the primary directory [url topdir] = UFlocation ; matrices = [topdir 'matrices'] ; if (~exist (matrices, 'dir')) mkdir (matrices) ; end % create the group directory if (~exist ([matrices filesep grp], 'dir')) mkdir ([matrices filesep grp]) ; end % determine the full path of the problem fullpath = regexprep ([matrices filesep fullname], '[\/\\]', filesep) ; ptitle = Problem.title ; z = 0 ; if (isfield (Problem, 'Zeros')) z = nnz (Problem.Zeros) ; Problem = rmfield (Problem, 'Zeros') ; end nblocks = index.nblocks (id) ; ncc = index.ncc (id) ; has_b = isfield (Problem, 'b') ; has_x = isfield (Problem, 'x') ; has_aux = isfield (Problem, 'aux') ; if (has_b) b = Problem.b ; Problem = rmfield (Problem, 'b') ; if (iscell (b)) b = sprintf ('cell %d-by-%d\n', size (b)) ; elseif (issparse (b)) b = sprintf ('sparse %d-by-%d\n', size (b)) ; else b = sprintf ('full %d-by-%d\n', size (b)) ; end end if (has_x) x = Problem.x ; Problem = rmfield (Problem, 'x') ; if (iscell (x)) x = sprintf ('cell %d-by-%d\n', size (x)) ; elseif (issparse (x)) x = sprintf ('sparse %d-by-%d\n', size (x)) ; else x = sprintf ('full %d-by-%d\n', size (x)) ; end end nodename = [ ] ; if (has_aux) aux = Problem.aux ; Problem = rmfield (Problem, 'aux') ; auxfields = fields (aux) ; has_coord = isfield (aux, 'coord') ; has_nodename = isfield (aux, 'nodename') ; auxs = cell (1, length (auxfields)) ; for k = 1:length(auxfields) siz = size (aux.(auxfields{k})) ; if (iscell (aux.(auxfields{k}))) auxs {k} = sprintf ('cell %d-by-%d\n', siz) ; elseif (issparse (aux.(auxfields{k}))) auxs {k} = sprintf ('sparse %d-by-%d\n', siz) ; else auxs {k} = sprintf ('full %d-by-%d\n', siz) ; end end if (has_coord) xyz = aux.coord ; end if (has_nodename) nodename = aux.nodename ; end clear aux else has_coord = 0 ; end kind = Problem.kind ; if (isfield (Problem, 'notes')) notes = Problem.notes ; else notes = '' ; end au = Problem.author ; ed = Problem.ed ; da = Problem.date ; m = index.nrows (id) ; n = index.ncols (id) ; nz = index.nnz (id) ; nnzdiag = index.nnzdiag (id) ; if (strfind (kind, 'graph')) bipartite = ~isempty (strfind (kind, 'bipartite')) ; directed = ~isempty (regexp (kind, '\ 1) & (isempty (strfind (kind, 'graph'))) ; if (do_dmspy) try cs_dmspy (A, 128) ; title ('Dulmage-Mendelsohn permutation') ; catch fprintf ('dmspy failed\n') ; delete ([fullpath '_dmperm.png']) ; do_dmspy = 0 ; end print (gcf, '-dpng', '-r64', [fullpath '_dmperm.png']) ; end %--------------------------------------------------------------------------- % create the ccspy figure %--------------------------------------------------------------------------- do_scc = (ncc > 1) ; if (do_dmspy && m == n && nnzdiag == n) % don't do scc for a square matrix with zero-free diagonal do_scc = 0 ; end if (do_scc) try ccspy (A, bipartite, 128) ; if (bipartite) title ('connected components of the bipartite graph') ; else title ('strongly connected components of the graph') ; end print (gcf, '-dpng', '-r64', [fullpath '_scc.png']) ; catch fprintf ('ccspy failed\n') ; delete ([fullpath '_cc.png']) ; do_scc = 0 ; end end else %--------------------------------------------------------------------------- % the plots already exist - check the files %--------------------------------------------------------------------------- do_scc = exist ([fullpath '_scc.png'], 'file') ; do_dmspy = exist ([fullpath '_dmperm.png'], 'file') ; do_gplot = exist ([fullpath '_gplot.png'], 'file') ; end clear Problem %------------------------------------------------------------------------------- % create the web page for the matrix %------------------------------------------------------------------------------- f = fopen ([fullpath '.html'], 'w') ; if (f < 0) error ('unable to create matrix web page') ; end % add the header fprintf (f,'\n'); fprintf (f, '\n') ; fprintf (f, '%s sparse matrix\n', fullname) ; fprintf (f, '\n') ; % link to UF collection fprintf (f, '
  • UF Sparse Matrix Collection\n') ; % link to group fprintf (f, '
  • Matrix group: %s\n', grp) ; % add link to mat//README.txt fprintf (f, '
  • ', grp) ; fprintf (f, 'Click here for a description of the %s group.\n', grp) ; % link to all matrices fprintf (f, '
  • ') ; fprintf (f, 'Click here for a list of all matrices\n') ; % link to all groups fprintf (f, '
  • ') ; fprintf (f, 'Click here for a list of all matrix groups\n') ; % matrix name and description fprintf (f, '


  • Matrix: %s\n', fullname) ; fprintf (f, '
  • Description: %s\n', ptitle) ; % download link for MATLAB format fprintf (f, ... '
  • download as a MATLAB mat-file',... fullname) ; fsize (f, [topdir 'mat/' fullname '.mat']) ; fprintf (f, 'Use UFget(%d)', url, id) ; fprintf (f, ' or UFget(''%s'') in MATLAB.\n', fullname) ; % download link for Matrix Market format fprintf (f, ... '
  • download in Matrix Market format',... fullname) ; fsize (f, [topdir 'MM/' fullname '.tar.gz']) ; % download link for Rutherford/Boeing format fprintf (f, ... '
  • download in Rutherford/Boeing format',... fullname) ; fsize (f, [topdir 'RB/' fullname '.tar.gz']) ; %------------------------------------------------------------------------------- % link to images %------------------------------------------------------------------------------- fprintf (f, '

    %s\n', fullname, name) ; % dmspy, if it exists if (do_dmspy) fprintf (f, '

    dmperm of %s\n', ... fullname, name) ; end % ccspy, if it exists if (do_scc) fprintf (f, '

    scc of %s\n', ... fullname, name) ; end % gplot, if it exists if (do_gplot) fprintf (f, '

    ') ; fprintf (f, ... '%s graph\n', ... name, fullname, name) ; end %------------------------------------------------------------------------------- % table of matrix properties %------------------------------------------------------------------------------- fprintf (f, '

    \n') ; stat (f, 'Matrix properties', '%s', ' ') ; stat (f, 'number of rows', '%s', UFint (m)) ; stat (f, 'number of columns', '%s', UFint (n)) ; stat (f, 'nonzeros', '%s', UFint (nz)) ; srank = index.sprank (id) ; if (srank == min (m,n)) stat (f, 'structural full rank?', '%s', 'yes') ; else stat (f, 'structural full rank?', '%s', 'no') ; end stat (f, 'structural rank', '%s', UFint (srank)) ; stat (f, '# of blocks from dmperm', '%s', UFint (nblocks)) ; stat (f, '# strongly connected comp.', '%s', UFint (ncc)) ; if (srank == min (m,n)) stat (f, 'entries not in dmperm blocks', '%s', ... UFint (index.nzoff (id))) ; end stat (f, 'explicit zero entries', '%s', UFint (z)) ; s = index.pattern_symmetry (id) ; if (s == 1) stat (f, 'nonzero pattern symmetry', '%s', 'symmetric') ; else stat (f, 'nonzero pattern symmetry', '%8.0f%%', s*100) ; end s = index.numerical_symmetry (id) ; if (s == -1) stat (f, 'numeric value symmetry', '%s', 'unknown') ; elseif (s == 1) stat (f, 'numeric value symmetry', '%s', 'symmetric') ; else stat (f, 'numeric value symmetry', '%8.0f%%', s*100) ; end % print the Rutherford/Boeing type mtype = index.RBtype (id,:) ; ss = '-' ; if (mtype (1) == 'r') ss = 'real' ; elseif (mtype (1) == 'c') ss = 'complex' ; elseif (mtype (1) == 'i') ss = 'integer' ; elseif (mtype (1) == 'p') ss = 'binary' ; end stat (f, 'type', '%s', ss) ; ss = '-' ; if (mtype (2) == 'r') ss = 'rectangular' ; elseif (mtype (2) == 'u') ss = 'unsymmetric' ; elseif (mtype (2) == 's') ss = 'symmetric' ; elseif (mtype (2) == 'h') ss = 'Hermitian' ; elseif (mtype (2) == 'z') ss = 'skew-symmetric' ; end stat (f, 'structure', '%s', ss) ; if (index.cholcand (id) == 1) ss = 'yes' ; elseif (index.cholcand (id) == 0) ss = 'no' ; else ss = '?' ; end stat (f, 'Cholesky candidate?', '%s', ss) ; s = index.posdef (id) ; if (s == 0) ss = 'no' ; elseif (s == 1) ss = 'yes' ; else ss = 'unknown' ; end stat (f, 'positive definite?', '%s', ss) ; fprintf (f, '

    \n') ; %------------------------------------------------------------------------------- % problem author, ed, kind %------------------------------------------------------------------------------- fprintf (f, '

    \n') ; fprintf (f, '\n', au) ; fprintf (f, '\n', ed) ; fprintf (f, '\n', da) ; fprintf (f, '\n', kind); s = index.isND (id) ; if (s == 0) ss = 'no' ; else ss = 'yes' ; end fprintf (f, '\n', ss) ; fprintf (f, '
    author%s
    editor%s
    date%s
    kind%s
    2D/3D problem?%s

    \n') ; %------------------------------------------------------------------------------- % fields %------------------------------------------------------------------------------- if (has_b || has_x || has_aux) fprintf (f, '

    \n') ; stat (f, 'Additional fields', '%s', 'size and type') ; if (has_b) stat (f, 'b', '%s', b) ; end if (has_x) stat (f, 'x', '%s', x) ; end if (has_aux) for k = 1:length(auxfields) stat (f, auxfields{k}, '%s', char (auxs{k})) ; end end fprintf (f, '

    \n') ; end %------------------------------------------------------------------------------- % Notes %------------------------------------------------------------------------------- if (~isempty (notes)) fprintf (f, '

    Notes:

    \n') ;
        for k = 1:size(notes,1)
    	fprintf (f, '%s\n', notes (k,:)) ;
        end
        fprintf (f, '
    \n') ; end %------------------------------------------------------------------------------- % ordering statistics %------------------------------------------------------------------------------- fprintf (f, '

    \n') ; if (nblocks == 1 || index.nzoff (id) == -2) stat (f, ... 'Ordering statistics:', ... '%s', 'AMD', 'METIS') ; if (index.amd_lnz (id) > -2) stat (f, 'nnz(chol(P*(A+A''+s*I)*P''))', '%s', ... UFint (index.amd_lnz (id)), ... UFint (index.metis_lnz (id))) ; stat (f, 'Cholesky flop count', '%7.1e', ... index.amd_flops (id), ... index.metis_flops (id)) ; stat (f, 'nnz(L+U), no partial pivoting', '%s', ... UFint (2*index.amd_lnz (id) - min(m,n)), ... UFint (2*index.metis_lnz (id) - min(m,n))) ; end stat (f, 'nnz(V) for QR, upper bound nnz(L) for LU', '%s', ... UFint (index.amd_vnz (id)), ... UFint (index.metis_vnz (id))) ; stat (f, 'nnz(R) for QR, upper bound nnz(U) for LU', '%s', ... UFint (index.amd_rnz (id)), ... UFint (index.metis_rnz (id))) ; else stat (f, ... 'Ordering statistics:', ... '%s', 'AMD', 'METIS', 'DMPERM+') ; if (index.amd_lnz (id) > -2) stat (f, 'nnz(chol(P*(A+A''+s*I)*P''))', '%s', ... UFint (index.amd_lnz (id)), ... UFint (index.metis_lnz (id)), ... UFint (index.dmperm_lnz (id))) ; stat (f, 'Cholesky flop count', '%7.1e', ... index.amd_flops (id), ... index.metis_flops (id), ... index.dmperm_flops (id)) ; stat (f, 'nnz(L+U), no partial pivoting', '%s', ... UFint (2*index.amd_lnz (id) - min(m,n)), ... UFint (2*index.metis_lnz (id) - min(m,n)), ... UFint (index.dmperm_lnz (id) + index.dmperm_unz (id)-min(m,n))) ; end stat (f, 'nnz(V) for QR, upper bound nnz(L) for LU', '%s', ... UFint (index.amd_vnz (id)), ... UFint (index.metis_vnz (id)), ... UFint (index.dmperm_vnz (id))) ; stat (f, 'nnz(R) for QR, upper bound nnz(U) for LU', '%s', ... UFint (index.amd_rnz (id)), ... UFint (index.metis_rnz (id)), ... UFint (index.dmperm_rnz (id))) ; end fprintf (f, '

    \n') ; %------------------------------------------------------------------------------- % note regarding orderings %------------------------------------------------------------------------------- if (z > 0) fprintf (f, '

    Note that all matrix statistics (except nonzero'); fprintf (f, ' pattern symmetry) exclude the %d explicit zero entries.\n',z); fprintf (f, '\n') ; end %------------------------------------------------------------------------------- % etc ... %------------------------------------------------------------------------------- fprintf (f, '

    Maintained by '); fprintf (f, 'Tim Davis, last updated %s.', date) ; fprintf (f, '
    Matrix pictures by cspy, a ', url) ; fprintf (f, 'MATLAB function in the CSparse', url) ; fprintf (f, ' package.\n\n\n') ; fclose (f) ; %------------------------------------------------------------------------------- % fsize: print the filesize %------------------------------------------------------------------------------- function fsize (f, filename) d = dir (regexprep (filename, '[\/\\]', filesep)) ; if (isempty (d)) fprintf ('\n') ; elseif (d.bytes < 1024) fprintf (f, ', file size: %4d bytes.\n', d.bytes) ; elseif (d.bytes > 2^20) fprintf (f, ', file size: %8.0f MB.\n', d.bytes / 2^20) ; else fprintf (f, ', file size: %8.0f KB.\n', d.bytes / 2^10) ; end %------------------------------------------------------------------------------- % stat: print one row of a table %------------------------------------------------------------------------------- function stat (f, what, format, value1, value2, value3) s = val (format, value1) ; fprintf (f, '%s%s\n', what, s) ; if (nargin > 4) fprintf (f, '%s\n', val (format, value2)) ; end if (nargin > 5) fprintf (f, '%s\n', val (format, value3)) ; end fprintf (f, '\n') ; %------------------------------------------------------------------------------- % val: print a value in a table %------------------------------------------------------------------------------- function s = val (format, value) if (~ischar (value) && value < 0) s = '-' ; else s = sprintf (format, value) ; end