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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 757 - (show annotations)
Mon Jun 26 13:12:56 2006 UTC (13 years, 2 months ago) by woo409
File MIME type: text/plain
File size: 13255 byte(s)
+ Merge of intelc_win32 branch (revision 741:755) with trunk. Tested on iVEC altix (run_tests and py_tests all pass)

1 /* $Id$ */
2
3 /*
4 ********************************************************************************
5 * Copyright 2006 by ACcESS MNRF *
6 * *
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 * 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 #include "mmio.h"
23
24 #include <string.h>
25 #include <malloc.h>
26 #include <ctype.h>
27
28
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