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