mmread.m 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. function [A,rows,cols,entries,rep,field,symm] = mmread(filename)
  2. %
  3. % function [A] = mmread(filename)
  4. %
  5. % function [A,rows,cols,entries,rep,field,symm] = mmread(filename)
  6. %
  7. % Reads the contents of the Matrix Market file 'filename'
  8. % into the matrix 'A'. 'A' will be either sparse or full,
  9. % depending on the Matrix Market format indicated by
  10. % 'coordinate' (coordinate sparse storage), or
  11. % 'array' (dense array storage). The data will be duplicated
  12. % as appropriate if symmetry is indicated in the header.
  13. %
  14. % Optionally, size information about the matrix can be
  15. % obtained by using the return values rows, cols, and
  16. % entries, where entries is the number of nonzero entries
  17. % in the final matrix. Type information can also be retrieved
  18. % using the optional return values rep (representation), field,
  19. % and symm (symmetry).
  20. %
  21. mmfile = fopen(filename,'r');
  22. if ( mmfile == -1 )
  23. disp(filename);
  24. error('File not found');
  25. end;
  26. header = fgets(mmfile);
  27. if (header == -1 )
  28. error('Empty file.')
  29. end
  30. % NOTE: If using a version of Matlab for which strtok is not
  31. % defined, substitute 'gettok' for 'strtok' in the
  32. % following lines, and download gettok.m from the
  33. % Matrix Market site.
  34. [head0,header] = strtok(header); % see note above
  35. [head1,header] = strtok(header);
  36. [rep,header] = strtok(header);
  37. [field,header] = strtok(header);
  38. [symm,header] = strtok(header);
  39. head1 = lower(head1);
  40. rep = lower(rep);
  41. field = lower(field);
  42. symm = lower(symm);
  43. if ( length(symm) == 0 )
  44. disp(['Not enough words in header line of file ',filename])
  45. disp('Recognized format: ')
  46. disp('%%MatrixMarket matrix representation field symmetry')
  47. error('Check header line.')
  48. end
  49. if ( ~ strcmp(head0,'%%MatrixMarket') )
  50. error('Not a valid MatrixMarket header.')
  51. end
  52. if ( ~ strcmp(head1,'matrix') )
  53. disp(['This seems to be a MatrixMarket ',head1,' file.']);
  54. disp('This function only knows how to read MatrixMarket matrix files.');
  55. disp(' ');
  56. error(' ');
  57. end
  58. % Read through comments, ignoring them
  59. commentline = fgets(mmfile);
  60. while length(commentline) > 0 & commentline(1) == '%',
  61. commentline = fgets(mmfile);
  62. end
  63. % Read size information, then branch according to
  64. % sparse or dense format
  65. if ( strcmp(rep,'coordinate')) % read matrix given in sparse
  66. % coordinate matrix format
  67. [sizeinfo,count] = sscanf(commentline,'%d%d%d');
  68. while ( count == 0 )
  69. commentline = fgets(mmfile);
  70. if (commentline == -1 )
  71. error('End-of-file reached before size information was found.')
  72. end
  73. [sizeinfo,count] = sscanf(commentline,'%d%d%d');
  74. if ( count > 0 & count ~= 3 )
  75. error('Invalid size specification line.')
  76. end
  77. end
  78. rows = sizeinfo(1);
  79. cols = sizeinfo(2);
  80. entries = sizeinfo(3);
  81. if ( strcmp(field,'real') ) % real valued entries:
  82. [T,count] = fscanf(mmfile,'%f',3);
  83. T = [T; fscanf(mmfile,'%f')];
  84. if ( size(T) ~= 3*entries )
  85. message = ...
  86. str2mat('Data file does not contain expected amount of data.',...
  87. 'Check that number of data lines matches nonzero count.');
  88. disp(message);
  89. error('Invalid data.');
  90. end
  91. T = reshape(T,3,entries)';
  92. A = sparse(T(:,1), T(:,2), T(:,3), rows , cols);
  93. elseif ( strcmp(field,'complex')) % complex valued entries:
  94. T = fscanf(mmfile,'%f',4);
  95. T = [T; fscanf(mmfile,'%f')];
  96. if ( size(T) ~= 4*entries )
  97. message = ...
  98. str2mat('Data file does not contain expected amount of data.',...
  99. 'Check that number of data lines matches nonzero count.');
  100. disp(message);
  101. error('Invalid data.');
  102. end
  103. T = reshape(T,4,entries)';
  104. A = sparse(T(:,1), T(:,2), T(:,3) + T(:,4)*sqrt(-1), rows , cols);
  105. elseif ( strcmp(field,'pattern')) % pattern matrix (no values given):
  106. T = fscanf(mmfile,'%f',2);
  107. T = [T; fscanf(mmfile,'%f')];
  108. if ( size(T) ~= 2*entries )
  109. message = ...
  110. str2mat('Data file does not contain expected amount of data.',...
  111. 'Check that number of data lines matches nonzero count.');
  112. disp(message);
  113. error('Invalid data.');
  114. end
  115. T = reshape(T,2,entries)';
  116. A = sparse(T(:,1), T(:,2), ones(entries,1) , rows , cols);
  117. end
  118. elseif ( strcmp(rep,'array') ) % read matrix given in dense
  119. % array (column major) format
  120. [sizeinfo,count] = sscanf(commentline,'%d%d');
  121. while ( count == 0 )
  122. commentline = fgets(mmfile);
  123. if (commentline == -1 )
  124. error('End-of-file reached before size information was found.')
  125. end
  126. [sizeinfo,count] = sscanf(commentline,'%d%d');
  127. if ( count > 0 & count ~= 2 )
  128. error('Invalid size specification line.')
  129. end
  130. end
  131. rows = sizeinfo(1);
  132. cols = sizeinfo(2);
  133. entries = rows*cols;
  134. if ( strcmp(field,'real') ) % real valued entries:
  135. A = fscanf(mmfile,'%f',1);
  136. A = [A; fscanf(mmfile,'%f')];
  137. if ( strcmp(symm,'symmetric') | strcmp(symm,'hermitian') | strcmp(symm,'skew-symmetric') )
  138. for j=1:cols-1,
  139. currenti = j*rows;
  140. A = [A(1:currenti); zeros(j,1);A(currenti+1:length(A))];
  141. end
  142. elseif ( ~ strcmp(symm,'general') )
  143. disp('Unrecognized symmetry')
  144. disp(symm)
  145. disp('Recognized choices:')
  146. disp(' symmetric')
  147. disp(' hermitian')
  148. disp(' skew-symmetric')
  149. disp(' general')
  150. error('Check symmetry specification in header.');
  151. end
  152. A = reshape(A,rows,cols);
  153. elseif ( strcmp(field,'complex')) % complx valued entries:
  154. tmpr = fscanf(mmfile,'%f',1);
  155. tmpi = fscanf(mmfile,'%f',1);
  156. A = tmpr+tmpi*i;
  157. for j=1:entries-1
  158. tmpr = fscanf(mmfile,'%f',1);
  159. tmpi = fscanf(mmfile,'%f',1);
  160. A = [A; tmpr + tmpi*i];
  161. end
  162. if ( strcmp(symm,'symmetric') | strcmp(symm,'hermitian') | strcmp(symm,'skew-symmetric') )
  163. for j=1:cols-1,
  164. currenti = j*rows;
  165. A = [A(1:currenti); zeros(j,1);A(currenti+1:length(A))];
  166. end
  167. elseif ( ~ strcmp(symm,'general') )
  168. disp('Unrecognized symmetry')
  169. disp(symm)
  170. disp('Recognized choices:')
  171. disp(' symmetric')
  172. disp(' hermitian')
  173. disp(' skew-symmetric')
  174. disp(' general')
  175. error('Check symmetry specification in header.');
  176. end
  177. A = reshape(A,rows,cols);
  178. elseif ( strcmp(field,'pattern')) % pattern (makes no sense for dense)
  179. disp('Matrix type:',field)
  180. error('Pattern matrix type invalid for array storage format.');
  181. else % Unknown matrix type
  182. disp('Matrix type:',field)
  183. error('Invalid matrix type specification. Check header against MM documentation.');
  184. end
  185. end
  186. %
  187. % If symmetric, skew-symmetric or Hermitian, duplicate lower
  188. % triangular part and modify entries as appropriate:
  189. %
  190. if ( strcmp(symm,'symmetric') )
  191. A = A + A.' - diag(diag(A));
  192. entries = nnz(A);
  193. elseif ( strcmp(symm,'hermitian') )
  194. A = A + A' - diag(diag(A));
  195. entries = nnz(A);
  196. elseif ( strcmp(symm,'skew-symmetric') )
  197. A = A - A';
  198. entries = nnz(A);
  199. end
  200. fclose(mmfile);
  201. % Done.