//=============================================================================
/*! 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 Data[p->second].v; }
}
//// (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 Data[p->second].v; }
}
//////// (i,j) component not found ////////
const long ii(std::max(i,j)), jj(std::min(i,j));
Line[ii].push_back(std::pair<long,long>(jj,Data.size()));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,Data.size()));
}
Data.push_back(dcomponent(ii,jj,0.));
return Data.back().v;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! return component for const object */
inline dcomponent dssmatrix::component(const long& c) const
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::component(const long&) const" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( c>=long(Data.size()) ){
std::cerr << "[ERROR] dssmatrix::component(long)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << c << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
return Data[c];
}
//=============================================================================
/*! return component for const object */
inline dcomponent& dssmatrix::component(const long& c)
{
#ifdef CPPL_VERBOSE
std::cerr << "# [MARK] dssmatrix::component(const long&)" << std::endl;
#endif//CPPL_VERBOSE
#ifdef CPPL_DEBUG
if( c>=long(Data.size()) ){
std::cerr << "[ERROR] dssmatrix::component(long)" << std::endl
<< "The required component is out of the matrix size." << std::endl
<< "Your input was (" << c << ")." << std::endl;
exit(1);
}
#endif//CPPL_DEBUG
return Data[c];
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//=============================================================================
/*! 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(std::vector<dcomponent>::const_iterator it=Data.begin(); it!=Data.end(); it++){
if(it->i==i && it->j==j){
std::cerr << "[ERROR] dssmatrix::put(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
//// push ////
const long ii(std::max(i,j)), jj(std::min(i,j));
Line[ii].push_back(std::pair<long,long>(jj,Data.size()));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,Data.size()));
}
Data.push_back(dcomponent(ii,jj,v));
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(std::max(i,j)), jj(std::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(isListed(ii,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
Line[ii].push_back(std::pair<long,long>(jj,Data.size()));
if(i!=j){//off-diagonal
Line[jj].push_back(std::pair<long,long>(ii,Data.size()));
}
Data.push_back(dcomponent(ii,jj,v));
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){//exists
//// data translation ////
long c(p->second);
Data[c]=Data.back();
Data.pop_back();
//// remove from List ////
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(Data[c].i), J(Data[c].j);
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_VERBOSE
std::cerr << "# [NOTE] dssmatrix::fdel(const long&)" << " The (" << Data[c].i << "," << Data[c].j << ") component is going to be deleted." << std::endl;
#endif//CPPL_VERBOSE
if( c==long(Data.size()-1) ){//if c is the last element
long i(Data[c].i), j(Data[c].j);
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; }
}
}
//// pop_back ////
Data.pop_back();
}
else{
//// data translation ////
long i(Data[c].i), j(Data[c].j), I(Data.back().i), J(Data.back().j);
Data[c]=Data.back();
//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; }
}
}
//// pop_back ////
Data.pop_back();
}
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.Data[q->second].v << " "; }
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.Data[q->second].v << "}"; }
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 ofs(filename, std::ios::trunc);
ofs.setf(std::cout.flags());
ofs.precision(std::cout.precision());
ofs.width(std::cout.width());
ofs.fill(std::cout.fill());
ofs << "dssmatrix" << " " << N << std::endl;
for(std::vector<dcomponent>::const_iterator it=Data.begin(); it!=Data.end(); it++){
ofs << it->i << " " << it->j << " " << it->v << std::endl;
}
ofs.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;
resize(N);
double val;
long i, j, pos, tmp;
while(!s.eof()){
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();
}