Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
mmio.c
Go to the documentation of this file.
1 /*
2 * Matrix Market I/O library for ANSI C
3 *
4 * See http://math.nist.gov/MatrixMarket for details.
5 * midified by ejim
6 *
7 */
8 
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <malloc.h>
13 #include <ctype.h>
14 
15 #include "mmio.h"
16 
18 {
19  if (!mm_is_matrix(matcode)) return 0;
20  if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
21  if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
22  if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
23  mm_is_skew(matcode))) return 0;
24  return 1;
25 }
26 
27 int mm_read_banner(FILE *f, MM_typecode *matcode)
28 {
29  char line[MM_MAX_LINE_LENGTH];
30  char banner[MM_MAX_TOKEN_LENGTH];
31  char mtx[MM_MAX_TOKEN_LENGTH];
32  char crd[MM_MAX_TOKEN_LENGTH];
33  char data_type[MM_MAX_TOKEN_LENGTH];
34  char storage_scheme[MM_MAX_TOKEN_LENGTH];
35  char *p;
36 
37 
38  mm_clear_typecode(matcode);
39 
40  if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
41  return MM_PREMATURE_EOF;
42 
43  if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
44  storage_scheme) != 5)
45  return MM_PREMATURE_EOF;
46 
47  for (p=mtx; *p!='\0'; *p=tolower(*p),p++); /* convert to lower case */
48  for (p=crd; *p!='\0'; *p=tolower(*p),p++);
49  for (p=data_type; *p!='\0'; *p=tolower(*p),p++);
50  for (p=storage_scheme; *p!='\0'; *p=tolower(*p),p++);
51 
52  /* check for banner */
53  if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
54  return MM_NO_HEADER;
55 
56  /* first field should be "mtx" */
57  if (strcmp(mtx, MM_MTX_STR) != 0)
58  return MM_UNSUPPORTED_TYPE;
59  mm_set_matrix(matcode);
60 
61 
62  /* second field describes whether this is a sparse matrix (in coordinate
63  storgae) or a dense array */
64 
65 
66  if (strcmp(crd, MM_SPARSEROW_STR) == 0)
67  mm_set_sparserow(matcode);
68  else
69  if (strcmp(crd, MM_COORDINATE_STR) == 0)
70  mm_set_coordinate(matcode);
71  else
72  if (strcmp(crd, MM_DENSE_STR) == 0)
73  mm_set_dense(matcode);
74  else
75  return MM_UNSUPPORTED_TYPE;
76 
77 
78  /* third field */
79 
80  if (strcmp(data_type, MM_REAL_STR) == 0)
81  mm_set_real(matcode);
82  else
83  if (strcmp(data_type, MM_COMPLEX_STR) == 0)
84  mm_set_complex(matcode);
85  else
86  if (strcmp(data_type, MM_PATTERN_STR) == 0)
87  mm_set_pattern(matcode);
88  else
89  if (strcmp(data_type, MM_INT_STR) == 0)
90  mm_set_integer(matcode);
91  else
92  return MM_UNSUPPORTED_TYPE;
93 
94 
95  /* fourth field */
96 
97  if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
98  mm_set_general(matcode);
99  else
100  if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
101  mm_set_symmetric(matcode);
102  else
103  if (strcmp(storage_scheme, MM_HERM_STR) == 0)
104  mm_set_hermitian(matcode);
105  else
106  if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
107  mm_set_skew(matcode);
108  else
109  return MM_UNSUPPORTED_TYPE;
110 
111 
112  return 0;
113 }
114 
115 int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
116 {
117  if (fprintf(f, "%d %d %d\n", M, N, nz) != 3)
119  else
120  return 0;
121 }
122 
123 int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
124 {
125  char line[MM_MAX_LINE_LENGTH];
126  int num_items_read;
127 
128  /* set return null parameter values, in case we exit with errors */
129  *M = *N = *nz = 0;
130 
131  /* now continue scanning until you reach the end-of-comments */
132  do
133  {
134  if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
135  return MM_PREMATURE_EOF;
136  }while (line[0] == '%');
137 
138  /* line[] is either blank or has M,N, nz */
139  if (sscanf(line, "%d %d %d", M, N, nz) == 3)
140  return 0;
141 
142  else
143  do
144  {
145  num_items_read = fscanf(f, "%d %d %d", M, N, nz);
146  if (num_items_read == EOF) return MM_PREMATURE_EOF;
147  }
148  while (num_items_read != 3);
149 
150  return 0;
151 }
152 
153 
154 int mm_read_mtx_array_size(FILE *f, int *M, int *N)
155 {
156  char line[MM_MAX_LINE_LENGTH];
157  int num_items_read;
158  int nz;
159 
160  /* set return null parameter values, in case we exit with errors */
161  *M = *N = 0;
162 
163  /* now continue scanning until you reach the end-of-comments */
164  do
165  {
166  if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
167  return MM_PREMATURE_EOF;
168  }while (line[0] == '%');
169 
170  /* line[] is either blank or has M,N, nz */
171  if (sscanf(line, "%d %d %*d", M, N) == 2)
172  return 0;
173 
174  else /* we have a blank line */
175  do
176  {
177  num_items_read = fscanf(f, "%d %d %*d", M, N);
178  if (num_items_read == EOF) return MM_PREMATURE_EOF;
179  }
180  while (num_items_read != 2);
181 
182  return 0;
183 }
184 
185 int mm_write_mtx_array_size(FILE *f, int M, int N)
186 {
187  if (fprintf(f, "%d %d\n", M, N) != 2)
189  else
190  return 0;
191 }
192 
193 
194 
195 /*-------------------------------------------------------------------------*/
196 
197 /******************************************************************/
198 /* use when I[], J[], and val[]J, and val[] are already allocated */
199 /******************************************************************/
200 
201 int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
202  double val[], MM_typecode matcode)
203 {
204  int i;
205  if (mm_is_complex(matcode))
206  {
207  for (i=0; i<nz; i++)
208  if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
209  != 4) return MM_PREMATURE_EOF;
210  }
211  else if (mm_is_real(matcode))
212  {
213  for (i=0; i<nz; i++)
214  {
215  if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
216  != 3) return MM_PREMATURE_EOF;
217 
218  }
219  }
220 
221  else if (mm_is_pattern(matcode))
222  {
223  for (i=0; i<nz; i++)
224  if (fscanf(f, "%d %d", &I[i], &J[i])
225  != 2) return MM_PREMATURE_EOF;
226  }
227  else
228  return MM_UNSUPPORTED_TYPE;
229 
230  return 0;
231 
232 }
233 
234 int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
235  double *real, double *imag, MM_typecode matcode)
236 {
237  if (mm_is_complex(matcode))
238  {
239  if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
240  != 4) return MM_PREMATURE_EOF;
241  }
242  else if (mm_is_real(matcode))
243  {
244  if (fscanf(f, "%d %d %lg\n", I, J, real)
245  != 3) return MM_PREMATURE_EOF;
246 
247  }
248 
249  else if (mm_is_pattern(matcode))
250  {
251  if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
252  }
253  else
254  return MM_UNSUPPORTED_TYPE;
255 
256  return 0;
257 
258 }
259 
260 
261 /************************************************************************
262  mm_read_mtx_crd() fills M, N, nz, array of values, and return
263  type code, e.g. 'MCRS'
264 
265  if matrix is complex, values[] is of size 2*nz,
266  (nz pairs of real/imaginary values)
267 ************************************************************************/
268 
269 int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
270  double **val, MM_typecode *matcode)
271 {
272  int ret_code;
273  FILE *f;
274 
275  if (strcmp(fname, "stdin") == 0) f=stdin;
276  else
277  if ((f = fopen(fname, "r")) == NULL)
278  return MM_COULD_NOT_READ_FILE;
279 
280 
281  if ((ret_code = mm_read_banner(f, matcode)) != 0)
282  return ret_code;
283 
284  if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
285  mm_is_matrix(*matcode)))
286  return MM_UNSUPPORTED_TYPE;
287 
288  if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
289  return ret_code;
290 
291 
292  *I = (int *) malloc(*nz * sizeof(int));
293  *J = (int *) malloc(*nz * sizeof(int));
294  *val = NULL;
295 
296  if (mm_is_complex(*matcode))
297  {
298  *val = (double *) malloc(*nz * 2 * sizeof(double));
299  ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
300  *matcode);
301  if (ret_code != 0) return ret_code;
302  }
303  else if (mm_is_real(*matcode))
304  {
305  *val = (double *) malloc(*nz * sizeof(double));
306  ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
307  *matcode);
308  if (ret_code != 0) return ret_code;
309  }
310 
311  else if (mm_is_pattern(*matcode))
312  {
313  ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
314  *matcode);
315  if (ret_code != 0) return ret_code;
316  }
317 
318  if (f != stdin) fclose(f);
319  return 0;
320 }
321 
322 int mm_write_banner(FILE *f, MM_typecode matcode)
323 {
324  char *str = mm_typecode_to_str(matcode);
325  int ret_code;
326 
327  ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
328  free(str);
329  if (ret_code !=2 )
331  else
332  return 0;
333 }
334 
335 int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
336  double val[], MM_typecode matcode)
337 {
338  FILE *f;
339  int i;
340 
341  if (strcmp(fname, "stdout") == 0)
342  f = stdout;
343  else
344  if ((f = fopen(fname, "w")) == NULL)
346 
347  /* print banner followed by typecode */
348  fprintf(f, "%s ", MatrixMarketBanner);
349  fprintf(f, "%s\n", mm_typecode_to_str(matcode));
350 
351  /* print matrix sizes and nonzeros */
352  fprintf(f, "%d %d %d\n", M, N, nz);
353 
354  /* print values */
355  if (mm_is_pattern(matcode))
356  for (i=0; i<nz; i++)
357  fprintf(f, "%d %d\n", I[i], J[i]);
358  else
359  if (mm_is_real(matcode))
360  for (i=0; i<nz; i++)
361  fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
362  else
363  if (mm_is_complex(matcode))
364  for (i=0; i<nz; i++)
365  fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
366  val[2*i+1]);
367  else
368  {
369  if (f != stdout) fclose(f);
370  return MM_UNSUPPORTED_TYPE;
371  }
372 
373  if (f !=stdout) fclose(f);
374 
375  return 0;
376 }
377 
378 
380 {
382  char *types[4];
383  int error =0;
384 
385  /* check for MTX type */
386  if (mm_is_matrix(matcode))
387  types[0] = MM_MTX_STR;
388  else
389  error=1;
390 
391  /* check for CRD or ARR matrix */
392  if (mm_is_sparserow(matcode))
393  types[1] = MM_SPARSEROW_STR;
394  else
395  if (mm_is_coordinate(matcode))
396  types[1] = MM_COORDINATE_STR;
397  else
398  if (mm_is_dense(matcode))
399  types[1] = MM_DENSE_STR;
400  else
401  return NULL;
402 
403  /* check for element data type */
404  if (mm_is_real(matcode))
405  types[2] = MM_REAL_STR;
406  else
407  if (mm_is_complex(matcode))
408  types[2] = MM_COMPLEX_STR;
409  else
410  if (mm_is_pattern(matcode))
411  types[2] = MM_PATTERN_STR;
412  else
413  if (mm_is_integer(matcode))
414  types[2] = MM_INT_STR;
415  else
416  return NULL;
417 
418 
419  /* check for symmetry type */
420  if (mm_is_general(matcode))
421  types[3] = MM_GENERAL_STR;
422  else
423  if (mm_is_symmetric(matcode))
424  types[3] = MM_SYMM_STR;
425  else
426  if (mm_is_hermitian(matcode))
427  types[3] = MM_HERM_STR;
428  else
429  if (mm_is_skew(matcode))
430  types[3] = MM_SKEW_STR;
431  else
432  return NULL;
433 
434  sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
435  return strdup(buffer);
436 
437 }
#define MM_PATTERN_STR
Definition: mmio.h:121
int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
Definition: matrix_io.c:176
#define mm_is_pattern(typecode)
Definition: mmio.h:45
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode)
Definition: matrix_io.c:396
#define MM_MAX_LINE_LENGTH
Definition: mmio.h:16
#define MM_SYMM_STR
Definition: mmio.h:118
#define mm_clear_typecode(typecode)
Definition: mmio.h:75
#define mm_set_real(typecode)
Definition: mmio.h:65
#define mm_set_pattern(typecode)
Definition: mmio.h:66
#define MM_GENERAL_STR
Definition: mmio.h:117
#define mm_set_coordinate(typecode)
Definition: mmio.h:59
#define MM_UNSUPPORTED_TYPE
Definition: mmio.h:88
#define mm_set_sparserow(typecode)
Definition: mmio.h:60
#define mm_set_complex(typecode)
Definition: mmio.h:64
int mm_write_banner(FILE *f, MM_typecode matcode)
Definition: matrix_io.c:383
#define MM_PREMATURE_EOF
Definition: mmio.h:85
#define mm_set_matrix(typecode)
Definition: mmio.h:58
int mm_read_mtx_array_size(FILE *f, int *M, int *N)
Definition: matrix_io.c:215
#define mm_set_dense(typecode)
Definition: mmio.h:62
#define mm_is_dense(typecode)
Definition: mmio.h:40
#define mm_is_sparserow(typecode)
Definition: mmio.h:38
#define MM_COORDINATE_STR
Definition: mmio.h:112
#define mm_is_skew(typecode)
Definition: mmio.h:50
#define MatrixMarketBanner
Definition: mmio.h:17
MPI_Datatype * types
Definition: refMPIluBack.c:109
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode)
Definition: matrix_io.c:262
int mm_read_mtx_crd_entry(FILE *f, int *I, int *J, double *real, double *imag, MM_typecode matcode)
Definition: matrix_io.c:295
#define mm_set_hermitian(typecode)
Definition: mmio.h:73
#define MM_DENSE_STR
Definition: mmio.h:111
#define MM_MAX_TOKEN_LENGTH
Definition: mmio.h:18
#define MM_INT_STR
Definition: mmio.h:116
int mm_write_mtx_array_size(FILE *f, int M, int N)
Definition: matrix_io.c:246
#define mm_set_skew(typecode)
Definition: mmio.h:72
#define mm_set_general(typecode)
Definition: mmio.h:71
char * mm_typecode_to_str(MM_typecode matcode)
Definition: matrix_io.c:440
#define mm_is_general(typecode)
Definition: mmio.h:49
#define mm_is_real(typecode)
Definition: mmio.h:44
int mm_read_banner(FILE *f, MM_typecode *matcode)
Definition: matrix_io.c:88
#define mm_is_coordinate(typecode)
Definition: mmio.h:39
#define mm_is_sparse(typecode)
Definition: mmio.h:37
#define mm_is_hermitian(typecode)
Definition: mmio.h:51
#define MM_MTX_STR
Definition: mmio.h:109
#define MM_COULD_NOT_READ_FILE
Definition: mmio.h:84
#define MM_COMPLEX_STR
Definition: mmio.h:114
int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J, double **val, MM_typecode *matcode)
Definition: matrix_io.c:330
#define MM_SKEW_STR
Definition: mmio.h:120
#define mm_is_integer(typecode)
Definition: mmio.h:46
#define MM_REAL_STR
Definition: mmio.h:115
#define MM_HERM_STR
Definition: mmio.h:119
char MM_typecode[4]
Definition: mmio.h:20
#define MM_NO_HEADER
Definition: mmio.h:87
#define mm_is_matrix(typecode)
Definition: mmio.h:35
int mm_is_valid(MM_typecode matcode)
Definition: matrix_io.c:78
#define MM_SPARSEROW_STR
Definition: mmio.h:113
#define mm_set_symmetric(typecode)
Definition: mmio.h:70
#define MM_COULD_NOT_WRITE_FILE
Definition: mmio.h:90
#define mm_is_complex(typecode)
Definition: mmio.h:43
#define mm_is_symmetric(typecode)
Definition: mmio.h:48
double ** buffer
Definition: refMPIluBack.c:103
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz)
Definition: matrix_io.c:184
#define mm_set_integer(typecode)
Definition: mmio.h:67