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_VEC
00034 #define __RVL_VEC
00035
00036 #include "data.hh"
00037 #include "linalg.hh"
00038 #include "write.hh"
00039
00040 namespace RVL {
00041
00055 template<class Scalar>
00056 class Space: public Writeable {
00057
00059 typedef typename ScalarFieldTraits<Scalar>::AbsType NormRetType;
00060
00061 protected:
00062
00063 #ifndef RVL_OPERATOR_NEW_ENABLED
00064 void * operator new(size_t size) {
00065 void * ptr;
00066 ptr = (void *) ::new unsigned char[size];
00067 return ptr;
00068 }
00069 #endif
00070
00083 virtual Space<Scalar> * clone() const = 0;
00084
00089 static Space<Scalar> * export_clone(Space<Scalar> const & sp) {
00090 return sp.clone();
00091 }
00092
00093 public:
00094
00095 Space() {}
00096 Space(const Space<Scalar> & sp) {}
00097 virtual ~Space(){}
00098
00100 static std::shared_ptr< Space<Scalar> > clonePtr(Space<Scalar> const & sp) {
00101 std::shared_ptr< Space<Scalar> > p(export_clone(sp));
00102 return p;
00103 }
00104
00109 virtual DataContainer * buildDataContainer() const = 0;
00110
00113 virtual bool operator ==(const Space<Scalar> & sp) const = 0;
00114 bool operator !=(const Space<Scalar> & sp) const {
00115 try {
00116 return !operator==(sp);
00117 }
00118 catch (RVLException & e) {
00119 e<<"\ncalled from Space::operator!=\n";
00120 throw e;
00121 }
00122 }
00123
00126 virtual bool isCompatible(DataContainer const & dc) const = 0;
00127
00131 virtual Scalar inner(DataContainer const & x,
00132 DataContainer const & y) const = 0;
00133
00135 virtual void zero(DataContainer & x) const = 0;
00136
00140 virtual void linComb(Scalar a, DataContainer const & x,
00141 Scalar b, DataContainer & y) const = 0;
00142
00149 virtual void copy(DataContainer & tgt, DataContainer const & src) const {
00150 try {
00151 Scalar one = ScalarFieldTraits<Scalar>::One();
00152 Scalar zip = ScalarFieldTraits<Scalar>::Zero();
00153 linComb(one,src,zip,tgt);
00154 }
00155 catch (RVLException & e) {
00156 e<<"\ncalled fom Space::copy\n";
00157 throw e;
00158 }
00159 }
00160
00166 virtual void negate(DataContainer & tgt) const {
00167 try {
00168 DataContainer const * jnk = this->buildDataContainer();
00169 Scalar zip = ScalarFieldTraits<Scalar>::Zero();
00170 Scalar one = ScalarFieldTraits<Scalar>::One();
00171 linComb(zip,*jnk,-one,tgt);
00172 delete jnk;
00173 }
00174 catch (RVLException & e) {
00175 e<<"\ncalled fom Space::negate\n";
00176 throw e;
00177 }
00178 }
00179
00181 virtual void negate(DataContainer & tgt,
00182 DataContainer const & src) const {
00183 try {
00184 Scalar one = ScalarFieldTraits<Scalar>::One();
00185 Scalar zip = ScalarFieldTraits<Scalar>::Zero();
00186 linComb(-one,src,zip,tgt);
00187 }
00188 catch (RVLException & e) {
00189 e<<"\ncalled fom Space::negate\n";
00190 throw e;
00191 }
00192 }
00193
00199 virtual void scale(DataContainer & tgt,
00200 Scalar c) const {
00201 try {
00202 DataContainer * jnk = this->buildDataContainer();
00203 zero(*jnk);
00204 Scalar zip = ScalarFieldTraits<Scalar>::Zero();
00205 linComb(zip,*jnk,c,tgt);
00206 delete jnk;
00207 }
00208 catch (RVLException & e) {
00209 e<<"\ncalled fom Space::scale\n";
00210 throw e;
00211 }
00212 }
00213
00215 virtual void scale(DataContainer & tgt,
00216 Scalar c,
00217 DataContainer const & src) const {
00218 try {
00219 Scalar zip = ScalarFieldTraits<Scalar>::Zero();
00220 linComb(c,src,zip,tgt);
00221 }
00222 catch (RVLException & e) {
00223 e<<"\ncalled fom Space::scale\n";
00224 throw e;
00225 }
00226 }
00227
00230 NormRetType normsq(DataContainer const & x) const {
00231 try {
00232 return abs(inner(x,x));
00233 }
00234 catch (RVLException & e) {
00235 e<<"\n*** called from Space::normsq\n";
00236 throw e;
00237 }
00238 }
00239
00241 NormRetType norm(DataContainer const & x) const {
00242 try {
00243 NormRetType f=normsq(x);
00244 return (NormRetType) sqrt(f);
00245 }
00246 catch (RVLException & e) {
00247 e<<"\n*** called from Space::norm\n";
00248 throw e;
00249 }
00250 }
00251
00252 };
00253
00275 template<class Scalar, class DataType = Scalar>
00276 class StdSpace: public Space<Scalar> {
00277
00278 public:
00279
00280 StdSpace() {}
00281 StdSpace(const StdSpace<Scalar, DataType> & sp) {}
00282 virtual ~StdSpace(){}
00283
00285 virtual DataContainerFactory const & getDCF() const = 0;
00287 virtual LinearAlgebraPackage<Scalar> const & getLAP() const = 0;
00288
00289
00290 DataContainer *
00291 buildDataContainer() const { return getDCF().build(); }
00292
00297 bool operator ==(const Space<Scalar> & sp) const {
00298 try {
00299 if (this == &sp) return true;
00300 const StdSpace<Scalar, DataType> & stdsp =
00301 dynamic_cast<const StdSpace<Scalar, DataType> &>(sp);
00302 return (getDCF().compare(stdsp.getDCF()) &&
00303 getLAP().compare(stdsp.getLAP()));
00304 }
00305 catch (bad_cast) {
00306 return 0;
00307 }
00308 }
00309
00310
00311 bool isCompatible(DataContainer const & dc) const {
00312 return getDCF().isCompatible(dc);
00313 }
00314
00315
00316 Scalar inner(DataContainer const & x,
00317 DataContainer const & y) const {
00318 try {
00319 getLAP().inner().setValue();
00320 vector<DataContainer const *> vy(1);
00321 vy[0]=&y;
00322 x.eval(getLAP().inner(),vy);
00323 return getLAP().inner().getValue();
00324 }
00325 catch (RVLException & e) {
00326 e<<"\ncalled from Space::inner\n";
00327 throw e;
00328 }
00329 }
00330
00331
00332 void zero(DataContainer & x) const {
00333 try {
00334 vector<DataContainer const *> vy(0);
00335 x.eval(getLAP().zero(),vy);
00336 }
00337 catch (RVLException & e) {
00338 e<<"\ncalled from StdSpace::zero\n";
00339 throw e;
00340 }
00341 }
00342
00343
00344 void linComb(Scalar a, DataContainer const & x,
00345 Scalar b, DataContainer & y) const {
00346 (getLAP().linComb()).setScalar(a,b);
00347 try {
00348 vector<DataContainer const *> vx(1);
00349 vx[0]=&x;
00350 y.eval(getLAP().linComb(),vx);
00351 }
00352 catch (RVLException & e) {
00353 e<<"\ncalled from StdSpace::linComb\n";
00354 throw e;
00355 }
00356 }
00357
00358 ostream & write(ostream & str) const {
00359 str<<"StdSpace defined by DataContainerFactory\n";
00360 getDCF().write(str);
00361 str<<"and LinearAlgebraPackage\n";
00362 getLAP().write(str);
00363 return str;
00364 }
00365 };
00366
00371 template<class Scalar>
00372 class SpaceDCF: public DataContainerFactory {
00373
00374 private:
00375
00376 Space<Scalar> const & sp;
00377 SpaceDCF();
00378
00379 public:
00380
00381 SpaceDCF(Space<Scalar> const & _sp): sp(_sp) {}
00382 SpaceDCF(SpaceDCF<Scalar> const & f): sp(f.sp) {}
00383 ~SpaceDCF() {}
00384
00385 DataContainer * build() const { return sp.buildDataContainer(); }
00386
00387 Space<Scalar> const & getSpace() const { return sp; }
00388
00389 bool compare( DataContainerFactory const & dcf ) const {
00390 SpaceDCF<Scalar> const * p = NULL;
00391 p = dynamic_cast< SpaceDCF<Scalar> const * >(&dcf);
00392 if (p) return (this->getSpace()==p->getSpace());
00393 return false;
00394 }
00395
00396 bool isCompatible(DataContainer const & dc) const {
00397 return sp.isCompatible(dc);
00398 }
00399
00400 ostream & write(ostream & str) const {
00401 str<<"Space-derived DataContainerFactory based on Space:\n";
00402 sp.write(str);
00403 return str;
00404 }
00405 };
00406
00407 template<class Scalar>
00408 class OpComp;
00409
00410
00411 template<class Scalar>
00412 class Components;
00413
00421 template<class Scalar>
00422 class Vector: public Writeable {
00423
00424 friend class Components<Scalar>;
00425
00426 private:
00427
00428
00429 const Space<Scalar> & sp;
00430
00431
00432 mutable DataContainer * d;
00433
00434
00435
00436
00437 bool own, initzero;
00438
00439 unsigned int & verref;
00440
00441 mutable unsigned int ver;
00442
00443
00444 Vector();
00445
00446 protected:
00447
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 DataContainer * getDataContainer() const {
00468 if( !d) {
00469 d = sp.buildDataContainer();
00470 if(initzero) sp.zero(*d);
00471 }
00472 return d;
00473 }
00474
00479 Vector(const Space<Scalar> & _sp,
00480 DataContainer * _d,
00481 unsigned int & _verref,
00482 bool _own = false)
00483 :sp(_sp), d(_d), own(_own), verref(_verref) {
00484 if (!(sp.isCompatible(*getDataContainer()))) {
00485 RVLException e; e<<"*** Error: Vector constructor (sp,dc)\n";
00486 e<<"*** input data container not compatible with space\n";
00487 e<<"*** this space:\n";
00488 sp.write(e);
00489 e<<"*** data container:\n";
00490 d->write(e);
00491 throw e;
00492 }
00493 ver = verref;
00494 }
00495
00498 Vector<Scalar> * build_from_kit(const Space<Scalar> & _sp,
00499 DataContainer * _d,
00500 unsigned int & _verref,
00501 bool _own = false) {
00502 return new Vector<Scalar>(_sp,_d,_verref,_own);
00503 }
00504
00508 Vector(const Vector<Scalar> * v)
00509 : sp(v->sp), d(v->d), own(false), ver(0), verref(ver) {}
00510
00524 #ifndef RVL_OPERATOR_NEW_ENABLED
00525 void * operator new(size_t size) {
00526 void * ptr;
00527 ptr = (void *) ::new unsigned char[size];
00528 return ptr;
00529 }
00530 #endif
00531 unsigned int & getVersionRef() const { return verref; }
00532
00533 public:
00534
00535 using RVL::Writeable::write;
00536
00538 typedef typename ScalarFieldTraits<Scalar>::AbsType NormRetType;
00539
00542 Vector(const Vector<Scalar> & x)
00543 : sp(x.sp),
00544 d(sp.buildDataContainer()),
00545 own(true),
00546 initzero(false),
00547 verref(ver) {
00548 try {
00549 sp.copy(*getDataContainer(),*(x.getDataContainer()));
00550 ver=0;
00551 }
00552 catch (RVLException & e) {
00553 e<<"\ncalled from Vector copy constructor\n";
00554 }
00555 }
00556
00566 Vector(const Space<Scalar> & _sp, bool _initZero = false)
00567 : sp(_sp), d(NULL), own(true),
00568 initzero(_initZero), verref(ver), ver(0) {}
00569
00572 ~Vector() { if (own&&(d!=NULL)) delete d; }
00573
00575 static std::shared_ptr< Vector<Scalar> > newPtr(Space<Scalar> const & sp) {
00576 std::shared_ptr< Vector<Scalar> > p(new Vector<Scalar>(sp));
00577 return p;
00578 }
00579
00581 const Space<Scalar> & getSpace() const { return sp; }
00582
00584 bool inSpace(const Space<Scalar> & sp1) const { return (sp==sp1); }
00587 bool inSameSpace(const Vector<Scalar> & x) const { return inSpace(x.sp); }
00588
00595 unsigned int getVersion() const { return ver; }
00596 void incrementVersion() {
00597 if (ver < numeric_limits<unsigned int>::max()) { ver++; }
00598 else {
00599 RVLException e;
00600 e<<"Error: Vector::incrementVersion\n";
00601 e<<"run out of unsigned ints!!!\n";
00602 throw e;
00603 }
00604 }
00605
00607 void eval(FunctionObject & f,
00608 vector<Vector<Scalar> const *> & x) {
00609 try {
00610
00611
00612
00613
00614
00615
00616 vector<DataContainer const *> dx(x.size());
00617 for (size_t i=0;i<x.size();i++) {
00618 dx[i] = x[i]->getDataContainer();
00619 }
00620 (this->getDataContainer())->eval(f,dx);
00621 incrementVersion();
00622 }
00623 catch (RVLException & e) {
00624 e<<"\ncalled from Vector::eval (generic)\n";
00625 throw e;
00626 }
00627 }
00628
00630 void eval(FunctionObject & f) {
00631 try {
00632 vector<Vector<Scalar> const *> v(0);
00633 this->eval(f,v);
00634 }
00635 catch (RVLException & e) {
00636 e<<"\n*** called from Vector::eval(fo &)\n";
00637 throw e;
00638 }
00639 }
00640
00642 void eval(FunctionObject & f,
00643 const Vector<Scalar> & x) {
00644 try {
00645 vector<Vector<Scalar> const *> v(1);
00646 v[0]=&x;
00647 this->eval(f,v);
00648 }
00649 catch (RVLException & e) {
00650 e<<"\n*** called from Vector::eval(fo &, vec &)\n";
00651 throw e;
00652 }
00653 }
00654
00656 void eval(FunctionObject & f,
00657 const Vector<Scalar> & x,
00658 const Vector<Scalar> & y) {
00659 try {
00660 vector<Vector<Scalar> const *> v(2);
00661 v[0]=&x;
00662 v[1]=&y;
00663 this->eval(f,v);
00664 }
00665 catch (RVLException & e) {
00666 e<<"\n*** called from Vector::eval(fo &, vec &, vec &)\n";
00667 throw e;
00668 }
00669 }
00670
00672 void eval(FunctionObject & f,
00673 const Vector<Scalar> & x,
00674 const Vector<Scalar> & y,
00675 const Vector<Scalar> & z) {
00676 try {
00677 vector<Vector<Scalar> const *> v(3);
00678 v[0]=&x;
00679 v[1]=&y;
00680 v[2]=&z;
00681 this->eval(f,v);
00682 }
00683 catch (RVLException & e) {
00684 e<<"\n*** called from Vector::eval(fo &, vec &, vec &, vec &)\n";
00685 throw e;
00686 }
00687 }
00688
00690 void eval(FunctionObjectConstEval & f,
00691 vector<Vector<Scalar> const *> & x) const {
00692 try {
00693 vector<DataContainer const *> dx(x.size());
00694 for (int i=0;i<(int)x.size();i++) {
00695 dx[i] = x[i]->getDataContainer();
00696 }
00697 (this->getDataContainer())->eval(f,dx);
00698 }
00699 catch (RVLException & e) {
00700 e<<"\ncalled from Vector::eval (FOR, generic)\n";
00701 throw e;
00702 }
00703 }
00704
00706 void eval(FunctionObjectConstEval & f) const {
00707 try {
00708 vector<Vector<Scalar> const *> v(0);
00709 this->eval(f,v);
00710 }
00711 catch (RVLException & e) {
00712 e<<"\n*** called from Vector::eval(for &)\n";
00713 throw e;
00714 }
00715 }
00716
00718 void eval(FunctionObjectConstEval & f,
00719 const Vector<Scalar> & x) const {
00720 try {
00721 vector<Vector<Scalar> const *> v(1);
00722 v[0]=&x;
00723 this->eval(f,v);
00724 }
00725 catch (RVLException & e) {
00726 e<<"\n*** called from Vector::eval(for &, vec &)\n";
00727 throw e;
00728 }
00729 }
00730
00732 void eval(FunctionObjectConstEval & f,
00733 const Vector<Scalar> & x,
00734 const Vector<Scalar> & y) const {
00735 try {
00736 vector<Vector<Scalar> const *> v(2);
00737 v[0]=&x;
00738 v[1]=&y;
00739 this->eval(f,v);
00740 }
00741 catch (RVLException & e) {
00742 e<<"\n*** called from Vector::eval(for &, vec &, vec &)\n";
00743 throw e;
00744 }
00745 }
00746
00748 void eval(FunctionObjectConstEval & f,
00749 const Vector<Scalar> & x,
00750 const Vector<Scalar> & y,
00751 const Vector<Scalar> & z) const {
00752 try {
00753 vector<Vector<Scalar> const *> v(3);
00754 v[0]=&x;
00755 v[1]=&y;
00756 v[2]=&z;
00757 this->eval(f,v);
00758 }
00759 catch (RVLException & e) {
00760 e<<"\n*** called from Vector::eval(for &, vec &, vec &, vec &)\n";
00761 throw e;
00762 }
00763 }
00764
00766 Scalar inner(const Vector<Scalar> & y) const {
00767 try {
00768 return sp.inner(*getDataContainer(),*(y.getDataContainer()));
00769 }
00770 catch (RVLException & e) {
00771 e<<"\n*** called from Vector::inner(Vector &)\n";
00772 throw e;
00773 }
00774 }
00775
00777 void linComb(Scalar a, const Vector<Scalar> & x,
00778 Scalar b = ScalarFieldTraits<Scalar>::One()) {
00779 try {
00780 sp.linComb(a,*(x.getDataContainer()),
00781 b,*(this->getDataContainer()));
00782 incrementVersion();
00783 }
00784 catch (RVLException & e) {
00785 e<<"\n*** called from Vector::linComb (this = a x + b this)\n";
00786 throw e;
00787 }
00788 }
00789
00791 void zero() {
00792 try {
00793 sp.zero(*(this->getDataContainer()));
00794 incrementVersion();
00795 }
00796 catch (RVLException & e) {
00797 e<<"\n*** called from Vector::zero()\n";
00798 throw e;
00799 }
00800 }
00801
00805 void copy( const Vector<Scalar> & x) {
00806 try {
00807 sp.copy(*(this->getDataContainer()),*(x.getDataContainer()));
00808 incrementVersion();
00809 }
00810 catch (RVLException & e) {
00811 e<<"\n*** called from Vector::copy()\n";
00812 throw e;
00813 }
00814 }
00815
00821 void scale(Scalar c) {
00822 try {
00823 sp.scale(*(this->getDataContainer()),c);
00824 incrementVersion();
00825 }
00826 catch (RVLException & e) {
00827 e<<"\n*** called from Vector::scale()\n";
00828 throw e;
00829 }
00830 }
00831
00833 void scale(Scalar c, const Vector<Scalar> & x) {
00834 try {
00835 sp.scale(*(this->getDataContainer()),c,*(x.getDataContainer()));
00836 incrementVersion();
00837 }
00838 catch (RVLException & e) {
00839 e<<"\n*** called from Vector::scale()\n";
00840 throw e;
00841 }
00842 }
00843
00845 void negate() {
00846 try {
00847 sp.negate(*(this->getDataContainer()));
00848 incrementVersion();
00849 }
00850 catch (RVLException & e) {
00851 e<<"\n*** called from Vector::negate()\n";
00852 throw e;
00853 }
00854 }
00855
00857 void negate(const Vector<Scalar> & x) {
00858 try {
00859 sp.negate(*(this->getDataContainer()),*(x.getDataContainer()));
00860 incrementVersion();
00861 }
00862 catch (RVLException & e) {
00863 e<<"\n*** called from Vector::negate()\n";
00864 throw e;
00865 }
00866 }
00867
00870 NormRetType normsq() const {
00871 try {
00872 return sp.normsq(*(this->getDataContainer()));
00873 }
00874 catch (RVLException & e) {
00875 e<<"\n*** called from Vector::normsq\n";
00876 throw e;
00877 }
00878 }
00879
00881 NormRetType norm() const {
00882 try {
00883 return sp.norm(*(this->getDataContainer()));
00884 }
00885 catch (RVLException & e) {
00886 e<<"\n*** called from Vector::norm\n";
00887 throw e;
00888 }
00889 }
00890
00891 ostream & write(ostream & str) const {
00892 str<<"Vector Object"<<endl;
00893 str<<"member of space:"<<endl;
00894 sp.write(str);
00895 str<<"data container:"<<endl;
00896 (this->getDataContainer())->write(str);
00897 return str;
00898 }
00899 };
00900
00905 template<class Scalar>
00906 class WatchedVecRef {
00907
00908 private:
00909
00910 Vector<Scalar> & x;
00911 mutable unsigned int ver;
00912 WatchedVecRef() {}
00913
00914 public:
00915
00916 WatchedVecRef(const Vector<Scalar> & _x)
00917 : x(const_cast< Vector<Scalar> & >(_x)),
00918 ver(x.getVersion()) {}
00919 WatchedVecRef(const WatchedVecRef<Scalar> & w)
00920 : x(w.x), ver(w.x.getVersion()) {}
00921 virtual ~WatchedVecRef() {}
00922
00923 Vector<Scalar> & get() { return x; }
00924 Vector<Scalar> const & get() const { return x; }
00925
00926 bool update() const {
00927 try {
00928 if (ver < x.getVersion()) {
00929 ver = x.getVersion();
00930 return true;
00931 }
00932 return false;
00933 }
00934 catch (RVLException & e) {
00935 e<<"\ncalled from WatchedVecRef::update\n";
00936 throw e;
00937 }
00938 }
00939 };
00940
00944 template<typename Scalar>
00945 void SpaceTest(Space<Scalar> const & sp,
00946 Vector<Scalar> const & v,
00947 std::string msg) {
00948 if (!v.inSpace(sp)) {
00949 RVLException e;
00950 e<<"Error: "<<msg<<"\n";
00951 e<<"vector not in space\n";
00952 e<<"vector:\n";
00953 v.write(e);
00954 e<<"space:\n";
00955 sp.write(e);
00956 throw e;
00957 }
00958 }
00959
00960 }
00961
00962 #endif
00963
00964
00965