extern "C"{ #include } #include #include #include #include class SystemLDL:SparseMatrix{ private: typedef std::map mapType; std::vector _B; std::vector _X; std::vector Lx,D,Y ; std::vector Li,Lp,Parent,Lnz,Flag,Pattern; mapType _M; public: ///allocate the resources for the system of equations void Initalize(int dimension) { _dimension=dimension; _Ap.resize(_dimension+1); _M.clear(); _B.resize(_dimension); _X.resize(_dimension); } double &A(int row,int col) { IndexType I=IndexType(row,col); mapType::const_iterator ci=_M.find(I); if (ci==_M.end()) { std::swap(I.first,I.second); ci=_M.find(I); } assert(ci!=_M.end()); int index=(*ci).second; return(_Ax[index]); } double &B(int i) {return(_B[i]);} double &X(int i) {return (_X[i]);} void Solve() { int d,i; // /* factorize A into LDL' (P and Pinv not used) */ ldl_symbolic (_dimension, &(*_Ap.begin()), &(*_Ai.begin()), &(*Lp.begin()), &(*Parent.begin()), &(*Lnz.begin()), &(*Flag.begin()), NULL, NULL) ; // printf ("Nonzeros in L, excluding diagonal: %d\n", Lp [_dimension]) ; d = ldl_numeric (_dimension, &(*_Ap.begin()), &(*_Ai.begin()), &(*_Ax.begin()), &(*Lp.begin()) , &(*Parent.begin()), &(*Lnz.begin()), &(*Li.begin()), &(*Lx.begin()), &(*D.begin()), &(*Y.begin()), &(*Pattern.begin()), &(*Flag.begin()), NULL, NULL) ; if (d == _dimension) { /* solve Ax=b, overwriting b with the solution x */ ldl_lsolve (_dimension, &(*_B.begin()), &(*Lp.begin()), &(*Li.begin()), &(*Lx.begin())) ; ldl_dsolve (_dimension, &(*_B.begin()), (&*D.begin()) ); ldl_ltsolve (_dimension, &(*_B.begin()), &(*Lp.begin()), &(*Li.begin()), &(*Lx.begin())) ; for (i = 0 ; i < _dimension ; i++) _X[i]=_B[i];//printf ("x [%d] = %g\n", i, b [i]) ; } else///dl_numeric failed { assert(0); } } bool IsSymmetric() {return true;} void Zero() { for (int i=0;i Entries) { _Ax.clear(); _Ai.clear(); int _nonzero=0; ///put the index of vertices for each edge ///in the right order for simmetry of the sistem std::vector::iterator Vi; for (Vi=Entries.begin();Vi=0); assert((*Vi).second>=0); if ((*Vi).first>(*Vi).second) std::swap((*Vi).first,(*Vi).second); } ///the sort and erase duplicates std::sort(Entries.begin(),Entries.end()); std::vector::iterator Vend=std::unique(Entries.begin(),Entries.end()); Entries.erase(Vend,Entries.end()); _Ax.resize(Entries.size()); _Ai.resize(Entries.size()); _M.clear(); int col=0; int i=0; Vi=Entries.begin(); while (Vi(I,_nonzero)); _Ai[_nonzero]=(*Vi).second; _nonzero++; Vi++; } i++; } _Ap[_dimension]=_nonzero; Lx.resize(_nonzero); D.resize(_dimension); Y.resize(_dimension); Li.resize(_nonzero); Lp.resize(_dimension+1); Parent.resize(_dimension); Lnz.resize(_dimension); Flag.resize(_dimension); Pattern.resize(_dimension); } };