2
* Matrix Market I/O library for ANSI C
4
* See http://math.nist.gov/MatrixMarket for details.
17
int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_,
18
double **val_, int **I_, int **J_)
27
if ((f = fopen(fname, "r")) == NULL)
31
if (mm_read_banner(f, &matcode) != 0)
33
printf("mm_read_unsymetric: Could not process Matrix Market banner ");
34
printf(" in file [%s]\n", fname);
40
if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) &&
41
mm_is_sparse(matcode)))
43
fprintf(stderr, "Sorry, this application does not support ");
44
fprintf(stderr, "Market Market type: [%s]\n",
45
mm_typecode_to_str(matcode));
49
/* find out size of sparse matrix: M, N, nz .... */
51
if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0)
53
fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n");
61
/* reseve memory for matrices */
63
I = (int *) malloc(nz * sizeof(int));
64
J = (int *) malloc(nz * sizeof(int));
65
val = (double *) malloc(nz * sizeof(double));
71
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
72
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
73
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
77
fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
78
I[i]--; /* adjust from 1-based to 0-based */
86
int mm_is_valid(MM_typecode matcode)
88
if (!mm_is_matrix(matcode)) return 0;
89
if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
90
if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
91
if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
92
mm_is_skew(matcode))) return 0;
96
int mm_read_banner(FILE *f, MM_typecode *matcode)
98
char line[MM_MAX_LINE_LENGTH];
99
char banner[MM_MAX_TOKEN_LENGTH];
100
char mtx[MM_MAX_TOKEN_LENGTH];
101
char crd[MM_MAX_TOKEN_LENGTH];
102
char data_type[MM_MAX_TOKEN_LENGTH];
103
char storage_scheme[MM_MAX_TOKEN_LENGTH];
107
mm_clear_typecode(matcode);
109
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
110
return MM_PREMATURE_EOF;
112
if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
113
storage_scheme) != 5)
114
return MM_PREMATURE_EOF;
116
for (p=mtx; *p!='\0'; *p=tolower(*p),p++); /* convert to lower case */
117
for (p=crd; *p!='\0'; *p=tolower(*p),p++);
118
for (p=data_type; *p!='\0'; *p=tolower(*p),p++);
119
for (p=storage_scheme; *p!='\0'; *p=tolower(*p),p++);
121
/* check for banner */
122
if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
125
/* first field should be "mtx" */
126
if (strcmp(mtx, MM_MTX_STR) != 0)
127
return MM_UNSUPPORTED_TYPE;
128
mm_set_matrix(matcode);
131
/* second field describes whether this is a sparse matrix (in coordinate
132
storgae) or a dense array */
135
if (strcmp(crd, MM_SPARSE_STR) == 0)
136
mm_set_sparse(matcode);
138
if (strcmp(crd, MM_DENSE_STR) == 0)
139
mm_set_dense(matcode);
141
return MM_UNSUPPORTED_TYPE;
146
if (strcmp(data_type, MM_REAL_STR) == 0)
147
mm_set_real(matcode);
149
if (strcmp(data_type, MM_COMPLEX_STR) == 0)
150
mm_set_complex(matcode);
152
if (strcmp(data_type, MM_PATTERN_STR) == 0)
153
mm_set_pattern(matcode);
155
if (strcmp(data_type, MM_INT_STR) == 0)
156
mm_set_integer(matcode);
158
return MM_UNSUPPORTED_TYPE;
163
if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
164
mm_set_general(matcode);
166
if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
167
mm_set_symmetric(matcode);
169
if (strcmp(storage_scheme, MM_HERM_STR) == 0)
170
mm_set_hermitian(matcode);
172
if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
173
mm_set_skew(matcode);
175
return MM_UNSUPPORTED_TYPE;
181
int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
183
if (fprintf(f, "%d %d %d\n", M, N, nz) != 3)
184
return MM_COULD_NOT_WRITE_FILE;
189
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
191
char line[MM_MAX_LINE_LENGTH];
194
/* set return null parameter values, in case we exit with errors */
197
/* now continue scanning until you reach the end-of-comments */
200
if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
201
return MM_PREMATURE_EOF;
202
}while (line[0] == '%');
204
/* line[] is either blank or has M,N, nz */
205
if (sscanf(line, "%d %d %d", M, N, nz) == 3)
211
num_items_read = fscanf(f, "%d %d %d", M, N, nz);
212
if (num_items_read == EOF) return MM_PREMATURE_EOF;
214
while (num_items_read != 3);
220
int mm_read_mtx_array_size(FILE *f, int *M, int *N)
222
char line[MM_MAX_LINE_LENGTH];
224
/* set return null parameter values, in case we exit with errors */
227
/* now continue scanning until you reach the end-of-comments */
230
if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
231
return MM_PREMATURE_EOF;
232
}while (line[0] == '%');
234
/* line[] is either blank or has M,N, nz */
235
if (sscanf(line, "%d %d", M, N) == 2)
238
else /* we have a blank line */
241
num_items_read = fscanf(f, "%d %d", M, N);
242
if (num_items_read == EOF) return MM_PREMATURE_EOF;
244
while (num_items_read != 2);
249
int mm_write_mtx_array_size(FILE *f, int M, int N)
251
if (fprintf(f, "%d %d\n", M, N) != 2)
252
return MM_COULD_NOT_WRITE_FILE;
259
/*-------------------------------------------------------------------------*/
261
/******************************************************************/
262
/* use when I[], J[], and val[]J, and val[] are already allocated */
263
/******************************************************************/
265
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
266
double val[], MM_typecode matcode)
269
if (mm_is_complex(matcode))
272
if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
273
!= 4) return MM_PREMATURE_EOF;
275
else if (mm_is_real(matcode))
279
if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
280
!= 3) return MM_PREMATURE_EOF;
285
else if (mm_is_pattern(matcode))
288
if (fscanf(f, "%d %d", &I[i], &J[i])
289
!= 2) return MM_PREMATURE_EOF;
292
return MM_UNSUPPORTED_TYPE;
298
int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
299
double *real, double *imag, MM_typecode matcode)
301
if (mm_is_complex(matcode))
303
if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
304
!= 4) return MM_PREMATURE_EOF;
306
else if (mm_is_real(matcode))
308
if (fscanf(f, "%d %d %lg\n", I, J, real)
309
!= 3) return MM_PREMATURE_EOF;
313
else if (mm_is_pattern(matcode))
315
if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
318
return MM_UNSUPPORTED_TYPE;
325
/************************************************************************
326
mm_read_mtx_crd() fills M, N, nz, array of values, and return
327
type code, e.g. 'MCRS'
329
if matrix is complex, values[] is of size 2*nz,
330
(nz pairs of real/imaginary values)
331
************************************************************************/
333
int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
334
double **val, MM_typecode *matcode)
339
if (strcmp(fname, "stdin") == 0) f=stdin;
341
if ((f = fopen(fname, "r")) == NULL)
342
return MM_COULD_NOT_READ_FILE;
345
if ((ret_code = mm_read_banner(f, matcode)) != 0)
348
if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
349
mm_is_matrix(*matcode)))
350
return MM_UNSUPPORTED_TYPE;
352
if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
356
*I = (int *) malloc(*nz * sizeof(int));
357
*J = (int *) malloc(*nz * sizeof(int));
360
if (mm_is_complex(*matcode))
362
*val = (double *) malloc(*nz * 2 * sizeof(double));
363
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
365
if (ret_code != 0) return ret_code;
367
else if (mm_is_real(*matcode))
369
*val = (double *) malloc(*nz * sizeof(double));
370
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
372
if (ret_code != 0) return ret_code;
375
else if (mm_is_pattern(*matcode))
377
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
379
if (ret_code != 0) return ret_code;
382
if (f != stdin) fclose(f);
386
int mm_write_banner(FILE *f, MM_typecode matcode)
388
char *str = mm_typecode_to_str(matcode);
391
ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
394
return MM_COULD_NOT_WRITE_FILE;
399
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
400
double val[], MM_typecode matcode)
405
if (strcmp(fname, "stdout") == 0)
408
if ((f = fopen(fname, "w")) == NULL)
409
return MM_COULD_NOT_WRITE_FILE;
411
/* print banner followed by typecode */
412
fprintf(f, "%s ", MatrixMarketBanner);
413
fprintf(f, "%s\n", mm_typecode_to_str(matcode));
415
/* print matrix sizes and nonzeros */
416
fprintf(f, "%d %d %d\n", M, N, nz);
419
if (mm_is_pattern(matcode))
421
fprintf(f, "%d %d\n", I[i], J[i]);
423
if (mm_is_real(matcode))
425
fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
427
if (mm_is_complex(matcode))
429
fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
433
if (f != stdout) fclose(f);
434
return MM_UNSUPPORTED_TYPE;
437
if (f !=stdout) fclose(f);
443
char *mm_typecode_to_str(MM_typecode matcode)
445
char buffer[MM_MAX_LINE_LENGTH];
449
/* check for MTX type */
450
if (mm_is_matrix(matcode))
451
types[0] = MM_MTX_STR;
455
/* check for CRD or ARR matrix */
456
if (mm_is_sparse(matcode))
457
types[1] = MM_SPARSE_STR;
459
if (mm_is_dense(matcode))
460
types[1] = MM_DENSE_STR;
464
/* check for element data type */
465
if (mm_is_real(matcode))
466
types[2] = MM_REAL_STR;
468
if (mm_is_complex(matcode))
469
types[2] = MM_COMPLEX_STR;
471
if (mm_is_pattern(matcode))
472
types[2] = MM_PATTERN_STR;
474
if (mm_is_integer(matcode))
475
types[2] = MM_INT_STR;
480
/* check for symmetry type */
481
if (mm_is_general(matcode))
482
types[3] = MM_GENERAL_STR;
484
if (mm_is_symmetric(matcode))
485
types[3] = MM_SYMM_STR;
487
if (mm_is_hermitian(matcode))
488
types[3] = MM_HERM_STR;
490
if (mm_is_skew(matcode))
491
types[3] = MM_SKEW_STR;
495
sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
496
return strdup(buffer);