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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 82 - (hide annotations)
Tue Oct 26 06:53:54 2004 UTC (14 years, 11 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 jgs 82 /* $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