00001 extern "C"{
00002 #include <ldl.h>
00003 }
00004 #include <vector>
00005 #include <map>
00006 #include <algorithm>
00007 #include <sparse_matrix.h>
00008
00009 class SystemLDL:SparseMatrix<double>{
00010 private:
00011 typedef std::map<IndexType,int> mapType;
00012 std::vector<double> _B;
00013 std::vector<double> _X;
00014
00015 std::vector<double> Lx,D,Y ;
00016 std::vector<int> Li,Lp,Parent,Lnz,Flag,Pattern;
00017
00018 mapType _M;
00019
00020 public:
00021
00023 void Initalize(int dimension)
00024 {
00025 _dimension=dimension;
00026 _Ap.resize(_dimension+1);
00027 _M.clear();
00028 _B.resize(_dimension);
00029 _X.resize(_dimension);
00030 }
00031
00032 double &A(int row,int col)
00033 {
00034
00035 IndexType I=IndexType(row,col);
00036 mapType::const_iterator ci=_M.find(I);
00037 if (ci==_M.end())
00038 {
00039 std::swap<int>(I.first,I.second);
00040 ci=_M.find(I);
00041 }
00042 assert(ci!=_M.end());
00043 int index=(*ci).second;
00044
00045 return(_Ax[index]);
00046 }
00047
00048 double &B(int i)
00049 {return(_B[i]);}
00050
00051 double &X(int i)
00052 {return (_X[i]);}
00053
00054
00055 void Solve()
00056 {
00057 int d,i;
00058
00059
00060 ldl_symbolic (_dimension, &(*_Ap.begin()), &(*_Ai.begin()), &(*Lp.begin()),
00061 &(*Parent.begin()), &(*Lnz.begin()), &(*Flag.begin()), NULL, NULL) ;
00062
00063
00064
00065 d = ldl_numeric (_dimension, &(*_Ap.begin()), &(*_Ai.begin()), &(*_Ax.begin()), &(*Lp.begin())
00066 , &(*Parent.begin()), &(*Lnz.begin()), &(*Li.begin()), &(*Lx.begin()),
00067 &(*D.begin()), &(*Y.begin()), &(*Pattern.begin()),
00068 &(*Flag.begin()), NULL, NULL) ;
00069
00070 if (d == _dimension)
00071 {
00072
00073 ldl_lsolve (_dimension, &(*_B.begin()), &(*Lp.begin()), &(*Li.begin()), &(*Lx.begin())) ;
00074 ldl_dsolve (_dimension, &(*_B.begin()), (&*D.begin()) );
00075 ldl_ltsolve (_dimension, &(*_B.begin()), &(*Lp.begin()), &(*Li.begin()), &(*Lx.begin())) ;
00076
00077 for (i = 0 ; i < _dimension ; i++)
00078 _X[i]=_B[i];
00079 }
00080 else
00081 {
00082 assert(0);
00083 }
00084 }
00085
00086 bool IsSymmetric()
00087 {return true;}
00088
00089 void Zero()
00090 {
00091 for (int i=0;i<Size();i++)
00092 _Ax[i]=0;
00093 }
00094
00095 int Size(){return (_dimension);}
00096
00098 void CreateSparse(std::vector<IndexType> Entries)
00099 {
00100 _Ax.clear();
00101 _Ai.clear();
00102 int _nonzero=0;
00103
00106 std::vector<IndexType>::iterator Vi;
00107 for (Vi=Entries.begin();Vi<Entries.end();Vi++)
00108 {
00109 assert((*Vi).first>=0);
00110 assert((*Vi).second>=0);
00111 if ((*Vi).first>(*Vi).second)
00112 std::swap<int>((*Vi).first,(*Vi).second);
00113 }
00114
00116 std::sort(Entries.begin(),Entries.end());
00117 std::vector<IndexType>::iterator Vend=std::unique(Entries.begin(),Entries.end());
00118 Entries.erase(Vend,Entries.end());
00119
00120 _Ax.resize(Entries.size());
00121 _Ai.resize(Entries.size());
00122 _M.clear();
00123
00124 int col=0;
00125 int i=0;
00126 Vi=Entries.begin();
00127 while (Vi<Entries.end())
00128 {
00129 col=(*Vi).first;
00130 _Ap[i]=_nonzero;
00131
00132 while ((col==(*Vi).first)&&(Vi<Entries.end()))
00133 {
00134 IndexType I=IndexType((*Vi).first,(*Vi).second);
00135 _M.insert(std::pair<IndexType,int>(I,_nonzero));
00136 _Ai[_nonzero]=(*Vi).second;
00137 _nonzero++;
00138 Vi++;
00139 }
00140 i++;
00141 }
00142
00143 _Ap[_dimension]=_nonzero;
00144 Lx.resize(_nonzero);
00145 D.resize(_dimension);
00146 Y.resize(_dimension);
00147 Li.resize(_nonzero);
00148 Lp.resize(_dimension+1);
00149 Parent.resize(_dimension);
00150 Lnz.resize(_dimension);
00151 Flag.resize(_dimension);
00152 Pattern.resize(_dimension);
00153 }
00154
00155 };