40 #ifndef GMM_INOUTPUT_H
41 #define GMM_INOUTPUT_H
75 inline void IOHBTerminate(
const char *a) { GMM_ASSERT1(
false, a);}
77 inline bool is_complex_double__(std::complex<double>) {
return true; }
78 inline bool is_complex_double__(
double) {
return false; }
80 inline int ParseIfmt(
const char *fmt,
int* perline,
int* width) {
81 if (SECURE_NONCHAR_SSCANF(fmt,
" (%dI%d)", perline, width) != 2) {
83 int s = SECURE_NONCHAR_SSCANF(fmt,
" (I%d)", width);
84 GMM_ASSERT1(s == 1,
"invalid HB I-format: " << fmt);
89 inline int ParseRfmt(
const char *fmt,
int* perline,
int* width,
90 int* prec,
int* flag) {
92 *perline = *width = *flag = *prec = 0;
94 if (sscanf_s(fmt,
" (%d%c%d.%d)", perline, &p,
sizeof(
char), width, prec)
95 < 3 || !strchr(
"PEDF", p))
97 if (sscanf(fmt,
" (%d%c%d.%d)", perline, &p, width, prec) < 3
98 || !strchr(
"PEDF", p))
102 #ifdef GMM_SECURE_CRT
103 int s = sscanf_s(fmt,
" (%c%d.%d)", &p,
sizeof(
char), width, prec);
105 int s = sscanf(fmt,
" (%c%d.%d)", &p, width, prec);
107 GMM_ASSERT1(s>=2 && strchr(
"PEDF",p),
"invalid HB REAL format: " << fmt);
115 int nrows()
const {
return Nrow; }
116 int ncols()
const {
return Ncol; }
117 int nnz()
const {
return Nnzero; }
118 int is_complex()
const {
return Type[0] ==
'C'; }
119 int is_symmetric()
const {
return Type[1] ==
'S'; }
120 int is_hermitian()
const {
return Type[1] ==
'H'; }
125 void open(
const char *filename);
127 template <
typename T,
typename IND_TYPE,
int shift>
void read(csc_matrix<T, IND_TYPE, shift>& A);
128 template <
typename MAT>
void read(MAT &M) IS_DEPRECATED;
129 template <
typename T,
typename IND_TYPE,
int shift>
130 static void write(
const char *filename,
const csc_matrix<T, IND_TYPE, shift>& A);
131 template <
typename T,
typename IND_TYPE,
int shift>
132 static void write(
const char *filename,
const csc_matrix<T, IND_TYPE, shift>& A,
133 const std::vector<T> &rhs);
134 template <
typename T,
typename INDI,
typename INDJ,
int shift>
135 static void write(
const char *filename,
136 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A);
137 template <
typename T,
typename INDI,
typename INDJ,
int shift>
138 static void write(
const char *filename,
139 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A,
140 const std::vector<T> &rhs);
143 template <
typename MAT>
static void write(
const char *filename,
144 const MAT& A) IS_DEPRECATED;
147 char Title[73], Key[9], Rhstype[4], Type[4];
148 int Nrow, Ncol, Nnzero, Nrhs;
149 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
150 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
154 void close() {
if (f) fclose(f); clear(); }
156 Nrow = Ncol = Nnzero = Nrhs = 0; f = 0; lcount = 0;
157 memset(Type, 0,
sizeof Type);
158 memset(Key, 0,
sizeof Key);
159 memset(Title, 0,
sizeof Title);
161 char *getline(
char *buf) {
162 char *p = fgets(buf, BUFSIZ, f); ++lcount;
163 int s = SECURE_NONCHAR_SSCANF(buf,
"%*s");
164 GMM_ASSERT1(s >= 0 && p != 0,
165 "blank line in HB file at line " << lcount);
169 int substrtoi(
const char *p, size_type len) {
170 char s[100]; len = std::min(len,
sizeof s - 1);
171 SECURE_STRNCPY(s, 100, p, len); s[len] = 0;
return atoi(s);
173 double substrtod(
const char *p, size_type len,
int Valflag) {
174 char s[100]; len = std::min(len,
sizeof s - 1);
175 SECURE_STRNCPY(s, 100, p, len); s[len] = 0;
176 if ( Valflag !=
'F' && !strchr(s,
'E')) {
178 int last = int(strlen(s));
179 for (
int j=last+1;j>=0;j--) {
181 if ( s[j] ==
'+' || s[j] ==
'-' ) {
182 s[j-1] = char(Valflag);
189 template <
typename IND_TYPE>
190 int readHB_data(IND_TYPE colptr[], IND_TYPE rowind[],
210 int i,ind,col,offset,count;
211 int Ptrperline, Ptrwidth, Indperline, Indwidth;
212 int Valperline, Valwidth, Valprec, Nentries;
215 gmm::standard_locale sl;
219 ParseIfmt(Ptrfmt,&Ptrperline,&Ptrwidth);
220 ParseIfmt(Indfmt,&Indperline,&Indwidth);
221 if ( Type[0] !=
'P' ) {
222 ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag);
229 for (count = 0, i=0;i<Ptrcrd;i++) {
231 for (col = 0, ind = 0;ind<Ptrperline;ind++) {
232 if (count > Ncol)
break;
233 colptr[count] = substrtoi(line+col,Ptrwidth)-offset;
234 count++; col += Ptrwidth;
239 for (count = 0, i=0;i<Indcrd;i++) {
241 for (col = 0, ind = 0;ind<Indperline;ind++) {
242 if (count == Nnzero)
break;
243 rowind[count] = substrtoi(line+col,Indwidth)-offset;
244 count++; col += Indwidth;
249 if ( Type[0] !=
'P' ) {
250 if ( Type[0] ==
'C' ) Nentries = 2*Nnzero;
251 else Nentries = Nnzero;
254 for (i=0;i<Valcrd;i++) {
256 if (Valflag ==
'D') {
259 while( (p =
const_cast<char *
>(strchr(line,
'D')) )) *p =
'E';
261 for (col = 0, ind = 0;ind<Valperline;ind++) {
262 if (count == Nentries)
break;
263 val[count] = substrtod(line+col, Valwidth, Valflag);
264 count++; col += Valwidth;
273 int Totcrd,Neltvl,Nrhsix;
276 SECURE_FOPEN(&f, filename,
"r");
277 GMM_ASSERT1(f,
"could not open " << filename);
279 #ifdef GMM_SECURE_CRT
280 sscanf_s(getline(line),
"%c%s", Title, 72, Key, 8);
282 sscanf(getline(line),
"%72c%8s", Title, Key);
284 Key[8] = Title[72] = 0;
286 Totcrd = Ptrcrd = Indcrd = Valcrd = Rhscrd = 0;
287 SECURE_NONCHAR_SSCANF(getline(line),
"%d%d%d%d%d", &Totcrd, &Ptrcrd,
288 &Indcrd, &Valcrd, &Rhscrd);
291 Nrow = Ncol = Nnzero = Neltvl = 0;
292 #ifdef GMM_SECURE_CRT
293 if (sscanf_s(getline(line),
"%c%d%d%d%d", Type, 3, &Nrow, &Ncol, &Nnzero,
296 if (sscanf(getline(line),
"%3c%d%d%d%d", Type, &Nrow, &Ncol, &Nnzero,
299 IOHBTerminate(
"Invalid Type info, line 3 of Harwell-Boeing file.\n");
300 for (size_type i = 0; i < 3; ++i) Type[i] =
char(toupper(Type[i]));
303 #ifdef GMM_SECURE_CRT
304 if ( sscanf_s(getline(line),
"%c%c%c%c",Ptrfmt, 16,Indfmt, 16,Valfmt,
307 if ( sscanf(getline(line),
"%16c%16c%20c%20c",Ptrfmt,Indfmt,Valfmt,
310 IOHBTerminate(
"Invalid format info, line 4 of Harwell-Boeing file.\n");
311 Ptrfmt[16] = Indfmt[16] = Valfmt[20] = Rhsfmt[20] = 0;
316 #ifdef GMM_SECURE_CRT
317 if ( sscanf_s(getline(line),
"%c%d%d", Rhstype, 3, &Nrhs, &Nrhsix) != 1)
319 if ( sscanf(getline(line),
"%3c%d%d", Rhstype, &Nrhs, &Nrhsix) != 1)
321 IOHBTerminate(
"Invalid RHS type information, line 5 of"
322 " Harwell-Boeing file.\n");
327 template <
typename T,
typename IND_TYPE,
int shift>
void
332 GMM_ASSERT1(f,
"no file opened!");
333 GMM_ASSERT1(Type[0] !=
'P',
334 "Bad HB matrix format (pattern matrices not supported)");
335 GMM_ASSERT1(!is_complex_double__(T()) || Type[0] !=
'R',
336 "Bad HB matrix format (file contains a REAL matrix)");
337 GMM_ASSERT1(is_complex_double__(T()) || Type[0] !=
'C',
338 "Bad HB matrix format (file contains a COMPLEX matrix)");
339 A.nc = ncols(); A.nr = nrows();
340 A.jc.resize(ncols()+1);
343 readHB_data(&A.jc[0], &A.ir[0], (
double*)&A.pr[0]);
344 for (
int i = 0; i <= ncols(); ++i) { A.jc[i] += shift; A.jc[i] -= 1; }
345 for (
int i = 0; i < nnz(); ++i) { A.ir[i] += shift; A.ir[i] -= 1; }
348 template <
typename MAT>
void
350 csc_matrix<typename gmm::linalg_traits<MAT>::value_type> csc;
352 resize(M, mat_nrows(csc), mat_ncols(csc));
356 template <
typename IND_TYPE>
357 inline int writeHB_mat_double(
const char* filename,
int M,
int N,
int nz,
358 const IND_TYPE colptr[],
359 const IND_TYPE rowind[],
360 const double val[],
int Nrhs,
361 const double rhs[],
const double guess[],
362 const double exact[],
const char* Title,
363 const char* Key,
const char* Type,
364 const char* Ptrfmt,
const char* Indfmt,
365 const char* Valfmt,
const char* Rhsfmt,
366 const char* Rhstype,
int shift) {
377 int i, entry, offset, j, acount, linemod;
378 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
379 int nvalentries, nrhsentries;
380 int Ptrperline, Ptrwidth, Indperline, Indwidth;
381 int Rhsperline, Rhswidth, Rhsprec, Rhsflag;
382 int Valperline, Valwidth, Valprec;
384 char pformat[16],iformat[16],vformat[19],rformat[19];
386 gmm::standard_locale sl;
388 if ( Type[0] ==
'C' )
389 { nvalentries = 2*nz; nrhsentries = 2*M; }
391 { nvalentries = nz; nrhsentries = M; }
393 if ( filename != NULL ) {
394 SECURE_FOPEN(&out_file, filename,
"w");
395 GMM_ASSERT1(out_file != NULL,
"Error: Cannot open file: " << filename);
396 }
else out_file = stdout;
398 if ( Ptrfmt == NULL ) Ptrfmt =
"(8I10)";
399 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
400 SECURE_SPRINTF1(pformat,
sizeof(pformat),
"%%%dd",Ptrwidth);
401 ptrcrd = (N+1)/Ptrperline;
402 if ( (N+1)%Ptrperline != 0) ptrcrd++;
404 if ( Indfmt == NULL ) Indfmt = Ptrfmt;
405 ParseIfmt(Indfmt, &Indperline, &Indwidth);
406 SECURE_SPRINTF1(iformat,
sizeof(iformat),
"%%%dd",Indwidth);
407 indcrd = nz/Indperline;
408 if ( nz%Indperline != 0) indcrd++;
410 if ( Type[0] !=
'P' ) {
411 if ( Valfmt == NULL ) Valfmt =
"(4E21.13)";
412 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
418 SECURE_SPRINTF2(vformat,
sizeof(vformat),
"%% %d.%df", Valwidth,
421 SECURE_SPRINTF2(vformat,
sizeof(vformat),
"%% %d.%dE", Valwidth,
423 valcrd = nvalentries/Valperline;
424 if ( nvalentries%Valperline != 0) valcrd++;
428 if ( Rhsfmt == NULL ) Rhsfmt = Valfmt;
429 ParseRfmt(Rhsfmt,&Rhsperline,&Rhswidth,&Rhsprec, &Rhsflag);
431 SECURE_SPRINTF2(rformat,
sizeof(rformat),
"%% %d.%df",Rhswidth,Rhsprec);
433 SECURE_SPRINTF2(rformat,
sizeof(rformat),
"%% %d.%dE",Rhswidth,Rhsprec);
438 rhscrd = nrhsentries/Rhsperline;
439 if ( nrhsentries%Rhsperline != 0) rhscrd++;
440 if ( Rhstype[1] ==
'G' ) rhscrd+=rhscrd;
441 if ( Rhstype[2] ==
'X' ) rhscrd+=rhscrd;
445 totcrd = 4+ptrcrd+indcrd+valcrd+rhscrd;
450 fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n",Title, Key, totcrd,
451 ptrcrd, indcrd, valcrd, rhscrd);
452 fprintf(out_file,
"%3s%11s%14d%14d%14d%14d\n",Type,
" ", M, N, nz, 0);
453 fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
457 fprintf(out_file,
"%-20s\n%-14s%d\n",Rhsfmt,Rhstype,Nrhs);
460 fprintf(out_file,
"\n");
466 for (i = 0; i < N+1; i++) {
467 entry = colptr[i]+offset;
468 fprintf(out_file,pformat,entry);
469 if ( (i+1)%Ptrperline == 0 ) fprintf(out_file,
"\n");
472 if ( (N+1) % Ptrperline != 0 ) fprintf(out_file,
"\n");
476 entry = rowind[i]+offset;
477 fprintf(out_file,iformat,entry);
478 if ( (i+1)%Indperline == 0 ) fprintf(out_file,
"\n");
481 if ( nz % Indperline != 0 ) fprintf(out_file,
"\n");
485 if ( Type[0] !=
'P' ) {
486 for (i=0;i<nvalentries;i++) {
487 fprintf(out_file,vformat,val[i]);
488 if ( (i+1)%Valperline == 0 ) fprintf(out_file,
"\n");
491 if ( nvalentries % Valperline != 0 ) fprintf(out_file,
"\n");
497 for (j=0;j<Nrhs;j++) {
498 for (i=0;i<nrhsentries;i++) {
499 fprintf(out_file,rformat,rhs[i] );
500 if ( acount++%Rhsperline == linemod ) fprintf(out_file,
"\n");
502 if ( acount%Rhsperline != linemod ) {
503 fprintf(out_file,
"\n");
504 linemod = (acount-1)%Rhsperline;
506 if ( Rhstype[1] ==
'G' ) {
507 for (i=0;i<nrhsentries;i++) {
508 fprintf(out_file,rformat,guess[i] );
509 if ( acount++%Rhsperline == linemod ) fprintf(out_file,
"\n");
511 if ( acount%Rhsperline != linemod ) {
512 fprintf(out_file,
"\n");
513 linemod = (acount-1)%Rhsperline;
516 if ( Rhstype[2] ==
'X' ) {
517 for (i=0;i<nrhsentries;i++) {
518 fprintf(out_file,rformat,exact[i] );
519 if ( acount++%Rhsperline == linemod ) fprintf(out_file,
"\n");
521 if ( acount%Rhsperline != linemod ) {
522 fprintf(out_file,
"\n");
523 linemod = (acount-1)%Rhsperline;
529 int s = fclose(out_file);
530 GMM_ASSERT1(s == 0,
"Error closing file in writeHB_mat_double().");
534 template <
typename T,
typename IND_TYPE,
int shift>
void
535 HarwellBoeing_IO::write(
const char *filename,
536 const csc_matrix<T, IND_TYPE, shift>& A) {
537 write(filename, csc_matrix_ref<
const T*,
const unsigned*,
538 const unsigned *, shift>
539 (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc));
542 template <
typename T,
typename IND_TYPE,
int shift>
void
543 HarwellBoeing_IO::write(
const char *filename,
544 const csc_matrix<T, IND_TYPE, shift>& A,
545 const std::vector<T> &rhs) {
546 write(filename, csc_matrix_ref<
const T*,
const unsigned*,
547 const unsigned *, shift>
548 (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc), rhs);
551 template <
typename T,
typename INDI,
typename INDJ,
int shift>
void
552 HarwellBoeing_IO::write(
const char *filename,
553 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A) {
555 if (is_complex_double__(T()))
556 if (mat_nrows(A) == mat_ncols(A)) t =
"CUA";
else t =
"CRA";
558 if (mat_nrows(A) == mat_ncols(A)) t =
"RUA";
else t =
"RRA";
559 writeHB_mat_double(filename,
int(mat_nrows(A)),
int(mat_ncols(A)),
560 A.jc[mat_ncols(A)], A.jc, A.ir,
561 (
const double *)A.pr,
562 0, 0, 0, 0,
"GETFEM++ CSC MATRIX",
"CSCMAT",
563 t, 0, 0, 0, 0,
"F", shift);
566 template <
typename T,
typename INDI,
typename INDJ,
int shift>
void
567 HarwellBoeing_IO::write(
const char *filename,
568 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A,
569 const std::vector<T> &rhs) {
571 if (is_complex_double__(T()))
572 if (mat_nrows(A) == mat_ncols(A)) t =
"CUA";
else t =
"CRA";
574 if (mat_nrows(A) == mat_ncols(A)) t =
"RUA";
else t =
"RRA";
575 int Nrhs = gmm::vect_size(rhs) / mat_nrows(A);
576 writeHB_mat_double(filename,
int(mat_nrows(A)),
int(mat_ncols(A)),
577 A.jc[mat_ncols(A)], A.jc, A.ir,
578 (
const double *)A.pr,
579 Nrhs, (
const double *)(&rhs[0]), 0, 0,
580 "GETFEM++ CSC MATRIX",
"CSCMAT",
581 t, 0, 0, 0, 0,
"F ", shift);
585 template <
typename MAT>
void
586 HarwellBoeing_IO::write(
const char *filename,
const MAT& A) {
587 gmm::csc_matrix<typename gmm::linalg_traits<MAT>::value_type>
588 tmp(gmm::mat_nrows(A), gmm::mat_ncols(A));
590 HarwellBoeing_IO::write(filename, tmp);
596 template <
typename T,
typename IND_TYPE,
int shift>
inline void
598 const csc_matrix<T, IND_TYPE, shift>& A)
599 { HarwellBoeing_IO::write(filename.c_str(), A); }
604 template <
typename T,
typename INDI,
typename INDJ,
int shift>
inline void
606 const csc_matrix_ref<T, INDI, INDJ, shift>& A)
607 { HarwellBoeing_IO::write(filename.c_str(), A); }
612 template <
typename MAT>
inline void
614 gmm::csc_matrix<typename gmm::linalg_traits<MAT>::value_type>
615 tmp(gmm::mat_nrows(A), gmm::mat_ncols(A));
617 HarwellBoeing_IO::write(filename.c_str(), tmp);
620 template <
typename MAT,
typename VECT>
inline void
621 Harwell_Boeing_save(
const std::string &filename,
const MAT& A,
623 typedef typename gmm::linalg_traits<MAT>::value_type T;
624 gmm::csc_matrix<T> tmp(gmm::mat_nrows(A), gmm::mat_ncols(A));
626 std::vector<T> tmprhs(gmm::vect_size(RHS));
627 gmm::copy(RHS, tmprhs);
628 HarwellBoeing_IO::write(filename.c_str(), tmp, tmprhs);
634 template <
typename T,
typename IND_TYPE,
int shift>
void
642 template <
typename MAT>
void
644 csc_matrix<typename gmm::linalg_traits<MAT>::value_type> csc;
646 resize(A, mat_nrows(csc), mat_ncols(csc));
664 #define MM_MAX_LINE_LENGTH 1025
665 #define MatrixMarketBanner "%%MatrixMarket"
666 #define MM_MAX_TOKEN_LENGTH 64
668 typedef char MM_typecode[4];
672 #define mm_is_matrix(typecode) ((typecode)[0]=='M')
674 #define mm_is_sparse(typecode) ((typecode)[1]=='C')
675 #define mm_is_coordinate(typecode) ((typecode)[1]=='C')
676 #define mm_is_dense(typecode) ((typecode)[1]=='A')
677 #define mm_is_array(typecode) ((typecode)[1]=='A')
679 #define mm_is_complex(typecode) ((typecode)[2]=='C')
680 #define mm_is_real(typecode) ((typecode)[2]=='R')
681 #define mm_is_pattern(typecode) ((typecode)[2]=='P')
682 #define mm_is_integer(typecode) ((typecode)[2]=='I')
684 #define mm_is_symmetric(typecode) ((typecode)[3]=='S')
685 #define mm_is_general(typecode) ((typecode)[3]=='G')
686 #define mm_is_skew(typecode) ((typecode)[3]=='K')
687 #define mm_is_hermitian(typecode) ((typecode)[3]=='H')
691 #define mm_set_matrix(typecode) ((*typecode)[0]='M')
692 #define mm_set_coordinate(typecode) ((*typecode)[1]='C')
693 #define mm_set_array(typecode) ((*typecode)[1]='A')
694 #define mm_set_dense(typecode) mm_set_array(typecode)
695 #define mm_set_sparse(typecode) mm_set_coordinate(typecode)
697 #define mm_set_complex(typecode) ((*typecode)[2]='C')
698 #define mm_set_real(typecode) ((*typecode)[2]='R')
699 #define mm_set_pattern(typecode) ((*typecode)[2]='P')
700 #define mm_set_integer(typecode) ((*typecode)[2]='I')
703 #define mm_set_symmetric(typecode) ((*typecode)[3]='S')
704 #define mm_set_general(typecode) ((*typecode)[3]='G')
705 #define mm_set_skew(typecode) ((*typecode)[3]='K')
706 #define mm_set_hermitian(typecode) ((*typecode)[3]='H')
708 #define mm_clear_typecode(typecode) ((*typecode)[0]=(*typecode)[1]= \
709 (*typecode)[2]=' ',(*typecode)[3]='G')
711 #define mm_initialize_typecode(typecode) mm_clear_typecode(typecode)
717 #define MM_COULD_NOT_READ_FILE 11
718 #define MM_PREMATURE_EOF 12
719 #define MM_NOT_MTX 13
720 #define MM_NO_HEADER 14
721 #define MM_UNSUPPORTED_TYPE 15
722 #define MM_LINE_TOO_LONG 16
723 #define MM_COULD_NOT_WRITE_FILE 17
742 #define MM_MTX_STR "matrix"
743 #define MM_ARRAY_STR "array"
744 #define MM_DENSE_STR "array"
745 #define MM_COORDINATE_STR "coordinate"
746 #define MM_SPARSE_STR "coordinate"
747 #define MM_COMPLEX_STR "complex"
748 #define MM_REAL_STR "real"
749 #define MM_INT_STR "integer"
750 #define MM_GENERAL_STR "general"
751 #define MM_SYMM_STR "symmetric"
752 #define MM_HERM_STR "hermitian"
753 #define MM_SKEW_STR "skew-symmetric"
754 #define MM_PATTERN_STR "pattern"
756 inline char *mm_typecode_to_str(MM_typecode matcode) {
757 char buffer[MM_MAX_LINE_LENGTH];
758 const char *types[4] = {0,0,0,0};
763 if (mm_is_matrix(matcode))
764 types[0] = MM_MTX_STR;
770 if (mm_is_sparse(matcode))
771 types[1] = MM_SPARSE_STR;
773 if (mm_is_dense(matcode))
774 types[1] = MM_DENSE_STR;
779 if (mm_is_real(matcode))
780 types[2] = MM_REAL_STR;
782 if (mm_is_complex(matcode))
783 types[2] = MM_COMPLEX_STR;
785 if (mm_is_pattern(matcode))
786 types[2] = MM_PATTERN_STR;
788 if (mm_is_integer(matcode))
789 types[2] = MM_INT_STR;
795 if (mm_is_general(matcode))
796 types[3] = MM_GENERAL_STR;
797 else if (mm_is_symmetric(matcode))
798 types[3] = MM_SYMM_STR;
799 else if (mm_is_hermitian(matcode))
800 types[3] = MM_HERM_STR;
801 else if (mm_is_skew(matcode))
802 types[3] = MM_SKEW_STR;
806 SECURE_SPRINTF4(buffer,
sizeof(buffer),
"%s %s %s %s", types[0], types[1],
808 return SECURE_STRDUP(buffer);
812 inline int mm_read_banner(FILE *f, MM_typecode *matcode) {
813 char line[MM_MAX_LINE_LENGTH];
814 char banner[MM_MAX_TOKEN_LENGTH];
815 char mtx[MM_MAX_TOKEN_LENGTH];
816 char crd[MM_MAX_TOKEN_LENGTH];
817 char data_type[MM_MAX_TOKEN_LENGTH];
818 char storage_scheme[MM_MAX_TOKEN_LENGTH];
820 gmm::standard_locale sl;
823 mm_clear_typecode(matcode);
825 if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
826 return MM_PREMATURE_EOF;
828 #ifdef GMM_SECURE_CRT
829 if (sscanf_s(line,
"%s %s %s %s %s", banner,
sizeof(banner),
830 mtx,
sizeof(mtx), crd,
sizeof(crd), data_type,
831 sizeof(data_type), storage_scheme,
832 sizeof(storage_scheme)) != 5)
834 if (sscanf(line,
"%s %s %s %s %s", banner, mtx, crd,
835 data_type, storage_scheme) != 5)
837 return MM_PREMATURE_EOF;
839 for (p=mtx; *p!=
'\0'; *p=char(tolower(*p)),p++) {};
840 for (p=crd; *p!=
'\0'; *p=char(tolower(*p)),p++) {};
841 for (p=data_type; *p!=
'\0'; *p=char(tolower(*p)),p++) {};
842 for (p=storage_scheme; *p!=
'\0'; *p=char(tolower(*p)),p++) {};
845 if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
849 if (strcmp(mtx, MM_MTX_STR) != 0)
850 return MM_UNSUPPORTED_TYPE;
851 mm_set_matrix(matcode);
858 if (strcmp(crd, MM_SPARSE_STR) == 0)
859 mm_set_sparse(matcode);
861 if (strcmp(crd, MM_DENSE_STR) == 0)
862 mm_set_dense(matcode);
864 return MM_UNSUPPORTED_TYPE;
869 if (strcmp(data_type, MM_REAL_STR) == 0)
870 mm_set_real(matcode);
872 if (strcmp(data_type, MM_COMPLEX_STR) == 0)
873 mm_set_complex(matcode);
875 if (strcmp(data_type, MM_PATTERN_STR) == 0)
876 mm_set_pattern(matcode);
878 if (strcmp(data_type, MM_INT_STR) == 0)
879 mm_set_integer(matcode);
881 return MM_UNSUPPORTED_TYPE;
886 if (strcmp(storage_scheme, MM_GENERAL_STR) == 0)
887 mm_set_general(matcode);
889 if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
890 mm_set_symmetric(matcode);
892 if (strcmp(storage_scheme, MM_HERM_STR) == 0)
893 mm_set_hermitian(matcode);
895 if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
896 mm_set_skew(matcode);
898 return MM_UNSUPPORTED_TYPE;
903 inline int mm_read_mtx_crd_size(FILE *f,
int *M,
int *N,
int *nz ) {
904 char line[MM_MAX_LINE_LENGTH];
913 if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL)
914 return MM_PREMATURE_EOF;
915 }
while (line[0] ==
'%');
918 if (SECURE_NONCHAR_SSCANF(line,
"%d %d %d", M, N, nz) == 3)
return 0;
921 num_items_read = SECURE_NONCHAR_FSCANF(f,
"%d %d %d", M, N, nz);
922 if (num_items_read == EOF)
return MM_PREMATURE_EOF;
924 while (num_items_read != 3);
930 inline int mm_read_mtx_crd_data(FILE *f,
int,
int,
int nz,
int II[],
931 int J[],
double val[], MM_typecode matcode) {
933 if (mm_is_complex(matcode)) {
935 if (SECURE_NONCHAR_FSCANF(f,
"%d %d %lg %lg", &II[i], &J[i],
936 &val[2*i], &val[2*i+1])
937 != 4)
return MM_PREMATURE_EOF;
939 else if (mm_is_real(matcode)) {
940 for (i=0; i<nz; i++) {
941 if (SECURE_NONCHAR_FSCANF(f,
"%d %d %lg\n", &II[i], &J[i], &val[i])
942 != 3)
return MM_PREMATURE_EOF;
946 else if (mm_is_pattern(matcode)) {
948 if (SECURE_NONCHAR_FSCANF(f,
"%d %d", &II[i], &J[i])
949 != 2)
return MM_PREMATURE_EOF;
951 else return MM_UNSUPPORTED_TYPE;
956 inline int mm_write_mtx_crd(
const char *fname,
int M,
int N,
int nz,
957 int II[],
int J[],
const double val[],
958 MM_typecode matcode) {
962 if (strcmp(fname,
"stdout") == 0)
965 SECURE_FOPEN(&f, fname,
"w");
967 return MM_COULD_NOT_WRITE_FILE;
971 fprintf(f,
"%s ", MatrixMarketBanner);
972 char *str = mm_typecode_to_str(matcode);
973 fprintf(f,
"%s\n", str);
977 fprintf(f,
"%d %d %d\n", M, N, nz);
980 if (mm_is_pattern(matcode))
982 fprintf(f,
"%d %d\n", II[i], J[i]);
984 if (mm_is_real(matcode))
986 fprintf(f,
"%d %d %20.16g\n", II[i], J[i], val[i]);
988 if (mm_is_complex(matcode))
990 fprintf(f,
"%d %d %20.16g %20.16g\n", II[i], J[i], val[2*i],
993 if (f != stdout) fclose(f);
994 return MM_UNSUPPORTED_TYPE;
997 if (f !=stdout) fclose(f);
1005 bool isComplex, isSymmetric, isHermitian;
1007 MM_typecode matcode;
1013 int nrows()
const {
return row; }
1014 int ncols()
const {
return col; }
1015 int nnz()
const {
return nz; }
1016 int is_complex()
const {
return isComplex; }
1017 int is_symmetric()
const {
return isSymmetric; }
1018 int is_hermitian()
const {
return isHermitian; }
1021 void open(
const char *filename);
1023 template <
typename Matrix>
void read(Matrix &A);
1025 template <
typename T,
typename IND_TYPE,
int shift>
static void
1026 write(
const char *filename,
const csc_matrix<T, IND_TYPE, shift>& A);
1027 template <
typename T,
typename INDI,
typename INDJ,
int shift>
static void
1028 write(
const char *filename,
1029 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A);
1030 template <
typename MAT>
static void
1031 write(
const char *filename,
const MAT& A);
1035 template <
typename Matrix>
inline void
1041 template <
typename T,
typename IND_TYPE,
int shift>
void
1046 template <
typename T,
typename INDI,
typename INDJ,
int shift>
inline void
1047 MatrixMarket_save(
const char *filename,
1048 const csc_matrix_ref<T, INDI, INDJ, shift>& A) {
1049 MatrixMarket_IO mm; mm.write(filename, A);
1053 inline void MatrixMarket_IO::open(
const char *filename) {
1054 gmm::standard_locale sl;
1055 if (f) { fclose(f); }
1056 SECURE_FOPEN(&f, filename,
"r");
1057 GMM_ASSERT1(f,
"Sorry, cannot open file " << filename);
1058 int s1 = mm_read_banner(f, &matcode);
1059 GMM_ASSERT1(s1 == 0,
"Sorry, cannnot find the matrix market banner in "
1061 int s2 = mm_is_coordinate(matcode), s3 = mm_is_matrix(matcode);
1062 GMM_ASSERT1(s2 > 0 && s3 > 0,
1063 "file is not coordinate storage or is not a matrix");
1064 int s4 = mm_is_pattern(matcode);
1065 GMM_ASSERT1(s4 == 0,
1066 "the file does only contain the pattern of a sparse matrix");
1067 int s5 = mm_is_skew(matcode);
1068 GMM_ASSERT1(s5 == 0,
"not currently supporting skew symmetric");
1069 isSymmetric = mm_is_symmetric(matcode) || mm_is_hermitian(matcode);
1070 isHermitian = mm_is_hermitian(matcode);
1071 isComplex = mm_is_complex(matcode);
1072 mm_read_mtx_crd_size(f, &row, &col, &nz);
1075 template <
typename Matrix>
void MatrixMarket_IO::read(Matrix &A) {
1076 gmm::standard_locale sl;
1077 typedef typename linalg_traits<Matrix>::value_type T;
1078 GMM_ASSERT1(f,
"no file opened!");
1079 GMM_ASSERT1(!is_complex_double__(T()) || isComplex,
1080 "Bad MM matrix format (complex matrix expected)");
1081 GMM_ASSERT1(is_complex_double__(T()) || !isComplex,
1082 "Bad MM matrix format (real matrix expected)");
1083 A = Matrix(row, col);
1086 std::vector<int> II(nz), J(nz);
1087 std::vector<typename Matrix::value_type> PR(nz);
1088 mm_read_mtx_crd_data(f, row, col, nz, &II[0], &J[0],
1089 (
double*)&PR[0], matcode);
1092 A(II[i]-1, J[i]-1) = PR[i];
1095 if (mm_is_hermitian(matcode) && (II[i] != J[i]) ) {
1096 A(J[i]-1, II[i]-1) = gmm::conj(PR[i]);
1099 if (mm_is_symmetric(matcode) && (II[i] != J[i]) ) {
1100 A(J[i]-1, II[i]-1) = PR[i];
1103 if (mm_is_skew(matcode) && (II[i] != J[i]) ) {
1104 A(J[i]-1, II[i]-1) = -PR[i];
1109 template <
typename T,
typename IND_TYPE,
int shift>
void
1110 MatrixMarket_IO::write(
const char *filename,
const csc_matrix<T, IND_TYPE, shift>& A) {
1111 write(filename, csc_matrix_ref<
const T*,
const unsigned*,
1112 const unsigned*,shift>
1113 (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc));
1116 template <
typename T,
typename INDI,
typename INDJ,
int shift>
void
1117 MatrixMarket_IO::write(
const char *filename,
1118 const csc_matrix_ref<T*, INDI*, INDJ*, shift>& A) {
1119 gmm::standard_locale sl;
1120 static MM_typecode t1 = {
'M',
'C',
'R',
'G'};
1121 static MM_typecode t2 = {
'M',
'C',
'C',
'G'};
1124 if (is_complex_double__(T())) std::copy(&(t2[0]), &(t2[0])+4, &(t[0]));
1125 else std::copy(&(t1[0]), &(t1[0])+4, &(t[0]));
1127 std::vector<int> II(nz), J(nz);
1128 for (
size_type j=0; j < mat_ncols(A); ++j) {
1129 for (
size_type i = A.jc[j]; i < A.jc[j+1]; ++i) {
1130 II[i] = A.ir[i] + 1 - shift;
1134 mm_write_mtx_crd(filename,
int(mat_nrows(A)),
int(mat_ncols(A)),
1135 int(nz), &II[0], &J[0], (
const double *)A.pr, t);
1139 template <
typename MAT>
void
1140 MatrixMarket_IO::write(
const char *filename,
const MAT& A) {
1141 gmm::csc_matrix<typename gmm::linalg_traits<MAT>::value_type>
1142 tmp(gmm::mat_nrows(A), gmm::mat_ncols(A));
1144 MatrixMarket_IO::write(filename, tmp);
1147 template<
typename VEC>
static void vecsave(std::string fname,
const VEC& V,
1148 bool binary=
false, std::string Vformat=
"") {
1150 std::ofstream f(fname.c_str(), std::ofstream::binary);
1151 for (
size_type i=0; i < gmm::vect_size(V); ++i)
1152 f.write(
reinterpret_cast<const char*
>(&V[i]),
sizeof(V[i]));
1155 if (Vformat.empty()){
1156 std::ofstream f(fname.c_str()); f.imbue(std::locale(
"C"));
1158 for (
size_type i=0; i < gmm::vect_size(V); ++i) f << V[i] <<
"\n";
1161 FILE* f = fopen(fname.c_str(),
"w");
1162 for (
size_type i=0; i < gmm::vect_size(V); ++i) fprintf(f, Vformat.c_str(), V[i]);
1168 template<
typename VEC>
static void vecload(std::string fname,
const VEC& V_,
1169 bool binary=
false) {
1170 VEC &V(
const_cast<VEC&
>(V_));
1172 std::ifstream f(fname.c_str(), std::ifstream::binary);
1173 for (
size_type i=0; i < gmm::vect_size(V); ++i)
1174 f.read(
reinterpret_cast<char*
>(&V[i]),
sizeof(V[i]));
1177 std::ifstream f(fname.c_str()); f.imbue(std::locale(
"C"));
1178 for (
size_type i=0; i < gmm::vect_size(V); ++i) f >> V[i];
1184 #endif // GMM_INOUTPUT_H