00001 #ifndef MATRIXSP_H
00002 #define MATRIXSP_H
00003
00033
00034 #include "matrix.h"
00035
00036 #include <vector>
00037 #include <map>
00038 #include <valarray>
00042 #ifdef USE_NAMESPACE_LINAL
00043 namespace LinAl {
00044 #endif
00045 00046 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 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 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 00304
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 00322 00324 00326
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 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366
00368
00369 00371 00373
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
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
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
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
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 }
00462 #endif
00463 #endif //MATRIXSP_H