productspace.hh

Go to the documentation of this file.
00001 /*************************************************************************
00002 
00003 Copyright Rice University, 2004, 2005, 2006.
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
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     // zero vector
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     // linear combination
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       //cerr<<"StdProductSpace constructed on "<<nfac<<" factors, not initialized\n";
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       //      cerr<<"StdProductSpace::set factor="<<i<<"\n";
00323       //      if (init()) cerr<<"   now initialized\n";
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     // inner product
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     // zero vector
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     // linear combination
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     /* Constructor. Uses protected Vector constructor to build
00540        (STL) vector of component Vector(s). */
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     // ensures that v's DC is initialized
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

Generated on 5 Jan 2017 for RVL by  doxygen 1.4.7