123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- function [A,rows,cols,entries,rep,field,symm] = mmread(filename)
- %
- % function [A] = mmread(filename)
- %
- % function [A,rows,cols,entries,rep,field,symm] = mmread(filename)
- %
- % Reads the contents of the Matrix Market file 'filename'
- % into the matrix 'A'. 'A' will be either sparse or full,
- % depending on the Matrix Market format indicated by
- % 'coordinate' (coordinate sparse storage), or
- % 'array' (dense array storage). The data will be duplicated
- % as appropriate if symmetry is indicated in the header.
- %
- % Optionally, size information about the matrix can be
- % obtained by using the return values rows, cols, and
- % entries, where entries is the number of nonzero entries
- % in the final matrix. Type information can also be retrieved
- % using the optional return values rep (representation), field,
- % and symm (symmetry).
- %
- mmfile = fopen(filename,'r');
- if ( mmfile == -1 )
- disp(filename);
- error('File not found');
- end;
- header = fgets(mmfile);
- if (header == -1 )
- error('Empty file.')
- end
- % NOTE: If using a version of Matlab for which strtok is not
- % defined, substitute 'gettok' for 'strtok' in the
- % following lines, and download gettok.m from the
- % Matrix Market site.
- [head0,header] = strtok(header); % see note above
- [head1,header] = strtok(header);
- [rep,header] = strtok(header);
- [field,header] = strtok(header);
- [symm,header] = strtok(header);
- head1 = lower(head1);
- rep = lower(rep);
- field = lower(field);
- symm = lower(symm);
- if ( length(symm) == 0 )
- disp(['Not enough words in header line of file ',filename])
- disp('Recognized format: ')
- disp('%%MatrixMarket matrix representation field symmetry')
- error('Check header line.')
- end
- if ( ~ strcmp(head0,'%%MatrixMarket') )
- error('Not a valid MatrixMarket header.')
- end
- if ( ~ strcmp(head1,'matrix') )
- disp(['This seems to be a MatrixMarket ',head1,' file.']);
- disp('This function only knows how to read MatrixMarket matrix files.');
- disp(' ');
- error(' ');
- end
- % Read through comments, ignoring them
- commentline = fgets(mmfile);
- while length(commentline) > 0 & commentline(1) == '%',
- commentline = fgets(mmfile);
- end
- % Read size information, then branch according to
- % sparse or dense format
- if ( strcmp(rep,'coordinate')) % read matrix given in sparse
- % coordinate matrix format
- [sizeinfo,count] = sscanf(commentline,'%d%d%d');
- while ( count == 0 )
- commentline = fgets(mmfile);
- if (commentline == -1 )
- error('End-of-file reached before size information was found.')
- end
- [sizeinfo,count] = sscanf(commentline,'%d%d%d');
- if ( count > 0 & count ~= 3 )
- error('Invalid size specification line.')
- end
- end
- rows = sizeinfo(1);
- cols = sizeinfo(2);
- entries = sizeinfo(3);
-
- if ( strcmp(field,'real') ) % real valued entries:
-
- [T,count] = fscanf(mmfile,'%f',3);
- T = [T; fscanf(mmfile,'%f')];
- if ( size(T) ~= 3*entries )
- message = ...
- str2mat('Data file does not contain expected amount of data.',...
- 'Check that number of data lines matches nonzero count.');
- disp(message);
- error('Invalid data.');
- end
- T = reshape(T,3,entries)';
- A = sparse(T(:,1), T(:,2), T(:,3), rows , cols);
-
- elseif ( strcmp(field,'complex')) % complex valued entries:
-
- T = fscanf(mmfile,'%f',4);
- T = [T; fscanf(mmfile,'%f')];
- if ( size(T) ~= 4*entries )
- message = ...
- str2mat('Data file does not contain expected amount of data.',...
- 'Check that number of data lines matches nonzero count.');
- disp(message);
- error('Invalid data.');
- end
- T = reshape(T,4,entries)';
- A = sparse(T(:,1), T(:,2), T(:,3) + T(:,4)*sqrt(-1), rows , cols);
-
- elseif ( strcmp(field,'pattern')) % pattern matrix (no values given):
-
- T = fscanf(mmfile,'%f',2);
- T = [T; fscanf(mmfile,'%f')];
- if ( size(T) ~= 2*entries )
- message = ...
- str2mat('Data file does not contain expected amount of data.',...
- 'Check that number of data lines matches nonzero count.');
- disp(message);
- error('Invalid data.');
- end
- T = reshape(T,2,entries)';
- A = sparse(T(:,1), T(:,2), ones(entries,1) , rows , cols);
- end
- elseif ( strcmp(rep,'array') ) % read matrix given in dense
- % array (column major) format
- [sizeinfo,count] = sscanf(commentline,'%d%d');
- while ( count == 0 )
- commentline = fgets(mmfile);
- if (commentline == -1 )
- error('End-of-file reached before size information was found.')
- end
- [sizeinfo,count] = sscanf(commentline,'%d%d');
- if ( count > 0 & count ~= 2 )
- error('Invalid size specification line.')
- end
- end
- rows = sizeinfo(1);
- cols = sizeinfo(2);
- entries = rows*cols;
- if ( strcmp(field,'real') ) % real valued entries:
- A = fscanf(mmfile,'%f',1);
- A = [A; fscanf(mmfile,'%f')];
- if ( strcmp(symm,'symmetric') | strcmp(symm,'hermitian') | strcmp(symm,'skew-symmetric') )
- for j=1:cols-1,
- currenti = j*rows;
- A = [A(1:currenti); zeros(j,1);A(currenti+1:length(A))];
- end
- elseif ( ~ strcmp(symm,'general') )
- disp('Unrecognized symmetry')
- disp(symm)
- disp('Recognized choices:')
- disp(' symmetric')
- disp(' hermitian')
- disp(' skew-symmetric')
- disp(' general')
- error('Check symmetry specification in header.');
- end
- A = reshape(A,rows,cols);
- elseif ( strcmp(field,'complex')) % complx valued entries:
- tmpr = fscanf(mmfile,'%f',1);
- tmpi = fscanf(mmfile,'%f',1);
- A = tmpr+tmpi*i;
- for j=1:entries-1
- tmpr = fscanf(mmfile,'%f',1);
- tmpi = fscanf(mmfile,'%f',1);
- A = [A; tmpr + tmpi*i];
- end
- if ( strcmp(symm,'symmetric') | strcmp(symm,'hermitian') | strcmp(symm,'skew-symmetric') )
- for j=1:cols-1,
- currenti = j*rows;
- A = [A(1:currenti); zeros(j,1);A(currenti+1:length(A))];
- end
- elseif ( ~ strcmp(symm,'general') )
- disp('Unrecognized symmetry')
- disp(symm)
- disp('Recognized choices:')
- disp(' symmetric')
- disp(' hermitian')
- disp(' skew-symmetric')
- disp(' general')
- error('Check symmetry specification in header.');
- end
- A = reshape(A,rows,cols);
- elseif ( strcmp(field,'pattern')) % pattern (makes no sense for dense)
- disp('Matrix type:',field)
- error('Pattern matrix type invalid for array storage format.');
- else % Unknown matrix type
- disp('Matrix type:',field)
- error('Invalid matrix type specification. Check header against MM documentation.');
- end
- end
- %
- % If symmetric, skew-symmetric or Hermitian, duplicate lower
- % triangular part and modify entries as appropriate:
- %
- if ( strcmp(symm,'symmetric') )
- A = A + A.' - diag(diag(A));
- entries = nnz(A);
- elseif ( strcmp(symm,'hermitian') )
- A = A + A' - diag(diag(A));
- entries = nnz(A);
- elseif ( strcmp(symm,'skew-symmetric') )
- A = A - A';
- entries = nnz(A);
- end
- fclose(mmfile);
- % Done.
|