00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include <ctype.h>
00014
00015 #include "mmio.h"
00016
00017 int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_,
00018 double **val_, int **I_, int **J_)
00019 {
00020 FILE *f;
00021 MM_typecode matcode;
00022 int M, N, nz;
00023 int i;
00024 double *val;
00025 int *I, *J;
00026
00027 if ((f = fopen(fname, "r")) == NULL)
00028 return -1;
00029
00030
00031 if (mm_read_banner(f, &matcode) != 0)
00032 {
00033 printf("mm_read_unsymetric: Could not process Matrix Market banner ");
00034 printf(" in file [%s]\n", fname);
00035 return -1;
00036 }
00037
00038
00039
00040 if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) &&
00041 mm_is_sparse(matcode)))
00042 {
00043 fprintf(stderr, "Sorry, this application does not support ");
00044 fprintf(stderr, "Market Market type: [%s]\n",
00045 mm_typecode_to_str(matcode));
00046 return -1;
00047 }
00048
00049
00050
00051 if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0)
00052 {
00053 fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n");
00054 return -1;
00055 }
00056
00057 *M_ = M;
00058 *N_ = N;
00059 *nz_ = nz;
00060
00061
00062
00063 I = (int *) malloc(nz * sizeof(int));
00064 J = (int *) malloc(nz * sizeof(int));
00065 val = (double *) malloc(nz * sizeof(double));
00066
00067 *val_ = val;
00068 *I_ = I;
00069 *J_ = J;
00070
00071
00072
00073
00074
00075 for (i=0; i<nz; i++)
00076 {
00077 fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
00078 I[i]--;
00079 J[i]--;
00080 }
00081 fclose(f);
00082
00083 return 0;
00084 }
00085
00086 int mm_is_valid(MM_typecode matcode)
00087 {
00088 if (!mm_is_matrix(matcode)) return 0;
00089 if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
00090 if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
00091 if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) ||
00092 mm_is_skew(matcode))) return 0;
00093 return 1;
00094 }
00095
00096 int mm_read_banner(FILE *f, MM_typecode *matcode)
00097 {
00098 char line[MM_MAX_LINE_LENGTH];
00099 char banner[MM_MAX_TOKEN_LENGTH];
00100 char mtx[MM_MAX_TOKEN_LENGTH];
00101 char crd[MM_MAX_TOKEN_LENGTH];
00102 char data_type[MM_MAX_TOKEN_LENGTH];
00103 char storage_scheme[MM_MAX_TOKEN_LENGTH];
00104 char *p;
00105
00106
00107 mm_clear_typecode(matcode);
00108
00109 if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
00110 return MM_PREMATURE_EOF;
00111
00112 if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type,
00113 storage_scheme) != 5)
00114 return MM_PREMATURE_EOF;
00115
00116 for (p=mtx; *p!='\0'; *p=tolower(*p),p++);
00117 for (p=crd; *p!='\0'; *p=tolower(*p),p++);
00118 for (p=data_type; *p!='\0'; *p=tolower(*p),p++);
00119 for (p=storage_scheme; *p!='\0'; *p=tolower(*p),p++);
00120
00121
00122 if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
00123 return MM_NO_HEADER;
00124
00125
00126 if (strcmp(mtx, MM_MTX_STR) != 0)
00127 return MM_UNSUPPORTED_TYPE;
00128 mm_set_matrix(matcode);
00129
00130
00131
00132
00133
00134
00135 if (strcmp(crd, MM_SPARSE_STR) == 0)
00136 mm_set_sparse(matcode);
00137 else
00138 if (strcmp(crd, MM_DENSE_STR) == 0)
00139 mm_set_dense(matcode);
00140 else
00141 return MM_UNSUPPORTED_TYPE;
00142
00143
00144
00145
00146 if (strcmp(data_type, MM_REAL_STR) == 0)
00147 mm_set_real(matcode);
00148 else
00149 if (strcmp(data_type, MM_COMPLEX_STR) == 0)
00150 mm_set_complex(matcode);
00151 else
00152 if (strcmp(data_type, MM_PATTERN_STR) == 0)
00153 mm_set_pattern(matcode);
00154 else
00155 if (strcmp(data_type, MM_INT_STR) == 0)
00156 mm_set_integer(matcode);
00157 else
00158 return MM_UNSUPPORTED_TYPE;
00159
00160
00161
00162
00163 if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
00164 mm_set_general(matcode);
00165 else
00166 if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
00167 mm_set_symmetric(matcode);
00168 else
00169 if (strcmp(storage_scheme, MM_HERM_STR) == 0)
00170 mm_set_hermitian(matcode);
00171 else
00172 if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
00173 mm_set_skew(matcode);
00174 else
00175 return MM_UNSUPPORTED_TYPE;
00176
00177
00178 return 0;
00179 }
00180
00181 int mm_write_mtx_crd_size(FILE *f, int M, int N, int nz)
00182 {
00183 if (fprintf(f, "%d %d %d\n", M, N, nz) != 3)
00184 return MM_COULD_NOT_WRITE_FILE;
00185 else
00186 return 0;
00187 }
00188
00189 int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz )
00190 {
00191 char line[MM_MAX_LINE_LENGTH];
00192 int num_items_read;
00193
00194
00195 *M = *N = *nz = 0;
00196
00197
00198 do
00199 {
00200 if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
00201 return MM_PREMATURE_EOF;
00202 }while (line[0] == '%');
00203
00204
00205 if (sscanf(line, "%d %d %d", M, N, nz) == 3)
00206 return 0;
00207
00208 else
00209 do
00210 {
00211 num_items_read = fscanf(f, "%d %d %d", M, N, nz);
00212 if (num_items_read == EOF) return MM_PREMATURE_EOF;
00213 }
00214 while (num_items_read != 3);
00215
00216 return 0;
00217 }
00218
00219
00220 int mm_read_mtx_array_size(FILE *f, int *M, int *N)
00221 {
00222 char line[MM_MAX_LINE_LENGTH];
00223 int num_items_read;
00224
00225 *M = *N = 0;
00226
00227
00228 do
00229 {
00230 if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
00231 return MM_PREMATURE_EOF;
00232 }while (line[0] == '%');
00233
00234
00235 if (sscanf(line, "%d %d", M, N) == 2)
00236 return 0;
00237
00238 else
00239 do
00240 {
00241 num_items_read = fscanf(f, "%d %d", M, N);
00242 if (num_items_read == EOF) return MM_PREMATURE_EOF;
00243 }
00244 while (num_items_read != 2);
00245
00246 return 0;
00247 }
00248
00249 int mm_write_mtx_array_size(FILE *f, int M, int N)
00250 {
00251 if (fprintf(f, "%d %d\n", M, N) != 2)
00252 return MM_COULD_NOT_WRITE_FILE;
00253 else
00254 return 0;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[],
00266 double val[], MM_typecode matcode)
00267 {
00268 int i;
00269 if (mm_is_complex(matcode))
00270 {
00271 for (i=0; i<nz; i++)
00272 if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1])
00273 != 4) return MM_PREMATURE_EOF;
00274 }
00275 else if (mm_is_real(matcode))
00276 {
00277 for (i=0; i<nz; i++)
00278 {
00279 if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i])
00280 != 3) return MM_PREMATURE_EOF;
00281
00282 }
00283 }
00284
00285 else if (mm_is_pattern(matcode))
00286 {
00287 for (i=0; i<nz; i++)
00288 if (fscanf(f, "%d %d", &I[i], &J[i])
00289 != 2) return MM_PREMATURE_EOF;
00290 }
00291 else
00292 return MM_UNSUPPORTED_TYPE;
00293
00294 return 0;
00295
00296 }
00297
00298 int mm_read_mtx_crd_entry(FILE *f, int *I, int *J,
00299 double *real, double *imag, MM_typecode matcode)
00300 {
00301 if (mm_is_complex(matcode))
00302 {
00303 if (fscanf(f, "%d %d %lg %lg", I, J, real, imag)
00304 != 4) return MM_PREMATURE_EOF;
00305 }
00306 else if (mm_is_real(matcode))
00307 {
00308 if (fscanf(f, "%d %d %lg\n", I, J, real)
00309 != 3) return MM_PREMATURE_EOF;
00310
00311 }
00312
00313 else if (mm_is_pattern(matcode))
00314 {
00315 if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
00316 }
00317 else
00318 return MM_UNSUPPORTED_TYPE;
00319
00320 return 0;
00321
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J,
00334 double **val, MM_typecode *matcode)
00335 {
00336 int ret_code;
00337 FILE *f;
00338
00339 if (strcmp(fname, "stdin") == 0) f=stdin;
00340 else
00341 if ((f = fopen(fname, "r")) == NULL)
00342 return MM_COULD_NOT_READ_FILE;
00343
00344
00345 if ((ret_code = mm_read_banner(f, matcode)) != 0)
00346 return ret_code;
00347
00348 if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
00349 mm_is_matrix(*matcode)))
00350 return MM_UNSUPPORTED_TYPE;
00351
00352 if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0)
00353 return ret_code;
00354
00355
00356 *I = (int *) malloc(*nz * sizeof(int));
00357 *J = (int *) malloc(*nz * sizeof(int));
00358 *val = NULL;
00359
00360 if (mm_is_complex(*matcode))
00361 {
00362 *val = (double *) malloc(*nz * 2 * sizeof(double));
00363 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
00364 *matcode);
00365 if (ret_code != 0) return ret_code;
00366 }
00367 else if (mm_is_real(*matcode))
00368 {
00369 *val = (double *) malloc(*nz * sizeof(double));
00370 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
00371 *matcode);
00372 if (ret_code != 0) return ret_code;
00373 }
00374
00375 else if (mm_is_pattern(*matcode))
00376 {
00377 ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val,
00378 *matcode);
00379 if (ret_code != 0) return ret_code;
00380 }
00381
00382 if (f != stdin) fclose(f);
00383 return 0;
00384 }
00385
00386 int mm_write_banner(FILE *f, MM_typecode matcode)
00387 {
00388 char *str = mm_typecode_to_str(matcode);
00389 int ret_code;
00390
00391 ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
00392 free(str);
00393 if (ret_code !=2 )
00394 return MM_COULD_NOT_WRITE_FILE;
00395 else
00396 return 0;
00397 }
00398
00399 int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[],
00400 double val[], MM_typecode matcode)
00401 {
00402 FILE *f;
00403 int i;
00404
00405 if (strcmp(fname, "stdout") == 0)
00406 f = stdout;
00407 else
00408 if ((f = fopen(fname, "w")) == NULL)
00409 return MM_COULD_NOT_WRITE_FILE;
00410
00411
00412 fprintf(f, "%s ", MatrixMarketBanner);
00413 fprintf(f, "%s\n", mm_typecode_to_str(matcode));
00414
00415
00416 fprintf(f, "%d %d %d\n", M, N, nz);
00417
00418
00419 if (mm_is_pattern(matcode))
00420 for (i=0; i<nz; i++)
00421 fprintf(f, "%d %d\n", I[i], J[i]);
00422 else
00423 if (mm_is_real(matcode))
00424 for (i=0; i<nz; i++)
00425 fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
00426 else
00427 if (mm_is_complex(matcode))
00428 for (i=0; i<nz; i++)
00429 fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i],
00430 val[2*i+1]);
00431 else
00432 {
00433 if (f != stdout) fclose(f);
00434 return MM_UNSUPPORTED_TYPE;
00435 }
00436
00437 if (f !=stdout) fclose(f);
00438
00439 return 0;
00440 }
00441
00442
00448 char *mm_strdup(const char *s)
00449 {
00450 int len = strlen(s);
00451 char *s2 = (char *) malloc((len+1)*sizeof(char));
00452 return strcpy(s2, s);
00453 }
00454
00455 char *mm_typecode_to_str(MM_typecode matcode)
00456 {
00457 char buffer[MM_MAX_LINE_LENGTH];
00458 char *types[4];
00459 char *mm_strdup(const char *);
00460 int error =0;
00461
00462
00463 if (mm_is_matrix(matcode))
00464 types[0] = MM_MTX_STR;
00465 else
00466 error=1;
00467
00468
00469 if (mm_is_sparse(matcode))
00470 types[1] = MM_SPARSE_STR;
00471 else
00472 if (mm_is_dense(matcode))
00473 types[1] = MM_DENSE_STR;
00474 else
00475 return NULL;
00476
00477
00478 if (mm_is_real(matcode))
00479 types[2] = MM_REAL_STR;
00480 else
00481 if (mm_is_complex(matcode))
00482 types[2] = MM_COMPLEX_STR;
00483 else
00484 if (mm_is_pattern(matcode))
00485 types[2] = MM_PATTERN_STR;
00486 else
00487 if (mm_is_integer(matcode))
00488 types[2] = MM_INT_STR;
00489 else
00490 return NULL;
00491
00492
00493
00494 if (mm_is_general(matcode))
00495 types[3] = MM_GENERAL_STR;
00496 else
00497 if (mm_is_symmetric(matcode))
00498 types[3] = MM_SYMM_STR;
00499 else
00500 if (mm_is_hermitian(matcode))
00501 types[3] = MM_HERM_STR;
00502 else
00503 if (mm_is_skew(matcode))
00504 types[3] = MM_SKEW_STR;
00505 else
00506 return NULL;
00507
00508 sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
00509 return mm_strdup(buffer);
00510
00511 }