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];
 
matrix input/output for MatrixMarket storage
 
void copy(const L1 &l1, L2 &l2)
*/
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void Harwell_Boeing_save(const std::string &filename, const csc_matrix< T, IND_TYPE, shift > &A)
save a "double" or "std::complex<double>" csc matrix into a HarwellBoeing file
 
void MatrixMarket_save(const char *filename, const csc_matrix< T, IND_TYPE, shift > &A)
write a matrix-market file
 
void Harwell_Boeing_load(const std::string &filename, csc_matrix< T, IND_TYPE, shift > &A)
load a "double" or "std::complex<double>" csc matrix from a HarwellBoeing file
 
void MatrixMarket_load(const char *filename, Matrix &A)
load a matrix-market file
 
Include the base gmm files.
 
size_t size_type
used as the common size type in the library
 
matrix input/output for Harwell-Boeing format
 
void open(const char *filename)
open filename and reads header
 
void read(csc_matrix< T, IND_TYPE, shift > &A)
read the opened file