//=============================================================================
/*! operator() for const object */
inline double dssmatrix::operator()(const long& i, const long& j) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::operator()(const long&, const long&) const" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::operator()(long, 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
//// search (i,j) component ////
for(std::vector< std::pair<long,long> >::const_iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){ return Array[p->second]; }
}
//// (i,j) component was not found ////
return 0.0;
}
//=============================================================================
/*! operator() for const object */
inline double& dssmatrix::operator()(const long& i, const long& j)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::operator()(const long&, const long&) const"
<< std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::operator()(long, 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
//////// search (i,j) component ////////
for(std::vector< std::pair<long,long> >::iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){ return Array[p->second]; }
}
//////// (i,j) component not found ////////
//// vol check ////
if(VOL==CAP){
expand(CPPL_SECTOR_SIZE);
#ifdef CPPL_VERBOSE
std::cerr << "# [NOTE] dssmatrix::put(long&, long&, double&) " << "The matrix volume was automatically expanded." << std::endl;
#endif//CPPL_VERBOSE
}
//// push_back ////
const long ii(max(i,j)), jj(min(i,j));
Array[VOL]=0.0;
Indx[VOL]=ii;
Jndx[VOL]=jj;
Line[ii].push_back(std::pair<long,long>(jj,VOL));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,VOL));
}
VOL++;
return Array[VOL-1];
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! put value with volume cheack without isListed check */
inline dssmatrix& dssmatrix::put(const long& i, const long& j, const double& v)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::put(const long&, const long&, const double&)"
<< std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::put(long&, long&, double&)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
for(long c=0; c<VOL; c++){
if(Indx[c]==i && Jndx[c]==j){
std::cerr << "[ERROR] dssmatrix::fput"
<< "(const long&, const long&, const double&)" << std::endl
<< "The required component is already listed." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
}
#endif//CPPL_DEBUG
//// vol check ////
if(VOL==CAP){
expand(CPPL_SECTOR_SIZE);
#ifdef CPPL_VERBOSE
std::cerr << "# [NOTE] dssmatrix::put(long&, long&, double&)" << "The matrix volume was automatically expanded." << std::endl;
#endif//CPPL_VERBOSE
}
//// push ////
const long ii(max(i,j)), jj(min(i,j));
Array[VOL]=v;
Indx[VOL]=ii;
Jndx[VOL]=jj;
Line[ii].push_back(std::pair<long,long>(jj,VOL));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,VOL));
}
VOL++;
return *this;
}
//=============================================================================
/*! put value without isListed check and volume cheack */
inline dssmatrix& dssmatrix::fput(const long& i, const long& j, const double& v)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::fput(const long&, const long&, const double&)" << std::endl;
#endif//CPPL_VERBOSE
const long ii(max(i,j)), jj(min(i,j));
#ifdef CPPL_DEBUG
if( i<0 || j<0 || N<=i || N<=j ){
std::cerr << "[ERROR] dssmatrix::fput(const long&, lconst ong&, const double&)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
if(VOL>=CAP){
std::cerr << "[ERROR] dssmatrix::fput(const long&, const long&, const double&)" << std::endl
<< "There is no free space to set a new entry." << std::endl;
exit(1);
}
for(long c=0; c<VOL; c++){
if(Indx[c]==ii && Jndx[c]==jj){
std::cerr << "[ERROR] dssmatrix::fput(const long&, const long&, const double&)" << std::endl
<< "The required component is already listed." << std::endl
<< "Your input was (" << i << "," << j << ")." << std::endl;
exit(1);
}
}
#endif//CPPL_DEBUG
Array[VOL]=v;
Indx[VOL]=ii;
Jndx[VOL]=jj;
Line[ii].push_back(std::pair<long,long>(jj,VOL));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,VOL));
}
VOL++;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! delete the entry of a component */
inline dssmatrix& dssmatrix::del(const long i, const long j)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::del(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::del(long&, long&, double&)" << 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
//////// search (i,j) component ////////
for(std::vector< std::pair<long,long> >::iterator p=Line[i].begin(); p!=Line[i].end(); p++){
if(p->first==j){
//// data translation ////
VOL--;
long c(p->second);
Array[c]=Array[VOL];
Indx[c]=Indx[VOL];
Jndx[c]=Jndx[VOL];
//// remove the entry of component ////
Line[i].erase(p);
if(i!=j){//off-diagonal
for(std::vector< std::pair<long,long> >::iterator pj=Line[j].begin(); pj!=Line[i].end(); pj++){
if(pj->first==i){ Line[j].erase(pj); break; }
}
}
//// modify the entry of translated component ////
long I(Indx[c]), J(Jndx[c]);
for(std::vector< std::pair<long,long> >::iterator q=Line[I].begin(); q!=Line[I].end(); q++){
if(q->first==J){ q->second=c; break; }
}
if(I!=J){//off-diagonal
for(std::vector< std::pair<long,long> >::iterator q=Line[J].begin(); q!=Line[J].end(); q++){
if(q->first==I){ q->second=c; break; }
}
}
return *this;
}
}
#ifdef CPPL_DEBUG
std::cerr << "# [NOTE] dssmatrix::del(long&, long&, double&) " << "The required component was not listed. " << "Your input was (" << i << "," << j << ")." << std::endl;
#endif//CPPL_DEBUG
return *this;
}
//=============================================================================
/*! delete the entry of an element */
inline dssmatrix& dssmatrix::fdel(const long c)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::fdel(const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( c<0 || c>=VOL ){
std::cerr << "[ERROR] dssmatrix::fdel(const long&)" << std::endl
<< "The required element is out of the matrix volume." << std::endl
<< "Your input was (" << c << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
#ifdef CPPL_VERBOSE
std::cerr << "# [NOTE] dssmatrix::fdel(const long&)" << " The (" << Indx[c] << "," << Jndx[c] << ") component is going to be deleted." << std::endl;
#endif//CPPL_VERBOSE
if(c==VOL-1){//if c is the last element
VOL--;
long i(Indx[c]), j(Jndx[c]);
for(std::vector< std::pair<long,long> >::iterator q=Line[i].begin(); q!=Line[i].end(); q++){
if(q->first==j){ Line[i].erase(q); break; }
}
if(i!=j){//off-diagonal
for(std::vector< std::pair<long,long> >::iterator q=Line[j].begin(); q!=Line[j].end(); q++){
if(q->first==i){ Line[j].erase(q); break; }
}
}
}
else{
//// data translation ////
VOL--;
long i(Indx[c]), j(Jndx[c]), I(Indx[VOL]), J(Jndx[VOL]);
Array[c]=Array[VOL];
Indx[c]=Indx[VOL];
Jndx[c]=Jndx[VOL];
//std::cerr << "c=" << c << " i=" << i << " j=" << j << " C=" << VOL << " I=" << I << " J=" << J << std::endl;
//// remove entry of component ////
for(std::vector< std::pair<long,long> >::iterator q=Line[i].begin(); q!=Line[i].end(); q++){
if(q->first==j){ Line[i].erase(q); break; }
}
if(i!=j){//off-diagonal
for(std::vector< std::pair<long,long> >::iterator q=Line[j].begin(); q!=Line[j].end(); q++){
if(q->first==i){ Line[j].erase(q); break; }
}
}
//// modify the entry of translated component ////
for(std::vector< std::pair<long,long> >::iterator q=Line[I].begin(); q!=Line[I].end(); q++){
if(q->first==J){ q->second=c; break; }
}
if(I!=J){//off-diagonal
for(std::vector< std::pair<long,long> >::iterator q=Line[J].begin(); q!=Line[J].end(); q++){
if(q->first==I){ q->second=c; break; }
}
}
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
inline std::ostream& operator<<(std::ostream& s, const dssmatrix& mat)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] operator<<(std::ostream&, const dssmatrix&)" << std::endl;
#endif//CPPL_VERBOSE
for(long i=0; i<mat.N; i++){
for(long j=0; j<mat.N; j++){
if( i >= j ){
std::vector< std::pair<long,long> >::const_iterator q;
for(q=mat.Line[i].begin(); q!=mat.Line[i].end(); q++){
if(q->first==j){ break; }
}
if(q!=mat.Line[i].end()){ s << " " << mat.Array[q->second] << " "; }
else{ s << " x "; }
}
else{//i<j
std::vector< std::pair<long,long> >::const_iterator q;
for(q=mat.Line[i].begin(); q!=mat.Line[i].end(); q++){
if(q->first==j){ break; }
}
if(q!=mat.Line[i].end()){ s << "{" << mat.Array[q->second] << "}"; }
else{ s << "{x}"; }
}
}
s << std::endl;
}
return s;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
inline void dssmatrix::write(const char* filename) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::write(const char*) const" << std::endl;
#endif//CPPL_VERBOSE
std::ofstream s(filename, std::ios::trunc);
s << "dssmatrix" << " " << N << " " << CAP << std::endl;
for(long c=0; c<VOL; c++){
s << Indx[c] << " " << Jndx[c] << " " << Array[c] << std::endl;
}
s.close();
}
//=============================================================================
inline void dssmatrix::read(const char* filename)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::read(const char*)" << std::endl;
#endif//CPPL_VERBOSE
std::ifstream s( filename );
if(!s){
std::cerr << "[ERROR] dssmatrix::read(const char*) " << std::endl
<< "The file \"" << filename << "\" can not be opened." << std::endl;
exit(1);
}
std::string id;
s >> id;
if( id != "dssmatrix" ){
std::cerr << "[ERROR] dssmatrix::read(const char*) " << std::endl
<< "The type name of the file \"" << filename << "\" is not dssmatrix." << std::endl
<< "Its type name was " << id << " ." << std::endl;
exit(1);
}
s >> N >> CAP;
resize(N, CAP);
double val;
long i, j, pos, tmp;
while(!s.eof() && VOL<CAP){
s >> i >> j >> val;
fput(i,j, val);
pos =s.tellg(); s >> tmp; s.seekg(pos);
}
if(!s.eof()){
std::cerr << "[ERROR] dssmatrix::read(const char*) " << std::endl
<< "There is something is wrong with the file \"" << filename << " ." << std::endl
<< "Most likely, there are too many data components over the context." << std::endl;
exit(1);
}
s.close();
}