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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3642 - (show annotations)
Thu Oct 27 03:41:51 2011 UTC (7 years, 5 months ago) by caltinay
File MIME type: text/plain
File size: 13193 byte(s)
Assorted spelling/comment fixes in paso.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26