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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 633 - (hide annotations)
Thu Mar 23 05:37:00 2006 UTC (13 years, 6 months ago) by dhawcroft
File MIME type: text/plain
File size: 13273 byte(s)


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26