00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_MATRIX_SPARSE_IOMATRIXMARKET_CXX
00021
00022
00023 #include "IOMatrixMarket.hxx"
00024 #include <iomanip>
00025
00026 namespace Seldon
00027 {
00028
00029
00031
00044 template <class Prop, class Allocator>
00045 void ReadHarwellBoeing(string filename,
00046 Matrix<float, Prop, ColSparse, Allocator>& A)
00047 {
00048 ReadHarwellBoeing(filename, "real", "general", A);
00049 }
00050
00051
00053 template <class Prop, class Allocator>
00054 void ReadHarwellBoeing(string filename,
00055 Matrix<double, Prop, ColSparse, Allocator>& A)
00056 {
00057 ReadHarwellBoeing(filename, "real", "general", A);
00058 }
00059
00060
00062
00080 template <class T, class Prop, class Storage, class Allocator>
00081 void ReadHarwellBoeing(string filename,
00082 string value_type, string matrix_type,
00083 Matrix<T, Prop, Storage, Allocator> & A)
00084 {
00085 int i, j, k;
00086 string line, element;
00087
00088
00089 int Nrow, Ncol;
00090 int Nnonzero;
00091
00092 ifstream input_stream(filename.c_str());
00093
00094 #ifdef SELDON_CHECK_IO
00095
00096 if (!input_stream.good())
00097 throw IOError("ReadHarwellBoeing(string filename, "
00098 "Matrix& A, string value_type, string matrix_type)",
00099 "Unable to read file \"" + filename + "\".");
00100 #endif
00101
00102
00103
00104
00105 string title, name;
00106 getline(input_stream, line);
00107 title = line.substr(0, 72);
00108 name = line.substr(72, 8);
00109
00110
00111 int Nline_ptr, Nline_ind, Nline_val, Nline_rhs;
00112 input_stream >> i >> Nline_ptr >> Nline_ind >> Nline_val >> Nline_rhs;
00113
00114
00115 string type;
00116 int Nelemental;
00117 input_stream >> type >> Nrow >> Ncol >> Nnonzero >> Nelemental;
00118
00119 if (type.size() != 3)
00120 throw WrongArgument("ReadHarwellBoeing(string filename, "
00121 "Matrix& A, string value_type, string matrix_type)",
00122 "File \"" + filename + "\" contains a matrix of "
00123 "type \"" + type + "\", which is not a valid type. "
00124 "The type must contain exactly three characters.");
00125
00126 if (type.substr(0, 1) != "R" && type.substr(0, 1) != "C"
00127 && type.substr(0, 1) != "P")
00128 throw WrongArgument("ReadHarwellBoeing(string filename, "
00129 "Matrix& A, string value_type, string matrix_type)",
00130 "File \"" + filename + "\" contains a matrix of "
00131 "type \"" + type + "\", which is not a valid type. "
00132 "The first character of that type must be 'R', 'C' "
00133 "(not supported anyway) or 'P'.");
00134
00135 if (type.substr(0, 1) == "C")
00136 throw WrongArgument("ReadHarwellBoeing(string filename, "
00137 "Matrix& A, string value_type, string matrix_type)",
00138 "File \"" + filename + "\" contains a "
00139 "complex-valued matrix, which is not supported.");
00140
00141 if (type.substr(0, 1) == "R" && value_type != "real")
00142 throw WrongArgument("ReadHarwellBoeing(string filename, "
00143 "Matrix& A, string value_type, string matrix_type)",
00144 "File \"" + filename + "\" contains a real-valued "
00145 "matrix, while the input matrix 'A' is not "
00146 "declared as such.");
00147
00148 if (type.substr(1, 1) == "H")
00149 throw WrongArgument("ReadHarwellBoeing(string filename, "
00150 "Matrix& A, string value_type, string matrix_type)",
00151 "File \"" + filename + "\" contains a Hermitian "
00152 "matrix, which is not supported.");
00153
00154 if (type.substr(1, 1) == "Z")
00155 throw WrongArgument("ReadHarwellBoeing(string filename, "
00156 "Matrix& A, string value_type, string matrix_type)",
00157 "File \"" + filename + "\" contains a skew "
00158 "symmetric matrix, which is not supported.");
00159
00160 if (type.substr(1, 1) == "S")
00161 throw WrongArgument("ReadHarwellBoeing(string filename, "
00162 "Matrix& A, string value_type, string matrix_type)",
00163 "File \"" + filename + "\" contains a "
00164 "symmetric matrix, which is not supported.");
00165
00166 if (Nelemental != 0 || type.substr(2, 1) == "E")
00167 throw WrongArgument("ReadHarwellBoeing(string filename, "
00168 "Matrix& A, string value_type, string matrix_type)",
00169 "File \"" + filename + "\" contains an elemental "
00170 "matrix, which is not supported.");
00171
00172 getline(input_stream, line);
00173
00174
00175 getline(input_stream, line);
00176 int line_width_ptr, element_width_ptr, line_width_ind, element_width_ind;
00177 element = line.substr(0, 16);
00178 sscanf(element.c_str(), "(%dI%d)", &line_width_ptr, &element_width_ptr);
00179 element = line.substr(16, 16);
00180 sscanf(element.c_str(), "(%dI%d)", &line_width_ind, &element_width_ind);
00181 int line_width_val = 0;
00182 int element_width_val = 0;
00183 if (type.substr(0, 1) != "P")
00184 {
00185 element = line.substr(32, 16);
00186
00187
00188
00189 vector<int> vect;
00190 string delimiter = " (ABEFGILOPZ*.)";
00191 string tmp_str;
00192 int tmp_int;
00193 string::size_type index_beg = element.find_first_not_of(delimiter);
00194 string::size_type index_end;
00195 while (index_beg != string::npos)
00196 {
00197 index_end = element.find_first_of(delimiter, index_beg);
00198 tmp_str = element.substr(index_beg,
00199 index_end == string::npos ?
00200 string::npos : (index_end-index_beg));
00201 istringstream(tmp_str) >> tmp_int;
00202 vect.push_back(tmp_int);
00203 index_beg = element.find_first_not_of(delimiter, index_end);
00204 }
00205
00206 if (vect.size() < 3)
00207 throw WrongArgument("ReadHarwellBoeing(string filename, Matrix& A, "
00208 "string value_type, string matrix_type)",
00209 "File \"" + filename + "\" contains values "
00210 "written in format \"" + element + "\", which "
00211 "could not be parsed.");
00212
00213 line_width_val = vect[vect.size() - 3];
00214 element_width_val = vect[vect.size() - 2];
00215 }
00216
00217
00218 if (Nline_rhs != 0)
00219 getline(input_stream, line);
00220
00221
00222
00223
00224 int* A_ptr;
00225 int* A_ind;
00226 T* A_data;
00227
00228 #ifdef SELDON_CHECK_MEMORY
00229 try
00230 {
00231 #endif
00232
00233 A_ptr = reinterpret_cast<int*>(calloc(Ncol + 1, sizeof(int)));
00234
00235 #ifdef SELDON_CHECK_MEMORY
00236 }
00237 catch (...)
00238 {
00239 A_ptr = NULL;
00240 }
00241
00242 if (A_ptr == NULL)
00243 throw NoMemory("ReadHarwellBoeing(string filename, "
00244 "Matrix& A, string value_type, string matrix_type)",
00245 "Unable to allocate memory for an array of "
00246 + to_str(Ncol + 1) + " integers.");
00247 #endif
00248
00249 #ifdef SELDON_CHECK_MEMORY
00250 try
00251 {
00252 #endif
00253
00254
00255
00256 A_ind = reinterpret_cast<int*>(calloc(Nnonzero, sizeof(int)));
00257 A_data = reinterpret_cast<T*>
00258 (A.GetAllocator().allocate(Nnonzero));
00259
00260 #ifdef SELDON_CHECK_MEMORY
00261 }
00262 catch (...)
00263 {
00264 A_ind = NULL;
00265 A_data = NULL;
00266 }
00267
00268 if (A_ind == NULL || A_data == NULL)
00269 throw NoMemory("ReadHarwellBoeing(string filename, "
00270 "Matrix& A, string value_type, string matrix_type)",
00271 "Unable to allocate memory for an array of "
00272 + to_str(Nnonzero) + " integers "
00273 "and for an array of "
00274 + to_str(sizeof(T) * Nnonzero) + " bytes.");
00275 #endif
00276
00277
00278
00279 int index = 0;
00280 for (i = 0; i < Nline_ptr; i++)
00281 {
00282 getline(input_stream, line);
00283 k = 0;
00284 for (j = 0; j < line_width_ptr; j++)
00285 {
00286 istringstream(line.substr(k, element_width_ptr)) >> A_ptr[index];
00287
00288 A_ptr[index]--;
00289 index++;
00290 if (index == Ncol + 1)
00291
00292
00293 break;
00294 k += element_width_ptr;
00295 }
00296 if (index == Ncol + 1)
00297 break;
00298 }
00299
00300 index = 0;
00301 for (i = 0; i < Nline_ind; i++)
00302 {
00303 getline(input_stream, line);
00304 k = 0;
00305 for (j = 0; j < line_width_ind; j++)
00306 {
00307 istringstream(line.substr(k, element_width_ind)) >> A_ind[index];
00308
00309 A_ind[index]--;
00310 index++;
00311 if (index == Nnonzero)
00312
00313
00314 break;
00315 k += element_width_ind;
00316 }
00317 if (index == Nnonzero)
00318 break;
00319 }
00320
00321
00322
00323 if (type.substr(0, 1) == "P")
00324 for (i = 0; i < Nnonzero; i++)
00325 A_data[i] = T(1);
00326 else
00327 {
00328 index = 0;
00329 for (i = 0; i < Nline_val; i++)
00330 {
00331 getline(input_stream, line);
00332 k = 0;
00333 for (j = 0; j < line_width_val; j++)
00334 {
00335 istringstream(line.substr(k, element_width_val))
00336 >> A_data[index];
00337 index++;
00338 if (index == Nnonzero)
00339
00340
00341 break;
00342 k += element_width_val;
00343 }
00344 if (index == Nnonzero)
00345 break;
00346 }
00347 }
00348
00349 #ifdef SELDON_CHECK_IO
00350
00351 if (!input_stream.good())
00352 throw IOError("ReadHarwellBoeing(string filename, "
00353 "Matrix& A, string value_type, string matrix_type)",
00354 "Unable to read all values in file \""
00355 + filename + "\".");
00356 #endif
00357
00358 input_stream.close();
00359
00360 A.SetData(Nrow, Ncol, Nnonzero, A_data, A_ptr, A_ind);
00361 }
00362
00363
00364 template<class T>
00365 void PrintComplexValuesHarwell(int nnz, const Vector<complex<T> >& Val,
00366 ofstream& file_out)
00367 {
00368 for (int i = 0; i < 2*nnz; i += 3)
00369 {
00370 for (int j = i; j < min(i+3, 2*nnz); j++)
00371 {
00372 if (j%2 == 0)
00373 file_out << setw(23) << real(Val(j/2));
00374 else
00375 file_out << setw(23) << imag(Val(j/2));
00376 }
00377
00378 file_out << '\n';
00379 }
00380 }
00381
00382
00383 template<class T>
00384 void PrintComplexValuesHarwell(int nnz, const Vector<T>& Val,
00385 ofstream& file_out)
00386 {
00387 for (int i = 0; i < nnz; i += 3)
00388 {
00389 for (int j = i; j < min(i+3, nnz); j++)
00390 file_out << setw(23) << Val(j);
00391
00392 file_out << '\n';
00393 }
00394 }
00395
00396
00397 template<class T, class Prop, class Storage, class Allocator>
00398 void WriteHarwellBoeing(const Matrix<T, Prop, Storage, Allocator>& A,
00399 const string& file_name, bool complex)
00400 {
00401
00402 IVect Ptr, Ind;
00403 Vector<T> Val;
00404 General sym;
00405 ConvertToCSC(A, sym, Ptr, Ind, Val);
00406
00407
00408 int nnz = Val.GetM();
00409 int m = A.GetM();
00410 int n = A.GetN();
00411
00412
00413 ofstream file_out(file_name.data());
00414
00415 string title("Seldon");
00416 string key("S0000008");
00417 file_out.setf(ios::left);
00418 file_out << setw(72) << title;
00419 file_out << setw(8) << key;
00420 file_out << endl;
00421
00422
00423 int ptr_len = int(ceil( log10(0.1 + nnz + 1) )) + 1;
00424 int ptr_nperline = min(80 / ptr_len, n+1);
00425 int ptrcrd = n / ptr_nperline + 1;
00426 string ptrfmt = string("(") + to_str(ptr_nperline)
00427 + "I" + to_str(ptr_len) + ")";
00428
00429
00430 int ind_len = int(ceil( log10(0.1 + n + 1) )) + 1;
00431 int ind_nperline = min(80 / ind_len, nnz);
00432 int indcrd = (nnz-1) / ind_nperline + 1;
00433 string indfmt = string("(") + to_str(ind_nperline)
00434 + 'I' + to_str(ind_len) + ')';
00435
00436
00437 string valfmt("(3D23.15)");
00438 int valcrd = (nnz-1) / 3 + 1;
00439 if (complex)
00440 valcrd = (2*nnz-1) / 3 + 1;
00441
00442 int rhscrd = 0;
00443 int totcrd = ptrcrd + indcrd + valcrd + rhscrd;
00444
00445
00446 file_out << setw(14) << totcrd;
00447 file_out << setw(14) << ptrcrd;
00448 file_out << setw(14) << indcrd;
00449 file_out << setw(14) << valcrd;
00450 file_out << setw(14) << rhscrd;
00451 file_out << endl;
00452
00453
00454 int neltvl = 0;
00455 char mxtype[4];
00456 if (complex)
00457 mxtype[0] = 'C';
00458 else
00459 mxtype[0] = 'R';
00460
00461 if (m == n)
00462 mxtype[1] = 'U';
00463 else
00464 mxtype[1] = 'R';
00465
00466 mxtype[2] = 'A';
00467 mxtype[3] = '\0';
00468
00469 file_out << mxtype << " ";
00470 file_out << setw(14) << m;
00471 file_out << setw(14) << n;
00472 file_out << setw(14) << nnz;
00473 file_out << setw(14) << neltvl;
00474 file_out << endl;
00475
00476
00477 file_out << setw(16) << ptrfmt;
00478 file_out << setw(16) << indfmt;
00479 file_out << setw(20) << valfmt;
00480 file_out << setw(20) << valfmt;
00481 file_out << endl;
00482
00483
00484 file_out.setf(ios::left);
00485 for (int i = 0; i <= n; i += ptr_nperline)
00486 {
00487 for (int j = i; j < min(i+ptr_nperline, n+1); j++)
00488 file_out << setw(ptr_len) << Ptr(j)+1;
00489
00490 file_out << '\n';
00491 }
00492
00493
00494 for (int i = 0; i < nnz; i += ind_nperline)
00495 {
00496 for (int j = i; j < min(i+ind_nperline, nnz); j++)
00497 file_out << setw(ind_len) << Ind(j)+1;
00498
00499 file_out << '\n';
00500 }
00501
00502
00503 file_out.precision(15);
00504 file_out.setf(ios::scientific);
00505 PrintComplexValuesHarwell(nnz, Val, file_out);
00506
00507 file_out.close();
00508 }
00509
00510
00512 template<class T, class Prop, class Storage, class Allocator>
00513 void WriteHarwellBoeing(const Matrix<T, Prop, Storage, Allocator>& A,
00514 const string& file_name)
00515 {
00516 WriteHarwellBoeing(A, file_name, false);
00517 }
00518
00519
00521 template<class T, class Prop, class Storage, class Allocator>
00522 void WriteHarwellBoeing(const Matrix<complex<T>,
00523 Prop, Storage, Allocator>& A,
00524 const string& file_name)
00525 {
00526 WriteHarwellBoeing(A, file_name, true);
00527 }
00528
00529 }
00530
00531
00532 #define SELDON_FILE_MATRIX_SPARSE_IOMATRIXMARKET_CXX
00533 #endif