00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __RVL_PVEC
00034 #define __RVL_PVEC
00035
00036 #include "space.hh"
00037 #include "productdata.hh"
00038
00039 namespace RVL {
00040
00051 template<class Scalar>
00052 class ProductSpace: public Space<Scalar>,
00053 public ROProduct< Space<Scalar> > {
00054
00055 public:
00056
00057 ProductSpace() {}
00058 ProductSpace(const ProductSpace<Scalar> &) {}
00059 virtual ~ProductSpace() {}
00060
00061 virtual bool isCompatible(DataContainer const & dc) const {
00062 try {
00063 ProductDataContainer const & pdc =
00064 dynamic_cast<ProductDataContainer const &>(dc);
00065 if (pdc.getSize() != this->getSize()) return 0;
00066 for (size_t i=0;i<this->getSize();i++) {
00067 if (!((*this)[i].isCompatible(pdc[i]))) return 0;
00068 }
00069 return true;
00070 }
00071 catch (bad_cast) {
00072 return false;
00073 }
00074 }
00075
00076 virtual bool operator ==(const Space<Scalar> & sp) const {
00077 if (this == &sp) return true;
00078 try {
00079 const ProductSpace<Scalar> & psp
00080 = dynamic_cast<const ProductSpace<Scalar> &>(sp);
00081 if (psp.getSize() != this->getSize()) return false;
00082 for (size_t i=0;i<this->getSize();i++) {
00083 if (psp[i] != (*this)[i]) return false;
00084 }
00085 return true;
00086 }
00087 catch (bad_cast) {
00088 return false;
00089 }
00090 }
00091
00094 virtual Scalar inner(DataContainer const & x,
00095 DataContainer const & y) const {
00096 Scalar res = ScalarFieldTraits<Scalar>::Zero();
00097 try {
00098 ProductDataContainer const & xp =
00099 dynamic_cast<ProductDataContainer const &>(x);
00100 ProductDataContainer const & yp =
00101 dynamic_cast<ProductDataContainer const &>(y);
00102 if (xp.getSize() != this->getSize() || yp.getSize() != this->getSize()) {
00103 RVLException e; e<<"Error: ProductSpace::inner\n";
00104 e<<"input data containers not of same size as space\n";
00105 throw e;
00106 }
00107 for (size_t i=0;i<this->getSize();i++) {
00108 try {
00109 res += (*this)[i].inner(xp[i],yp[i]);
00110 }
00111 catch (RVLException & e) {
00112 e<<"\ncalled from ProductSpace::inner\n";
00113 throw e;
00114 }
00115 }
00116 return res;
00117 }
00118 catch (bad_cast) {
00119 RVLException e; e<<"Error: ProductSpace::inner\n";
00120 e<<"inputs not (both) product vectors\n";
00121 throw e;
00122 }
00123 }
00124
00125
00126 virtual void zero(DataContainer & x) const {
00127 try {
00128 ProductDataContainer & xp =
00129 dynamic_cast<ProductDataContainer &>(x);
00130 if (xp.getSize() != this->getSize()) {
00131 RVLException e; e<<"Error: ProductSpace::zero\n";
00132 e<<"input data container not of same size as space\n";
00133 throw e;
00134 }
00135 for (size_t i=0;i<this->getSize();i++) {
00136 (*this)[i].zero(xp[i]);
00137 }
00138 }
00139 catch (RVLException & e) {
00140 e<<"\ncalled from ProductSpace::zero\n";
00141 throw e;
00142 }
00143 catch (bad_cast) {
00144 RVLException e; e<<"Error: ProductSpace::zero\n";
00145 e<<"input not product vector\n";
00146 throw e;
00147 }
00148 }
00149
00150
00151 virtual void linComb(Scalar a, DataContainer const & x,
00152 Scalar b, DataContainer & y) const {
00153 try {
00154 ProductDataContainer const & xp =
00155 dynamic_cast<ProductDataContainer const &>(x);
00156 ProductDataContainer & yp =
00157 dynamic_cast<ProductDataContainer &>(y);
00158 if (xp.getSize() != this->getSize() ||
00159 yp.getSize() != this->getSize()) {
00160 RVLException e; e<<"Error: ProductSpace::linComb\n";
00161 e<<"input data containers not of same size as space\n";
00162 e<<"**** FIRST INPUT PDC:\n";
00163 x.write(e);
00164 e<<"**** SECOND INPUT PDC:\n";
00165 y.write(e);
00166 e<<"**** SPACE:\n";
00167 Space<Scalar>::write(e);
00168 throw e;
00169 }
00170 for (size_t i=0;i<this->getSize();i++) {
00171 (*this)[i].linComb(a,xp[i],b,yp[i]);
00172 }
00173 }
00174 catch (RVLException & e) {
00175 e<<"\ncalled from ProductSpace::linComb\n";
00176 throw e;
00177 }
00178 catch (bad_cast) {
00179 RVLException e; e<<"Error: ProductSpace::linComb\n";
00180 e<<"inputs not all product vectors\n";
00181 throw e;
00182 }
00183 }
00184
00186 virtual ostream & write(ostream & str) const {
00187 str<<"Product Space"<<endl;
00188 str<<"size = "<<this->getSize()<<"\n";
00189 for (size_t i=0; i<this->getSize(); i++) {
00190 str<<"***factor "<<i<<":"<<endl;
00191 (*this)[i].write(str);
00192 }
00193 return str;
00194 }
00195 };
00196
00206 template<class Scalar>
00207 class StdProductSpace: public ProductSpace<Scalar> {
00208
00209 private:
00210
00212 std::vector< Space<Scalar> * > s;
00213
00215 StdProductSpace();
00216
00217 protected:
00218
00219 Space<Scalar> * clone() const {
00220 return new StdProductSpace<Scalar>(*this);
00221 }
00222
00224 bool init() const {
00225 bool res = true;
00226 for (size_t i=0; i< s.size(); i++) if (s[i]==NULL) res=false;
00227 return res;
00228 }
00229
00230 public:
00231
00233 StdProductSpace(const StdProductSpace<Scalar> & sp): s(sp.s.size(),NULL) {
00234 for (size_t i=0;i<s.size();i++) {
00235 if ((sp.s)[i])
00236 s[i]=RVL::Space<Scalar>::export_clone(*((sp.s)[i]));
00237 }
00238 }
00239
00241 StdProductSpace(size_t nfac): s(nfac,NULL) {
00242
00243 }
00244
00247 StdProductSpace(Space<Scalar> const & s1): s() {
00248 s.push_back(RVL::Space<Scalar>::export_clone(s1));
00249 }
00250
00252 StdProductSpace(Space<Scalar> const & s1,
00253 Space<Scalar> const & s2): s() {
00254 s.push_back(RVL::Space<Scalar>::export_clone(s1));
00255 s.push_back(RVL::Space<Scalar>::export_clone(s2));
00256 }
00258 StdProductSpace(Space<Scalar> const & s1,
00259 Space<Scalar> const & s2,
00260 Space<Scalar> const & s3): s() {
00261 s.push_back(RVL::Space<Scalar>::export_clone(s1));
00262 s.push_back(RVL::Space<Scalar>::export_clone(s2));
00263 s.push_back(RVL::Space<Scalar>::export_clone(s3));
00264 }
00266 StdProductSpace(Space<Scalar> const & s1,
00267 Space<Scalar> const & s2,
00268 Space<Scalar> const & s3,
00269 Space<Scalar> const & s4): s() {
00270 s.push_back(RVL::Space<Scalar>::export_clone(s1));
00271 s.push_back(RVL::Space<Scalar>::export_clone(s2));
00272 s.push_back(RVL::Space<Scalar>::export_clone(s3));
00273 s.push_back(RVL::Space<Scalar>::export_clone(s4));
00274 }
00275
00276 ~StdProductSpace() {
00277 for (size_t i=0; i<getSize(); i++) {
00278 if (s[i]) delete s[i];
00279 }
00280 }
00281
00285 virtual DataContainer * buildDataContainer() const {
00286 if (init()) {
00287 StdProductDataContainer * d =
00288 new StdProductDataContainer();
00289 for (size_t i=0; i<getSize(); i++) {
00290 SpaceDCF<Scalar> f(*(s[i]));
00291 d->push(f);
00292 }
00293 return d;
00294 }
00295 else {
00296 RVLException e;
00297 e<<"ERROR: StdProductSpace::buildDataContainer\n";
00298 e<<" called on uninitialized StdProductSpace object\n";
00299 throw e;
00300 }
00301 }
00302
00303 size_t getSize() const { return s.size(); }
00304 Space<Scalar> const & operator[](size_t i) const {
00305 if (init()) return *(s[i]);
00306 else {
00307 RVLException e;
00308 e<<"ERROR: StdProductSpace::operator[]\n";
00309 e<<" called on uninitialized StdProductSpace object\n";
00310 throw e;
00311 }
00312 }
00314 void set(Space<Scalar> const & sp, size_t i) {
00315 if (s[i]) {
00316 RVLException e;
00317 e<<"ERROR: StdProductSpace::set\n";
00318 e<<" cannot assign factor "<<i<<" because it is already assigned\n";
00319 throw e;
00320 }
00321 s[i]=RVL::Space<Scalar>::export_clone(sp);
00322
00323
00324 }
00325 };
00326
00327
00338 template<class Scalar>
00339 class CartesianPowerSpace: public ProductSpace<Scalar> {
00340
00341 private:
00342
00343 CartesianPowerSpace();
00344
00345 protected:
00346
00347 size_t size;
00348 const Space<Scalar> & subspc;
00349
00350 Space<Scalar> * clone() const { return new CartesianPowerSpace<Scalar>(*this); }
00351
00352 public:
00353 CartesianPowerSpace(size_t _size, const Space<Scalar> & _subspc)
00354 :size(_size), subspc(_subspc) {}
00355
00356 CartesianPowerSpace(const CartesianPowerSpace<Scalar> & s)
00357 :size(s.size), subspc(s.subspc) {}
00358
00359 virtual ~CartesianPowerSpace() {}
00360
00362 size_t getSize() const { return size; }
00363
00365 Space<Scalar> const & operator[](size_t i) const {
00366 return subspc;
00367 }
00368
00369 bool isCompatible(DataContainer const & dc) const {
00370 try {
00371 ProductDataContainer const & pdc =
00372 dynamic_cast<ProductDataContainer const &>(dc);
00373 if (pdc.getSize() != getSize()) return 0;
00374 for (size_t i=0;i<getSize();i++) {
00375 if (!(subspc.isCompatible(pdc[i]))) return 0;
00376 }
00377 return true;
00378 }
00379 catch (bad_cast) {
00380 return false;
00381 }
00382 }
00383
00384 bool operator ==(const Space<Scalar> & sp) const {
00385 if (this == &sp) return true;
00386 try {
00387 const CartesianPowerSpace<Scalar> & psp
00388 = dynamic_cast<const CartesianPowerSpace<Scalar> &>(sp);
00389 if (psp.getSize() != getSize()) return false;
00390 if (psp[0] != subspc) return false;
00391 return true;
00392 }
00393 catch (bad_cast) {
00394 try {
00395 const ProductSpace<Scalar> & psp
00396 = dynamic_cast<const ProductSpace<Scalar> &>(sp);
00397 if (psp.getSize() != getSize()) return 0;
00398 for (size_t i=0;i<getSize();i++) {
00399 if (subspc != psp[i]) return 0;
00400 }
00401 return true;
00402 }
00403 catch (bad_cast) {
00404 return false;
00405 }
00406 }
00407 }
00408
00409
00410 Scalar inner(DataContainer const & x,
00411 DataContainer const & y) const {
00412 Scalar res = 0.0;
00413 try {
00414 ProductDataContainer const & xp =
00415 dynamic_cast<ProductDataContainer const &>(x);
00416 ProductDataContainer const & yp =
00417 dynamic_cast<ProductDataContainer const &>(y);
00418 if (xp.getSize() != getSize() || yp.getSize() != getSize()) {
00419 RVLException e; e<<"Error: CartesianPowerSpace::inner\n";
00420 e<<"input data containers not of same size as space\n";
00421 throw e;
00422 }
00423 for (size_t i=0;i<getSize();i++) {
00424 try {
00425 res += subspc.inner(xp[i],yp[i]);
00426 }
00427 catch (RVLException & e) {
00428 e<<"\ncalled from CartesianPowerSpace::inner\n";
00429 throw e;
00430 }
00431 }
00432 return res;
00433 }
00434 catch (bad_cast) {
00435 RVLException e; e<<"Error: CartesianPowerSpace::inner\n";
00436 e<<"inputs not (both) product vectors\n";
00437 throw e;
00438 }
00439 }
00440
00441
00442 void zero(DataContainer & x) const {
00443 try {
00444 ProductDataContainer & xp =
00445 dynamic_cast<ProductDataContainer &>(x);
00446 if (xp.getSize() != getSize()) {
00447 RVLException e; e<<"Error: CartesianPowerSpace::zero\n";
00448 e<<"input data container not of same size as space\n";
00449 throw e;
00450 }
00451 for (size_t i=0;i<getSize();i++) {
00452 subspc.zero(xp[i]);
00453 }
00454 }
00455 catch (RVLException & e) {
00456 e<<"\ncalled from CartesianPowerSpace::zero\n";
00457 throw e;
00458 }
00459 catch (bad_cast) {
00460 RVLException e; e<<"Error: CartesianPowerSpace::zero\n";
00461 e<<"input not product vector\n";
00462 throw e;
00463 }
00464 }
00465
00466
00467 void linComb(Scalar a, DataContainer const & x,
00468 Scalar b, DataContainer & y) const {
00469 try {
00470 ProductDataContainer const & xp =
00471 dynamic_cast<ProductDataContainer const &>(x);
00472 ProductDataContainer & yp =
00473 dynamic_cast<ProductDataContainer &>(y);
00474 if (xp.getSize() != getSize() ||
00475 yp.getSize() != getSize()) {
00476 RVLException e; e<<"Error: CartesianPowerSpace::linComb\n";
00477 e<<"input data containers not of same size as space\n";
00478 throw e;
00479 }
00480 for (size_t i=0;i<getSize();i++) {
00481 subspc.linComb(a,xp[i],b,yp[i]);
00482 }
00483 }
00484 catch (RVLException & e) {
00485 e<<"\ncalled from CartesianPowerSpace::linComb\n";
00486 throw e;
00487 }
00488 catch (bad_cast) {
00489 RVLException e; e<<"Error: CartesianPowerSpace::linComb\n";
00490 e<<"inputs not all product vectors\n";
00491 throw e;
00492 }
00493 }
00494
00497 DataContainer * buildDataContainer() const {
00498 StdProductDataContainer * d =
00499 new StdProductDataContainer();
00500 SpaceDCF<Scalar> f(subspc);
00501 for (size_t i=0; i<getSize(); i++) d->push(f);
00502 return d;
00503 }
00504
00505 ostream & write(ostream & str) const {
00506 str<<"CartesianPowerSpace"<<endl;
00507 str<<"size = "<<getSize()<<"\n";
00508 str <<"based on subspace : "<< endl;
00509 subspc.write(str);
00510 return str;
00511 }
00512
00513 };
00514
00521 template<class Scalar>
00522 class Components: public Product< Vector<Scalar> > {
00523
00524 private:
00525
00526 size_t size;
00527 int newflag;
00528
00529 ProductDataContainer * pdc;
00530 const ProductSpace<Scalar> * psp;
00531
00532 vector< Vector<Scalar>* > comp;
00533
00534 Components();
00535 Components(const Components<Scalar> &);
00536
00537 public:
00538
00539
00540
00541 Components(const Vector<Scalar> & v)
00542 : size(1), pdc(NULL), psp(NULL), comp(1) {
00543 if ((pdc =
00544 dynamic_cast<ProductDataContainer *>
00545 (v.getDataContainer()))
00546 &&
00547 (psp = dynamic_cast<const ProductSpace<Scalar> *>(&(v.getSpace())))) {
00548 if (pdc->getSize() == psp->getSize()) {
00549 size = psp->getSize();
00550 comp.resize(size);
00551 for( size_t i=0;i<size;i++ ) {
00552 comp[i]=
00553 new Vector<Scalar>((*psp)[i],&((*pdc)[i]),
00554 v.getVersionRef(), false);
00555 }
00556 newflag=1;
00557 }
00558 }
00559 else {
00560 comp[0]=const_cast<Vector<Scalar> *>(&v);
00561
00562 v.getDataContainer();
00563 newflag=0;
00564 }
00565 }
00566
00568 ~Components() {
00569 if( newflag )
00570 for( size_t i=0;i<size;i++ ) delete comp[i];
00571 }
00572
00574 size_t getSize() const { return size; }
00576 Vector<Scalar> & operator[](size_t i) {
00577 if (i>size-1) {
00578 RVLException e; e<<"Error: Components::operator[]\n";
00579 e<<"index "<<i<<" out of range [0, "<<size-1<<"]\n";
00580 throw e;
00581 }
00582 return *(comp[i]);
00583 }
00584 Vector<Scalar> const & operator[](size_t i) const {
00585 if (i>size-1) {
00586 RVLException e; e<<"Error: Components::operator[]\n";
00587 e<<"index out of range [0, "<<size-1<<"]\n";
00588 throw e;
00589 }
00590 return *(comp[i]);
00591 }
00592
00593 ostream & write(ostream & str) const {
00594 str<<"Components of a Vector"<<endl;
00595 str<<" number = "<<size<<endl;
00596 for (size_t i=0;i<size;i++) {
00597 str<<"***component "<<i<<":"<<endl;
00598 (*this)[i].write(str);
00599 }
00600 return str;
00601 }
00602 };
00603 }
00604
00605 #endif