Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

matrixSP.h

Go to the documentation of this file.
00001 #ifndef MATRIXSP_H
00002 #define MATRIXSP_H
00003 
00033 // project includes
00034 #include    "matrix.h"
00035 // standard includes
00036 #include    <vector>
00037 #include    <map>
00038 #include    <valarray>
00042 #ifdef USE_NAMESPACE_LINAL
00043 namespace LinAl {
00044 #endif
00045 /*
00046  * Classes
00047  */
00048 class MatrixSP;
00049 
00054 #define REF_SP(A,I,J)   ((*(((A).D)->v))[(J)][(I)])
00055 
00058 #define FTN_OFFSET  1
00059 
00062 class MatrixSP;
00063 istream& operator>> (istream& s, MatrixSP& M) ;
00064 ostream& operator<< (ostream& s, const MatrixSP& M) ;
00070 class MatrixSP:public Matrix<double> {
00071     friend istream& operator>> (istream& s, MatrixSP& M) ;
00072     friend ostream& operator<< (ostream& s, const MatrixSP& M) ;
00074     typedef map<int,double>  vectorsp ;
00075 public:
00077     enum status {open=0,closed=1};
00078 protected:
00103     class MrepSP {
00104     public:
00106         status              s;
00108         valarray<double>*   m;
00110         valarray<int>*      ia;
00112         valarray<int>*      izh;
00114         vector<vectorsp>*   v ;
00116         int                 ncol ;
00118         int                 nref ;
00120         MrepSP (const int nc=0, const status S=open) : 
00121                 s(S),m(0),ia(0),izh(0),v(0),ncol(nc) {
00122             nref=1;
00123             if (S==open) v=new vector<vectorsp>(nc);
00124             else {
00125                 izh=new valarray<int>(nc);
00126                 ia=new valarray<int>();
00127                 m=new valarray<double>();
00128             }
00129         }
00131         MrepSP (const int nc, const int nel, const status _s=closed) :
00132                 s(_s),m(0),ia(0),izh(0),v(0),ncol(nc) {
00133             nref=1;
00134             if (_s==open) v=new vector<vectorsp>(nc);
00135             else {
00136                 izh=new valarray<int>(nc);
00137                 ia=new valarray<int>(nel);
00138                 m=new valarray<double>(nel);
00139             }
00140         }
00142         ~MrepSP () {
00143             if (s==closed) {
00144                 delete m;
00145                 delete ia;
00146                 delete izh;
00147             }
00148             else
00149                 delete v;
00150         }
00152         MrepSP* get_own_copy()
00153         {
00154             if (nref==1) return this ;
00155             nref-- ;
00156             return new MrepSP(*this) ;
00157         }
00159         void assign(const double value) {
00160             if (s==open) {
00161                 for (int i=0;i<ncol;++i) {
00162                     vectorsp::iterator j=(*v)[i].begin(),je=(*v)[i].end();
00163                     while (j!=je) {
00164                         j->second=value;
00165                         j++;
00166                     }
00167                 }
00168             }
00169             else {
00170                 fill (&(*m)[0],&(*m)[m->size()],value);
00171             }
00172         }
00173 /*
00174  *      
00175  *      void assign(const int nr, const T* value)
00176  *      {
00177  *          if (nr>(int)m.size()) m.resize(nr) ;
00178  *          for (int i=0;i<nr;++i) m[i]=value[i] ;
00179  *      }
00180  *      
00181  *      void assign(const int nr, const int nc, const T** value)
00182  *      {
00183  *          if ((nr*nc)>(int)m.size()) m.resize(nr*nc) ;
00184  *          int k=0;
00185  *          for (int j=0;j<nc;++j) 
00186  *              for (int i=0;i<nr;++i) m[k++]=value[i][j] ;                 
00187  *      }
00188  */
00190         int size() const {
00191             if (s==closed) return m->size();
00192             else {
00193                 int is=0;
00194                 for (int i=0;i<ncol;++i) is += (*v)[i].size() ;
00195                 return is;
00196             }
00197         }
00199         void set_status(status ns=open) {
00200             int ftn_offset=FTN_OFFSET;
00201             if (ns==s) return ;
00202             if (ns==open)
00203             {
00204                 if (!v) v=new vector<vectorsp>(ncol);
00205                 int k=0,nel=m->size();
00206                 for (int j=0;j<ncol;++j)
00207                 {
00208                     int nr=(j<(ncol-1)?((*izh)[j+1]-(*izh)[j]):(nel-(*izh)[j]));
00209                     for (int i=0;i<nr;++i)
00210                     {
00211                         int key; double value;
00212                         key=(*ia)[k]-ftn_offset;
00213                         value=(*m)[k];
00214                         (*v)[j][key]=value;
00215                         k++;
00216                     }
00217                 }
00218                 delete izh; izh=0;
00219                 delete ia; ia=0;
00220                 delete m; m=0;
00221                 s=open;
00222             }
00223             else if (ns==closed)
00224             {
00225                 typedef map<int,double>::const_iterator ci;
00226                 int nel=0;
00227                 int k=0;
00228                 int j;
00229                 nel=size();
00230                 if (!izh) izh=new valarray<int>(ncol);
00231                 if (!ia) ia=new valarray<int>(nel);
00232                 if (!m) m=new valarray<double>(nel);
00233                 for (j=0;j<ncol;++j)
00234                 {
00235                     (*izh)[j]=k+ftn_offset;
00236                     for (ci i=(*v)[j].begin();i!=(*v)[j].end();++i)
00237                     {
00238                         (*ia)[k] = i->first+ftn_offset ;
00239                         (*m)[k] = i->second ;
00240                          k++;
00241                     }
00242                 }
00243                 delete v; v=0;
00244                 s=closed;
00245             }
00246             return;
00247         }
00248         status get_status() {return s;}
00249     private:
00251         MrepSP (const MrepSP& D)
00252         : s(D.s),m(0),ia(0),izh(0),v(0),ncol(D.ncol)
00253         {
00254             if (s==open) v=new vector<vectorsp>(*(D.v));
00255             else {
00256                 izh=new valarray<int>(*(D.izh));
00257                 ia=new valarray<int>(*(D.ia));
00258                 m=new valarray<double>(*(D.m));
00259             }           
00260             nref=1;
00261         }
00262         MrepSP& operator= (const MrepSP&) ;
00263     };
00264     MrepSP *D ;
00265 public:
00267     MatrixSP (const int nc=0,const status S=open) {D=new MrepSP(nc,S);}
00269     MatrixSP (const int _ncol, const int _nel, const status _s=closed) {D=new MrepSP(_ncol,_nel,_s);}
00271     MatrixSP (const MatrixSP& B) {B.D->nref++;D=B.D;}
00273     virtual ~MatrixSP () {if (--D->nref==0) delete D;} ;
00275     virtual MatrixSP& operator = (const MatrixSP& B)
00276     {
00277         if (&B != this) {
00278             B.D->nref++ ;
00279             if (--D->nref==0) delete D ;
00280             D=B.D ;
00281         }
00282         return *this ;
00283     }
00285     virtual MatrixSP& operator = (const double value)
00286     {
00287         D=D->get_own_copy();
00288         D->assign(value);
00289         return *this;
00290     }
00292     void get_own_copy() {D=D->get_own_copy();}
00294     void set_open() {D->set_status(open);}
00296     void set_closed() {D->set_status(closed);}
00298     bool is_open() {return D->s==open?true:false;}
00300     void resize (const int nc, const double value=0) {cout << "not yet implemented" <<endl;}
00302     //void reserve (const int nr_x_nc) { D->m.reserve(nr_x_nc) ;}
00304     virtual int nr (const int i=0) const {
00305         if (D->s==closed) {
00306             if (i==D->ncol-1) return D->ia->size()-(*D->izh)[i];
00307             else return (*D->izh)[i+1]-(*D->izh)[i];
00308         }
00309         else {
00310             return (*D->v)[i].size();
00311         }
00312     } ;
00314     virtual int nc (const int i=0) const {return D->ncol;} ;
00316     virtual int size() const {return D->size();}
00318     virtual bool empty() const {return D->v->empty();}
00320     //virtual int   capacity() const {return D->m.capacity();}
00322     double* get_m() const {assert(D->s==closed);return (&(*(D->m))[0]);}
00324     int* get_ia() const {assert(D->s==closed);return (&(*(D->ia))[0]);}
00326     int* get_izh() const {assert(D->s==closed);return (&(*(D->izh))[0]);}
00327 protected:
00329     vectorsp& operator [] (const int i) const {assert(D->s==open);return (*D->v)[i];}
00330 public:
00332     virtual Ref<double> operator () (const int i, const int j=0) {assert(D->s==open);return Ref<double>(*this,i,j);}
00334     virtual double operator () (const int i, const int j=0) const {assert(D->s==open);return REF_SP(*this,i,j);}
00335 protected:
00337     double* ref(const int i, const int j) const {assert(D->s==open);return &REF_SP(*this,i,j);}
00339     double read(const int i, const int j) const {assert(D->s==open);return REF_SP(*this,i,j);}
00341     void write(const int i, const int j, const double v) {assert(D->s==open);D=D->get_own_copy();REF_SP(*this,i,j)=v;}
00343     void add(const int i, const int j, const double v) {assert(D->s==open);D=D->get_own_copy();REF_SP(*this,i,j)+=v;}
00345     void sub(const int i, const int j, const double v) {assert(D->s==open);D=D->get_own_copy();REF_SP(*this,i,j)-=v;}
00347     void mul(const int i, const int j, const double v) {assert(D->s==open);D=D->get_own_copy();REF_SP(*this,i,j)*=v;}
00349     void div(const int i, const int j, const double v) {assert(D->s==open);D=D->get_own_copy();REF_SP(*this,i,j)/=v;}
00350 public:
00351 /*
00352  *  
00353  *  virtual MatrixC& assign (const int nr, const T* value)
00354  *  {
00355  *      D=D->get_own_copy();
00356  *      D->assign(nr,value);
00357  *      return *this;ve
00358  *  }
00359  *  
00360  *  virtual MatrixC& assign (const int nr, const int nc, const T** value)
00361  *  {
00362  *      D=D->get_own_copy();
00363  *      D->assign(nr,nc,value);
00364  *      return *this;
00365  *  }
00366  */
00368     //virtual operator double*() const {cout << "not yet implemented" <<endl;/*return &D->m[0];*/}
00369     //virtual operator double*() {cout << "not yet implemented" <<endl;/*return &D->m[0];*/}
00371     virtual bool operator == (const MatrixSP &B)    {return (*(D->v))==(*(B.D->v));}
00373     virtual bool operator <  (const MatrixSP &B) {return (*(D->v))<(*(B.D->v));}
00374 protected:
00375 };
00376 
00377 
00378 
00382 ostream& operator<< (ostream& s, const MatrixSP& M)
00383 {
00384     typedef map<int,double>::const_iterator ci;
00385     s.precision(OUTPUT_PREC) ;
00386     s.setf(ios::scientific,ios::floatfield) ;
00387     //  open 
00388     if (M.D->s==MatrixSP::open) 
00389     {
00390         s << M.nc() << endl;
00391         for (int i=0;i<M.nc();++i) 
00392         {
00393             s << M[i].size() << endl;
00394             ci j;
00395             for (j=M[i].begin();j!=M[i].end();++j) s << j->first << " ";
00396             s << endl ;
00397             for (j=M[i].begin();j!=M[i].end();++j) s << j->second << " ";
00398             s << endl ;
00399         }
00400     }
00401     //  closed
00402     else
00403     {
00404         valarray<int>& izh=*(M.D->izh);
00405         valarray<int>& ia=*(M.D->ia);
00406         valarray<double>& m=*(M.D->m);
00407         int *i,*izh_begin=&izh[0],*izh_end=&izh[izh.size()],*ia_begin=&ia[0],*ia_end=&ia[ia.size()];
00408         double* data=&m[0];
00409         s << izh.size() << endl;
00410         for (i=izh_begin;i!=izh_end;++i)    s << *i <<" " ;
00411         s << endl ;
00412         s << ia.size() << endl;
00413         for (i=ia_begin;i<ia_end;++i)
00414         {
00415             s << *i <<" "<< *data <<" " ;
00416             data++;
00417         }
00418         s << endl ;
00419     }
00420     s.setf(0,ios::floatfield) ;
00421     return s ;
00422 }
00426 istream& operator>> (istream& s, MatrixSP& M)
00427 {
00428     // open 
00429     if (M.D->s==MatrixSP::open) 
00430     {
00431         for (int i=0;i<M.nc();++i) 
00432         {
00433             int nr;
00434             s >> nr;
00435             for (int j=0;j<nr;++j) 
00436             {
00437                 int k;double value;
00438                 s >> k >> value;
00439                 M(k,i)=value;
00440             }
00441         }
00442     }
00443     // closed
00444     else 
00445     {
00446         M.D->izh->resize(M.D->ncol);
00447         valarray<int>& izh=*(M.D->izh);
00448         valarray<int>& ia=*(M.D->ia);
00449         valarray<double>& m=*(M.D->m);
00450         int *i,*izh_begin=&izh[0],*izh_end=&izh[izh.size()],*ia_begin=&ia[0],*ia_end=&ia[ia.size()];
00451         double* data=&m[0];
00452         for (i=izh_begin;i!=izh_end;++i) {cin >> *i ;}
00453         for (i=ia_begin;i!=ia_end;++i) {
00454             cin >> *i >> *data ;
00455             ++data;
00456         }
00457     }
00458     return s;
00459 }
00460 #ifdef USE_NAMESPACE_LINAL
00461 }   // namespace LinAL
00462 #endif
00463 #endif //MATRIXSP_H

Generated at Wed Nov 22 08:38:28 2000 for LinAl - a simple and efficient Matrix library - by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000