20 #ifndef SELDON_FILE_UMFPACK_CXX
22 #include "UmfPack.hxx"
36 Control.Reallocate(UMFPACK_CONTROL);
37 Info.Reallocate(UMFPACK_INFO);
52 Control(UMFPACK_PRL) = 0;
61 Control(UMFPACK_PRL) = 2;
73 bool MatrixUmfPack_Base<T>::UseInteger8()
const
75 if (
sizeof(umfpack_int_t) == 8)
83 int MatrixUmfPack_Base<T>::GetInfoFactorization()
const
90 size_t MatrixUmfPack_Base<T>::GetMemorySize()
const
94 size_t size_mem = (this->Info(UMFPACK_SYMBOLIC_SIZE)
95 + this->Info(UMFPACK_NUMERIC_SIZE_ESTIMATE))
96 *
size_t(this->Info(UMFPACK_SIZE_OF_UNIT));
108 Control(UMFPACK_ORDERING) = type;
115 throw Undefined(
"MatrixUmfPack_Base::SetPermutation(const Vector&)");
125 #ifdef UMFPACK_INTSIZE64
126 umfpack_dl_defaults(this->Control.GetData());
128 umfpack_di_defaults(this->Control.GetData());
142 #ifdef UMFPACK_INTSIZE64
143 umfpack_zl_defaults(this->Control.GetData());
145 umfpack_zi_defaults(this->Control.GetData());
162 allocator AllocatorInt;
170 AllocatorInt::deallocate(ptr_, this->
n+1);
171 AllocatorInt::deallocate(ind_, this->
n+1);
172 Allocator::deallocate(data_, this->
n+1);
175 #ifdef UMFPACK_INTSIZE64
176 umfpack_dl_free_symbolic(&this->Symbolic) ;
178 umfpack_di_free_symbolic(&this->Symbolic) ;
182 #ifdef UMFPACK_INTSIZE64
183 umfpack_dl_free_numeric(&this->
Numeric) ;
185 umfpack_di_free_numeric(&this->
Numeric) ;
189 this->Symbolic = NULL;
209 allocator AllocatorInt;
217 AllocatorInt::deallocate(ptr_, this->n+1);
218 AllocatorInt::deallocate(ind_, this->n+1);
219 Allocator::deallocate(data_real_, this->n+1);
220 Allocator::deallocate(data_imag_, this->n+1);
223 #ifdef UMFPACK_INTSIZE64
224 umfpack_zl_free_symbolic(&this->Symbolic) ;
226 umfpack_zi_free_symbolic(&this->Symbolic) ;
230 #ifdef UMFPACK_INTSIZE64
231 umfpack_zl_free_numeric(&this->Numeric) ;
233 umfpack_zi_free_numeric(&this->Numeric) ;
237 this->Symbolic = NULL;
238 this->Numeric = NULL;
249 template<
class T0,
class Prop,
class Storage,
class Allocator>
262 ConvertToCSC(mat, prop, Ptr, IndRow, Val,
false);
266 FactorizeCSC(Ptr, IndRow, Val,
false);
275 this->n = Ptr.GetM()-1;
278 ptr_ = Ptr.GetData();
279 ind_ = IndRow.GetData();
280 data_ = Val.GetData();
281 Ptr.Nullify(); IndRow.Nullify(); Val.Nullify();
284 #ifdef UMFPACK_INTSIZE64
285 umfpack_dl_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
286 this->Control.GetData(), this->Info.GetData());
288 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
289 this->Control.GetData(), this->Info.GetData());
293 #ifdef UMFPACK_INTSIZE64
295 umfpack_dl_numeric(ptr_, ind_, data_,
296 this->Symbolic, &this->Numeric,
297 this->Control.GetData(), this->Info.GetData());
300 umfpack_di_numeric(ptr_, ind_, data_,
301 this->Symbolic, &this->Numeric,
302 this->Control.GetData(), this->Info.GetData());
308 #ifdef UMFPACK_INTSIZE64
309 umfpack_dl_report_status(this->Control.GetData(), status_facto);
310 umfpack_dl_report_info(this->Control.GetData(),this->Info.GetData());
312 umfpack_di_report_status(this->Control.GetData(), status_facto);
313 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
319 int64_t size_mem = int64_t(this->Info(UMFPACK_SYMBOLIC_SIZE)
320 + this->Info(UMFPACK_NUMERIC_SIZE_ESTIMATE))
321 *int64_t(this->Info(UMFPACK_SIZE_OF_UNIT));
323 cout <<
"Memory used to store LU factors: "
324 << double(size_mem)/(1024*1024) <<
" MB" << endl;
330 template<
class Prop,
class Allocator>
342 ConvertToCSR(mat, prop, Ptr, IndCol, Val);
348 this->n = Ptr.GetM()-1;
349 ptr_ = Ptr.GetData();
350 ind_ = IndCol.GetData();
351 data_ = Val.GetData();
352 Ptr.Nullify(); IndCol.Nullify(); Val.Nullify();
355 #ifdef UMFPACK_INTSIZE64
356 umfpack_dl_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
357 this->Control.GetData(), this->Info.GetData());
359 umfpack_di_symbolic(this->n, this->n, ptr_, ind_, data_, &this->Symbolic,
360 this->Control.GetData(), this->Info.GetData());
367 template<
class Prop,
class Allocator>
372 double* data = mat.GetData();
373 for (
int i = 0; i < mat.GetDataSize(); i++)
376 #ifdef UMFPACK_INTSIZE64
378 umfpack_dl_numeric(ptr_, ind_, data_,
379 this->Symbolic, &this->Numeric,
380 this->Control.GetData(), this->Info.GetData());
383 umfpack_di_numeric(ptr_, ind_, data_,
384 this->Symbolic, &this->Numeric,
385 this->Control.GetData(), this->Info.GetData());
391 #ifdef UMFPACK_INTSIZE64
392 umfpack_dl_report_status(this->Control.GetData(), status_facto);
393 umfpack_dl_report_info(this->Control.GetData(),this->Info.GetData());
395 umfpack_di_report_status(this->Control.GetData(), status_facto);
396 umfpack_di_report_info(this->Control.GetData(),this->Info.GetData());
403 template<
class Allocator2>
406 Solve(SeldonNoTrans, x);
410 template<
class Allocator2>
414 Solve(TransA, x.GetData(), 1);
418 template<
class Allocator2>
419 void MatrixUmfPack<double>::
420 Solve(
const SeldonTranspose& TransA,
421 Matrix<double, General, ColMajor, Allocator2>& x)
423 Solve(TransA, x.GetData(), x.GetN());
428 double* x_ptr,
int nrhs)
431 Vector<double> b(this->
n);
433 int sys = UMFPACK_Aat;
434 if (TransA.NoTrans())
446 for (
int k = 0; k < nrhs; k++)
448 for (
int i = 0; i < this->
n; i++)
449 b(i) = x_ptr[i + this->n*k];
451 #ifdef UMFPACK_INTSIZE64
453 = umfpack_dl_solve(sys, ptr_, ind_, data_, &x_ptr[this->n*k],
454 b.GetData(), this->Numeric, this->Control.GetData(),
455 this->Info.GetData());
458 = umfpack_di_solve(sys, ptr_, ind_, data_, &x_ptr[this->n*k],
459 b.GetData(), this->Numeric, this->Control.GetData(),
460 this->Info.GetData());
466 umfpack_di_report_status(this->Control.GetData(), status);
471 template<
class T0,
class Prop,
class Storage,
class Allocator>
472 void MatrixUmfPack<complex<double> >::
483 ConvertToCSC(mat, prop, Ptr, IndRow, Val,
false);
487 FactorizeCSC(Ptr, IndRow, Val,
false);
493 Vector<complex<double> >& Val,
bool sym)
496 this->n = Ptr.GetM()-1;
498 long nnz = IndRow.GetDataSize();
499 complex<double>* data = Val.GetData();
502 for (
long i = 0; i < nnz; i++)
504 ValuesReal(i) = real(data[i]);
505 ValuesImag(i) = imag(data[i]);
512 data_real_ = ValuesReal.GetData();
513 data_imag_ = ValuesImag.GetData();
514 ptr_ = Ptr.GetData();
515 ind_ = IndRow.GetData();
516 ValuesReal.Nullify(); ValuesImag.Nullify();
517 Ptr.Nullify(); IndRow.Nullify();
520 #ifdef UMFPACK_INTSIZE64
521 umfpack_zl_symbolic(this->n, this->n, ptr_, ind_,
522 data_real_, data_imag_,
523 &this->Symbolic, this->Control.GetData(),
524 this->Info.GetData());
527 = umfpack_zl_numeric(ptr_, ind_, data_real_, data_imag_,
528 this->Symbolic, &this->Numeric,
529 this->Control.GetData(), this->Info.GetData());
531 umfpack_zi_symbolic(this->n, this->n, ptr_, ind_,
532 data_real_, data_imag_,
533 &this->Symbolic, this->Control.GetData(),
534 this->Info.GetData());
537 = umfpack_zi_numeric(ptr_, ind_, data_real_, data_imag_,
538 this->Symbolic, &this->Numeric,
539 this->Control.GetData(), this->Info.GetData());
544 #ifdef UMFPACK_INTSIZE64
545 umfpack_zl_report_status(this->Control.GetData(), status_facto);
546 umfpack_zl_report_info(this->Control.GetData(), this->Info.GetData());
548 umfpack_zi_report_status(this->Control.GetData(), status_facto);
549 umfpack_zi_report_info(this->Control.GetData(), this->Info.GetData());
555 int64_t size_mem = int64_t(this->Info(UMFPACK_SYMBOLIC_SIZE)
556 + this->Info(UMFPACK_NUMERIC_SIZE_ESTIMATE))
557 *int64_t(this->Info(UMFPACK_SIZE_OF_UNIT));
559 cout <<
"Estimated memory used to store LU factors: "
560 << double(size_mem)/(1024*1024) <<
" MiB" << endl;
566 template<
class Allocator2>
567 void MatrixUmfPack<complex<double> >::
570 Solve(SeldonNoTrans, x);
575 template<
class Allocator2>
580 Solve(TransA, x.GetData(), 1);
585 template<
class Allocator2>
590 Solve(TransA, x.GetData(), x.GetN());
603 int sys = UMFPACK_Aat;
604 if (TransA.NoTrans())
616 for (
int k = 0; k < nrhs; k++)
619 for (
int i = 0; i < this->n; i++)
621 b_real(i) = real(x_ptr[i + k*this->n]);
622 b_imag(i) = imag(x_ptr[i+k*this->n]);
625 #ifdef UMFPACK_INTSIZE64
627 = umfpack_zl_solve(sys, ptr_, ind_, data_real_, data_imag_,
628 x_real.GetData(), x_imag.GetData(),
629 b_real.GetData(), b_imag.GetData(),
631 this->Control.GetData(), this->Info.GetData());
634 = umfpack_zi_solve(sys, ptr_, ind_, data_real_, data_imag_,
635 x_real.GetData(), x_imag.GetData(),
636 b_real.GetData(), b_imag.GetData(),
638 this->Control.GetData(), this->Info.GetData());
641 for (
int i = 0; i < this->n; i++)
642 x_ptr[i+k*this->n] = complex<double>(x_real(i), x_imag(i));
647 #ifdef UMFPACK_INTSIZE64
648 umfpack_zl_report_status(this->Control.GetData(), status);
650 umfpack_zi_report_status(this->Control.GetData(), status);
657 template<
class MatrixSparse,
class T>
660 mat_lu.FactorizeMatrix(A, keep_matrix);
665 template<
class MatrixSparse,
class T>
667 bool keep_matrix, complex<T>& x)
669 throw WrongArgument(
"GetLU(Matrix<complex<T> >& A, MatrixUmfPack<T>& mat_lu, bool)",
670 "The LU matrix must be complex");
675 template<
class MatrixSparse,
class T>
677 bool keep_matrix, T& x)
679 throw WrongArgument(
"GetLU(Matrix<T>& A, MatrixUmfPack<complex<T> >& mat_lu, bool)",
680 "The sparse matrix must be complex");
685 template<
class T0,
class Prop,
class Storage,
class Allocator,
class T>
695 GetLU(A, mat_lu, keep_matrix, x);
700 template<
class T,
class Allocator>
709 template<
class T,
class Allocator>
713 mat_lu.Solve(TransA, x);
718 template<
class T,
class Prop,
class Allocator>
722 mat_lu.Solve(SeldonNoTrans, x);
728 template<
class T,
class Prop,
class Allocator>
732 mat_lu.Solve(TransA, x);
737 template<
class Allocator>
743 for (
int i = 0; i < x.GetM(); i++)
745 y(i, 0) = real(x(i));
746 y(i, 1) = imag(x(i));
751 for (
int i = 0; i < x.GetM(); i++)
752 x(i) = complex<double>(y(i, 0), y(i, 1));
757 template<
class Allocator>
764 for (
int i = 0; i < x.GetM(); i++)
766 y(i, 0) = real(x(i));
767 y(i, 1) = imag(x(i));
770 SolveLU(TransA, mat_lu, y);
772 for (
int i = 0; i < x.GetM(); i++)
773 x(i) = complex<double>(y(i, 0), y(i, 1));
779 template<
class Allocator>
783 throw WrongArgument(
"SolveLU(MatrixPastix<complex<double> >, Vector<double>)",
784 "The result should be a complex vector");
789 template<
class Allocator>
794 throw WrongArgument(
"SolveLU(MatrixPastix<complex<double> >, Vector<double>)",
795 "The result should be a complex vector");
800 #define SELDON_FILE_UMFPACK_CXX