first release version
This commit is contained in:
parent
0a7cd4af5c
commit
91c6c86b54
|
@ -0,0 +1,48 @@
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
///this class define the interface to use sparse matrix
|
||||||
|
///you must extend this class and implement the code of each function in order
|
||||||
|
///to the system solver you're using.
|
||||||
|
///For details on implementation see system_interface_LDL.h as example
|
||||||
|
template <class ScalarType>
|
||||||
|
class SparseMatrix{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::vector<int> _Ap;
|
||||||
|
std::vector<int> _Ai;
|
||||||
|
std::vector<double> _Ax;
|
||||||
|
|
||||||
|
typedef typename std::pair<int,int> IndexType;
|
||||||
|
|
||||||
|
int _dimension;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
///initilaization of the system
|
||||||
|
virtual void Initalize(int dimension)
|
||||||
|
{_dimension=dimension;}
|
||||||
|
|
||||||
|
///create a sparse matrix given a set of entries as vector
|
||||||
|
///of pair of int
|
||||||
|
virtual void CreateSparse(std::vector<IndexType> Entries)
|
||||||
|
{}
|
||||||
|
|
||||||
|
///return the value of the matrix
|
||||||
|
virtual ScalarType &A(int row,int col)
|
||||||
|
{return (_Ax[0]);}
|
||||||
|
|
||||||
|
///return true if the rapresention of sparse matriz is symmetric
|
||||||
|
virtual bool IsSymmetric()
|
||||||
|
{return false;}
|
||||||
|
|
||||||
|
virtual void Zero()
|
||||||
|
{}
|
||||||
|
|
||||||
|
///return the dimension of the matrix
|
||||||
|
virtual int Size(){return _dimension;}
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,155 @@
|
||||||
|
extern "C"{
|
||||||
|
#include <ldl.h>
|
||||||
|
}
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <sparse_matrix.h>
|
||||||
|
|
||||||
|
class SystemLDL:SparseMatrix<double>{
|
||||||
|
private:
|
||||||
|
typedef std::map<IndexType,int> mapType;
|
||||||
|
std::vector<double> _B;
|
||||||
|
std::vector<double> _X;
|
||||||
|
|
||||||
|
std::vector<double> Lx,D,Y ;
|
||||||
|
std::vector<int> 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<int>(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<Size();i++)
|
||||||
|
_Ax[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Size(){return (_dimension);}
|
||||||
|
|
||||||
|
///K is symmetric positice definite matrix
|
||||||
|
void CreateSparse(std::vector<IndexType> 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<IndexType>::iterator Vi;
|
||||||
|
for (Vi=Entries.begin();Vi<Entries.end();Vi++)
|
||||||
|
{
|
||||||
|
assert((*Vi).first>=0);
|
||||||
|
assert((*Vi).second>=0);
|
||||||
|
if ((*Vi).first>(*Vi).second)
|
||||||
|
std::swap<int>((*Vi).first,(*Vi).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
///the sort and erase duplicates
|
||||||
|
std::sort(Entries.begin(),Entries.end());
|
||||||
|
std::vector<IndexType>::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<Entries.end())
|
||||||
|
{
|
||||||
|
col=(*Vi).first;
|
||||||
|
_Ap[i]=_nonzero;
|
||||||
|
//go to next colummn
|
||||||
|
while ((col==(*Vi).first)&&(Vi<Entries.end()))
|
||||||
|
{
|
||||||
|
IndexType I=IndexType((*Vi).first,(*Vi).second);
|
||||||
|
_M.insert(std::pair<IndexType,int>(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in New Issue