/[escript]/trunk/tools/mmio/src/mmio.c
ViewVC logotype

Contents of /trunk/tools/mmio/src/mmio.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 82 - (show annotations)
Tue Oct 26 06:53:54 2004 UTC (18 years, 5 months ago) by jgs
Original Path: trunk/esys2/tools/mmio/src/mmio.c
File MIME type: text/plain
File size: 12628 byte(s)
Initial revision

1 /* $Id$ */
2
3 /*
4 * Matrix Market I/O library for ANSI C
5 *
6 * See http://math.nist.gov/MatrixMarket for details.
7 *
8 * (Version 1.01, 5/2003)
9 */
10
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <malloc.h>
15 #include <ctype.h>
16
17 #include "mmio.h"
18
19 int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_,
20 double **val_, int **I_, int **J_)
21 {
22 FILE *f;
23 MM_typecode matcode;
24 int M, N, nz;
25 int i;
26 double *val;
27 int *I, *J;
28
29 if ((f = fopen(fname, "r")) == NULL)
30 return -1;
31
32
33 if (mm_read_banner(f, &matcode) != 0)
34 {
35 printf("mm_read_unsymetric: Could not process Matrix Market banner ");
36 printf(" in file [%s]\n", fname);
37 return -1;
38 }
39
40
41
42 if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) &&
43 mm_is_sparse(matcode)))
44 {
45 fprintf(stderr, "Sorry, this application does not support ");
46 fprintf(stderr, "Market Market type: [%s]\n",
47 mm_typecode_to_str(matcode));
48 return -1;
49 }
50
51 /* find out size of sparse matrix: M, N, nz .... */
52
53 if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0)
54 {
55 fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n");
56 return -1;
57 }
58
59 *M_ = M;
60 *N_ = N;
61 *nz_ = nz;
62
63 /* reseve memory for matrices */
64
65 I = (int *) malloc(nz * sizeof(int));
66 J = (int *) malloc(nz * sizeof(int));
67 val = (double *) malloc(nz * sizeof(double));
68
69 *val_ = val;
70 *I_ = I;
71 *J_ = J;
72
73 /* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
74 /* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
75 /* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
76
77 for (i=0; i<nz; i++)
78 {
79 fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
80 I[i]--; /* adjust from 1-based to 0-based */
81 J[i]--;
82 }
83 fclose(f);
84
85 return 0;
86 }
87
88 int mm_is_valid(MM_typecode matcode)
89 {
90 if (!mm_is_matrix(matcode)) return 0;
91 if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
92 if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
93 if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
94 mm_is_skew(matcode))) return 0;
95 return 1;
96 }
97
98 int mm_read_banner(FILE *f, MM_typecode *matcode)
99 {
100 char line[MM_MAX_LINE_LENGTH];
101 char banner[MM_MAX_TOKEN_LENGTH];
102 char mtx[MM_MAX_TOKEN_LENGTH];
103 char crd[MM_MAX_TOKEN_LENGTH];
104 char data_type[MM_MAX_TOKEN_LENGTH];
105 char storage_scheme[MM_MAX_TOKEN_LENGTH];
106 char *p;
107
108
109 mm_clear_typecode(matcode);
110
111 if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
112 return MM_PREMATURE_EOF;
113
114 if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
115 storage_scheme) != 5)
116 return MM_PREMATURE_EOF;
117
118 /* convert to lower case */
119 for (p=mtx; *p!='\0'; *p= (char) tolower(*p),p++);
120 for (p=crd; *p!='\0'; *p= (char) tolower(*p),p++);
121 for (p=data_type; *p!='\0'; *p= (char) tolower(*p),p++);
122 for (p=storage_scheme; *p!='\0'; *p= (char) tolower(*p),p++);
123
124 /* check for banner */
125 if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
126 return MM_NO_HEADER;
127
128 /* first field should be "mtx" */
129 if (strcmp(mtx, MM_MTX_STR) != 0)
130 return MM_UNSUPPORTED_TYPE;
131 mm_set_matrix(matcode);
132
133
134 /* second field describes whether this is a sparse matrix (in coordinate
135 storgae) or a dense array */
136
137
138 if (strcmp(crd, MM_SPARSE_STR) == 0)
139 mm_set_sparse(matcode);
140 else
141 if (strcmp(crd, MM_DENSE_STR) == 0)
142 mm_set_dense(matcode);
143 else
144 return MM_UNSUPPORTED_TYPE;
145
146
147 /* third field */
148
149 if (strcmp(data_type, MM_REAL_STR) == 0)
150 mm_set_real(matcode);
151 else
152 if (strcmp(data_type, MM_COMPLEX_STR) == 0)
153 mm_set_complex(matcode);
154 else
155 if (strcmp(data_type, MM_PATTERN_STR) == 0)
156 mm_set_pattern(matcode);
157 else
158 if (strcmp(data_type, MM_INT_STR) == 0)
159 mm_set_integer(matcode);
160 else
161 return MM_UNSUPPORTED_TYPE;
162
163
164 /* fourth field */
165
166 if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
167 mm_set_general(matcode);
168 else
169 if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
170 mm_set_symmetric(matcode);
171 else
172 if (strcmp(storage_scheme, MM_HERM_STR) == 0)
173 mm_set_hermitian(matcode);
174 else
175 if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
176 mm_set_skew(matcode);
177 else
178 return MM_UNSUPPORTED_TYPE;
179
180
181 return 0;
182 }
183
184 int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
185 {
186 if (fprintf(f, "%d %d %d\n", M, N, nz) < 0)
187 return MM_COULD_NOT_WRITE_FILE;
188 else
189 return 0;
190 }
191
192 int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
193 {
194 char line[MM_MAX_LINE_LENGTH];
195 int num_items_read;
196
197 /* set return null parameter values, in case we exit with errors */
198 *M = *N = *nz = 0;
199
200 /* now continue scanning until you reach the end-of-comments */
201 do
202 {
203 if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
204 return MM_PREMATURE_EOF;
205 }while (line[0] == '%');
206
207 /* line[] is either blank or has M,N, nz */
208 if (sscanf(line, "%d %d %d", M, N, nz) == 3)
209 return 0;
210
211 else
212 do
213 {
214 num_items_read = fscanf(f, "%d %d %d", M, N, nz);
215 if (num_items_read == EOF) return MM_PREMATURE_EOF;
216 }
217 while (num_items_read != 3);
218
219 return 0;
220 }
221
222
223 int mm_read_mtx_array_size(FILE *f, int *M, int *N)
224 {
225 char line[MM_MAX_LINE_LENGTH];
226 int num_items_read;
227 /* set return null parameter values, in case we exit with errors */
228 *M = *N = 0;
229
230 /* now continue scanning until you reach the end-of-comments */
231 do
232 {
233 if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
234 return MM_PREMATURE_EOF;
235 }while (line[0] == '%');
236
237 /* line[] is either blank or has M,N, nz */
238 if (sscanf(line, "%d %d", M, N) == 2)
239 return 0;
240
241 else /* we have a blank line */
242 do
243 {
244 num_items_read = fscanf(f, "%d %d", M, N);
245 if (num_items_read == EOF) return MM_PREMATURE_EOF;
246 }
247 while (num_items_read != 2);
248
249 return 0;
250 }
251
252 int mm_write_mtx_array_size(FILE *f, int M, int N)
253 {
254 if (fprintf(f, "%d %d\n", M, N) < 0)
255 return MM_COULD_NOT_WRITE_FILE;
256 else
257 return 0;
258 }
259
260
261
262 /*-------------------------------------------------------------------------*/
263
264 /******************************************************************/
265 /* use when I[], J[], and val[]J, and val[] are already allocated */
266 /******************************************************************/
267
268 int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
269 double val[], MM_typecode matcode)
270 {
271 int i;
272 if (mm_is_complex(matcode))
273 {
274 for (i=0; i<nz; i++)
275 if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
276 != 4) return MM_PREMATURE_EOF;
277 }
278 else if (mm_is_real(matcode))
279 {
280 for (i=0; i<nz; i++)
281 {
282 if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
283 != 3) return MM_PREMATURE_EOF;
284
285 }
286 }
287
288 else if (mm_is_pattern(matcode))
289 {
290 for (i=0; i<nz; i++)
291 if (fscanf(f, "%d %d", &I[i], &J[i])
292 != 2) return MM_PREMATURE_EOF;
293 }
294 else
295 return MM_UNSUPPORTED_TYPE;
296
297 return 0;
298
299 }
300
301 int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
302 double *real, double *imag, MM_typecode matcode)
303 {
304 if (mm_is_complex(matcode))
305 {
306 if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
307 != 4) return MM_PREMATURE_EOF;
308 }
309 else if (mm_is_real(matcode))
310 {
311 if (fscanf(f, "%d %d %lg\n", I, J, real)
312 != 3) return MM_PREMATURE_EOF;
313
314 }
315
316 else if (mm_is_pattern(matcode))
317 {
318 if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
319 }
320 else
321 return MM_UNSUPPORTED_TYPE;
322
323 return 0;
324
325 }
326
327
328 /************************************************************************
329 mm_read_mtx_crd() fills M, N, nz, array of values, and return
330 type code, e.g. 'MCRS'
331
332 if matrix is complex, values[] is of size 2*nz,
333 (nz pairs of real/imaginary values)
334 ************************************************************************/
335
336 int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
337 double **val, MM_typecode *matcode)
338 {
339 int ret_code;
340 FILE *f;
341
342 if (strcmp(fname, "stdin") == 0) f=stdin;
343 else
344 if ((f = fopen(fname, "r")) == NULL)
345 return MM_COULD_NOT_READ_FILE;
346
347
348 if ((ret_code = mm_read_banner(f, matcode)) != 0)
349 return ret_code;
350
351 if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
352 mm_is_matrix(*matcode)))
353 return MM_UNSUPPORTED_TYPE;
354
355 if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
356 return ret_code;
357
358
359 *I = (int *) malloc(*nz * sizeof(int));
360 *J = (int *) malloc(*nz * sizeof(int));
361 *val = NULL;
362
363 if (mm_is_complex(*matcode))
364 {
365 *val = (double *) malloc(*nz * 2 * sizeof(double));
366 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
367 *matcode);
368 if (ret_code != 0) return ret_code;
369 }
370 else if (mm_is_real(*matcode))
371 {
372 *val = (double *) malloc(*nz * sizeof(double));
373 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
374 *matcode);
375 if (ret_code != 0) return ret_code;
376 }
377
378 else if (mm_is_pattern(*matcode))
379 {
380 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
381 *matcode);
382 if (ret_code != 0) return ret_code;
383 }
384
385 if (f != stdin) fclose(f);
386 return 0;
387 }
388
389 int mm_write_banner(FILE *f, MM_typecode matcode)
390 {
391 int ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, mm_typecode_to_str(matcode));
392 if (ret_code < 0 )
393 return MM_COULD_NOT_WRITE_FILE;
394 else
395 return 0;
396 }
397
398 int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
399 double val[], MM_typecode matcode)
400 {
401 FILE *f;
402 int i;
403
404 if (strcmp(fname, "stdout") == 0)
405 f = stdout;
406 else
407 if ((f = fopen(fname, "w")) == NULL)
408 return MM_COULD_NOT_WRITE_FILE;
409
410 /* print banner followed by typecode */
411 fprintf(f, "%s ", MatrixMarketBanner);
412 fprintf(f, "%s\n", mm_typecode_to_str(matcode));
413
414 /* print matrix sizes and nonzeros */
415 fprintf(f, "%d %d %d\n", M, N, nz);
416
417 /* print values */
418 if (mm_is_pattern(matcode))
419 for (i=0; i<nz; i++)
420 fprintf(f, "%d %d\n", I[i], J[i]);
421 else
422 if (mm_is_real(matcode))
423 for (i=0; i<nz; i++)
424 fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
425 else
426 if (mm_is_complex(matcode))
427 for (i=0; i<nz; i++)
428 fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
429 val[2*i+1]);
430 else
431 {
432 if (f != stdout) fclose(f);
433 return MM_UNSUPPORTED_TYPE;
434 }
435
436 if (f !=stdout) fclose(f);
437
438 return 0;
439 }
440
441
442 char *mm_typecode_to_str(MM_typecode matcode)
443 {
444 static char buffer[MM_MAX_LINE_LENGTH];
445 char *types[4];
446
447 /* check for MTX type */
448 if (mm_is_matrix(matcode))
449 types[0] = MM_MTX_STR;
450 else
451 return NULL;
452
453 /* check for CRD or ARR matrix */
454 if (mm_is_sparse(matcode))
455 types[1] = MM_SPARSE_STR;
456 else
457 if (mm_is_dense(matcode))
458 types[1] = MM_DENSE_STR;
459 else
460 return NULL;
461
462 /* check for element data type */
463 if (mm_is_real(matcode))
464 types[2] = MM_REAL_STR;
465 else
466 if (mm_is_complex(matcode))
467 types[2] = MM_COMPLEX_STR;
468 else
469 if (mm_is_pattern(matcode))
470 types[2] = MM_PATTERN_STR;
471 else
472 if (mm_is_integer(matcode))
473 types[2] = MM_INT_STR;
474 else
475 return NULL;
476
477
478 /* check for symmetry type */
479 if (mm_is_general(matcode))
480 types[3] = MM_GENERAL_STR;
481 else
482 if (mm_is_symmetric(matcode))
483 types[3] = MM_SYMM_STR;
484 else
485 if (mm_is_hermitian(matcode))
486 types[3] = MM_HERM_STR;
487 else
488 if (mm_is_skew(matcode))
489 types[3] = MM_SKEW_STR;
490 else
491 return NULL;
492
493 sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
494 return & buffer[0];
495
496 }
497
498 /*
499 * $Log$
500 * Revision 1.1 2004/10/26 06:53:59 jgs
501 * Initial revision
502 *
503 * Revision 1.1 2004/07/02 00:48:35 gross
504 * matrix market io function added
505 *
506 *
507 */

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26