00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_UMFPACK_CXX
00021
00022 #include "UmfPack.hxx"
00023
00024 namespace Seldon
00025 {
00026
00028 template<class T>
00029 MatrixUmfPack_Base<T>::MatrixUmfPack_Base()
00030 {
00031 Symbolic = NULL;
00032 Numeric = NULL;
00033 n = 0;
00034
00035
00036 Control.Reallocate(UMFPACK_CONTROL);
00037 Info.Reallocate(UMFPACK_INFO);
00038
00039 print_level = -1;
00040 transpose = false;
00041 status_facto = 0;
00042 }
00043
00044
00046 template<class T>
00047 void MatrixUmfPack_Base<T>::HideMessages()
00048 {
00049 print_level = -1;
00050 Control(UMFPACK_PRL) = 0;
00051 }
00052
00053
00055 template<class T>
00056 void MatrixUmfPack_Base<T>::ShowMessages()
00057 {
00058 print_level = 1;
00059 Control(UMFPACK_PRL) = 2;
00060 }
00061
00062
00063 template<class T>
00064 void MatrixUmfPack_Base<T>::ShowFullHistory()
00065 {
00066 print_level = 2;
00067 }
00068
00069
00070 template<class T>
00071 int MatrixUmfPack_Base<T>::GetInfoFactorization() const
00072 {
00073 return status_facto;
00074 }
00075
00076
00077 template<class T>
00078 void MatrixUmfPack_Base<T>::SelectOrdering(int type)
00079 {
00080 Control(UMFPACK_ORDERING) = type;
00081 }
00082
00083
00084 template<class T>
00085 void MatrixUmfPack_Base<T>::SetPermutation(const IVect& permut)
00086 {
00087 throw Undefined("MatrixUmfPack_Base::SetPermutation(const Vector&)");
00088 }
00089
00090
00092 MatrixUmfPack<double>::MatrixUmfPack() : MatrixUmfPack_Base<double>()
00093 {
00094 ptr_ = NULL;
00095 ind_ = NULL;
00096 data_ = NULL;
00097 umfpack_di_defaults(this->Control.GetData());
00098 this->HideMessages();
00099 }
00100
00101
00103 MatrixUmfPack<complex<double> >::MatrixUmfPack()
00104 : MatrixUmfPack_Base<complex<double> >()
00105 {
00106 ptr_ = NULL;
00107 ind_ = NULL;
00108 data_real_ = NULL;
00109 data_imag_ = NULL;
00110 umfpack_zi_defaults(this->Control.GetData());
00111 this->HideMessages();
00112 }
00113
00114
00116 MatrixUmfPack<double>::~MatrixUmfPack()
00117 {
00118 Clear();
00119 }
00120
00121
00123 void MatrixUmfPack<double>::Clear()
00124 {
00125 if (this->n > 0)
00126 {
00127
00128 free(ptr_);
00129 free(ind_);
00130 free(data_);
00131
00132
00133 umfpack_di_free_symbolic(&this->Symbolic) ;
00134
00135
00136 umfpack_di_free_numeric(&this->Numeric) ;
00137
00138 this->n = 0;
00139 this->Symbolic = NULL;
00140 this->Numeric = NULL;
00141 ptr_ = NULL;
00142 ind_ = NULL;
00143 data_ = NULL;
00144 }
00145 }
00146
00147
00149 MatrixUmfPack<complex<double> >::~MatrixUmfPack()
00150 {
00151 Clear();
00152 }
00153
00154
00156 void MatrixUmfPack<complex<double> >::Clear()
00157 {
00158 if (this->n > 0)
00159 {
00160
00161 free(ptr_);
00162 free(ind_);
00163 free(data_real_);
00164 free(data_imag_);
00165
00166
00167 umfpack_zi_free_symbolic(&this->Symbolic) ;
00168
00169
00170 umfpack_zi_free_numeric(&this->Numeric) ;
00171
00172 this->n = 0;
00173 this->Symbolic = NULL;
00174 this->Numeric = NULL;
00175
00176 ptr_ = NULL;
00177 ind_ = NULL;
00178 data_real_ = NULL;
00179 data_imag_ = NULL;
00180 }
00181 }
00182
00183
00185 template<class Prop, class Storage, class Allocator>
00186 void MatrixUmfPack<double>::
00187 FactorizeMatrix(Matrix<double, Prop, Storage, Allocator> & mat,
00188 bool keep_matrix)
00189 {
00190
00191 Clear();
00192
00193
00194 Matrix<double, General, ColSparse, MallocAlloc<double> > Acsc;
00195 transpose = false;
00196
00197 this->n = mat.GetM();
00198 Copy(mat, Acsc);
00199 if (!keep_matrix)
00200 mat.Clear();
00201
00202
00203 ptr_ = Acsc.GetPtr();
00204 ind_ = Acsc.GetInd();
00205 data_ = Acsc.GetData();
00206 Acsc.Nullify();
00207
00208
00209 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
00210 this->Control.GetData(), this->Info.GetData());
00211
00212
00213 status_facto =
00214 umfpack_di_numeric(ptr_, ind_, data_,
00215 this->Symbolic, &this->Numeric,
00216 this->Control.GetData(), this->Info.GetData());
00217
00218
00219 if (print_level > 1)
00220 {
00221 umfpack_di_report_status(this->Control.GetData(), status_facto);
00222 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
00223 }
00224
00225 if (print_level > 0)
00226 {
00227 int size_mem = (this->Info(UMFPACK_SYMBOLIC_SIZE)
00228 + this->Info(UMFPACK_NUMERIC_SIZE_ESTIMATE))
00229 *this->Info(UMFPACK_SIZE_OF_UNIT);
00230
00231 cout << "Memory used to store LU factors: "
00232 << double(size_mem)/(1024*1024) << " MB" << endl;
00233 }
00234 }
00235
00236
00238 template<class Prop, class Allocator>
00239 void MatrixUmfPack<double>
00240 ::PerformAnalysis(Matrix<double, Prop, RowSparse, Allocator> & mat)
00241 {
00242
00243 Clear();
00244
00245
00246 Matrix<double, General, RowSparse, MallocAlloc<double> > Acsr;
00247 transpose = true;
00248
00249 Copy(mat, Acsr);
00250
00251
00252 this->n = mat.GetM();
00253 ptr_ = Acsr.GetPtr();
00254 ind_ = Acsr.GetInd();
00255 data_ = Acsr.GetData();
00256 Acsr.Nullify();
00257
00258
00259 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
00260 this->Control.GetData(), this->Info.GetData());
00261
00262 }
00263
00264
00266 template<class Prop, class Allocator>
00267 void MatrixUmfPack<double>
00268 ::PerformFactorization(Matrix<double, Prop, RowSparse, Allocator> & mat)
00269 {
00270
00271 double* data = mat.GetData();
00272 for (int i = 0; i < mat.GetDataSize(); i++)
00273 data_[i] = data[i];
00274
00275 status_facto =
00276 umfpack_di_numeric(ptr_, ind_, data_,
00277 this->Symbolic, &this->Numeric,
00278 this->Control.GetData(), this->Info.GetData());
00279
00280
00281 if (print_level > 1)
00282 {
00283 umfpack_di_report_status(this->Control.GetData(), status_facto);
00284 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
00285 }
00286 }
00287
00288
00290 template<class Allocator2>
00291 void MatrixUmfPack<double>::Solve(Vector<double, VectFull, Allocator2>& x)
00292 {
00293
00294 Vector<double, VectFull, Allocator2> b(x);
00295
00296 int sys = UMFPACK_A;
00297 if (transpose)
00298 sys = UMFPACK_Aat;
00299
00300 int status
00301 = umfpack_di_solve(sys, ptr_, ind_, data_, x.GetData(),
00302 b.GetData(), this->Numeric, this->Control.GetData(),
00303 this->Info.GetData());
00304
00305
00306 if (print_level > 1)
00307 umfpack_di_report_status(this->Control.GetData(), status);
00308 }
00309
00310
00311 template<class StatusTrans, class Allocator2>
00312 void MatrixUmfPack<double>::Solve(const StatusTrans& TransA,
00313 Vector<double, VectFull, Allocator2>& x)
00314 {
00315 if (TransA.NoTrans())
00316 {
00317 Solve(x);
00318 return;
00319 }
00320
00321
00322 Vector<double, VectFull, Allocator2> b(x);
00323
00324 int sys = UMFPACK_Aat;
00325 if (transpose)
00326 sys = UMFPACK_A;
00327
00328 int status
00329 = umfpack_di_solve(sys, ptr_, ind_, data_, x.GetData(),
00330 b.GetData(), this->Numeric, this->Control.GetData(),
00331 this->Info.GetData());
00332
00333
00334 if (print_level > 1)
00335 umfpack_di_report_status(this->Control.GetData(), status);
00336 }
00337
00338
00340 template<class Prop, class Storage,class Allocator>
00341 void MatrixUmfPack<complex<double> >::
00342 FactorizeMatrix(Matrix<complex<double>, Prop, Storage, Allocator> & mat,
00343 bool keep_matrix)
00344 {
00345 Clear();
00346
00347 this->n = mat.GetM();
00348
00349 Matrix<complex<double>, General, ColSparse,
00350 MallocAlloc<complex<double> > > Acsc;
00351 transpose = false;
00352
00353 Copy(mat, Acsc);
00354 if (!keep_matrix)
00355 mat.Clear();
00356
00357 int nnz = Acsc.GetDataSize();
00358 complex<double>* data = Acsc.GetData();
00359 int* ptr = Acsc.GetPtr();
00360 int* ind = Acsc.GetInd();
00361 Vector<double, VectFull, MallocAlloc<double> >
00362 ValuesReal(nnz), ValuesImag(nnz);
00363
00364 Vector<int, VectFull, MallocAlloc<int> > Ptr(this->n+1), Ind(nnz);
00365
00366 for (int i = 0; i < nnz; i++)
00367 {
00368 ValuesReal(i) = real(data[i]);
00369 ValuesImag(i) = imag(data[i]);
00370 Ind(i) = ind[i];
00371 }
00372
00373 for (int i = 0; i <= this->n; i++)
00374 Ptr(i) = ptr[i];
00375
00376
00377 Acsc.Clear();
00378
00379
00380 data_real_ = ValuesReal.GetData();
00381 data_imag_ = ValuesImag.GetData();
00382 ptr_ = Ptr.GetData();
00383 ind_ = Ind.GetData();
00384 ValuesReal.Nullify(); ValuesImag.Nullify();
00385 Ptr.Nullify(); Ind.Nullify();
00386
00387
00388 umfpack_zi_symbolic(this->n, this->n, ptr_, ind_,
00389 data_real_, data_imag_,
00390 &this->Symbolic, this->Control.GetData(),
00391 this->Info.GetData());
00392
00393 status_facto
00394 = umfpack_zi_numeric(ptr_, ind_, data_real_, data_imag_,
00395 this->Symbolic, &this->Numeric,
00396 this->Control.GetData(), this->Info.GetData());
00397
00398 if (print_level > 1)
00399 {
00400 umfpack_zi_report_status(this->Control.GetData(), status_facto);
00401 umfpack_zi_report_info(this->Control.GetData(), this->Info.GetData());
00402 }
00403
00404 if (print_level > 0)
00405 {
00406 int size_mem = (this->Info(UMFPACK_SYMBOLIC_SIZE)
00407 + this->Info(UMFPACK_NUMERIC_SIZE_ESTIMATE))
00408 *this->Info(UMFPACK_SIZE_OF_UNIT);
00409
00410 cout << "Estimated memory used to store LU factors: "
00411 << double(size_mem)/(1024*1024) << " MB" << endl;
00412 }
00413 }
00414
00415
00417 template<class Allocator2>
00418 void MatrixUmfPack<complex<double> >::
00419 Solve(Vector<complex<double>, VectFull, Allocator2>& x)
00420 {
00421 Solve(SeldonNoTrans, x);
00422 }
00423
00424
00426 template<class StatusTrans, class Allocator2>
00427 void MatrixUmfPack<complex<double> >::
00428 Solve(const StatusTrans& TransA,
00429 Vector<complex<double>, VectFull, Allocator2>& x)
00430 {
00431 int m = x.GetM();
00432
00433 Vector<double> b_real(m), b_imag(m);
00434 for (int i = 0; i < m; i++)
00435 {
00436 b_real(i) = real(x(i));
00437 b_imag(i) = imag(x(i));
00438 }
00439
00440 Vector<double> x_real(m), x_imag(m);
00441 x_real.Zero();
00442 x_imag.Zero();
00443
00444 int sys = UMFPACK_A;
00445 if (TransA.Trans())
00446 sys = UMFPACK_Aat;
00447
00448 int status
00449 = umfpack_zi_solve(sys, ptr_, ind_, data_real_, data_imag_,
00450 x_real.GetData(), x_imag.GetData(),
00451 b_real.GetData(), b_imag.GetData(),
00452 this->Numeric,
00453 this->Control.GetData(), this->Info.GetData());
00454 b_real.Clear();
00455 b_imag.Clear();
00456
00457 for (int i = 0; i < m; i++)
00458 x(i) = complex<double>(x_real(i), x_imag(i));
00459
00460 if (print_level > 1)
00461 umfpack_zi_report_status(this->Control.GetData(), status);
00462 }
00463
00464
00466 template<class T, class Prop, class Storage, class Allocator>
00467 void GetLU(Matrix<T, Prop, Storage, Allocator>& A, MatrixUmfPack<T>& mat_lu,
00468 bool keep_matrix = false)
00469 {
00470 mat_lu.FactorizeMatrix(A, keep_matrix);
00471 }
00472
00473
00475 template<class T, class Allocator>
00476 void SolveLU(MatrixUmfPack<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00477 {
00478 mat_lu.Solve(x);
00479 }
00480
00481
00482 template<class T, class Allocator>
00483 void SolveLU(const SeldonTranspose& TransA,
00484 MatrixUmfPack<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00485 {
00486 mat_lu.Solve(TransA, x);
00487 }
00488
00489 }
00490
00491 #define SELDON_FILE_UMFPACK_CXX
00492 #endif