00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_TAUCSSUPPORT_H
00026 #define EIGEN_TAUCSSUPPORT_H
00027
00028 template<typename Derived>
00029 taucs_ccs_matrix SparseMatrixBase<Derived>::asTaucsMatrix()
00030 {
00031 taucs_ccs_matrix res;
00032 res.n = cols();
00033 res.m = rows();
00034 res.flags = 0;
00035 res.colptr = derived()._outerIndexPtr();
00036 res.rowind = derived()._innerIndexPtr();
00037 res.values.v = derived()._valuePtr();
00038 if (ei_is_same_type<Scalar,int>::ret)
00039 res.flags |= TAUCS_INT;
00040 else if (ei_is_same_type<Scalar,float>::ret)
00041 res.flags |= TAUCS_SINGLE;
00042 else if (ei_is_same_type<Scalar,double>::ret)
00043 res.flags |= TAUCS_DOUBLE;
00044 else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
00045 res.flags |= TAUCS_SCOMPLEX;
00046 else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
00047 res.flags |= TAUCS_DCOMPLEX;
00048 else
00049 {
00050 ei_assert(false && "Scalar type not supported by TAUCS");
00051 }
00052
00053 if (Flags & UpperTriangular)
00054 res.flags |= TAUCS_UPPER;
00055 if (Flags & LowerTriangular)
00056 res.flags |= TAUCS_LOWER;
00057 if (Flags & SelfAdjoint)
00058 res.flags |= (NumTraits<Scalar>::IsComplex ? TAUCS_HERMITIAN : TAUCS_SYMMETRIC);
00059 else if ((Flags & UpperTriangular) || (Flags & LowerTriangular))
00060 res.flags |= TAUCS_TRIANGULAR;
00061
00062 return res;
00063 }
00064
00065 template<typename Scalar, int Flags>
00066 MappedSparseMatrix<Scalar,Flags>::MappedSparseMatrix(taucs_ccs_matrix& taucsMat)
00067 {
00068 m_innerSize = taucsMat.m;
00069 m_outerSize = taucsMat.n;
00070 m_outerIndex = taucsMat.colptr;
00071 m_innerIndices = taucsMat.rowind;
00072 m_values = reinterpret_cast<Scalar*>(taucsMat.values.v);
00073 m_nnz = taucsMat.colptr[taucsMat.n];
00074 }
00075
00076 template<typename MatrixType>
00077 class SparseLLT<MatrixType,Taucs> : public SparseLLT<MatrixType>
00078 {
00079 protected:
00080 typedef SparseLLT<MatrixType> Base;
00081 typedef typename Base::Scalar Scalar;
00082 typedef typename Base::RealScalar RealScalar;
00083 using Base::MatrixLIsDirty;
00084 using Base::SupernodalFactorIsDirty;
00085 using Base::m_flags;
00086 using Base::m_matrix;
00087 using Base::m_status;
00088
00089 public:
00090
00091 SparseLLT(int flags = 0)
00092 : Base(flags), m_taucsSupernodalFactor(0)
00093 {
00094 }
00095
00096 SparseLLT(const MatrixType& matrix, int flags = 0)
00097 : Base(flags), m_taucsSupernodalFactor(0)
00098 {
00099 compute(matrix);
00100 }
00101
00102 ~SparseLLT()
00103 {
00104 if (m_taucsSupernodalFactor)
00105 taucs_supernodal_factor_free(m_taucsSupernodalFactor);
00106 }
00107
00108 inline const typename Base::CholMatrixType& matrixL(void) const;
00109
00110 template<typename Derived>
00111 void solveInPlace(MatrixBase<Derived> &b) const;
00112
00113 void compute(const MatrixType& matrix);
00114
00115 protected:
00116 void* m_taucsSupernodalFactor;
00117 };
00118
00119 template<typename MatrixType>
00120 void SparseLLT<MatrixType,Taucs>::compute(const MatrixType& a)
00121 {
00122 if (m_taucsSupernodalFactor)
00123 {
00124 taucs_supernodal_factor_free(m_taucsSupernodalFactor);
00125 m_taucsSupernodalFactor = 0;
00126 }
00127
00128 if (m_flags & IncompleteFactorization)
00129 {
00130 taucs_ccs_matrix taucsMatA = const_cast<MatrixType&>(a).asTaucsMatrix();
00131 taucs_ccs_matrix* taucsRes = taucs_ccs_factor_llt(&taucsMatA, Base::m_precision, 0);
00132
00133
00134 DynamicSparseMatrix<Scalar,RowMajor> tmp = MappedSparseMatrix<Scalar>(*taucsRes);
00135 m_matrix = tmp;
00136 free(taucsRes);
00137 m_status = (m_status & ~(CompleteFactorization|MatrixLIsDirty))
00138 | IncompleteFactorization
00139 | SupernodalFactorIsDirty;
00140 }
00141 else
00142 {
00143 taucs_ccs_matrix taucsMatA = const_cast<MatrixType&>(a).asTaucsMatrix();
00144 if ( (m_flags & SupernodalLeftLooking)
00145 || ((!(m_flags & SupernodalMultifrontal)) && (m_flags & MemoryEfficient)) )
00146 {
00147 m_taucsSupernodalFactor = taucs_ccs_factor_llt_ll(&taucsMatA);
00148 }
00149 else
00150 {
00151
00152 m_taucsSupernodalFactor = taucs_ccs_factor_llt_mf(&taucsMatA);
00153 }
00154 m_status = (m_status & ~IncompleteFactorization) | CompleteFactorization | MatrixLIsDirty;
00155 }
00156 }
00157
00158 template<typename MatrixType>
00159 inline const typename SparseLLT<MatrixType>::CholMatrixType&
00160 SparseLLT<MatrixType,Taucs>::matrixL() const
00161 {
00162 if (m_status & MatrixLIsDirty)
00163 {
00164 ei_assert(!(m_status & SupernodalFactorIsDirty));
00165
00166 taucs_ccs_matrix* taucsL = taucs_supernodal_factor_to_ccs(m_taucsSupernodalFactor);
00167
00168
00169
00170 DynamicSparseMatrix<Scalar,RowMajor> tmp = MappedSparseMatrix<Scalar>(*taucsL);
00171 const_cast<typename Base::CholMatrixType&>(m_matrix) = tmp;
00172 free(taucsL);
00173 m_status = (m_status & ~MatrixLIsDirty);
00174 }
00175 return m_matrix;
00176 }
00177
00178 template<typename MatrixType>
00179 template<typename Derived>
00180 void SparseLLT<MatrixType,Taucs>::solveInPlace(MatrixBase<Derived> &b) const
00181 {
00182 bool inputIsCompatibleWithTaucs = (Derived::Flags&RowMajorBit)==0;
00183
00184 if (!inputIsCompatibleWithTaucs)
00185 {
00186 matrixL();
00187 Base::solveInPlace(b);
00188 }
00189 else if (m_flags & IncompleteFactorization)
00190 {
00191 taucs_ccs_matrix taucsLLT = const_cast<typename Base::CholMatrixType&>(m_matrix).asTaucsMatrix();
00192 typename ei_plain_matrix_type<Derived>::type x(b.rows());
00193 for (int j=0; j<b.cols(); ++j)
00194 {
00195 taucs_ccs_solve_llt(&taucsLLT,x.data(),&b.col(j).coeffRef(0));
00196 b.col(j) = x;
00197 }
00198 }
00199 else
00200 {
00201 typename ei_plain_matrix_type<Derived>::type x(b.rows());
00202 for (int j=0; j<b.cols(); ++j)
00203 {
00204 taucs_supernodal_solve_llt(m_taucsSupernodalFactor,x.data(),&b.col(j).coeffRef(0));
00205 b.col(j) = x;
00206 }
00207 }
00208 }
00209
00210 #endif // EIGEN_TAUCSSUPPORT_H