SCM

SCM Repository

[matrix] Annotation of /pkg/src/mmio.c
ViewVC logotype

Annotation of /pkg/src/mmio.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 825 - (view) (download) (as text)

1 : bates 825 /*
2 :     Fri Aug 15 16:29:47 EDT 1997
3 :     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 :     Matrix Market I/O library for ANSI C
5 :     Roldan Pozo, NIST (pozo@nist.gov)
6 :    
7 :     See http://math.nist.gov/MatrixMarket for details and sample
8 :     calling programs.
9 :    
10 :     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 :     NOTICE
12 :    
13 :     Permission to use, copy, modify, and distribute this software and
14 :     its documentation for any purpose and without fee is hereby granted
15 :     provided that the above copyright notice appear in all copies and
16 :     that both the copyright notice and this permission notice appear in
17 :     supporting documentation.
18 :    
19 :     Neither the Author nor the Institution (National Institute of Standards
20 :     and Technology) make any representations about the suitability of this
21 :     software for any purpose. This software is provided "as is" without
22 :     expressed or implied warranty.
23 :     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 :     */
25 :     #include <stdio.h>
26 :     #include <string.h>
27 :     #include <malloc.h>
28 :     #include <ctype.h>
29 :    
30 :     #include "mmio.h"
31 :    
32 :     int mm_is_valid(MM_typecode matcode)
33 :     {
34 :     if (!mm_is_matrix(matcode)) return 0;
35 :     if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
36 :     if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
37 :     if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
38 :     mm_is_skew(matcode))) return 0;
39 :     return 1;
40 :     }
41 :    
42 :     int mm_read_banner(FILE *f, MM_typecode *matcode)
43 :     {
44 :     char line[MM_MAX_LINE_LENGTH];
45 :     char banner[MM_MAX_TOKEN_LENGTH];
46 :     char mtx[MM_MAX_TOKEN_LENGTH];
47 :     char crd[MM_MAX_TOKEN_LENGTH];
48 :     char data_type[MM_MAX_TOKEN_LENGTH];
49 :     char storage_scheme[MM_MAX_TOKEN_LENGTH];
50 :     char *p;
51 :    
52 :    
53 :     mm_clear_typecode(matcode);
54 :    
55 :     if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
56 :     return MM_PREMATURE_EOF;
57 :    
58 :     if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
59 :     storage_scheme) != 5)
60 :     return MM_PREMATURE_EOF;
61 :    
62 :     /* these tokens are compared to lower-case constants */
63 :     for (p=mtx; *p!='\0'; *p=tolower(*p),p++); /* convert to lower case */
64 :     for (p=crd; *p!='\0'; *p=tolower(*p),p++);
65 :     for (p=data_type; *p!='\0'; *p=tolower(*p),p++);
66 :     for (p=storage_scheme; *p!='\0'; *p=tolower(*p),p++);
67 :    
68 :     /* check for banner */
69 :     if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
70 :     return MM_NO_HEADER;
71 :    
72 :     /* first field should be "mtx" */
73 :     if (strcmp(mtx, MM_MTX_STR) != 0)
74 :     return MM_NOT_MTX;
75 :     mm_set_matrix(matcode);
76 :    
77 :    
78 :     /* second field describes whether this is a sparse matrix (in coordinate
79 :     storgae) or a dense array */
80 :    
81 :    
82 :     if (strcmp(crd, MM_SPARSE_STR) == 0)
83 :     mm_set_sparse(matcode);
84 :     else
85 :     if (strcmp(crd, MM_DENSE_STR) == 0)
86 :     mm_set_dense(matcode);
87 :     else
88 :     return MM_UNSUPPORTED_TYPE;
89 :    
90 :    
91 :     /* third field */
92 :    
93 :     if (strcmp(data_type, MM_REAL_STR) == 0)
94 :     mm_set_real(matcode);
95 :     else
96 :     if (strcmp(data_type, MM_COMPLEX_STR) == 0)
97 :     mm_set_complex(matcode);
98 :     else
99 :     if (strcmp(data_type, MM_PATTERN_STR) == 0)
100 :     mm_set_pattern(matcode);
101 :     else
102 :     if (strcmp(data_type, MM_INT_STR) == 0)
103 :     mm_set_integer(matcode);
104 :     else
105 :     return MM_UNSUPPORTED_TYPE;
106 :    
107 :    
108 :     /* fourth field */
109 :    
110 :     if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
111 :     mm_set_general(matcode);
112 :     else
113 :     if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
114 :     mm_set_symmetric(matcode);
115 :     else
116 :     if (strcmp(storage_scheme, MM_HERM_STR) == 0)
117 :     mm_set_hermitian(matcode);
118 :     else
119 :     if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
120 :     mm_set_skew(matcode);
121 :     else
122 :     return MM_UNSUPPORTED_TYPE;
123 :    
124 :    
125 :     return 0;
126 :     }
127 :    
128 :     int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
129 :     {
130 :     if (fprintf(f, "%d %d %d\n", M, N, nz) != 3)
131 :     return MM_COULD_NOT_WRITE_FILE;
132 :     else
133 :     return 0;
134 :     }
135 :    
136 :     int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
137 :     {
138 :     char line[MM_MAX_LINE_LENGTH];
139 :     int num_items_read;
140 :    
141 :     /* set return null parameter values, in case we exit with errors */
142 :     *M = *N = *nz = 0;
143 :    
144 :     /* now continue scanning until you reach the end-of-comments */
145 :     do
146 :     {
147 :     if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
148 :     return MM_PREMATURE_EOF;
149 :     }while (line[0] == '%');
150 :    
151 :     /* line[] is either blank or has M,N, nz */
152 :     if (sscanf(line, "%d %d %d", M, N, nz) == 3)
153 :     return 0;
154 :    
155 :     else
156 :     do
157 :     {
158 :     num_items_read = fscanf(f, "%d %d %d", M, N, nz);
159 :     if (num_items_read == EOF) return MM_PREMATURE_EOF;
160 :     }
161 :     while (num_items_read != 3);
162 :    
163 :     return 0;
164 :     }
165 :    
166 :    
167 :     int mm_read_mtx_array_size(FILE *f, int *M, int *N)
168 :     {
169 :     char line[MM_MAX_LINE_LENGTH];
170 :     int num_items_read;
171 :    
172 :     /* set return null parameter values, in case we exit with errors */
173 :     *M = *N = 0;
174 :    
175 :     /* now continue scanning until you reach the end-of-comments */
176 :     do
177 :     {
178 :     if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
179 :     return MM_PREMATURE_EOF;
180 :     }while (line[0] == '%');
181 :    
182 :     /* line[] is either blank or has M,N, nz */
183 :     if (sscanf(line, "%d %d", M, N) == 2)
184 :     return 0;
185 :    
186 :     else /* we have a blank line */
187 :     do
188 :     {
189 :     num_items_read = fscanf(f, "%d %d", M, N);
190 :     if (num_items_read == EOF) return MM_PREMATURE_EOF;
191 :     }
192 :     while (num_items_read != 2);
193 :    
194 :     return 0;
195 :     }
196 :    
197 :     int mm_write_mtx_array_size(FILE *f, int M, int N)
198 :     {
199 :     if (fprintf(f, "%d %d\n", M, N) != 2)
200 :     return MM_COULD_NOT_WRITE_FILE;
201 :     else
202 :     return 0;
203 :     }
204 :    
205 :    
206 :    
207 :     /*-------------------------------------------------------------------------*/
208 :    
209 :     /******************************************************************/
210 :     /* use when I[], J[], and val[]J, and val[] are already allocated */
211 :     /******************************************************************/
212 :    
213 :     int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
214 :     double val[], MM_typecode matcode)
215 :     {
216 :     int i;
217 :     if (mm_is_complex(matcode))
218 :     {
219 :     for (i=0; i<nz; i++)
220 :     if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
221 :     != 4) return MM_PREMATURE_EOF;
222 :     }
223 :     else if (mm_is_real(matcode))
224 :     {
225 :     for (i=0; i<nz; i++)
226 :     {
227 :     if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
228 :     != 3) return MM_PREMATURE_EOF;
229 :    
230 :     }
231 :     }
232 :    
233 :     else if (mm_is_pattern(matcode))
234 :     {
235 :     for (i=0; i<nz; i++)
236 :     if (fscanf(f, "%d %d", &I[i], &J[i])
237 :     != 2) return MM_PREMATURE_EOF;
238 :     }
239 :     else
240 :     return MM_UNSUPPORTED_TYPE;
241 :    
242 :     return 0;
243 :    
244 :     }
245 :    
246 :     int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
247 :     double *real, double *imag, MM_typecode matcode)
248 :     {
249 :     if (mm_is_complex(matcode))
250 :     {
251 :     if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
252 :     != 4) return MM_PREMATURE_EOF;
253 :     }
254 :     else if (mm_is_real(matcode))
255 :     {
256 :     if (fscanf(f, "%d %d %lg\n", I, J, real)
257 :     != 3) return MM_PREMATURE_EOF;
258 :    
259 :     }
260 :    
261 :     else if (mm_is_pattern(matcode))
262 :     {
263 :     if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
264 :     }
265 :     else
266 :     return MM_UNSUPPORTED_TYPE;
267 :    
268 :     return 0;
269 :    
270 :     }
271 :    
272 :    
273 :     /************************************************************************
274 :     mm_read_mtx_crd() fills M, N, nz, array of values, and return
275 :     type code, e.g. 'MCRS'
276 :    
277 :     if matrix is complex, values[] is of size 2*nz,
278 :     (nz pairs of real/imaginary values)
279 :     ************************************************************************/
280 :    
281 :     int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
282 :     double **val, MM_typecode *matcode)
283 :     {
284 :     int ret_code;
285 :     FILE *f;
286 :    
287 :     if (strcmp(fname, "stdin") == 0) f=stdin;
288 :     else
289 :     if ((f = fopen(fname, "r")) == NULL)
290 :     return MM_COULD_NOT_READ_FILE;
291 :    
292 :    
293 :     if ((ret_code = mm_read_banner(f, matcode)) != 0)
294 :     return ret_code;
295 :    
296 :     if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
297 :     mm_is_matrix(*matcode)))
298 :     return MM_UNSUPPORTED_TYPE;
299 :    
300 :     if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
301 :     return ret_code;
302 :    
303 :    
304 :     *I = (int *) malloc(*nz * sizeof(int));
305 :     *J = (int *) malloc(*nz * sizeof(int));
306 :     *val = NULL;
307 :    
308 :     if (mm_is_complex(*matcode))
309 :     {
310 :     *val = (double *) malloc(*nz * 2 * sizeof(double));
311 :     ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
312 :     *matcode);
313 :     if (ret_code != 0) return ret_code;
314 :     }
315 :     else if (mm_is_real(*matcode))
316 :     {
317 :     *val = (double *) malloc(*nz * sizeof(double));
318 :     ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
319 :     *matcode);
320 :     if (ret_code != 0) return ret_code;
321 :     }
322 :    
323 :     else if (mm_is_pattern(*matcode))
324 :     {
325 :     ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
326 :     *matcode);
327 :     if (ret_code != 0) return ret_code;
328 :     }
329 :    
330 :     if (f != stdin) fclose(f);
331 :     return 0;
332 :     }
333 :    
334 :     int mm_write_banner(FILE *f, MM_typecode matcode)
335 :     {
336 :     char *str = mm_typecode_to_str(matcode);
337 :    
338 :     fprintf(f, "%s ", MatrixMarketBanner);
339 :     fprintf(f, "%s\n", str);
340 :     free(str);
341 :     }
342 :    
343 :     int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
344 :     double val[], MM_typecode matcode)
345 :     {
346 :     FILE *f;
347 :     int i;
348 :    
349 :     if (strcmp(fname, "stdout") == 0)
350 :     f = stdout;
351 :     else
352 :     if ((f = fopen(fname, "w")) == NULL)
353 :     return MM_COULD_NOT_WRITE_FILE;
354 :    
355 :     /* print banner followed by typecode */
356 :     fprintf(f, "%s ", MatrixMarketBanner);
357 :     fprintf(f, "%s\n", mm_typecode_to_str(matcode));
358 :    
359 :     /* print matrix sizes and nonzeros */
360 :     fprintf(f, "%d %d %d\n", M, N, nz);
361 :    
362 :     /* print values */
363 :     if (mm_is_pattern(matcode))
364 :     for (i=0; i<nz; i++)
365 :     fprintf(f, "%d %d\n", I[i], J[i]);
366 :     else
367 :     if (mm_is_real(matcode))
368 :     for (i=0; i<nz; i++)
369 :     fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
370 :     else
371 :     if (mm_is_complex(matcode))
372 :     for (i=0; i<nz; i++)
373 :     fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
374 :     val[2*i+1]);
375 :     else
376 :     {
377 :     if (f != stdout) fclose(f);
378 :     return MM_UNSUPPORTED_TYPE;
379 :     }
380 :    
381 :     if (f !=stdout) fclose(f);
382 :    
383 :     return 0;
384 :     }
385 :    
386 :    
387 :     char *mm_typecode_to_str(MM_typecode matcode)
388 :     {
389 :     char buffer[MM_MAX_LINE_LENGTH];
390 :     char *types[4];
391 :     int error =0;
392 :    
393 :     /* check for MTX type */
394 :     if (mm_is_matrix(matcode))
395 :     types[0] = MM_MTX_STR;
396 :     else
397 :     error=1;
398 :    
399 :     /* check for CRD or ARR matrix */
400 :     if (mm_is_sparse(matcode))
401 :     types[1] = MM_SPARSE_STR;
402 :     else
403 :     if (mm_is_dense(matcode))
404 :     types[1] = MM_DENSE_STR;
405 :     else
406 :     return NULL;
407 :    
408 :     /* check for element data type */
409 :     if (mm_is_real(matcode))
410 :     types[2] = MM_REAL_STR;
411 :     else
412 :     if (mm_is_complex(matcode))
413 :     types[2] = MM_COMPLEX_STR;
414 :     else
415 :     if (mm_is_pattern(matcode))
416 :     types[2] = MM_PATTERN_STR;
417 :     else
418 :     if (mm_is_integer(matcode))
419 :     types[2] = MM_INT_STR;
420 :     else
421 :     return NULL;
422 :    
423 :    
424 :     /* check for symmetry type */
425 :     if (mm_is_general(matcode))
426 :     types[3] = MM_GENERAL_STR;
427 :     else
428 :     if (mm_is_symmetric(matcode))
429 :     types[3] = MM_SYMM_STR;
430 :     else
431 :     if (mm_is_hermitian(matcode))
432 :     types[3] = MM_HERM_STR;
433 :     else
434 :     if (mm_is_skew(matcode))
435 :     types[3] = MM_SKEW_STR;
436 :     else
437 :     return NULL;
438 :    
439 :     sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
440 :     return strdup(buffer);
441 :    
442 :     }

root@r-forge.r-project.org
ViewVC Help
Powered by ViewVC 1.0.0  
Thanks to:
Vienna University of Economics and Business Powered By FusionForge