21 #ifndef SELDON_FILE_MATRIX_SPARSE_IOMATRIXMARKET_CXX
24 #include "IOMatrixMarket.hxx"
74 entry = complex<T>(a, b);
90 FileStream << real(entry) <<
" " << imag(entry);
103 template<
class T
int,
class AllocInt,
class T,
class Allocator>
104 void ReadCoordinateMatrix(istream& FileStream,
110 #ifdef SELDON_CHECK_IO
112 if (!FileStream.good())
113 throw IOError(
"ReadCoordinateMatrix",
"Stream is not ready.");
116 T entry;
int row = 0, col = 0;
118 SetComplexZero(entry);
120 while (!FileStream.eof())
123 FileStream >> row >> col;
129 if (FileStream.fail())
133 #ifdef SELDON_CHECK_IO
135 throw IOError(
string(
"ReadCoordinateMatrix"),
136 string(
"Error : Row number should be greater ")
137 +
"than 0 but is equal to " +
to_str(row));
140 throw IOError(
string(
"ReadCoordinateMatrix"),
141 string(
"Error : Column number should be greater")
142 +
" than 0 but is equal to " +
to_str(col));
148 if (nb_elt > values.
GetM())
151 row_numbers.Resize(2*nb_elt);
152 col_numbers.Resize(2*nb_elt);
155 values(nb_elt-1) = entry;
156 row_numbers(nb_elt-1) = row;
157 col_numbers(nb_elt-1) = col;
163 row_numbers.Resize(nb_elt);
164 col_numbers.Resize(nb_elt);
182 template<
class Matrix1,
class T>
183 void ReadCoordinateMatrix(Matrix1& A, istream& FileStream, T& zero,
184 int index,
long nnz,
bool cplx)
193 values.Reallocate(nnz);
194 row_numbers.Reallocate(nnz);
195 col_numbers.Reallocate(nnz);
201 ReadCoordinateMatrix(FileStream, row_numbers, col_numbers, values, cplx);
203 if (row_numbers.GetM() > 0)
204 ConvertMatrix_from_Coordinates(row_numbers, col_numbers, values,
218 template<
class T
int,
class AllocInt,
class T,
class Allocator>
219 void WriteCoordinateMatrix(ostream& FileStream,
227 for (
int i = 0; i < row_numbers.GetM(); i++)
229 FileStream << row_numbers(i) <<
" " << col_numbers(i) <<
" ";
236 for (
int i = 0; i < row_numbers.GetM(); i++)
237 FileStream << row_numbers(i) <<
" " << col_numbers(i)
238 <<
" " << values(i) <<
'\n';
252 template<
class T0,
class Prop0,
class Storage0,
class Alloc0,
class T>
254 ostream& FileStream, T& zero,
255 int index,
bool cplx)
261 ConvertMatrix_to_Coordinates(A, IndRow, IndCol,
264 WriteCoordinateMatrix(FileStream, IndRow, IndCol, Value, cplx);
267 long N = IndRow.GetM()-1;
270 int m = A.GetM()-1, n = A.GetN()-1;
271 SetComplexZero(zero);
272 if ( (IndRow(N) != m+index) || (IndCol(N) != n+index))
276 FileStream << m+index <<
" " << n+index <<
" ";
302 template <
class T,
class Prop,
class Allocator>
303 void ReadHarwellBoeing(
string filename,
306 ReadHarwellBoeing(filename,
"real",
"general", A);
312 template <
class T,
class Prop,
class Allocator>
313 void ReadHarwellBoeing(
string filename,
316 ReadHarwellBoeing(filename,
"complex",
"general", A);
322 template <
class T,
class Prop,
class Allocator>
323 void ReadHarwellBoeing(
string filename,
326 ReadHarwellBoeing(filename,
"real",
"symmetric", A);
332 template <
class T,
class Prop,
class Allocator>
333 void ReadHarwellBoeing(
string filename,
336 ReadHarwellBoeing(filename,
"complex",
"symmetric", A);
342 template <
class T,
class T2,
class Storage,
class Allocator>
343 void ReadHarwellBoeing(
string filename,
const T2& val,
347 ReadHarwellBoeing(filename,
"real",
"symmetric", B);
354 template <
class T,
class T2,
class Storage,
class Allocator>
355 void ReadHarwellBoeing(
string filename,
const T2& val,
359 ReadHarwellBoeing(filename,
"real",
"general", B);
366 template <
class T,
class T2,
class Storage,
class Allocator>
367 void ReadHarwellBoeing(
string filename,
const complex<T2>& val,
371 ReadHarwellBoeing(filename,
"complex",
"symmetric", B);
378 template <
class T,
class T2,
class Storage,
class Allocator>
379 void ReadHarwellBoeing(
string filename,
const complex<T2>& val,
383 ReadHarwellBoeing(filename,
"complex",
"general", B);
390 template <
class T,
class Prop,
class Storage,
class Allocator>
391 void ReadHarwellBoeing(
string filename,
395 ReadHarwellBoeing(filename, val, A);
400 void ReadComplexValuesHarwell(
long Nnonzero,
int Nline_val,
int line_width_val,
401 int element_width_val,
402 istream& input_stream, T* A_data)
405 string::size_type pos;
407 for (
int i = 0; i < Nline_val; i++)
409 getline(input_stream, line);
411 for (
int j = 0; j < line_width_val; j++)
413 value = line.substr(k, element_width_val);
414 pos = value.find(
'D');
415 if (pos != string::npos)
418 istringstream flux(value);
419 flux >> A_data[index];
421 if (index == Nnonzero)
425 k += element_width_val;
427 if (index == Nnonzero)
434 void ReadComplexValuesHarwell(
long Nnonzero,
int Nline_val,
int line_width_val,
435 int element_width_val,
436 istream& input_stream, complex<T>* A_data)
439 string::size_type pos;
440 long index = 0, nb = 0; T a, b(0);
441 for (
int i = 0; i < Nline_val; i++)
443 getline(input_stream, line);
445 for (
int j = 0; j < line_width_val; j++)
448 value = line.substr(k, element_width_val);
449 pos = value.find(
'D');
450 if (pos != string::npos)
453 istringstream flux(value);
457 A_data[nb] = complex<T>(a, b);
462 if (index == 2*Nnonzero)
466 k += element_width_val;
468 if (index == 2*Nnonzero)
492 template <
class T,
class Prop,
class Storage,
class Allocator>
493 void ReadHarwellBoeing(
string filename,
494 string value_type,
string matrix_type,
498 string line, element;
504 ifstream input_stream(filename.c_str());
506 #ifdef SELDON_CHECK_IO
508 if (!input_stream.good())
509 throw IOError(
"ReadHarwellBoeing(string filename, "
510 "Matrix& A, string value_type, string matrix_type)",
511 "Unable to read file \"" + filename +
"\".");
518 getline(input_stream, line);
519 title = line.substr(0, 72);
520 name = line.substr(72, 8);
523 int Nline_ptr, Nline_ind, Nline_val, Nline_rhs;
524 input_stream >> i >> Nline_ptr >> Nline_ind >> Nline_val >> Nline_rhs;
529 input_stream >> type >> Nrow >> Ncol >> Nnonzero >> Nelemental;
531 #ifdef SELDON_CHECK_IO
533 if (!input_stream.good())
534 throw IOError(
"ReadHarwellBoeing(string filename, "
535 "Matrix& A, string value_type, string matrix_type)",
536 "Unable to read integers in file \""
540 if (type.size() != 3)
542 "Matrix& A, string value_type, string matrix_type)",
543 "File \"" + filename +
"\" contains a matrix of "
544 "type \"" + type +
"\", which is not a valid type. "
545 "The type must contain exactly three characters.");
547 if (type.substr(0, 1) !=
"R" && type.substr(0, 1) !=
"C"
548 && type.substr(0, 1) !=
"P")
550 "Matrix& A, string value_type, string matrix_type)",
551 "File \"" + filename +
"\" contains a matrix of "
552 "type \"" + type +
"\", which is not a valid type. "
553 "The first character of that type must be 'R', 'C' "
554 "(not supported anyway) or 'P'.");
556 if (type.substr(0, 1) ==
"R" && value_type !=
"real")
558 "Matrix& A, string value_type, string matrix_type)",
559 "File \"" + filename +
"\" contains a real-valued "
560 "matrix, while the input matrix 'A' is not "
561 "declared as such.");
563 if (type.substr(0, 1) ==
"C" && value_type !=
"complex")
565 "Matrix& A, string value_type, string matrix_type)",
566 "File \"" + filename +
"\" contains a complex-valued "
567 "matrix, while the input matrix 'A' is not "
568 "declared as such.");
570 if (type.substr(1, 1) ==
"H")
572 "Matrix& A, string value_type, string matrix_type)",
573 "File \"" + filename +
"\" contains a Hermitian "
574 "matrix, which is not supported.");
576 if (type.substr(1, 1) ==
"Z")
578 "Matrix& A, string value_type, string matrix_type)",
579 "File \"" + filename +
"\" contains a skew "
580 "symmetric matrix, which is not supported.");
582 if (type.substr(2, 1) ==
"E")
584 "Matrix& A, string value_type, string matrix_type)",
585 "File \"" + filename +
"\" contains an elemental "
586 "matrix, which is not supported.");
588 getline(input_stream, line);
591 getline(input_stream, line);
592 int line_width_ptr(0), element_width_ptr(0);
593 int line_width_ind(0), element_width_ind(0);
594 string::size_type pos1 = line.find(
'(', 0);
595 string::size_type pos2 = line.find(
'I', 0);
596 if ((pos2 < 16) && (pos1 < pos2))
597 line_width_ptr = to_num<int>(line.substr(pos1+1, pos2-pos1-1));
600 pos2 = line.find(
')', 0);
601 if ((pos2 < 16) && (pos1 < pos2))
602 element_width_ptr = to_num<int>(line.substr(pos1+1, pos2-pos1-1));
604 pos1 = line.find(
'(', 16);
605 pos2 = line.find(
'I', 16);
606 if ((pos2 < 32) && (pos1 < pos2))
607 line_width_ind = to_num<int>(line.substr(pos1+1, pos2-pos1-1));
610 pos2 = line.find(
')', 16);
611 if ((pos2 < 32) && (pos1 < pos2))
612 element_width_ind = to_num<int>(line.substr(pos1+1, pos2-pos1-1));
614 int line_width_val = 0;
615 int element_width_val = 0;
616 if (type.substr(0, 1) !=
"P")
618 element = line.substr(32, 20);
623 string delimiter =
" (ABDEFGILOPZ*.)";
626 string::size_type index_beg = element.find_first_not_of(delimiter);
627 string::size_type index_end;
628 while (index_beg != string::npos)
630 index_end = element.find_first_of(delimiter, index_beg);
631 tmp_str = element.substr(index_beg,
632 index_end == string::npos ?
633 string::npos : (index_end-index_beg));
634 istringstream(tmp_str) >> tmp_int;
635 vect.PushBack(tmp_int);
636 index_beg = element.find_first_not_of(delimiter, index_end);
640 throw WrongArgument(
"ReadHarwellBoeing(string filename, Matrix& A, "
641 "string value_type, string matrix_type)",
642 "File \"" + filename +
"\" contains values "
643 "written in format \"" + element +
"\", which "
644 "could not be parsed.");
646 line_width_val = vect(vect.GetM() - 3);
647 element_width_val = vect(vect.GetM() - 2);
650 if ((line_width_ptr == 0) || (element_width_ptr == 0) ||
651 (line_width_ind == 0) || (element_width_ind == 0) ||
652 (line_width_val == 0) || (element_width_val == 0) )
653 throw WrongArgument(
"ReadHarwellBoeing(string filename, Matrix& A, "
654 "string value_type, string matrix_type)",
655 "Failed to read formats in file"+filename);
659 getline(input_stream, line);
663 typedef typename SeldonDefaultAllocator<VectFull, int>::allocator
666 typedef typename SeldonDefaultAllocator<VectFull, long>::allocator
674 #ifdef SELDON_CHECK_MEMORY
679 A_ptr =
reinterpret_cast<long*
>(AllocatorLong::
682 #ifdef SELDON_CHECK_MEMORY
690 throw NoMemory(
"ReadHarwellBoeing(string filename, "
691 "Matrix& A, string value_type, string matrix_type)",
692 "Unable to allocate memory for an array of "
693 +
to_str(Ncol + 1) +
" integers.");
696 #ifdef SELDON_CHECK_MEMORY
703 A_ind =
reinterpret_cast<int*
>(AllocatorInt::allocate(Nnonzero));
704 A_data =
reinterpret_cast<T*
>
705 (Allocator::allocate(Nnonzero));
707 #ifdef SELDON_CHECK_MEMORY
715 if (A_ind == NULL || A_data == NULL)
716 throw NoMemory(
"ReadHarwellBoeing(string filename, "
717 "Matrix& A, string value_type, string matrix_type)",
718 "Unable to allocate memory for an array of "
719 +
to_str(Nnonzero) +
" integers "
720 "and for an array of "
721 +
to_str(
sizeof(T) * Nnonzero) +
" bytes.");
727 for (i = 0; i < Nline_ptr; i++)
729 getline(input_stream, line);
731 for (j = 0; j < line_width_ptr; j++)
733 istringstream(line.substr(k, element_width_ptr)) >> A_ptr[index];
738 if (index == Ncol + 1)
742 k += element_width_ptr;
744 if (index == Ncol + 1)
749 for (i = 0; i < Nline_ind; i++)
751 getline(input_stream, line);
753 for (j = 0; j < line_width_ind; j++)
755 istringstream(line.substr(k, element_width_ind)) >> A_ind[index];
759 if (index == Nnonzero)
763 k += element_width_ind;
765 if (index == Nnonzero)
771 if (type.substr(0, 1) ==
"P")
772 for (
long i0 = 0; i0 < Nnonzero; i0++)
777 ReadComplexValuesHarwell(Nnonzero, Nline_val, line_width_val,
778 element_width_val, input_stream, A_data);
781 #ifdef SELDON_CHECK_IO
783 if (!input_stream.good())
784 throw IOError(
"ReadHarwellBoeing(string filename, "
785 "Matrix& A, string value_type, string matrix_type)",
786 "Unable to read all values in file \""
790 input_stream.close();
792 A.SetData(Nrow, Ncol, Nnonzero, A_data, A_ptr, A_ind);
797 void PrintComplexValuesHarwell(
long nnz,
const Vector<complex<T> >& Val,
800 for (
long i = 0; i < 2*nnz; i += 3)
802 for (
long j = i; j < min(i+3, 2*nnz); j++)
805 file_out << setw(23) << std::real(Val(j/2));
807 file_out << setw(23) << std::imag(Val(j/2));
816 void PrintComplexValuesHarwell(
long nnz,
const Vector<T>& Val,
819 for (
long i = 0; i < nnz; i += 3)
821 for (
long j = i; j < min(i+3, nnz); j++)
822 file_out << setw(23) << Val(j);
830 template<
class T,
class Prop,
class Storage,
class Allocator>
832 const string& file_name)
835 typedef typename ClassComplexType<T>::Treal Treal;
836 bool complex = (
sizeof(Tcplx)/
sizeof(Treal) == 2);
843 ConvertToCSR(A, sym, Ptr, Ind, Val);
845 ConvertToCSC(A, sym, Ptr, Ind, Val);
848 long nnz = Val.GetM();
853 ofstream file_out(file_name.data());
855 #ifdef SELDON_CHECK_IO
857 if (!file_out.good())
858 throw IOError(
"WriteHarwellBoeing(const Matrix& A, string filename)",
859 "Unable to open file \"" + file_name +
"\".");
862 string title(
"Seldon");
863 string key(
"S0000008");
864 file_out.setf(ios::left);
865 file_out << setw(72) << title;
866 file_out << setw(8) << key;
870 int ptr_len = int(ceil( log10(0.1 + nnz + 1) )) + 1;
871 int ptr_nperline = min(80 / ptr_len, n+1);
872 int ptrcrd = n / ptr_nperline + 1;
873 string ptrfmt = string(
"(") +
to_str(ptr_nperline)
874 +
"I" +
to_str(ptr_len) +
")";
877 int ind_len = int(ceil( log10(0.1 + n + 1) )) + 1;
878 int ind_nperline = min(80 / ind_len,
int(nnz));
879 int indcrd = (nnz-1) / ind_nperline + 1;
880 string indfmt = string(
"(") +
to_str(ind_nperline)
881 +
'I' +
to_str(ind_len) +
')';
884 string valfmt(
"(3D23.15)");
885 int valcrd = (nnz-1) / 3 + 1;
887 valcrd = (2*nnz-1) / 3 + 1;
890 int totcrd = ptrcrd + indcrd + valcrd + rhscrd;
893 file_out << setw(14) << totcrd;
894 file_out << setw(14) << ptrcrd;
895 file_out << setw(14) << indcrd;
896 file_out << setw(14) << valcrd;
897 file_out << setw(14) << rhscrd;
921 file_out << mxtype <<
" ";
922 file_out << setw(14) << m;
923 file_out << setw(14) << n;
924 file_out << setw(14) << nnz;
925 file_out << setw(14) << neltvl;
929 file_out << setw(16) << ptrfmt;
930 file_out << setw(16) << indfmt;
931 file_out << setw(20) << valfmt;
932 file_out << setw(20) << valfmt;
936 file_out.setf(ios::left);
937 for (
int i = 0; i <= n; i += ptr_nperline)
939 for (
int j = i; j < min(i+ptr_nperline, n+1); j++)
940 file_out << setw(ptr_len) << Ptr(j)+1;
946 for (
long i = 0; i < nnz; i += ind_nperline)
948 for (
long j = i; j < min(i+ind_nperline, nnz); j++)
949 file_out << setw(ind_len) << Ind(j)+1;
955 file_out.precision(15);
956 file_out.setf(ios::scientific);
957 PrintComplexValuesHarwell(nnz, Val, file_out);
964 template <
class T,
class Prop,
class Storage,
class Allocator>
965 void ReadMatrixMarket(
string filename,
969 typedef typename ClassComplexType<T>::Treal Treal;
970 bool complex = (
sizeof(Tcplx)/
sizeof(Treal) == 2);
973 ifstream input_stream(filename.c_str());
975 #ifdef SELDON_CHECK_IO
977 if (!input_stream.good())
978 throw IOError(
"ReadMatrixMarket(string filename, Matrix& A)",
979 "Unable to read file \"" + filename +
"\".");
983 string line, word1, word2, storage_type, value_type, matrix_type;
984 getline(input_stream, line);
986 istringstream header(line);
987 header >> word1 >> word2 >> storage_type >> value_type >> matrix_type;
989 if (storage_type !=
"coordinate")
990 throw WrongArgument(
"ReadMatrixMarket(string filename, Matrix& A)",
991 "The storage should be coordinate in the file");
993 if ( complex && (value_type !=
"complex") )
994 throw WrongArgument(
"ReadMatrixMarket(string filename, Matrix& A)",
995 "The matrix should contain complex values");
997 if ( !complex && (value_type !=
"real") )
998 throw WrongArgument(
"ReadMatrixMarket(string filename, Matrix& A)",
999 "The matrix should contain real values");
1001 if ( symmetric && (matrix_type !=
"symmetric") )
1002 throw WrongArgument(
"ReadMatrixMarket(string filename, Matrix& A)",
1003 "Problem of symmetry");
1005 if ( !symmetric && (matrix_type !=
"general") )
1006 throw WrongArgument(
"ReadMatrixMarket(string filename, Matrix& A)",
1007 "Problem of symmetry");
1010 bool comment_line =
true;
1011 while (comment_line)
1013 getline(input_stream, line);
1014 if ( (line.size() > 0) && (line[0] !=
'%'))
1015 comment_line =
false;
1017 if (input_stream.eof())
1018 comment_line =
false;
1022 int m = 0, n = 0;
long nnz = 0;
1023 istringstream size_stream(line);
1024 size_stream >> m >> n >> nnz;
1029 ReadCoordinateMatrix(input_stream, row, col, val, complex);
1032 input_stream.close();
1039 ConvertMatrix_from_Coordinates(col, row, val, A, 1);
1041 ConvertMatrix_from_Coordinates(row, col, val, A, 1);
1046 template<
class T,
class Prop,
class Storage,
class Allocator>
1048 const string& file_name)
1051 typedef typename ClassComplexType<T>::Treal Treal;
1052 bool complex = (
sizeof(Tcplx)/
sizeof(Treal) == 2);
1055 ofstream file_out(file_name.data());
1056 file_out.precision(15);
1057 file_out.setf(ios::scientific);
1059 #ifdef SELDON_CHECK_IO
1061 if (!file_out.good())
1062 throw IOError(
"WriteHarwellBoeing(const Matrix& A, string filename)",
1063 "Unable to open file \"" + file_name +
"\".");
1066 file_out <<
"%%MatrixMarket matrix coordinate ";
1068 file_out <<
"complex ";
1070 file_out <<
"real ";
1073 file_out <<
"symmetric\n";
1075 file_out <<
"general\n";
1080 ConvertMatrix_to_Coordinates(A, row, col, val, 1,
false);
1082 file_out << A.GetM() <<
" " << A.GetN() <<
" " << val.GetM() <<
'\n';
1088 for (
long i = 0; i < row.GetM(); i++)
1090 if (row(i) < col(i))
1099 WriteCoordinateMatrix(file_out, row, col, val, complex);
1107 #define SELDON_FILE_MATRIX_SPARSE_IOMATRIXMARKET_CXX