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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1887 - (hide annotations)
Wed Oct 15 03:26:25 2008 UTC (11 years, 4 months ago) by ksteube
File MIME type: text/plain
File size: 13094 byte(s)
Fixed two typos that stopped the test suite from running.

Also, gcc 4.3.2 issued several warnings not seen before:
ignoring the return value of fscanf and using the wrong format
with printf.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26