00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_CHOLMOD_CXX
00021
00022 #include "Cholmod.hxx"
00023
00024 namespace Seldon
00025 {
00026
00027 MatrixCholmod::MatrixCholmod()
00028 {
00029
00030 cholmod_start(¶m_chol);
00031
00032 n = 0;
00033 }
00034
00035
00036
00037 MatrixCholmod::~MatrixCholmod()
00038 {
00039 if (n > 0)
00040 {
00041 Clear();
00042 cholmod_finish(¶m_chol);
00043 }
00044 }
00045
00046
00047 void MatrixCholmod::Clear()
00048 {
00049 if (n > 0)
00050 {
00051 n = 0;
00052 cholmod_free_factor(&L, ¶m_chol);
00053 }
00054 }
00055
00056
00057 template<class Prop, class Storage, class Allocator>
00058 void MatrixCholmod::
00059 FactorizeMatrix(Matrix<double, Prop, Storage, Allocator> & mat,
00060 bool keep_matrix)
00061 {
00062 Clear();
00063
00064 n = mat.GetM();
00065 Matrix<double, Symmetric, RowSymSparse, MallocAlloc<double> > Acsc;
00066 Copy(mat, Acsc);
00067 if (!keep_matrix)
00068 mat.Clear();
00069
00070
00071 cholmod_sparse A;
00072
00073 A.nrow = n;
00074 A.ncol = n;
00075 A.nzmax = Acsc.GetDataSize();
00076 A.nz = NULL;
00077 A.p = Acsc.GetPtr();
00078 A.i = Acsc.GetInd();
00079 A.x = Acsc.GetData();
00080 A.z = NULL;
00081 A.stype = -1;
00082 A.xtype = CHOLMOD_REAL;
00083 A.dtype = CHOLMOD_DOUBLE;
00084 A.sorted = true;
00085 A.packed = true;
00086
00087 L = cholmod_analyze(&A, ¶m_chol);
00088
00089 cholmod_factorize(&A, L, ¶m_chol);
00090
00091 cholmod_change_factor(CHOLMOD_REAL, true, L->is_super,
00092 true, L->is_monotonic, L, ¶m_chol);
00093 }
00094
00095
00096 template<class Transpose_status, class Allocator>
00097 void MatrixCholmod::Solve(const Transpose_status& TransA,
00098 Vector<double, VectFull, Allocator>& x)
00099 {
00100
00101 cholmod_dense b_rhs;
00102 b_rhs.nrow = x.GetM();
00103 b_rhs.ncol = 1;
00104 b_rhs.nzmax = b_rhs.nrow;
00105 b_rhs.d = b_rhs.nrow;
00106 b_rhs.x = x.GetData();
00107 b_rhs.z = NULL;
00108 b_rhs.xtype = CHOLMOD_REAL;
00109 b_rhs.dtype = CHOLMOD_DOUBLE;
00110
00111 cholmod_dense* x_sol, *y;
00112 if (TransA.Trans())
00113 {
00114 y = cholmod_solve(CHOLMOD_Lt, L, &b_rhs, ¶m_chol);
00115 x_sol = cholmod_solve(CHOLMOD_Pt, L, y, ¶m_chol);
00116 }
00117 else
00118 {
00119 y = cholmod_solve(CHOLMOD_P, L, &b_rhs, ¶m_chol);
00120 x_sol = cholmod_solve(CHOLMOD_L, L, y, ¶m_chol);
00121 }
00122
00123 double* data = reinterpret_cast<double*>(x_sol->x);
00124 for (int i = 0; i < x.GetM(); i++)
00125 x(i) = data[i];
00126
00127 cholmod_free_dense(&x_sol, ¶m_chol);
00128 cholmod_free_dense(&y, ¶m_chol);
00129 }
00130
00131
00132 template<class T, class Prop, class Storage, class Allocator>
00133 void GetCholesky(Matrix<T, Prop, Storage, Allocator>& A,
00134 MatrixCholmod& mat_chol, bool keep_matrix = false)
00135 {
00136 mat_chol.FactorizeMatrix(A, keep_matrix);
00137 }
00138
00139 template<class T, class Allocator, class Transpose_status>
00140 void
00141 SolveCholesky(const Transpose_status& TransA,
00142 MatrixCholmod& mat_chol, Vector<T, VectFull, Allocator>& x)
00143 {
00144 mat_chol.Solve(TransA, x);
00145 }
00146
00147 }
00148
00149 #define SELDON_FILE_CHOLMOD_CXX
00150 #endif