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 display_info = false;
00040 transpose = false;
00041 }
00042
00043
00045 template<class T>
00046 void MatrixUmfPack_Base<T>::HideMessages()
00047 {
00048 display_info = false;
00049 Control(UMFPACK_PRL) = 0;
00050 }
00051
00052
00054 template<class T>
00055 void MatrixUmfPack_Base<T>::ShowMessages()
00056 {
00057 display_info = true;
00058 Control(UMFPACK_PRL) = 2;
00059 }
00060
00061
00063 MatrixUmfPack<double>::MatrixUmfPack() : MatrixUmfPack_Base<double>()
00064 {
00065 ptr_ = NULL;
00066 ind_ = NULL;
00067 data_ = NULL;
00068 umfpack_di_defaults(this->Control.GetData());
00069 this->HideMessages();
00070 }
00071
00072
00074 MatrixUmfPack<complex<double> >::MatrixUmfPack()
00075 : MatrixUmfPack_Base<complex<double> >()
00076 {
00077 ptr_ = NULL;
00078 ind_ = NULL;
00079 data_real_ = NULL;
00080 data_imag_ = NULL;
00081 umfpack_zi_defaults(this->Control.GetData());
00082 this->HideMessages();
00083 }
00084
00085
00087 MatrixUmfPack<double>::~MatrixUmfPack()
00088 {
00089 Clear();
00090 }
00091
00092
00094 void MatrixUmfPack<double>::Clear()
00095 {
00096 if (this->n > 0)
00097 {
00098
00099 free(ptr_);
00100 free(ind_);
00101 free(data_);
00102
00103
00104 umfpack_di_free_symbolic(&this->Symbolic) ;
00105
00106
00107 umfpack_di_free_numeric(&this->Numeric) ;
00108
00109 this->n = 0;
00110 this->Symbolic = NULL;
00111 this->Numeric = NULL;
00112 ptr_ = NULL;
00113 ind_ = NULL;
00114 data_ = NULL;
00115 }
00116 }
00117
00118
00120 MatrixUmfPack<complex<double> >::~MatrixUmfPack()
00121 {
00122 Clear();
00123 }
00124
00125
00127 void MatrixUmfPack<complex<double> >::Clear()
00128 {
00129 if (this->n > 0)
00130 {
00131
00132 free(ptr_);
00133 free(ind_);
00134 free(data_real_);
00135 free(data_imag_);
00136
00137
00138 umfpack_zi_free_symbolic(&this->Symbolic) ;
00139
00140
00141 umfpack_zi_free_numeric(&this->Numeric) ;
00142
00143 this->n = 0;
00144 this->Symbolic = NULL;
00145 this->Numeric = NULL;
00146
00147 ptr_ = NULL;
00148 ind_ = NULL;
00149 data_real_ = NULL;
00150 data_imag_ = NULL;
00151 }
00152 }
00153
00154
00156 template<class Prop, class Storage, class Allocator>
00157 void MatrixUmfPack<double>::
00158 FactorizeMatrix(Matrix<double, Prop, Storage, Allocator> & mat,
00159 bool keep_matrix)
00160 {
00161
00162 Clear();
00163
00164
00165 Matrix<double, General, ColSparse, MallocAlloc<double> > Acsc;
00166 transpose = false;
00167
00168 this->n = mat.GetM();
00169 Copy(mat, Acsc);
00170 if (!keep_matrix)
00171 mat.Clear();
00172
00173
00174 ptr_ = Acsc.GetPtr();
00175 ind_ = Acsc.GetInd();
00176 data_ = Acsc.GetData();
00177 Acsc.Nullify();
00178
00179
00180 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
00181 this->Control.GetData(), this->Info.GetData());
00182
00183
00184 int status =
00185 umfpack_di_numeric(ptr_, ind_, data_,
00186 this->Symbolic, &this->Numeric,
00187 this->Control.GetData(), this->Info.GetData());
00188
00189
00190 if (this->display_info)
00191 {
00192 umfpack_di_report_status(this->Control.GetData(), status);
00193 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
00194 }
00195 }
00196
00197
00199 template<class Prop, class Allocator>
00200 void MatrixUmfPack<double>
00201 ::PerformAnalysis(Matrix<double, Prop, RowSparse, Allocator> & mat)
00202 {
00203
00204 Clear();
00205
00206
00207 Matrix<double, General, RowSparse, MallocAlloc<double> > Acsr;
00208 transpose = true;
00209
00210 Copy(mat, Acsr);
00211
00212
00213 this->n = mat.GetM();
00214 ptr_ = Acsr.GetPtr();
00215 ind_ = Acsr.GetInd();
00216 data_ = Acsr.GetData();
00217 Acsr.Nullify();
00218
00219
00220 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
00221 this->Control.GetData(), this->Info.GetData());
00222
00223 }
00224
00225
00227 template<class Prop, class Allocator>
00228 void MatrixUmfPack<double>
00229 ::PerformFactorization(Matrix<double, Prop, RowSparse, Allocator> & mat)
00230 {
00231
00232 double* data = mat.GetData();
00233 for (int i = 0; i < mat.GetDataSize(); i++)
00234 data_[i] = data[i];
00235
00236 int status =
00237 umfpack_di_numeric(ptr_, ind_, data_,
00238 this->Symbolic, &this->Numeric,
00239 this->Control.GetData(), this->Info.GetData());
00240
00241
00242 if (this->display_info)
00243 {
00244 umfpack_di_report_status(this->Control.GetData(), status);
00245 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
00246 }
00247 }
00248
00249
00251 template<class Allocator2>
00252 void MatrixUmfPack<double>::Solve(Vector<double, VectFull, Allocator2>& x)
00253 {
00254
00255 Vector<double, VectFull, Allocator2> b(x);
00256
00257 int sys = UMFPACK_A;
00258 if (transpose)
00259 sys = UMFPACK_Aat;
00260
00261 int status
00262 = umfpack_di_solve(sys, ptr_, ind_, data_, x.GetData(),
00263 b.GetData(), this->Numeric, this->Control.GetData(),
00264 this->Info.GetData());
00265
00266
00267 if (this->display_info)
00268 umfpack_di_report_status(this->Control.GetData(), status);
00269 }
00270
00271
00273 template<class Prop, class Storage,class Allocator>
00274 void MatrixUmfPack<complex<double> >::
00275 FactorizeMatrix(Matrix<complex<double>, Prop, Storage, Allocator> & mat,
00276 bool keep_matrix)
00277 {
00278 Clear();
00279
00280 this->n = mat.GetM();
00281
00282 Matrix<complex<double>, General, ColSparse,
00283 MallocAlloc<complex<double> > > Acsc;
00284 transpose = false;
00285
00286 Copy(mat, Acsc);
00287 if (!keep_matrix)
00288 mat.Clear();
00289
00290 int nnz = Acsc.GetDataSize();
00291 complex<double>* data = Acsc.GetData();
00292 int* ptr = Acsc.GetPtr();
00293 int* ind = Acsc.GetInd();
00294 Vector<double, VectFull, MallocAlloc<double> >
00295 ValuesReal(nnz), ValuesImag(nnz);
00296
00297 Vector<int, VectFull, MallocAlloc<int> > Ptr(this->n+1), Ind(nnz);
00298
00299 for (int i = 0; i < nnz; i++)
00300 {
00301 ValuesReal(i) = real(data[i]);
00302 ValuesImag(i) = imag(data[i]);
00303 Ind(i) = ind[i];
00304 }
00305
00306 for (int i = 0; i <= this->n; i++)
00307 Ptr(i) = ptr[i];
00308
00309
00310 Acsc.Clear();
00311
00312
00313 data_real_ = ValuesReal.GetData();
00314 data_imag_ = ValuesImag.GetData();
00315 ptr_ = Ptr.GetData();
00316 ind_ = Ind.GetData();
00317 ValuesReal.Nullify(); ValuesImag.Nullify();
00318 Ptr.Nullify(); Ind.Nullify();
00319
00320
00321 umfpack_zi_symbolic(this->n, this->n, ptr_, ind_,
00322 data_real_, data_imag_,
00323 &this->Symbolic, this->Control.GetData(),
00324 this->Info.GetData());
00325
00326 int status
00327 = umfpack_zi_numeric(ptr_, ind_, data_real_, data_imag_,
00328 this->Symbolic, &this->Numeric,
00329 this->Control.GetData(), this->Info.GetData());
00330
00331 if (this->display_info)
00332 {
00333 umfpack_zi_report_status(this->Control.GetData(), status);
00334 umfpack_zi_report_info(this->Control.GetData(), this->Info.GetData());
00335 }
00336 }
00337
00338
00340 template<class Allocator2>
00341 void MatrixUmfPack<complex<double> >::
00342 Solve(Vector<complex<double>, VectFull, Allocator2>& x)
00343 {
00344 int m = x.GetM();
00345
00346 Vector<double> b_real(m), b_imag(m);
00347 for (int i = 0; i < m; i++)
00348 {
00349 b_real(i) = real(x(i));
00350 b_imag(i) = imag(x(i));
00351 }
00352
00353 Vector<double> x_real(m), x_imag(m);
00354 x_real.Zero();
00355 x_imag.Zero();
00356 int status
00357 = umfpack_zi_solve(UMFPACK_A, ptr_, ind_, data_real_, data_imag_,
00358 x_real.GetData(), x_imag.GetData(),
00359 b_real.GetData(), b_imag.GetData(),
00360 this->Numeric,
00361 this->Control.GetData(), this->Info.GetData());
00362 b_real.Clear();
00363 b_imag.Clear();
00364
00365 for (int i = 0; i < m; i++)
00366 x(i) = complex<double>(x_real(i), x_imag(i));
00367
00368 if (this->display_info)
00369 umfpack_zi_report_status(this->Control.GetData(), status);
00370 }
00371
00372
00374 template<class T, class Prop, class Storage, class Allocator>
00375 void GetLU(Matrix<T, Prop, Storage, Allocator>& A, MatrixUmfPack<T>& mat_lu,
00376 bool keep_matrix = false)
00377 {
00378 mat_lu.FactorizeMatrix(A, keep_matrix);
00379 }
00380
00381
00383 template<class T, class Allocator>
00384 void SolveLU(MatrixUmfPack<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00385 {
00386 mat_lu.Solve(x);
00387 }
00388
00389
00390 template<class T, class Allocator>
00391 void SolveLU(const SeldonTranspose& TransA,
00392 MatrixUmfPack<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00393 {
00394 if (!TransA.NoTrans())
00395 throw
00396 WrongArgument("SolveLU(SeldonTranspose&, MatrixUmfPack&, Vector&)",
00397 "Only non-transposed matrices are supported.");
00398 mat_lu.Solve(x);
00399 }
00400
00401 }
00402
00403 #define SELDON_FILE_UMFPACK_CXX
00404 #endif