//=============================================================================
/*! clear all the matrix data and set the sizes 0 */
inline void dssmatrix::clear()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::clear()" << std::endl;
std::cerr << "# [NOTE] dssmatrix::clear()" << " An array at " << Array << " is going to be cleared." << std::endl;
#endif//CPPL_VERBOSE
N =0;
Data.clear();
Line.clear();
}
//=============================================================================
/*! change the matrix into a zero matrix */
inline dssmatrix& dssmatrix::zero()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::zero()" << std::endl;
#endif//CPPL_VERBOSE
Data.resize(0);
for(long i=0; i<N; i++){ Line[i].resize(0); }
return *this;
}
//=============================================================================
/*! change sign(+/-) of the matrix */
inline void dssmatrix::chsign()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::chsign()" << std::endl;
#endif//CPPL_VERBOSE
for(std::vector<dcomponent>::iterator it=Data.begin(); it!=Data.end(); it++){
it->v =-it->v;
}
}
//=============================================================================
/*! make a deep copy of the matrix */
inline void dssmatrix::copy(const dssmatrix& mat)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::copy(const dssmatrix&)" << std::endl;
std::cerr << "# [NOTE] dssmatrix::copy(const dssmatrix&)" << " A dssmatrix at " << Array << " is going to be deleted." << std::endl;
#endif//CPPL_VERBOSE
N =mat.N;
Data =mat.Data;
Line =mat.Line;
#ifdef CPPL_VERBOSE
std::cerr << " Then, a COPY of a dssmatrix has been cleated at " << Array << "." << std::endl;
#endif//CPPL_VERBOSE
}
//=============================================================================
/*! make a shallow copy of the matrix\n
This function is not designed to be used in project codes. */
inline void dssmatrix::shallow_copy(const _dssmatrix& mat)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::shallow_copy(const _dssmatrix&)" << std::endl;
std::cerr << "# [NOTE] dssmatrix:shallow_copy(const _dssmatrix&) " << "A dssmatrix at " << Array << " is going to be deleted, " << "and point at " << mat.Array << " instead." << std::endl;
#endif//CPPL_VERBOSE
Data.clear();
Line.clear();
N =mat.N;
Data.swap(mat.Data);
Line.swap(mat.Line);
mat.nullify();
}
//=============================================================================
/*! resize the matrix */
inline dssmatrix& dssmatrix::resize(const long& _n, const long _c, const long _l)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::resize(const long&, const long&, const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( _n<0 || _c<0 || _l<0 ){
std::cerr << "[ERROR] dssmatrix::resize(const long&, const long&, const long&)" << std::endl
<< "Matrix sizes, the length of arrays, and line size must be positive integers. " << std::endl
<< "Your input was (" << _n << "," << _c << "," << _l << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
N =_n;
Data.resize(0);
Data.reserve(_c);
Line.resize(N);
for(long i=0; i<N; i++){
Line[i].resize(0);
Line[i].reserve(_l);
}
return *this;
}
//=============================================================================
/*! stretch the matrix size */
inline void dssmatrix::stretch(const long& dn)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::stretch(const long&)" << std::endl;
#endif//CPPL_VERBOSE
if(dn==0){ return; }
#ifdef CPPL_DEBUG
if( n+dn<0 ){
std::cerr << "[ERROR] dssmatrix::stretch(const long&)" << std::endl
<< "The new matrix size must be larger than zero." << std::endl
<< "Your input was (" << dn << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
N +=dn;
if(dn<0){
//// delete components over the new size ////
for(std::vector<dcomponent>::reverse_iterator it=Data.rbegin(); it!=Data.rend(); it++){
if( (it->i)>=N ){ fdel(Data.rend()-it-1); }
}
//// shrink Line ////
for(long i=0; i<-dn; i++){
Line.pop_back();
}
}
else{//dn>0
//// expand Line ////
for(long i=0; i<dn; i++){
Line.push_back( std::vector< std::pair<long,long> >() );
}
}
}
//=============================================================================
/*! check if the component is listed */
inline bool dssmatrix::isListed(const long& i, const long& j) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::isListed(const long&, const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::isListed(const long&, const long&)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
for(std::vector< std::pair<long,long> >::const_iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){ return 1; }
}
return 0;
}
//=============================================================================
/*! return the element number of the component */
inline long dssmatrix::number(const long& i, const long& j)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::number(const long&, const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::number(const long&, const long&)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
for(std::vector< std::pair<long,long> >::iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){ return p->second; }
}
return -1;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! get row of the matrix */
inline _drovector dssmatrix::row(const long& _m) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::row(const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( _m<0 || _m>M ){
std::cerr << "[ERROR] dssmatrix::row(const long&)" << std::endl
<< "Input row number must be between 0 and " << M << "." << std::endl
<< "Your input was " << _m << "." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
drovector vec(N);
vec.zero();
for(std::vector< std::pair<long,long> >::const_iterator p=line[_m].begin(); p!=line[_m].end(); p++){
vec(p->first) =Data[p->second].v;
}
return _(vec);
}
//=============================================================================
/*! get column of the matrix */
inline _dcovector dssmatrix::col(const long& _n) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::col(const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( _n<0 || _n>N ){
std::cerr << "[ERROR] dssmatrix::col(const long&)" << std::endl
<< "Input row number must be between 0 and " << N << "." << std::endl
<< "Your input was " << _n << "." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
dcovector vec(M);
vec.zero();
for(std::vector< std::pair<long,long> >::const_iterator p=line[_n].begin(); p!=line[_n].end(); p++){
vec(p->first) =Data[p->second].v;
}
return _(vec);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! erase components less than DBL_MIN */
inline void dssmatrix::diet(const double eps)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::diet()" << std::endl;
#endif//CPPL_VERBOSE
for(std::vector<dcomponent>::reverse_iterator it=Data.rbegin(); it!=Data.rend(); it++){
if( fabs(it->v)<eps ){ fdel(Data.rend()-it-1); }
}
}
//=============================================================================
/*! reorder components so that all diagonal componets are placed in front */
inline long dssmatrix::diag_front()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::diag_front()" << std::endl;
#endif//CPPL_VERBOSE
long dsize(0);
for(std::vector<dcomponent>::reverse_iterator it=Data.rbegin(); it!=Data.rend()-dsize; it++){
if(it->i==it->j){
long c(Data.rend()-it-1);
long i(Data[dsize].i), j(Data[dsize].j), k(it->i);
//// search (k,k) line ////
for(std::vector< std::pair<long,long> >::iterator p=Line[k].begin(); p!=Line[k].end(); p++){
if(p->first==k){ p->second=dsize; }
}
//// search (i,j) line ////
for(std::vector< std::pair<long,long> >::iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){ p->second=c; }
}
//// search (j,i) line ////
if(i!=j){
for(std::vector< std::pair<long,long> >::iterator p=Line[j].begin(); p!=Line[j].end(); p++){
if(p->first==i){ p->second=c; }
}
}
else{//i==j
it--;
}
//// swap ////
std::swap(Data[dsize],Data[c]);
//// update ////
dsize++;
}
}
return dsize;
}
//=============================================================================
/*! reorder components */
/*
inline long dssmatrix::reorder()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::reorder()" << std::endl;
#endif//CPPL_VERBOSE
}
*/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! health checkup */
inline void dssmatrix::checkup()
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::checkup()" << std::endl;
#endif//CPPL_VERBOSE
//////// write ////////
for(std::vector<dcomponent>::const_iterator it=Data.begin(); it!=Data.end(); it++){
std::cerr << "Array[" << it-Data.begin() << "] = (" << it->i << "," << it->j << ") = " << it->v << std::endl;
}
std::cerr << std::endl;
for(long i=0; i<N; i++){
std::cerr << "Line[" << i << "] =" << std::flush;
for(unsigned long k=0; k<Line[i].size(); k++){
std::cerr << " <" << Line[i][k].first << "," << Line[i][k].second << ">" << std::flush;
}
std::cerr << std::endl;
}
std::cerr << std::endl;
//////// Elements ////////
for(std::vector<dcomponent>::const_iterator it=Data.begin(); it!=Data.end(); it++){
//// m bound ////
if( (it->i)<0 || (it->i)>=N ){
std::cerr << "[ERROR] dssmatrix::checkup()" << std::endl
<< "The indx of the " << it-Data.begin() << "th element is out of the matrix size." << std::endl
<< "Its i index was " << it->i << "." << std::endl;
exit(1);
}
//// n bound ////
if(it->j<0 || it->j>=N){
std::cerr << "[ERROR] dssmatrix::checkup()" << std::endl
<< "The jndx of the " << it-Data.begin() << "th element is out of the matrix size." << std::endl
<< "Its j index was " << it->j << "." << std::endl;
exit(1);
}
//// double-listed ////
for(std::vector<dcomponent>::const_iterator IT=it+1; IT!=Data.end(); IT++){
if( it->i==IT->i && it->j==IT->j ){
std::cerr << "[ERROR]@dssmatrix::checkup():" << std::endl
<< "The (" << it->i << ", " << it->j << ") component is double-listed at the " << it-Data.begin() << "th and the" << IT-Data.begin() << "the elements."<< std::endl;
exit(1);
}
}
}
//////// ijc consistence ////////
//////// NOTE ////////
std::cerr << "# [NOTE]@dssmatrix::checkup(): This symmetric sparse matrix is fine." << std::endl;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! swap two matrices */
inline void swap(dssmatrix& A, dssmatrix& B)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] swap(dssmatrix&, dssmatrix&)" << std::endl;
#endif//CPPL_VERBOSE
std::swap(A.N,B.N);
std::swap(A.Data,B.Data);
std::swap(A.Line,B.Line);
}
//=============================================================================
/*! convert user object to smart-temporary object */
inline _dssmatrix _(dssmatrix& mat)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] _(dssmatrix&)" << std::endl;
#endif//CPPL_VERBOSE
_dssmatrix newmat;
//////// shallow copy ////////
newmat.N =mat.N;
std::swap(newmat.Data,mat.Data);
std::swap(newmat.Line,mat.Line);
//////// nullify ////////
mat.N =0;
return newmat;
}