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_OP
00034 #define __RVL_OP
00035
00036 #include "space.hh"
00037 #include "linop_base.hh"
00038 #include "productspace.hh"
00039 #include "write.hh"
00040
00041 namespace RVL {
00042
00043
00044
00045 template<class Scalar>
00046 class OperatorEvaluation;
00047
00048 template<class Scalar>
00049 class DerivEvaluation;
00050
00051 template<class Scalar>
00052 class Deriv2Evaluation;
00053
00054 template<class Scalar>
00055 class OpComp;
00056
00057 template<class Scalar>
00058 class FcnlOpComp;
00059
00111 template<class Scalar>
00112 class Operator: public Writeable {
00113
00114 friend class OperatorEvaluation<Scalar>;
00115 friend class FcnlOpComp<Scalar>;
00116
00117 protected:
00118
00124 virtual void apply(const Vector<Scalar> & x,
00125 Vector<Scalar> & y) const = 0;
00126
00128 virtual void applyDeriv(const Vector<Scalar> & x,
00129 const Vector<Scalar> & dx,
00130 Vector<Scalar> & dy) const = 0;
00131
00133 virtual void applyAdjDeriv(const Vector<Scalar> & x,
00134 const Vector<Scalar> & dy,
00135 Vector<Scalar> & dx) const = 0;
00136
00137
00138
00139
00140
00141 virtual void applyDeriv2(const Vector<Scalar> &,
00142 const Vector<Scalar> &,
00143 const Vector<Scalar> &,
00144 Vector<Scalar> &) const {
00145 RVLException e;
00146 e<<"Error: Operator::applyDeriv2 not implemented\n";
00147 throw e;
00148 }
00149
00157 virtual void applyAdjDeriv2(const Vector<Scalar> &,
00158 const Vector<Scalar> &,
00159 const Vector<Scalar> &,
00160 Vector<Scalar> &) const {
00161 RVLException e;
00162 e<<"Error: Operator::applyAdjDeriv2 not implemented\n";
00163 throw e;
00164 }
00165
00170 static void export_apply(Operator<Scalar> const & f,
00171 const Vector<Scalar> & x,
00172 Vector<Scalar> & y) {
00173 f.apply(x,y);
00174 }
00175
00176 static void export_applyDeriv(Operator<Scalar> const & f,
00177 const Vector<Scalar> & x,
00178 const Vector<Scalar> & dx,
00179 Vector<Scalar> & dy) {
00180 f.applyDeriv(x,dx,dy);
00181 }
00182
00183 static void export_applyAdjDeriv(Operator<Scalar> const & f,
00184 const Vector<Scalar> & x,
00185 const Vector<Scalar> & dy,
00186 Vector<Scalar> & dx) {
00187 f.applyAdjDeriv(x,dy,dx);
00188 }
00189
00190 static void export_applyDeriv2(Operator<Scalar> const & f,
00191 const Vector<Scalar> & x,
00192 const Vector<Scalar> & dx0,
00193 const Vector<Scalar> & dx1,
00194 Vector<Scalar> & dy) {
00195 f.applyDeriv2(x,dx0,dx1,dy);
00196 }
00197
00198 static void export_applyAdjDeriv2(Operator<Scalar> const & f,
00199 const Vector<Scalar> & x,
00200 const Vector<Scalar> & dx0,
00201 const Vector<Scalar> & dy,
00202 Vector<Scalar> & dx1) {
00203 f.applyAdjDeriv2(x,dx0,dy,dx1);
00204 }
00205
00213 #ifndef RVL_OPERATOR_NEW_ENABLED
00214 void * operator new(size_t size) {
00215 void * ptr;
00216 ptr = (void *) ::new unsigned char[size];
00217 return ptr;
00218 }
00219 #endif
00220
00225 virtual Operator<Scalar> * clone() const = 0;
00226
00228 static Operator<Scalar> * export_clone(Operator<Scalar> const & op) {
00229 return op.clone();
00230 }
00231
00236 DerivEvaluation<Scalar> *
00237 createDerivEvaluation(OperatorEvaluation<Scalar> & opeval) const {
00238 return new DerivEvaluation<Scalar>(opeval);
00239 }
00240
00246 Deriv2Evaluation<Scalar> *
00247 createDeriv2Evaluation(OperatorEvaluation<Scalar> & opeval) const {
00248 return new Deriv2Evaluation<Scalar>(opeval);
00249 }
00250
00251 public:
00252
00253 using Writeable::write;
00254
00255 Operator() {}
00256 Operator(const Operator<Scalar> &) {}
00257 virtual ~Operator() {}
00258
00260 virtual const Space<Scalar> & getDomain() const = 0;
00261 virtual const Space<Scalar> & getRange() const = 0;
00262
00264 static std::shared_ptr<Operator<Scalar> > clonePtr(Operator<Scalar> const & op) {
00265 std::shared_ptr<Operator<Scalar> > p(RVL::Operator<Scalar>::export_clone(op));
00266 return p;
00267 }
00268
00273 virtual typename ScalarFieldTraits<Scalar>::AbsType
00274 getMaxStep(const Vector<Scalar> &,
00275 const Vector<Scalar> &) const {
00276 return numeric_limits<typename ScalarFieldTraits<Scalar>::AbsType>::max();
00277 }
00278
00279 };
00280
00281 template<class Scalar>
00282 class OperatorProductDomainEvaluation;
00283
00284 template<class Scalar>
00285 class PartialDerivEvaluation;
00286
00287 template<class Scalar>
00288 class RestrictOp;
00289
00297 template<class Scalar>
00298 class OperatorProductDomain: public Operator<Scalar> {
00299
00300 friend class OperatorEvaluation<Scalar>;
00301 friend class RestrictOp<Scalar>;
00302
00303 protected:
00304
00306 virtual void applyPartialDeriv(int i,
00307 const Vector<Scalar> & x,
00308 const Vector<Scalar> & dxi,
00309 Vector<Scalar> & dy) const = 0;
00310
00315 virtual void applyDeriv(const Vector<Scalar> & x,
00316 const Vector<Scalar> & dx,
00317 Vector<Scalar> & dy) const {
00318 try {
00319 Components<Scalar> dxc(dx);
00320 applyPartialDeriv(0,x,dxc[0],dy);
00321 Vector<Scalar> tmp(dy);
00322 for (int i=1; i<dxc.getSize(); i++) {
00323 applyPartialDeriv(i,x,dxc[i],tmp);
00324 dy.linComb(1.0,tmp);
00325 }
00326 }
00327 catch (RVLException & e) {
00328 e<<"\ncalled from OperatorProductDomain::applyDeriv\n";
00329 throw e;
00330 }
00331 }
00332
00334 virtual void applyAdjPartialDeriv(int i,
00335 const Vector<Scalar> & x,
00336 const Vector<Scalar> & dy,
00337 Vector<Scalar> & dxi) const = 0;
00338
00342 virtual void applyAdjDeriv(const Vector<Scalar> & x,
00343 const Vector<Scalar> & dy,
00344 Vector<Scalar> & dx) const {
00345 try {
00346 Components<Scalar> dxc(dx);
00347 for (int i=0; i<dxc.getSize(); i++) {
00348 applyAdjPartialDeriv(i,x,dy,dxc[i]);
00349 }
00350 }
00351 catch (RVLException & e) {
00352 e<<"\ncalled from OperatorProductDomain::applyAdjDeriv\n";
00353 throw e;
00354 }
00355 }
00356
00360 virtual void applyPartialDeriv2(int i, int j,
00361 const Vector<Scalar> & x,
00362 const Vector<Scalar> & dxi,
00363 const Vector<Scalar> & dxj,
00364 Vector<Scalar> & dy) const {
00365 RVLException e;
00366 e<<"ERROR: no override for applyPartialDeriv2 supplied for \n";
00367 e<<"OperatorProductDomain:\n";
00368 this->write(e);
00369 throw e;
00370 }
00371
00376 virtual void applyDeriv2(const Vector<Scalar> & x,
00377 const Vector<Scalar> & dx0,
00378 const Vector<Scalar> & dx1,
00379 Vector<Scalar> & dy) const {
00380 try {
00381 Components<Scalar> cdx0(dx0);
00382 Components<Scalar> cdx1(dx1);
00383 dy.zero();
00384 Vector<Scalar> tmp(this->getRange());
00385 int dim = (this->getProductDomain()).getSize();
00386 for (int i=0; i<dim; i++) {
00387 for (int j=0; j<dim; j++) {
00388 this->applyPartialDeriv2(i,j,x,cdx0[i],cdx1[j],tmp);
00389 dy.linComb(1.0,tmp);
00390 }
00391 }
00392 }
00393 catch (RVLException & e) {
00394 e<<"\ncalled from OperatorProductDomain::applyDeriv2\n";
00395 throw e;
00396 }
00397 }
00398
00405 virtual void applyAdjPartialDeriv2(int i, int j,
00406 const Vector<Scalar> & x,
00407 const Vector<Scalar> & dy,
00408 const Vector<Scalar> & dxj,
00409 Vector<Scalar> & dxi) const {
00410 RVLException e;
00411 e<<"ERROR: no override for applyAdjPartialDeriv2 supplied for \n";
00412 e<<"OperatorProductDomain:\n";
00413 this->write(e);
00414 throw e;
00415 }
00416
00421 virtual void applyAdjDeriv2(const Vector<Scalar> & x,
00422 const Vector<Scalar> & dy,
00423 const Vector<Scalar> & dx1,
00424 Vector<Scalar> & dx0) const {
00425 try {
00426 Components<Scalar> cdx0(dx0);
00427 Components<Scalar> cdx1(dx1);
00428 dx0.zero();
00429 Vector<Scalar> tmp(this->getDomain());
00430 Components<Scalar> ctmp(tmp);
00431 int dim = (this->getProductDomain()).getSize();
00432 for (int i=0; i<dim; i++) {
00433 for (int j=0; j<dim; j++) {
00434 this->applyAdjPartialDeriv2(i,j,x,dy,cdx1[j],ctmp[i]);
00435 cdx0[i].linComb(1.0,ctmp[i]);
00436 }
00437 }
00438 }
00439 catch (RVLException & e) {
00440 e<<"\ncalled from OperatorProductDomain::applyAdjDeriv2\n";
00441 throw e;
00442 }
00443 }
00444
00445 static void export_applyPartialDeriv(OperatorProductDomain<Scalar> const & f,
00446 int i,
00447 const Vector<Scalar> & x,
00448 const Vector<Scalar> & dxi,
00449 Vector<Scalar> & dy) {
00450 try {
00451 f.applyPartialDeriv(i,x,dxi,dy);
00452 }
00453 catch (RVLException & e) {
00454 e<<"\ncalled from OperatorProductDomain::export_applyPartialDeriv\n";
00455 throw e;
00456 }
00457 }
00458
00459 static void export_applyAdjPartialDeriv(OperatorProductDomain<Scalar> const & f,
00460 int i,
00461 const Vector<Scalar> & x,
00462 const Vector<Scalar> & dy,
00463 Vector<Scalar> & dxi) {
00464 try {
00465 f.applyAdjPartialDeriv(i,x,dy,dxi);
00466 }
00467 catch (RVLException & e) {
00468 e<<"\ncalled from OperatorProductDomain::export_applyAdjPartialDeriv\n";
00469 throw e;
00470 }
00471 }
00472
00473 static void export_applyPartialDeriv2(OperatorProductDomain<Scalar> const & f,
00474 int i, int j,
00475 const Vector<Scalar> & x,
00476 const Vector<Scalar> & dxi,
00477 const Vector<Scalar> & dxj,
00478 Vector<Scalar> & dy) {
00479 try {
00480 f.applyPartialDeriv2(i,j,x,dxi,dxj,dy);
00481 }
00482 catch (RVLException & e) {
00483 e<<"\ncalled from OperatorProductDomain::export_applyPartialDeriv2\n";
00484 throw e;
00485 }
00486 }
00487
00488 static void export_applyAdjPartialDeriv2(OperatorProductDomain<Scalar> const & f,
00489 int i, int j,
00490 const Vector<Scalar> & x,
00491 const Vector<Scalar> & dy,
00492 const Vector<Scalar> & dxj,
00493 Vector<Scalar> & dxi) {
00494 try {
00495 f.applyAdjPartialDeriv2(i,j,x,dy,dxj,dxi);
00496 }
00497 catch (RVLException & e) {
00498 e<<"\ncalled from OperatorProductDomain::export_applyAdjPartialDeriv2\n";
00499 throw e;
00500 }
00501 }
00502
00505 virtual OperatorProductDomain<Scalar> * clonePD() const = 0;
00506 Operator<Scalar> * clone() const { return clonePD(); }
00507
00508 public:
00509
00510 OperatorProductDomain() {}
00511 OperatorProductDomain(const OperatorProductDomain<Scalar> &) {}
00512 virtual ~OperatorProductDomain() {}
00513
00515 virtual const ProductSpace<Scalar> & getProductDomain() const = 0;
00517 const Space<Scalar> & getDomain() const {
00518 return getProductDomain();
00519 }
00520
00521 };
00522
00527 template<typename Scalar>
00528 class RestrictOp: public Operator<Scalar> {
00529
00530 private:
00531
00532
00533 OperatorProductDomain<Scalar> const & ff;
00534
00535 mutable Vector<Scalar> xx;
00536
00537 mutable Components<Scalar> cxx;
00538
00539 int i;
00540
00541 RestrictOp();
00542
00543 protected:
00544
00545 void apply(Vector<Scalar> const & x,
00546 Vector<Scalar> & y) const {
00547 try {
00548 cxx[i].copy(x);
00549 RVL::OperatorProductDomain<Scalar>::export_apply(ff, xx, y);
00550 }
00551 catch (RVLException & e) {
00552 e<<"\ncalled from RestrictOp::apply\n";
00553 throw e;
00554 }
00555 }
00556
00557 void applyDeriv(Vector<Scalar> const & x,
00558 Vector<Scalar> const & dx,
00559 Vector<Scalar> & dy) const {
00560 try {
00561 cxx[i].copy(x);
00562 RVL::OperatorProductDomain<Scalar>::export_applyPartialDeriv(ff, i, xx, dx, dy);
00563 }
00564 catch (RVLException & e) {
00565 e<<"\ncalled from RestrictOp::applyDeriv\n";
00566 throw e;
00567 }
00568 }
00569
00570 void applyAdjDeriv(Vector<Scalar> const & x,
00571 Vector<Scalar> const & dy,
00572 Vector<Scalar> & dx) const {
00573 try {
00574 cxx[i].copy(x);
00575 RVL::OperatorProductDomain<Scalar>::export_applyAdjPartialDeriv(ff, i, xx, dy, dx);
00576 }
00577 catch (RVLException & e) {
00578 e<<"\ncalled from RestrictOp::applyAdjDeriv\n";
00579 throw e;
00580 }
00581 }
00582
00583 void applyDeriv2(Vector<Scalar> const & x,
00584 Vector<Scalar> const & dx0,
00585 Vector<Scalar> const & dx1,
00586 Vector<Scalar> & dy) const {
00587 try {
00588 cxx[i].copy(x);
00589 RVL::OperatorProductDomain<Scalar>::export_applyPartialDeriv2(ff, i, i, xx, dx0, dx1, dy);
00590 }
00591 catch (RVLException & e) {
00592 e<<"\ncalled from RestrictOp::applyDeriv\n";
00593 throw e;
00594 }
00595 }
00596
00597 void applyAdjDeriv2(Vector<Scalar> const & x,
00598 Vector<Scalar> const & dy,
00599 Vector<Scalar> const & dx1,
00600 Vector<Scalar> & dx0) const {
00601 try {
00602 cxx[i].copy(x);
00603 RVL::OperatorProductDomain<Scalar>::export_applyAdjPartialDeriv2(ff, i,i, xx, dy, dx1, dx0);
00604 }
00605 catch (RVLException & e) {
00606 e<<"\ncalled from RestrictOp::applyAdjDeriv\n";
00607 throw e;
00608 }
00609 }
00610
00611 Operator<Scalar> * clone() const {
00612 return new RestrictOp(*this);
00613 }
00614
00615 public:
00616
00622 RestrictOp(OperatorProductDomain<Scalar> const & _f,
00623 Vector<Scalar> const & x0, int _i)
00624 : ff(_f), xx(_f.getDomain()), cxx(xx), i(_i) {
00625 try {
00626 xx.copy(x0);
00627 }
00628 catch (RVLException & e) {
00629 e<<"\ncalled from RestrictOp constructor\n";
00630
00631
00632
00633
00634 e<<" copy x0 to xx:\n";
00635 e<<" x0 in space:\n";
00636 x0.getSpace().write(e);
00637 e<<" xx in space:\n";
00638 xx.getSpace().write(e);
00639
00640
00641 throw e;
00642 }
00643 }
00644
00645 RestrictOp(RestrictOp<Scalar> const & g): ff(g.ff), xx(g.xx), cxx(xx), i(g.i) {}
00646
00647 ~RestrictOp() {}
00648
00649 Space<Scalar> const & getDomain() const { return ff.getProductDomain()[i]; }
00650 Space<Scalar> const & getRange() const { return ff.getRange(); }
00651
00652 Scalar getMaxStep(const Vector<Scalar> & x,
00653 const Vector<Scalar> & dx) const {
00654 try {
00655
00656 cxx[i].copy(x);
00657 Vector<Scalar> dxx(ff.getDomain(),true);
00658 Components<Scalar> cdxx(dxx);
00659 cdxx[i].copy(dx);
00660 return ff.getMaxStep(xx,dxx);
00661 }
00662 catch (RVLException & e) {
00663 e<<"\ncalled from RestrictOp::getMaxStep\n";
00664 throw e;
00665 }
00666 }
00667
00668 ostream & write(ostream & str) const {
00669 str<<"RestrictOp on domain subspace index "<<i<<" with\n";
00670 str<<" Vector (for fixed components):\n";
00671 xx.write(str);
00672 str<<" OpProdDom:\n";
00673 ff.write(str);
00674 return str;
00675 }
00676 };
00677
00678 template<typename Scalar>
00679 class LinearRestrictOp;
00680
00693 template<class Scalar>
00694 class LinOpValOp: public OperatorProductDomain<Scalar> {
00695
00696 friend class LinearRestrictOp<Scalar>;
00697
00698 protected:
00699
00701 virtual void apply0(const Vector<Scalar> & x0,
00702 const Vector<Scalar> & x1,
00703 Vector<Scalar> & y) const = 0;
00704
00706 virtual void applyAdj0(const Vector<Scalar> & x0,
00707 const Vector<Scalar> & y,
00708 Vector<Scalar> & x1) const = 0;
00709
00711 virtual void applyPartialDeriv0(const Vector<Scalar> & x0,
00712 const Vector<Scalar> & x1,
00713 const Vector<Scalar> & dx0,
00714 Vector<Scalar> & dy) const = 0;
00715
00717 virtual void applyAdjPartialDeriv0(const Vector<Scalar> & x0,
00718 const Vector<Scalar> & x1,
00719 const Vector<Scalar> & dy,
00720 Vector<Scalar> & dx0) const = 0;
00721
00724 virtual void applyAdjPartialDeriv1(const Vector<Scalar> & x0,
00725 const Vector<Scalar> & dx0,
00726 const Vector<Scalar> & dy,
00727 Vector<Scalar> & x1) const {
00728 RVLException e;
00729 e<<"ERROR: LinOpValOp::applyPartialDeriv1\n";
00730 e<<" not pure virtual and no implementation supplied\n";
00731 throw e;
00732 }
00733
00734
00735 virtual void applyPartialDeriv20(const Vector<Scalar> & x0,
00736 const Vector<Scalar> & x1,
00737 const Vector<Scalar> & dx00,
00738 const Vector<Scalar> & dx01,
00739 Vector<Scalar> & dy) const {
00740 RVLException e;
00741 e<<"ERROR: LinOpValOp::applyPartialDeriv20\n";
00742 e<<" not pure virtual and no implementation supplied\n";
00743 throw e;
00744 }
00745
00746
00747 virtual void applyAdjPartialDeriv20(const Vector<Scalar> & x0,
00748 const Vector<Scalar> & x1,
00749 const Vector<Scalar> & dy,
00750 const Vector<Scalar> & dx01,
00751 Vector<Scalar> & dx00) const {
00752 RVLException e;
00753 e<<"ERROR: LinOpValOp::applyPartialDeriv20\n";
00754 e<<" not pure virtual and no implementation supplied\n";
00755 throw e;
00756 }
00757
00758 static void export_apply0(LinOpValOp<Scalar> const & op,
00759 const Vector<Scalar> & x0,
00760 const Vector<Scalar> & x1,
00761 Vector<Scalar> & y) {
00762 op.apply0(x0,x1,y);
00763 }
00764
00765 static void export_applyAdj0(LinOpValOp<Scalar> const & op,
00766 const Vector<Scalar> & x0,
00767 const Vector<Scalar> & y,
00768 Vector<Scalar> & x1) {
00769 op.applyAdj0(x0,y,x1);
00770 }
00771
00772 static void export_applyPartialDeriv0(LinOpValOp<Scalar> const & op,
00773 const Vector<Scalar> & x0,
00774 const Vector<Scalar> & x1,
00775 const Vector<Scalar> & dx0,
00776 Vector<Scalar> & dy) {
00777 op.applyPartialDeriv0(x0,x1,dx0,dy);
00778 }
00779
00780 static void export_applyAdjPartialDeriv0(LinOpValOp<Scalar> const & op,
00781 const Vector<Scalar> & x0,
00782 const Vector<Scalar> & x1,
00783 const Vector<Scalar> & dy,
00784 Vector<Scalar> & dx0) {
00785 op.applyAdjPartialDeriv0(x0,x1,dy,dx0);
00786 }
00787
00788 static void export_applyAdjPartialDeriv1(LinOpValOp<Scalar> const & op,
00789 const Vector<Scalar> & x0,
00790 const Vector<Scalar> & x1,
00791 const Vector<Scalar> & dy,
00792 Vector<Scalar> & dx0) {
00793 op.applyAdjPartialDeriv1(x0,dx0,dy,x1);
00794 }
00795
00796 static void export_applyPartialDeriv20(LinOpValOp<Scalar> const & op,
00797 const Vector<Scalar> & x0,
00798 const Vector<Scalar> & x1,
00799 const Vector<Scalar> & dx00,
00800 const Vector<Scalar> & dx01,
00801 Vector<Scalar> & dy) {
00802 op.applyPartialDeriv20(x0,x1,dx00,dx01,dy);
00803 }
00804
00805 static void export_applyAdjPartialDeriv20(LinOpValOp<Scalar> const & op,
00806 const Vector<Scalar> & x0,
00807 const Vector<Scalar> & x1,
00808 const Vector<Scalar> & dy,
00809 const Vector<Scalar> & dx01,
00810 Vector<Scalar> & dx00) {
00811 op.applyAdjPartialDeriv20(x0,x1,dy,dx01,dx00);
00812 }
00813
00814 void apply(Vector<Scalar> const & x,
00815 Vector<Scalar> & y) const {
00816 try {
00817 Components<Scalar> cx(x);
00818 apply0(cx[0],cx[1],y);
00819 }
00820 catch (RVLException & e) {
00821 e<<"\ncalled from LinOpValOp::apply\n";
00822 throw e;
00823 }
00824 }
00825
00826 void applyPartialDeriv(int i,
00827 const Vector<Scalar> & x,
00828 const Vector<Scalar> & dxi,
00829 Vector<Scalar> & dy) const {
00830 try {
00831 Components<Scalar> cx(x);
00832 if (i==0) applyPartialDeriv0(cx[0],cx[1],dxi,dy);
00833 else {
00834 apply0(cx[0],dxi,dy);
00835 }
00836 }
00837 catch (RVLException & e) {
00838 e<<"\ncalled from LinOpValOp::applyPartialDeriv\n";
00839 throw e;
00840 }
00841 }
00842
00843 void applyAdjPartialDeriv(int i,
00844 const Vector<Scalar> & x,
00845 const Vector<Scalar> & dy,
00846 Vector<Scalar> & dxi) const {
00847 try {
00848 Components<Scalar> cx(x);
00849 if (i==0) applyAdjPartialDeriv0(cx[0],cx[1],dy,dxi);
00850 else {
00851 applyAdj0(cx[0],dy,dxi);
00852 }
00853 }
00854 catch (RVLException & e) {
00855 e<<"\ncalled from LinOpValOp::applyAdjPartialDeriv\n";
00856 throw e;
00857 }
00858 }
00859
00860
00861
00862
00863 void applyPartialDeriv2(int i,
00864 int j,
00865 const Vector<Scalar> & x,
00866 const Vector<Scalar> & dxi,
00867 const Vector<Scalar> & dxj,
00868 Vector<Scalar> & dy) const {
00869 try {
00870 Components<Scalar> cx(x);
00871 if (i==0) {
00872 if (j==0)
00873 applyPartialDeriv20(cx[0],cx[1],dxi,dxj,dy);
00874 else
00875
00876 applyPartialDeriv0(cx[0],dxj,dxi,dy);
00877 }
00878 else {
00879 if (j==0)
00880
00881 applyPartialDeriv0(cx[0],dxi,dxj,dy);
00882 else
00883 dy.zero();
00884 }
00885 }
00886 catch (RVLException & e) {
00887 e<<"\ncalled from LinOpValOp::applyAdjPartialDeriv\n";
00888 throw e;
00889 }
00890 }
00891
00892 void applyAdjPartialDeriv2(int i,
00893 int j,
00894 const Vector<Scalar> & x,
00895 const Vector<Scalar> & dy,
00896 const Vector<Scalar> & dxj,
00897 Vector<Scalar> & dxi) const {
00898 try {
00899 Components<Scalar> cx(x);
00900 if (i==0) {
00901 if (j==0)
00902 applyAdjPartialDeriv20(cx[0],cx[1],dy,dxj,dxi);
00903 else
00904 applyAdjPartialDeriv0(cx[0],dxj,dy,dxi);
00905 }
00906 else {
00907 if (j==0)
00908 applyAdjPartialDeriv1(cx[0],dxj,dy,dxi);
00909 else
00910 dxi.zero();
00911 }
00912 }
00913 catch (RVLException & e) {
00914 e<<"\ncalled from LinOpValOp::applyAdjPartialDeriv2\n";
00915 throw e;
00916 }
00917 }
00918 };
00919
00920
00929 template<class Scalar>
00930 class ConstLinOpValOp: public LinOpValOp<Scalar> {
00931
00932 private:
00933
00934 StdProductSpace<Scalar> dom;
00935 LinearOp<Scalar> const &lop;
00936
00937 protected:
00938
00939 void apply0(const Vector<Scalar> & x0,
00940 const Vector<Scalar> & x1,
00941 Vector<Scalar> & y) const {
00942 lop.applyOp(x1,y);
00943 }
00944
00946 void applyAdj0(const Vector<Scalar> & x0,
00947 const Vector<Scalar> & y,
00948 Vector<Scalar> & x1) const {
00949 lop.applyAdjOp(y,x1);
00950 }
00951
00952 void applyPartialDeriv0(const Vector<Scalar> & x0,
00953 const Vector<Scalar> & x1,
00954 const Vector<Scalar> & dx0,
00955 Vector<Scalar> & dy) const {
00956 dy.zero();
00957 }
00958
00959 void applyAdjPartialDeriv0(const Vector<Scalar> & x0,
00960 const Vector<Scalar> & x1,
00961 const Vector<Scalar> & dy,
00962 Vector<Scalar> & dx0) const {
00963 dx0.zero();
00964 }
00965
00966 void applyPartialDeriv20(const Vector<Scalar> & x0,
00967 const Vector<Scalar> & x1,
00968 const Vector<Scalar> & dx00,
00969 const Vector<Scalar> & dx01,
00970 Vector<Scalar> & dy) const {
00971 dy.zero();
00972 }
00973
00974 void applyAdjPartialDeriv20(const Vector<Scalar> & x0,
00975 const Vector<Scalar> & x1,
00976 const Vector<Scalar> & dy,
00977 const Vector<Scalar> & dx01,
00978 Vector<Scalar> & dx00) const {
00979 dx00.zero();
00980 }
00981
00982 OperatorProductDomain<Scalar> * clonePD() const {
00983 return new ConstLinOpValOp<Scalar>(*this);
00984 }
00985
00986 public:
00987
00988 ConstLinOpValOp(LinearOp<Scalar> const & _lop, Space<Scalar> const & _NLsp)
00989 : lop(_lop), dom(_NLsp,_lop.getDomain()) {}
00990
00991 ConstLinOpValOp(ConstLinOpValOp<Scalar> const & lovo)
00992 : lop(lovo.lop), dom(lovo.dom) {}
00993
00994 ProductSpace<Scalar> const & getProductDomain() const { return dom; }
00995 Space<Scalar> const & getRange() const { return lop.getRange(); }
00996
00997 ostream & write(ostream & str) const {
00998 str<<"ConstLinOpValOp of \n";
00999 lop.write(str);
01000 return str;
01001 }
01002 };
01003
01004
01008 template<class Scalar>
01009 class TangentMap: public LinOpValOp<Scalar> {
01010
01011 private:
01012
01013 Operator<Scalar> const & op;
01014 StdProductSpace<Scalar> dom;
01015
01016 protected:
01017
01018 void apply0(const Vector<Scalar> & x0,
01019 const Vector<Scalar> & x1,
01020 Vector<Scalar> & y) const {
01021 try {
01022 RVL::Operator<Scalar>::export_applyDeriv(op,x0,x1,y);
01023 }
01024 catch (RVLException & e) {
01025 e<<"\ncalled from TangentMap::apply0\n";
01026 throw e;
01027 }
01028 }
01029
01030 void applyAdj0(const Vector<Scalar> & x0,
01031 const Vector<Scalar> & y,
01032 Vector<Scalar> & x1) const {
01033 try {
01034 RVL::Operator<Scalar>::export_applyAdjDeriv(op,x0,y,x1);
01035 }
01036 catch (RVLException & e) {
01037 e<<"\ncalled from TangentMap::applyAdj0\n";
01038 throw e;
01039 }
01040 }
01041
01042 void applyPartialDeriv0(const Vector<Scalar> & x0,
01043 const Vector<Scalar> & x1,
01044 const Vector<Scalar> & dx0,
01045 Vector<Scalar> & dy) const {
01046 try {
01047 RVL::Operator<Scalar>::export_applyDeriv2(op,x0,x1,dx0,dy);
01048 }
01049 catch (RVLException & e) {
01050 e<<"\ncalled from TangentMap::applyPartialDeriv0\n";
01051 throw e;
01052 }
01053 }
01054
01055 void applyAdjPartialDeriv0(const Vector<Scalar> & x0,
01056 const Vector<Scalar> & x1,
01057 const Vector<Scalar> & dy,
01058 Vector<Scalar> & dx0) const {
01059 try {
01060 RVL::Operator<Scalar>::export_applyAdjDeriv2(op,x0,dy,x1,dx0);
01061 }
01062 catch (RVLException & e) {
01063 e<<"\ncalled from TangentMap::applyPartialDeriv0\n";
01064 throw e;
01065 }
01066 }
01067
01068 void applyPartialDeriv20(const Vector<Scalar> & x0,
01069 const Vector<Scalar> & x1,
01070 const Vector<Scalar> & dx00,
01071 const Vector<Scalar> & dx01,
01072 Vector<Scalar> & dy) const {
01073 RVLException e;
01074 e<<"ERROR: TangentMap::applyPartialDeriv20\n";
01075 e<<" not defined - would involve 3rd order partial of underlying map\n";
01076 throw e;
01077 }
01078
01079 void applyAdjPartialDeriv20(const Vector<Scalar> & x0,
01080 const Vector<Scalar> & x1,
01081 const Vector<Scalar> & dy,
01082 const Vector<Scalar> & dx01,
01083 Vector<Scalar> & dx00) const {
01084 RVLException e;
01085 e<<"ERROR: TangentMap::applyPartialDeriv20\n";
01086 e<<" not defined - would involve 3rd order partial of underlying map\n";
01087 throw e;
01088 }
01089
01090 OperatorProductDomain<Scalar> * clonePD() const {
01091 return new TangentMap<Scalar>(*this);
01092 }
01093
01094 public:
01095
01096 TangentMap(Operator<Scalar> const & _op)
01097 : op(_op), dom(op.getDomain(),op.getDomain()) {}
01098
01099 TangentMap(TangentMap<Scalar> const & t)
01100 : op(t.op), dom(t.dom) {}
01101
01102 ProductSpace<Scalar> const & getProductDomain() const { return dom; }
01103 Space<Scalar> const & getRange() const { return op.getRange(); }
01104
01105 ostream & write(ostream & str) const {
01106 str<<"Tangent Map of \n";
01107 op.write(str);
01108 return str;
01109 }
01110 };
01111
01118 template<typename Scalar>
01119 class LinearRestrictOp: public LinearOp<Scalar> {
01120
01121 private:
01122
01123
01124 LinOpValOp<Scalar> const & ff;
01125
01126 Vector<Scalar> x0;
01127
01128 LinearRestrictOp();
01129
01130 protected:
01131
01132 void apply(Vector<Scalar> const & x,
01133 Vector<Scalar> & y) const {
01134 try {
01135 ff.apply0(x0,x,y);
01136 }
01137 catch (RVLException & e) {
01138 e<<"\ncalled from LinearRestrictOp::apply\n";
01139 throw e;
01140 }
01141 }
01142
01143 void applyAdj(Vector<Scalar> const & y,
01144 Vector<Scalar> & x) const {
01145 try {
01146 ff.applyAdj0(x0,y,x);
01147 }
01148 catch (RVLException & e) {
01149 e<<"\ncalled from LinearRestrictOp::applyAdj\n";
01150 throw e;
01151 }
01152 }
01153
01154 Operator<Scalar> * clone() const {
01155 return new LinearRestrictOp(*this);
01156 }
01157
01158 public:
01159
01164 LinearRestrictOp(LinOpValOp<Scalar> const & _f,
01165 Vector<Scalar> const & _x)
01166 : ff(_f), x0((_f.getProductDomain())[0]) {
01167 try {
01168 x0.copy(_x);
01169 }
01170 catch (RVLException & e) {
01171 e<<"\ncalled from LinearRestrictOp constructor\n";
01172 throw e;
01173 }
01174 }
01175
01176 LinearRestrictOp(LinearRestrictOp<Scalar> const & g): ff(g.ff), x0(g.x0) {}
01177
01178 ~LinearRestrictOp() {}
01179
01180 Space<Scalar> const & getDomain() const { return ff.getProductDomain()[1]; }
01181 Space<Scalar> const & getRange() const { return ff.getRange(); }
01182
01183 ostream & write(ostream & str) const {
01184 str<<"LinearRestrictOp with\n";
01185 str<<" Vector (for 0th fixed component):\n";
01186 x0.write(str);
01187 str<<" LinOpValOp:\n";
01188 ff.write(str);
01189 return str;
01190 }
01191 };
01192
01196 template<class Scalar>
01197 class CompLOVOp: public LinOpValOp<Scalar> {
01198
01199 private:
01200
01201 std::shared_ptr<Operator<Scalar> > op;
01202 std::shared_ptr<LinOpValOp<Scalar> > lovop;
01203 StdProductSpace<Scalar> dom;
01204
01205 protected:
01206
01207 void apply0(const Vector<Scalar> & x0,
01208 const Vector<Scalar> & x1,
01209 Vector<Scalar> & y) const {
01210 try {
01211 Vector<Scalar> z(op->getRange());
01212 RVL::Operator<Scalar>::export_apply(*op,x0,z);
01213 RVL::LinOpValOp<Scalar>::export_apply0(*lovop,z,x1,y);
01214 }
01215 catch (RVLException & e) {
01216 e<<"\ncalled from CompLOVOp::apply0\n";
01217 throw e;
01218 }
01219 }
01220
01221 void applyAdj0(const Vector<Scalar> & x0,
01222 const Vector<Scalar> & y,
01223 Vector<Scalar> & x1) const {
01224 try {
01225 Vector<Scalar> z(op->getRange());
01226 RVL::Operator<Scalar>::export_apply(*op,x0,z);
01227 RVL::LinOpValOp<Scalar>::export_applyAdj0(*lovop,z,y,x1);
01228 }
01229 catch (RVLException & e) {
01230 e<<"\ncalled from CompLOVOp::applyAdj0\n";
01231 throw e;
01232 }
01233 }
01234
01235 void applyPartialDeriv0(const Vector<Scalar> & x0,
01236 const Vector<Scalar> & x1,
01237 const Vector<Scalar> & dx0,
01238 Vector<Scalar> & dy) const {
01239 try {
01240 Vector<Scalar> z0(op->getRange());
01241 RVL::Operator<Scalar>::export_apply(*op,x0,z0);
01242 Vector<Scalar> dz(op->getRange());
01243 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dx0,dz);
01244 RVL::LinOpValOp<Scalar>::export_applyPartialDeriv0(*lovop,z0,x1,dz,dy);
01245 }
01246 catch (RVLException & e) {
01247 e<<"\ncalled from CompLOVOp::applyPartialDeriv0\n";
01248 throw e;
01249 }
01250 }
01251
01252 void applyAdjPartialDeriv0(const Vector<Scalar> & x0,
01253 const Vector<Scalar> & x1,
01254 const Vector<Scalar> & dy,
01255 Vector<Scalar> & dx0) const {
01256 try {
01257 Vector<Scalar> z0(op->getRange());
01258 RVL::Operator<Scalar>::export_apply(*op,x0,z0);
01259 Vector<Scalar> dz(op->getRange());
01260 RVL::LinOpValOp<Scalar>::export_applyAdjPartialDeriv0(*lovop,z0,x1,dy,dz);
01261 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dz,dx0);
01262 }
01263 catch (RVLException & e) {
01264 e<<"\ncalled from CompLOVOp::applyAdjPartialDeriv0\n";
01265 throw e;
01266 }
01267 }
01268
01269 void applyPartialDeriv20(const Vector<Scalar> & x0,
01270 const Vector<Scalar> & x1,
01271 const Vector<Scalar> & dx00,
01272 const Vector<Scalar> & dx01,
01273 Vector<Scalar> & dy) const {
01274 try {
01275 Vector<Scalar> z0(op->getRange());
01276 RVL::Operator<Scalar>::export_apply(*op,x0,z0);
01277 Vector<Scalar> dz0(op->getRange());
01278 Vector<Scalar> dz1(op->getRange());
01279 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dx00,dz0);
01280 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dx01,dz1);
01281 RVL::LinOpValOp<Scalar>::export_applyPartialDeriv20(*lovop,z0,x1,dz0,dz1,dy);
01282 }
01283 catch (RVLException & e) {
01284 e<<"\ncalled from CompLOVOp::applyPartialDeriv20\n";
01285 throw e;
01286 }
01287
01288 }
01289
01290 void applyAdjPartialDeriv20(const Vector<Scalar> & x0,
01291 const Vector<Scalar> & x1,
01292 const Vector<Scalar> & dy,
01293 const Vector<Scalar> & dx01,
01294 Vector<Scalar> & dx00) const {
01295 try {
01296 Vector<Scalar> z0(op->getRange());
01297 RVL::Operator<Scalar>::export_apply(*op,x0,z0);
01298 Vector<Scalar> dz0(op->getRange());
01299 Vector<Scalar> dz1(op->getRange());
01300 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dx01,dz1);
01301 RVL::LinOpValOp<Scalar>::export_applyAdjPartialDeriv20(*lovop,z0,x1,dy,dz1,dz0);
01302 RVL::Operator<Scalar>::export_applyDeriv(*op,x0,dz0,dx00);
01303 }
01304 catch (RVLException & e) {
01305 e<<"\ncalled from CompLOVOp::applyAdjPartialDeriv20\n";
01306 throw e;
01307 }
01308 }
01309
01310 OperatorProductDomain<Scalar> * clonePD() const {
01311 return new CompLOVOp<Scalar>(*this);
01312 }
01313
01314 public:
01315
01316 CompLOVOp(Operator<Scalar> const & _op,
01317 LinOpValOp<Scalar> const & _lovop)
01318 : dom(_op.getDomain(),_lovop.getProductDomain()[1]) {
01319 op = RVL::Operator<Scalar>::clonePtr(_op);
01320 std::shared_ptr<RVL::Operator<Scalar> > tmp = RVL::Operator<Scalar>::clonePtr(_lovop);
01321 lovop = dynamic_pointer_cast<RVL::LinOpValOp<Scalar> >(tmp);
01322 if (!(lovop.get())) {
01323 RVLException e;
01324 e<<"ERROR: CompLOVOp constructor\n";
01325 e<<" bad, bad, bad...\n";
01326 throw e;
01327 }
01328 }
01329
01330
01331 CompLOVOp(CompLOVOp<Scalar> const & t)
01332 : op(t.op), lovop(t.lovop), dom(t.dom) {}
01333
01334 ProductSpace<Scalar> const & getProductDomain() const { return dom; }
01335 Space<Scalar> const & getRange() const { return lovop->getRange(); }
01336
01337 ostream & write(ostream & str) const {
01338 str<<"Composition of Operator followed by LinOpValOp\n";
01339 str<<"Operator acts only on first component of LOVO domain\n";
01340 str<<"Operator (first factor):\n";
01341 op->write(str);
01342 str<<"LinOpValOp (second factor):\n";
01343 lovop->write(str);
01344 return str;
01345 }
01346 };
01347
01351 template<class Scalar>
01352 class LinCompLOVOp: public LinOpValOp<Scalar> {
01353
01354 private:
01355
01356 std::shared_ptr<LinearOp<Scalar> > lop;
01357 std::shared_ptr<LinOpValOp<Scalar> > lovop;
01358 StdProductSpace<Scalar> dom;
01359
01360 protected:
01361
01362 void apply0(const Vector<Scalar> & x0,
01363 const Vector<Scalar> & x1,
01364 Vector<Scalar> & y) const {
01365 try {
01366 Vector<Scalar> z(lop->getRange());
01367 lop->applyOp(x1,z);
01368 RVL::LinOpValOp<Scalar>::export_apply0(*lovop,x0,z,y);
01369 }
01370 catch (RVLException & e) {
01371 e<<"\ncalled from LinCompLOVOp::apply0\n";
01372 throw e;
01373 }
01374 }
01375
01376 void applyAdj0(const Vector<Scalar> & x0,
01377 const Vector<Scalar> & y,
01378 Vector<Scalar> & x1) const {
01379 try {
01380 Vector<Scalar> z(lop->getRange());
01381 RVL::LinOpValOp<Scalar>::export_applyAdj0(*lovop,x0,y,z);
01382 lop->applyAdjOp(z,x1);
01383 }
01384 catch (RVLException & e) {
01385 e<<"\ncalled from LinCompLOVOp::applyAdj0\n";
01386 throw e;
01387 }
01388 }
01389
01390 void applyPartialDeriv0(const Vector<Scalar> & x0,
01391 const Vector<Scalar> & x1,
01392 const Vector<Scalar> & dx0,
01393 Vector<Scalar> & dy) const {
01394 try {
01395 Vector<Scalar> z(lop->getRange());
01396 lop->applyOp(x1,z);
01397 RVL::LinOpValOp<Scalar>::export_applyPartialDeriv0(*lovop,x0,z,dx0,dy);
01398 }
01399 catch (RVLException & e) {
01400 e<<"\ncalled from LinCompLOVOp::applyPartialDeriv0\n";
01401 throw e;
01402 }
01403 }
01404
01405 void applyAdjPartialDeriv0(const Vector<Scalar> & x0,
01406 const Vector<Scalar> & x1,
01407 const Vector<Scalar> & dy,
01408 Vector<Scalar> & dx0) const {
01409 try {
01410 Vector<Scalar> z(lop->getRange());
01411 lop->applyOp(x1,z);
01412 RVL::LinOpValOp<Scalar>::export_applyAdjPartialDeriv0(*lovop,x0,z,dy,dx0);
01413 }
01414 catch (RVLException & e) {
01415 e<<"\ncalled from LinCompLOVOp::applyAdjPartialDeriv0\n";
01416 throw e;
01417 }
01418 }
01419
01420 void applyPartialDeriv20(const Vector<Scalar> & x0,
01421 const Vector<Scalar> & x1,
01422 const Vector<Scalar> & dx00,
01423 const Vector<Scalar> & dx01,
01424 Vector<Scalar> & dy) const {
01425 try {
01426 Vector<Scalar> z(lop->getRange());
01427 lop->applyOp(x1,z);
01428 RVL::LinOpValOp<Scalar>::export_applyPartialDeriv20(*lovop,x0,z,dx00,dx01,dy);
01429 }
01430 catch (RVLException & e) {
01431 e<<"\ncalled from LinCompLOVOp::applyPartialDeriv20\n";
01432 throw e;
01433 }
01434 }
01435
01436 void applyAdjPartialDeriv20(const Vector<Scalar> & x0,
01437 const Vector<Scalar> & x1,
01438 const Vector<Scalar> & dy,
01439 const Vector<Scalar> & dx01,
01440 Vector<Scalar> & dx00) const {
01441 try {
01442 Vector<Scalar> z(lop->getRange());
01443 lop->applyOp(x1,z);
01444 RVL::LinOpValOp<Scalar>::export_applyAdjPartialDeriv20(*lovop,x0,z,dy,dx01,dx00);
01445 }
01446 catch (RVLException & e) {
01447 e<<"\ncalled from LinCompLOVOp::applyAdjPartialDeriv20\n";
01448 throw e;
01449 }
01450 }
01451
01452 OperatorProductDomain<Scalar> * clonePD() const {
01453 return new LinCompLOVOp<Scalar>(*this);
01454 }
01455
01456 public:
01457
01458 LinCompLOVOp(LinearOp<Scalar> const & _lop,
01459 LinOpValOp<Scalar> const & _lovop)
01460 : dom(_lovop.getProductDomain()[0],_lop.getDomain()) {
01461
01462 std::shared_ptr<RVL::Operator<Scalar> > tmp_lop
01463 = RVL::Operator<Scalar>::clonePtr(_lop);
01464 lop = dynamic_pointer_cast<RVL::LinearOp<Scalar> >(tmp_lop);
01465
01466 std::shared_ptr<RVL::Operator<Scalar> > tmp_lovop
01467 = RVL::Operator<Scalar>::clonePtr(_lovop);
01468 lovop = dynamic_pointer_cast<RVL::LinOpValOp<Scalar> >(tmp_lovop);
01469
01470 if ( !(lovop.get())||!(lop.get()) ) {
01471 RVLException e;
01472 e<<"ERROR: LinCompLOVOp constructor\n";
01473 e<<" bad, bad, bad...\n";
01474 throw e;
01475 }
01476 }
01477
01478 LinCompLOVOp(LinCompLOVOp<Scalar> const & t)
01479 : lop(t.lop), lovop(t.lovop), dom(t.dom) {}
01480
01481 ProductSpace<Scalar> const & getProductDomain() const { return dom; }
01482 Space<Scalar> const & getRange() const { return lovop->getRange(); }
01483
01484 ostream & write(ostream & str) const {
01485 str<<"Composition of Operator followed by LinOpValOp\n";
01486 str<<"Operator acts only on second component of LOVO domain\n";
01487 str<<"LinearOp:\n";
01488 lop->write(str);
01489 str<<"LinOpValOp:\n";
01490 lovop->write(str);
01491 return str;
01492 }
01493 };
01494
01495
01496 template<class Scalar>
01497 class InvertibleDerivEvaluation;
01498
01503 template<class Scalar>
01504 class OperatorWithInvertibleDeriv : public Operator<Scalar> {
01505
01506 friend class InvertibleDerivEvaluation<Scalar>;
01507 typedef typename ScalarFieldTraits<Scalar>::AbsType NormRetType;
01508
01509 protected:
01510
01511 virtual void applyInverseDeriv(const Vector<Scalar> & x,
01512 const Vector<Scalar> & dy,
01513 Vector<Scalar> & dx) const = 0;
01514 virtual void applyAdjInverseDeriv(const Vector<Scalar> & x,
01515 const Vector<Scalar> & dx,
01516 Vector<Scalar> & dy) const = 0;
01517
01518 DerivEvaluation<Scalar>
01519 * createDerivEvaluation(OperatorEvaluation<Scalar> & opeval) const;
01520
01521 public:
01522
01523 OperatorWithInvertibleDeriv() {}
01524 ~OperatorWithInvertibleDeriv() {}
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 };
01536
01607 template<class Scalar>
01608 class OperatorEvaluation: public Writeable {
01609
01610 friend class OpComp<Scalar>;
01611 friend class FcnlOpComp<Scalar>;
01612 friend class DerivEvaluation<Scalar>;
01613 friend class Deriv2Evaluation<Scalar>;
01614 friend class PartialDerivEvaluation<Scalar>;
01615
01616 private:
01617
01618 const Operator<Scalar> & fref;
01619 WatchedVecRef<Scalar> wx;
01620 mutable Operator<Scalar> * f;
01621
01622 mutable Vector<Scalar> val;
01623 mutable bool applied;
01624 DerivEvaluation<Scalar> * deriv;
01625 Deriv2Evaluation<Scalar> * deriv2;
01626
01627
01628 OperatorEvaluation();
01629
01630 void reset() const {
01631 try {
01632 if (f) delete f;
01633 f = fref.clone();
01634 applied=false;
01635 }
01636 catch (RVLException & e) {
01637 e<<"\ncalled from OperatorEvaluation::reset\n";
01638 throw e;
01639 }
01640 }
01641
01642 protected:
01643
01647 void applyDeriv(const Vector<Scalar> & yin,
01648 Vector<Scalar> & yout) const {
01649 try {
01650 if (wx.update()) reset();
01651 f->applyDeriv(wx.get(),yin,yout);
01652 }
01653 catch (RVLException & e) {
01654 e<<"\ncalled from OperatorEvaluation::applyDeriv()\n";
01655 throw e;
01656 }
01657 }
01658
01662 void applyAdjDeriv(const Vector<Scalar> & yin,
01663 Vector<Scalar> & yout) const {
01664 try {
01665 if (wx.update()) reset();
01666 f->applyAdjDeriv(wx.get(),yin,yout);
01667 }
01668 catch (RVLException & e) {
01669 e<<"\ncalled from OperatorEvaluation::applyAdjDeriv()\n";
01670 throw e;
01671 }
01672 }
01673
01677 void applyDeriv2(const Vector<Scalar> & x0,
01678 const Vector<Scalar> & x1,
01679 Vector<Scalar> & y) const {
01680 try {
01681 if (wx.update()) reset();
01682 f->applyDeriv2(wx.get(),x0,x1,y);
01683 }
01684 catch (RVLException & e) {
01685 e<<"\ncalled from OperatorEvaluation::applyDeriv2()\n";
01686 throw e;
01687 }
01688 }
01689
01693 void applyAdjDeriv2(const Vector<Scalar> & x0,
01694 const Vector<Scalar> & y,
01695 Vector<Scalar> & x1) const {
01696 try {
01697 if (wx.update()) reset();
01698 f->applyAdjDeriv2(wx.get(),x0,y,x1);
01699 }
01700 catch (RVLException & e) {
01701 e<<"\ncalled from OperatorEvaluation::applyAdjDeriv2()\n";
01702 throw e;
01703 }
01704 }
01705
01713 const ProductSpace<Scalar> & getProductDomain() const {
01714
01715 try {
01716 OperatorProductDomain<Scalar> * pf = NULL;
01717 if ((pf = dynamic_cast<OperatorProductDomain<Scalar> *>(f))) {
01718 return pf->getProductDomain();
01719 }
01720 else {
01721 RVLException e;
01722 e<<"Error: OperatorEvaluation::getProductDomain\n";
01723 e<<"referenced Operator does not have ProductSpace domain\n";
01724 throw e;
01725 }
01726 }
01727 catch (RVLException & e) {
01728 e<<"\ncalled from OperatorEvaluation::getProductDomain\n";
01729 throw e;
01730 }
01731 }
01732
01733
01734 void applyPartialDeriv(int i,
01735 const Vector<Scalar> & yin,
01736 Vector<Scalar> & yout) const {
01737 try {
01738 if (wx.update()) reset();
01739 OperatorProductDomain<Scalar> * pf = NULL;
01740 if ((pf = dynamic_cast<OperatorProductDomain<Scalar> *>(f))) {
01741 pf->applyPartialDeriv(i,wx.get(),yin,yout);
01742 }
01743 else {
01744 RVLException e;
01745 e<<"Error: OperatorEvaluation::applyPartialDeriv\n";
01746 e<<"referenced Operator does not have ProductSpace domain\n";
01747 e<<"so partial derivatives are not defined\n";
01748 throw e;
01749 }
01750 }
01751 catch (RVLException & e) {
01752 e<<"\ncalled from OperatorEvaluation";
01753 e<<"::applyPartialDeriv()\n";
01754 throw e;
01755 }
01756 }
01757
01758
01759 void applyAdjPartialDeriv(int i,
01760 const Vector<Scalar> & yin,
01761 Vector<Scalar> & yout) const {
01762 try {
01763 if (wx.update()) reset();
01764 OperatorProductDomain<Scalar> * pf = NULL;
01765 if ((pf = dynamic_cast<OperatorProductDomain<Scalar> *>(f))) {
01766 pf->applyAdjPartialDeriv(i,wx.get(),yin,yout);
01767 }
01768 else {
01769 RVLException e;
01770 e<<"Error: OperatorEvaluation::applyAdjPartialDeriv\n";
01771 e<<"referenced Operator does not have ProductSpace domain\n";
01772 e<<"so partial derivatives are not defined\n";
01773 throw e;
01774 }
01775 }
01776 catch (RVLException & e) {
01777 e<<"\ncalled from OperatorEvaluation";
01778 e<<"::applyAdjPartialDeriv()\n";
01779 throw e;
01780 }
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01834 #ifndef RVL_OPERATOR_NEW_ENABLED
01835 void * operator new(size_t size) {
01836 void * ptr;
01837 ptr = (void *) ::new unsigned char[size];
01838 return ptr;
01839 }
01840 #endif
01841
01842 public:
01843
01844 OperatorEvaluation(const Operator<Scalar> & _f,
01845 const Vector<Scalar> & x)
01846 : fref(_f), wx(x),
01847 val(fref.getRange()), applied(false),
01848 deriv(_f.createDerivEvaluation(*this)),
01849 deriv2(_f.createDeriv2Evaluation(*this)) {
01850 f = fref.clone();
01851
01852 if (x.getSpace() != fref.getDomain()) {
01853 RVLException e;
01854 e<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
01855 e<<"Error: OperatorEvaluation constructor\n";
01856 e<<"-- evaluation point not in domain of operator\n";
01857 e<<"**********************\n";
01858 e<<"*** operator: ***\n";
01859 e<<"**********************\n";
01860 fref.write(e);
01861 e<<"**********************\n";
01862 e<<"*** domain space: ***\n";
01863 e<<"**********************\n";
01864 fref.getDomain().write(e);
01865 e<<"**********************\n";
01866 e<<"*** input space: ***\n";
01867 e<<"**********************\n";
01868 x.getSpace().write(e);
01869 e<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
01870 throw e;
01871 }
01872
01873 }
01874
01875 OperatorEvaluation(const OperatorEvaluation<Scalar> & ev)
01876 : wx(ev.wx), f(ev.fref.clone()), fref(ev.fref),
01877 val(fref.getRange()), applied(false),
01878 deriv(f->createDerivEvaluation(*this)),
01879 deriv2(f->createDeriv2Evaluation(*this)) { }
01880
01881 virtual ~OperatorEvaluation() {
01882 if( deriv) {
01883 delete deriv;
01884 deriv = NULL;
01885 }
01886 if( deriv2) {
01887 delete deriv2;
01888 deriv2 = NULL;
01889 }
01890 if (f) delete f;
01891 }
01892
01896 Space<Scalar> const & getDomain() const { return fref.getDomain(); }
01897
01901 Space<Scalar> const & getRange() const { return fref.getRange(); }
01902
01904 Vector<Scalar> & getPoint() { return wx.get(); }
01905 Vector<Scalar> const & getPoint() const { return wx.get(); }
01906
01915 Operator<Scalar> const & getOp() const { return *f; }
01916
01919 Vector<Scalar> const & getValue() const {
01920 try {
01921 if (wx.update()) reset();
01922 if (!applied) {
01923 f->apply(wx.get(),val);
01924 applied=true;
01925 }
01926 return val;
01927 }
01928 catch (RVLException & e) {
01929 e<<"\ncalled in OperatorEvaluation::getValue\n";
01930 throw e;
01931 }
01932 }
01933
01935 LinearOp<Scalar> const & getDeriv() const { return *deriv; }
01937 SymmetricBilinearOp<Scalar> const & getDeriv2() const { return *deriv2; }
01938
01939 ostream & write(ostream & str) const{
01940 str<<"Operator Evaluation:"<<"\n";
01941 str<<" Operator:\n";
01942 fref.write(str);
01943 str<<" evaluated at Vector:\n";
01944 wx.get().write(str);
01945 return str;
01946 }
01947 };
01948
01957 template<class Scalar>
01958 class DerivEvaluation: public LinearOp<Scalar> {
01959
01960 friend class OperatorEvaluation<Scalar>;
01961 friend class Operator<Scalar>;
01962
01963 private:
01964
01965
01966 DerivEvaluation();
01967
01968 protected:
01969
01970 OperatorEvaluation<Scalar> & fx;
01971
01972 DerivEvaluation(const DerivEvaluation<Scalar> & d)
01973 : fx(d.fx) {}
01974
01976 DerivEvaluation(OperatorEvaluation<Scalar> & _fx): fx(_fx) {}
01977
01978 LinearOp<Scalar> * clone() const {
01979 return new DerivEvaluation<Scalar>(*this);
01980 }
01981
01984 Operator<Scalar> & getOp() const { return fx.getOp(); }
01985
01988 void apply(const Vector<Scalar> & y,
01989 Vector<Scalar> & z) const {
01990 try {
01991 fx.applyDeriv(y,z);
01992 }
01993 catch (RVLException & e) {
01994 e<<"\ncalled in DerivEvaluation::applyOp\n";
01995 throw e;
01996 }
01997 }
01998
02001 void applyAdj(const Vector<Scalar> & y,
02002 Vector<Scalar> & z) const {
02003 try {
02004 fx.applyAdjDeriv(y,z);
02005 }
02006 catch (RVLException & e) {
02007 e<<"\ncalled in DerivEvaluation::applyAdjOp\n";
02008 throw e;
02009 }
02010 }
02011
02012 public:
02013
02014 ~DerivEvaluation() {}
02015
02017 const Space<Scalar> & getDomain() const { return fx.getDomain(); }
02019 const Space<Scalar> & getRange() const { return fx.getRange(); }
02020
02021 ostream & write(ostream & str) const{
02022 str<<"Derivative operator"<<"\n";
02023 str<<"part of operator evaluation"<<"\n";
02024 fx.write(str);
02025 return str;
02026 }
02027 };
02028
02037 template<class Scalar>
02038 class Deriv2Evaluation: public SymmetricBilinearOp<Scalar> {
02039
02040 friend class OperatorEvaluation<Scalar>;
02041 friend class Operator<Scalar>;
02042
02043 private:
02044
02045
02046 Deriv2Evaluation();
02047
02048 protected:
02049
02050 OperatorEvaluation<Scalar> & fx;
02051
02052 Deriv2Evaluation(const Deriv2Evaluation<Scalar> & d)
02053 : fx(d.fx) {}
02054
02056 Deriv2Evaluation(OperatorEvaluation<Scalar> & _fx): fx(_fx) {}
02057
02058 SymmetricBilinearOp<Scalar> * clone() const {
02059 return new Deriv2Evaluation<Scalar>(*this);
02060 }
02061
02064 Operator<Scalar> & getOp() const { return fx.getOp(); }
02065
02068 void apply(const Vector<Scalar> & y0,
02069 const Vector<Scalar> & y1,
02070 Vector<Scalar> & z) const {
02071 try {
02072 fx.applyDeriv2(y0,y1,z);
02073 }
02074 catch (RVLException & e) {
02075 e<<"\ncalled in Deriv2Evaluation::applyOp\n";
02076 throw e;
02077 }
02078 }
02079
02082 void applyAdj(const Vector<Scalar> & y0,
02083 const Vector<Scalar> & z,
02084 Vector<Scalar> & y1) const {
02085 try {
02086 fx.applyAdjDeriv2(y0,z,y1);
02087 }
02088 catch (RVLException & e) {
02089 e<<"\ncalled in Deriv2Evaluation::applyAdjOp\n";
02090 throw e;
02091 }
02092 }
02093
02094 public:
02095
02096 ~Deriv2Evaluation() {}
02097
02099 const Space<Scalar> & getDomain() const { return fx.getDomain(); }
02101 const Space<Scalar> & getRange() const { return fx.getRange(); }
02102
02103 ostream & write(ostream & str) const{
02104 str<<"Second Derivative operator"<<"\n";
02105 str<<"part of operator evaluation"<<"\n";
02106 fx.write(str);
02107 return str;
02108 }
02109 };
02110
02113 template<class Scalar>
02114 class InvertibleDerivEvaluation
02115 : public DerivEvaluation<Scalar>, public Invertible<Scalar> {
02116
02117 friend class OperatorWithInvertibleDeriv<Scalar>;
02118
02119 protected:
02120
02121 LinearOp<Scalar> * clone() const {
02122 return new InvertibleDerivEvaluation<Scalar>(*this);
02123 }
02124
02125 InvertibleDerivEvaluation(const InvertibleDerivEvaluation<Scalar> & s)
02126 :DerivEvaluation<Scalar>(s) {}
02127
02131 void applyInv(const Vector<Scalar> & x,
02132 Vector<Scalar> & y) const {
02133 try {
02134 OperatorWithInvertibleDeriv<Scalar> & opwid =
02135 dynamic_cast<OperatorWithInvertibleDeriv<Scalar> &>(this->getOp());
02136 opwid.applyInverseDeriv(this->fx.getPoint(), x, y);
02137 }
02138 catch (bad_cast) {
02139 RVLException e;
02140 e<<"Error: InvertibleDerivEvaluation::applyInv\n";
02141 e<<"operator does not have invertible deriv\n";
02142 throw e;
02143 }
02144 }
02145
02149 void applyInvAdj(const Vector<Scalar> & x,
02150 Vector<Scalar> & y) const {
02151 try {
02152 OperatorWithInvertibleDeriv<Scalar> & opwid =
02153 dynamic_cast<OperatorWithInvertibleDeriv<Scalar> &>(this->getOp());
02154 opwid.applyAdjInverseDeriv(this->fx.getPoint(), x, y);
02155 }
02156 catch (bad_cast) {
02157 RVLException e;
02158 e<<"Error: InvertibleDerivEvaluation::applyInvAdj\n";
02159 e<<"operator does not have invertible deriv\n";
02160 throw e;
02161 }
02162 }
02163
02164 public:
02165
02166 InvertibleDerivEvaluation(OperatorEvaluation<Scalar> & _fx)
02167 : DerivEvaluation<Scalar>(_fx) {}
02168
02170 const Space<Scalar> & getDomain() const { return this->fx.getDomain(); }
02172 const Space<Scalar> & getRange() const { return this->fx.getRange(); }
02173
02174 ostream & write(ostream & str) const{
02175 str<<"Invertible Derivative operator"<<"\n";
02176 str<<"part of operator evaluation"<<"\n";
02177 this->fx.write(str);
02178 return str;
02179 }
02180
02181 };
02182
02184 template<class Scalar>
02185 class OperatorProductDomainEvaluation: public OperatorEvaluation<Scalar> {
02186
02187 friend class PartialDerivEvaluation<Scalar>;
02188
02189 PartialDerivEvaluation<Scalar> deriv;
02190
02191
02192 OperatorProductDomainEvaluation();
02193 OperatorProductDomainEvaluation
02194 (const OperatorProductDomainEvaluation<Scalar> &);
02195
02196 public:
02197
02200 OperatorProductDomainEvaluation(OperatorProductDomain<Scalar> & _f,
02201 const Vector<Scalar> & _x)
02202 : OperatorEvaluation<Scalar>(_f,_x), deriv(*this) {}
02203
02204 virtual ~OperatorProductDomainEvaluation() {}
02205
02208 const LinearOp<Scalar> & getPartialDeriv(int ic) {
02209 try {
02210 deriv.setBlock(ic);
02211 return deriv;
02212 }
02213 catch (RVLException & e) {
02214 e<<"\ncalled from OperatorProductDomainEvaluation::getPartialDeriv\n";
02215 throw e;
02216 }
02217 }
02218
02219 ostream & write(ostream & str) const{
02220 str<<"Operator Evaluation with Product Domain; as"<<"\n";
02221 return OperatorEvaluation<Scalar>::write(str);
02222 }
02223 };
02224
02227 template<class Scalar>
02228 class PartialDerivEvaluation: public LinearOp<Scalar> {
02229
02230 friend class OperatorProductDomainEvaluation<Scalar>;
02231
02232 private:
02233
02234 OperatorProductDomainEvaluation<Scalar> & fx;
02235 int ic;
02236
02237
02238 PartialDerivEvaluation();
02239 PartialDerivEvaluation(const PartialDerivEvaluation<Scalar> & d)
02240 : fx(d.fx), ic(d.ic) {}
02241
02242 protected:
02243
02244 PartialDerivEvaluation(OperatorProductDomainEvaluation<Scalar> & _fx)
02245 : fx(_fx), ic(0) {}
02246
02247 LinearOp<Scalar> * clone() const {
02248 return new PartialDerivEvaluation<Scalar>(*this);
02249 }
02250
02251
02252 void apply(const Vector<Scalar> & y,
02253 Vector<Scalar> & z) const {
02254 try { fx.applyPartialDeriv(ic,y,z); }
02255 catch (RVLException & e) {
02256 e<<"\ncalled in PartialDerivEvaluation::apply\n";
02257 throw e;
02258 }
02259 }
02260
02261
02262 void applyAdj(const Vector<Scalar> & y,
02263 Vector<Scalar> & z) const {
02264 try { fx.applyAdjPartialDeriv(ic,y,z); }
02265 catch (RVLException & e) {
02266 e<<"\ncalled in PartialDerivEvaluation::applyAdj\n";
02267 throw e;
02268 }
02269 }
02270
02271 public:
02272
02273 ~PartialDerivEvaluation() {}
02274
02275 const Space<Scalar> & getDomain() const {
02276 try { return (fx.getProductDomain())[ic]; }
02277 catch (RVLException & e) {
02278 e<<"\ncalled from PartialDerivEvaluation::getProductDomain()\n";
02279 throw e;
02280 }
02281 }
02282
02283 const Space<Scalar> & getRange() const { return fx.getRange(); }
02284
02285 void setBlock(int i) { ic=i; }
02286
02287 ostream & write(ostream & str) const{
02288 str<<"Partial Derivative operator"<<"\n";
02289 str<<"component "<<ic<<"\n";
02290 str<<"part of functional evaluation"<<"\n";
02291 fx.write(str);
02292 return str;
02293 }
02294 };
02295
02305 template<class Scalar>
02306 class LNLOperator: public Operator<Scalar> {
02307 private:
02308
02309 LinearOp<Scalar> const & L;
02310
02311 LNLOperator();
02312
02313 protected:
02314
02315 void apply(const Vector<Scalar> & x,
02316 Vector<Scalar> & y) const {
02317 try {
02318 L.applyOp(x,y);
02319 }
02320 catch (RVLException & e) {
02321 e<<"\ncalled from LNLOperator::apply\n";
02322 throw e;
02323 }
02324 }
02325
02326 void applyDeriv(const Vector<Scalar> & x,
02327 const Vector<Scalar> & dx,
02328 Vector<Scalar> & dy) const {
02329 try {
02330 L.applyOp(dx,dy);
02331 }
02332 catch (RVLException & e) {
02333 e<<"\ncalled from LNLOperator::applyDeriv\n";
02334 throw e;
02335 }
02336 }
02337
02338 void applyAdjDeriv(const Vector<Scalar> & x,
02339 const Vector<Scalar> & dy,
02340 Vector<Scalar> & dx) const {
02341 try {
02342 L.applyAdjOp(dy,dx);
02343 }
02344 catch (RVLException & e) {
02345 e<<"\ncalled from LNLOperator::applyAdjDeriv\n";
02346 throw e;
02347 }
02348 }
02349
02350 public:
02351
02353 LNLOperator(LinearOp<Scalar> const & LL) : L(LL) {}
02354 LNLOperator(const LNLOperator<Scalar> & op) : L(op.L) {}
02355 ~LNLOperator() {}
02356
02357
02358 virtual Operator<Scalar> * clone() const {
02359 return new LNLOperator<Scalar>(*this);
02360 }
02361
02363 const Space<Scalar> & getDomain() const { return L.getDomain(); }
02364 const Space<Scalar> & getRange() const { return L.getRange(); }
02365
02366 ostream & write(ostream & str) const {
02367 str<<"Linear operator as operator"<<"\n";
02368 L.write(str);
02369 return str;
02370 }
02371 };
02372
02383 template<class Scalar>
02384 class ANLOperator: public Operator<Scalar> {
02385 private:
02386
02387 LinearOp<Scalar> const & L;
02388 Vector<Scalar> const & d;
02389
02390 ANLOperator();
02391
02392 protected:
02393
02394 void apply(const Vector<Scalar> & x,
02395 Vector<Scalar> & y) const {
02396 try {
02397 L.applyOp(x,y);
02398 y.linComb(-1.0,d);
02399 }
02400 catch (RVLException & e) {
02401 e<<"\ncalled from ANLOperator::apply\n";
02402 throw e;
02403 }
02404 }
02405
02406 void applyDeriv(const Vector<Scalar> & x,
02407 const Vector<Scalar> & dx,
02408 Vector<Scalar> & dy) const {
02409 try {
02410 L.applyOp(dx,dy);
02411 }
02412 catch (RVLException & e) {
02413 e<<"\ncalled from ANLOperator::applyDeriv\n";
02414 throw e;
02415 }
02416 }
02417
02418 void applyAdjDeriv(const Vector<Scalar> & x,
02419 const Vector<Scalar> & dy,
02420 Vector<Scalar> & dx) const {
02421 try {
02422 L.applyAdjOp(dy,dx);
02423 }
02424 catch (RVLException & e) {
02425 e<<"\ncalled from ANLOperator::applyAdjDeriv\n";
02426 throw e;
02427 }
02428 }
02429
02430 public:
02431
02433 ANLOperator(LinearOp<Scalar> const & LL, Vector<Scalar> const & dd)
02434 : L(LL), d(dd) {}
02435 ANLOperator(const ANLOperator<Scalar> & op) : L(op.L), d(op.d) {}
02436 ~ANLOperator() {}
02437
02438
02439 virtual Operator<Scalar> * clone() const {
02440 return new ANLOperator<Scalar>(*this);
02441 }
02442
02444 Space<Scalar> & getDomain() const { return L.getDomain(); }
02445 Space<Scalar> & getRange() const { return L.getRange(); }
02446
02447 ostream & write(ostream & str) const {
02448 str<<"Affine operator as operator: linear op"<<"\n";
02449 L.write(str);
02450 str<<"*** shift vector\n";
02451 d.write(str);
02452 return str;
02453 }
02454 };
02455
02472 template<class Scalar>
02473 class OpFO: public Operator<Scalar> {
02474 private:
02475
02476 FunctionObject & f;
02477 FunctionObject & dff;
02478 FunctionObject & dfa;
02479
02480 Space<Scalar> const & dom;
02481 Space<Scalar> const & rng;
02482
02483 mutable std::vector< RVL::Vector<Scalar> const *> inp;
02484 mutable std::vector< RVL::Vector<Scalar> const *> inpd;
02485
02486 OpFO();
02487
02488 protected:
02489
02490 void apply(const Vector<Scalar> & x,
02491 Vector<Scalar> & y) const {
02492 try {
02493 inp[0]=&x;
02494 y.eval(f,inp);
02495 }
02496 catch (RVLException & e) {
02497 e<<"\ncalled in OpFO::apply\n";
02498 throw e;
02499 }
02500 }
02501
02502 void applyDeriv(const Vector<Scalar> & x,
02503 const Vector<Scalar> & dx,
02504 Vector<Scalar> & z) const {
02505 try {
02506 inpd[0]=&x;
02507 inpd[1]=&dx;
02508 z.eval(dff,inpd);
02509 }
02510 catch (RVLException & e) {
02511 e<<"\ncalled in OpFO::applyDeriv\n";
02512 throw e;
02513 }
02514 }
02515
02516 void applyAdjDeriv(const Vector<Scalar> & x,
02517 const Vector<Scalar> & y,
02518 Vector<Scalar> & z) const {
02519 try {
02520 inpd[0]=&x;
02521 inpd[1]=&y;
02522 z.eval(dfa,inpd);
02523 }
02524 catch (RVLException & e) {
02525 e<<"\ncalled in OpFO::applyAdjDeriv\n";
02526 throw e;
02527 }
02528 }
02529
02530
02531 public:
02532
02533 OpFO(const OpFO<Scalar> & A):
02534 dom(A.dom), rng(A.rng),
02535 f(A.f), dff(A.dff), dfa(A.dfa),
02536 inp(A.inp), inpd(A.inpd) {}
02537
02538 OpFO(Space<Scalar> const & _dom,
02539 Space<Scalar> const & _rng,
02540 FunctionObject & _f,
02541 FunctionObject & _dff,
02542 FunctionObject & _dfa):
02543 dom(_dom), rng(_rng), f(_f), dff(_dff), dfa(_dfa),
02544 inp(1), inpd(2) {}
02545
02546 OpFO(Space<Scalar> const & _dom,
02547 Space<Scalar> const & _rng,
02548 FunctionObject & _f,
02549 FunctionObject & _dff,
02550 FunctionObject & _dfa,
02551 std::vector<RVL::Vector<Scalar> const *> par):
02552 dom(_dom), rng(_rng), f(_f), dff(_dff), dfa(_dfa),
02553 inp(1+par.size()), inpd(2+par.size()) {
02554 for (int i=0;i<par.size();i++) { inp[i+1]=par[i]; inpd[i+2]=par[i]; }
02555 }
02556
02557 ~OpFO() {}
02558
02559
02560
02561 Operator<Scalar> * clone() const { return new OpFO<Scalar>(*this); }
02562
02563
02564 const Space<Scalar> & getDomain() const { return dom; }
02565 const Space<Scalar> & getRange() const { return rng; }
02566
02567 ostream & write(ostream & str) const {
02568 str<<"Operator built of function object components"<<endl;
02569 str<<"image function:"<<endl;
02570 f.write(str);
02571 str<<"derivative image function:"<<endl;
02572 dff.write(str);
02573 str<<"derivative adjoint image function:"<<endl;
02574 dfa.write(str);
02575 return str;
02576 }
02577
02578 };
02579
02604 template<class Scalar>
02605 class LinCombOperator: public Operator<Scalar> {
02606 private:
02607
02608 mutable std::vector<Operator<Scalar> *> opvec;
02609 mutable std::vector<Scalar> wtvec;
02610 mutable bool applied;
02611
02613 void setNext(Scalar a, Operator<Scalar> const & op) {
02614 try {
02615 if (applied) {
02616 RVLException e;
02617 e<<"Error: LinCombOperator::setNext\n";
02618 e<<"object already initialized - non-initialization method called\n";
02619 e<<"further alteration to object data not allowed\n";
02620 throw e;
02621 }
02622 if (opvec.size() > 0) {
02623 if ( (op.getDomain() != opvec[0]->getDomain()) ||
02624 (op.getRange() != opvec[0]->getRange()) ) {
02625 RVLException e;
02626 e<<"Error: LinCombOp::setNext\n";
02627 e<<"domain or ranges of input operator incompatible with reference (summand 0)\n";
02628 e<<"*** input operator:\n";
02629 op.write(e);
02630 e<<"*** reference operator:\n";
02631 opvec[0]->write(e);
02632 throw e;
02633 }
02634 }
02635 wtvec.push_back(a);
02636 opvec.push_back(RVL::Operator<Scalar>::export_clone(op));
02637 }
02638 catch (RVLException & e) {
02639 e<<"\ncalled from LinCombOperator::setNext\n";
02640 }
02641 }
02642
02643 protected:
02644
02645 void apply(const Vector<Scalar> & x,
02646 Vector<Scalar> & val) const {
02647 try {
02648
02649 if (opvec.size()<1) {
02650 RVLException e;
02651 e<<"Error: LinCombOp::apply\n";
02652 e<<"not initialized\n";
02653 throw e;
02654 }
02655 applied = true;
02656 this->export_apply(*(opvec[0]),x,val);
02657 val.scale(wtvec[0]);
02658 if (opvec.size() > 1) {
02659 Vector<Scalar> tmp(opvec[0]->getRange());
02660 for (int i=i; i<(int)opvec.size(); i++) {
02661 this->export_apply(*(opvec[i]),x,tmp);
02662 val.linComb(wtvec[i],tmp);
02663 }
02664 }
02665 }
02666 catch (RVLException & e) {
02667 e<<"\ncalled from LinCombOperator::apply\n";
02668 throw e;
02669 }
02670 }
02671
02672 void applyDeriv(const Vector<Scalar> & x,
02673 const Vector<Scalar> & dx,
02674 Vector<Scalar> & dy) const {
02675 try {
02676 if (opvec.size()<1) {
02677 RVLException e;
02678 e<<"Error: LinCombOp::applyDeriv\n";
02679 e<<"not initialized\n";
02680 throw e;
02681 }
02682 applied = true;
02683 this->export_applyDeriv(*(opvec[0]),x,dx,dy);
02684 dy.scale(wtvec[0]);
02685 if (opvec.size() > 1) {
02686 Vector<Scalar> tmp(opvec[0]->getRange());
02687 for (int i=i; i<(int)opvec.size(); i++) {
02688 this->export_applyDeriv(*(opvec[i]),x,dx,tmp);
02689 dy.linComb(wtvec[i],tmp);
02690 }
02691 }
02692 }
02693 catch (RVLException & e) {
02694 e<<"\ncalled from LinCombOperator::applyDeriv\n";
02695 throw e;
02696 }
02697 }
02698
02699 void applyAdjDeriv(const Vector<Scalar> & x,
02700 const Vector<Scalar> & dy,
02701 Vector<Scalar> & dx) const {
02702 try {
02703 if (opvec.size()<1) {
02704 RVLException e;
02705 e<<"Error: LinCombOp::applyAdjDeriv\n";
02706 e<<"not initialized\n";
02707 throw e;
02708 }
02709 applied = true;
02710 this->export_applyAdjDeriv(*(opvec[0]),x,dy,dx);
02711 dx.scale(wtvec[0]);
02712 if (opvec.size() > 1) {
02713 Vector<Scalar> tmp(opvec[0]->getDomain());
02714 for (int i=i; i<(int)opvec.size(); i++) {
02715 this->export_applyAdjDeriv(*(opvec[i]),x,dy,tmp);
02716 dx.linComb(wtvec[i],tmp);
02717 }
02718 }
02719 }
02720 catch (RVLException & e) {
02721 e<<"\ncalled from LinCombOperator::applyAdjDeriv\n";
02722 throw e;
02723 }
02724 }
02725
02726 Operator<Scalar> * clone() const {
02727 applied = true;
02728 return new LinCombOperator<Scalar>(*this);
02729 }
02730
02731 public:
02732
02733 LinCombOperator(LinCombOperator<Scalar> const & op) {
02734 try {
02735 for (int i=0;i<op.opvec.size(); i++) {
02736 opvec.push_back(op.opvec[i]->clone());
02737 wtvec.push_back(op.wtvec[i]);
02738 }
02739 }
02740 catch (RVLException & e) {
02741 e<<"\ncalled from LinCombOperator copy constructor\n";
02742 }
02743 }
02744
02745 LinCombOperator(Scalar a1, Operator<Scalar> const & op1,
02746 Scalar a2, Operator<Scalar> const & op2)
02747 : opvec(2), wtvec(2) {
02748 try {
02749 this->setNext(a1, op1);
02750 this->setNext(a2, op2);
02751 }
02752 catch (RVLException & e) {
02753 e<<"\ncalled from LinCombOperator pair constructor\n";
02754 throw e;
02755 }
02756 }
02757
02758 LinCombOperator(Scalar a1, Operator<Scalar> const & op1,
02759 Scalar a2, Operator<Scalar> const & op2,
02760 Scalar a3, Operator<Scalar> const & op3)
02761 : opvec(3), wtvec(3) {
02762 try {
02763 this->setNext(a1, op1);
02764 this->setNext(a2, op2);
02765 this->setNext(a3, op3);
02766 }
02767 catch (RVLException & e) {
02768 e<<"\ncalled from LinCombOperator triple constructor\n";
02769 throw e;
02770 }
02771 }
02772
02773 LinCombOperator(Scalar a1, Operator<Scalar> const & op1,
02774 Scalar a2, Operator<Scalar> const & op2,
02775 Scalar a3, Operator<Scalar> const & op3,
02776 Scalar a4, Operator<Scalar> const & op4)
02777 : opvec(4), wtvec(4) {
02778 try {
02779 this->setNext(a1, op1);
02780 this->setNext(a2, op2);
02781 this->setNext(a3, op3);
02782 this->setNext(a4, op4);
02783 }
02784 catch (RVLException & e) {
02785 e<<"\ncalled from LinCombOperator quad constructor\n";
02786 throw e;
02787 }
02788 }
02789
02790 LinCombOperator(Scalar a1, Operator<Scalar> const & op1,
02791 Scalar a2, Operator<Scalar> const & op2,
02792 Scalar a3, Operator<Scalar> const & op3,
02793 Scalar a4, Operator<Scalar> const & op4,
02794 Scalar a5, Operator<Scalar> const & op5)
02795 : opvec(2), wtvec(2) {
02796 try {
02797 this->setNext(a1, op1);
02798 this->setNext(a2, op2);
02799 this->setNext(a3, op3);
02800 this->setNext(a4, op4);
02801 this->setNext(a5, op5);
02802 }
02803 catch (RVLException & e) {
02804 e<<"\ncalled from LinCombOperator quint constructor\n";
02805 throw e;
02806 }
02807 }
02808
02809 ~LinCombOperator() {
02810 for (int i=0;i<(int)opvec.size(); i++) if (opvec[i]) delete opvec[i];
02811 }
02812
02814 const Space<Scalar> & getDomain() const {
02815 try {
02816 if (opvec.size()<1) {
02817 RVLException e;
02818 e<<"Error: LinCombOperator::getDomain\n";
02819 e<<"object not initialized\n";
02820 throw e;
02821 }
02822 applied = true;
02823 return opvec[0]->getDomain();
02824 }
02825 catch (RVLException & e) {
02826 e<<"\ncalled from LinCombOperator::getDomain\n";
02827 }
02828 }
02829
02830 const Space<Scalar> & getRange() const {
02831 try {
02832 if (opvec.size()<1) {
02833 RVLException e;
02834 e<<"Error: LinCombOperator::getDomain\n";
02835 e<<"object not initialized\n";
02836 throw e;
02837 }
02838 applied = true;
02839 return opvec[0]->getRange();
02840 }
02841 catch (RVLException & e) {
02842 e<<"\ncalled from LinCombOperator::getRange\n";
02843 }
02844 }
02845
02846 ostream & write(ostream & str) const {
02847 str<<"LinCombOperator: linear combination of vector-valued functions\n";
02848 if (opvec.size()<1) {
02849 str<<"not initialized\n";
02850 }
02851 else {
02852 for (int i=0;i<(int)opvec.size();i++) {
02853 str<<" --- Operator "<<i<<" with weight "<<wtvec[i]<<"\n";
02854 opvec[i]->write(str);
02855 }
02856 }
02857 return str;
02858 }
02859 };
02860
02866 template<typename Scalar>
02867 class LinearOpEvaluation {
02868
02869 private:
02870
02871 Vector<Scalar> const & ref;
02872 LinearOp<Scalar> const & op;
02873 mutable Vector<Scalar> val;
02874 mutable bool applied;
02875
02876 LinearOpEvaluation();
02877 LinearOpEvaluation(LinearOpEvaluation<Scalar> const &);
02878
02879 public:
02880
02881 LinearOpEvaluation(LinearOp<Scalar> const & _op,
02882 Vector<Scalar> const & _ref)
02883 : ref(_ref), op(_op), val(op.getRange()), applied(false) {
02884 if (ref.getSpace() != op.getDomain()) {
02885 RVLException e;
02886 e<<"Error: LinearOpEvaluation constructor\n";
02887 e<<"input vector not in domain of operator\n";
02888 e<<"\nvector:\n";
02889 ref.write(e);
02890 e<<"\noperator:\n";
02891 op.write(e);
02892 throw e;
02893 }
02894 }
02895
02896 Vector<Scalar> const & getValue() const {
02897 if (!applied) {
02898 op.applyOp(ref,val);
02899 applied=true;
02900 }
02901 return val;
02902 }
02903
02904 };
02905
02911 template<typename Scalar>
02912 class LinearOpAdjEvaluation {
02913
02914 private:
02915
02916 Vector<Scalar> const & ref;
02917 LinearOp<Scalar> const & op;
02918 mutable Vector<Scalar> val;
02919 mutable bool applied;
02920
02921 LinearOpAdjEvaluation();
02922 LinearOpAdjEvaluation(LinearOpEvaluation<Scalar> const &);
02923
02924 public:
02925
02926 LinearOpAdjEvaluation(LinearOp<Scalar> const & _op,
02927 Vector<Scalar> const & _ref)
02928 : ref(_ref), op(_op), val(op.getDomain()), applied(false) {
02929 if (ref.getSpace() != op.getRange()) {
02930 RVLException e;
02931 e<<"Error: LinearOpAdjEvaluation constructor\n";
02932 e<<"input vector not in range of operator\n";
02933 e<<"\nvector:\n";
02934 ref.write(e);
02935 e<<"\noperator:\n";
02936 op.write(e);
02937 throw e;
02938 }
02939 }
02940
02941 Vector<Scalar> const & getValue() const {
02942 if (!applied) {
02943 op.applyAdjOp(ref,val);
02944 applied=true;
02945 }
02946 return val;
02947 }
02948
02949 };
02950
03001 template<class Scalar>
03002 class OpComp: public Operator<Scalar> {
03003
03004 private:
03005
03006 mutable std::vector<Operator<Scalar> *> opvec;
03007 mutable bool applied;
03008
03009
03010 protected:
03011
03013 void apply(const Vector<Scalar> & x,
03014 Vector<Scalar> & val) const {
03015 try {
03016 if (opvec.size()<1) {
03017 RVLException e;
03018 e<<"Error: OpComp::apply\n";
03019 e<<"object not initialized\n";
03020 throw e;
03021 }
03022
03023 applied = true;
03024
03025
03026
03027 if (opvec.size()==1)
03028 this->export_apply(*(opvec[0]),x,val);
03029 else {
03030 std::vector<OperatorEvaluation<Scalar> *> opeval(opvec.size()-1);
03031 opeval[0] = new OperatorEvaluation<Scalar>(*(opvec[0]),x);
03032 for (int i=1;i<(int)opvec.size()-1;i++)
03033 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),opeval[i-1]->getValue());
03034 this->export_apply(*(opvec[opvec.size()-1]),opeval[opvec.size()-2]->getValue(),val);
03035 for (int i=opvec.size()-2;i>-1;i--) delete opeval[i];
03036 }
03037 }
03038 catch (RVLException & e) {
03039 e<<"\ncalled from OpComp::apply\n";
03040 throw e;
03041 }
03042 }
03043
03045 void applyDeriv(const Vector<Scalar> & x,
03046 const Vector<Scalar> & dx,
03047 Vector<Scalar> & dy) const {
03048 try {
03049
03050 if (opvec.size()<1) {
03051 RVLException e;
03052 e<<"Error: OpComp::applyDeriv\n";
03053 e<<"object not initialized\n";
03054 throw e;
03055 }
03056
03057 applied = true;
03058
03059
03060
03061 if (opvec.size()==1)
03062 this->export_applyDeriv(*(opvec[0]),x,dx,dy);
03063
03064
03065 else {
03066
03067 std::vector<LinearOp<Scalar> *> linop(opvec.size(),NULL);
03068 std::vector<OperatorEvaluation<Scalar> *> opeval(opvec.size(), NULL);
03069 std::vector<LinearOpEvaluation<Scalar> *> lineval(opvec.size(),NULL);
03070
03071
03072 int lastlin=opvec.size();
03073
03074 while ((lastlin>0) && (linop[lastlin-1]=dynamic_cast<LinearOp<Scalar> *>(opvec[lastlin-1])) ) {
03075 lastlin--;
03076 }
03077 for (int i=0;i<lastlin;i++) {
03078 if (i==0) {
03079 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),x);
03080 lineval[i] = new LinearOpEvaluation<Scalar>(opeval[i]->getDeriv(),dx);
03081 }
03082 else if (i==(int)opvec.size()-1) {
03083 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),opeval[i-1]->getValue());
03084 opeval[i]->getDeriv().applyOp(lineval[i-1]->getValue(),dy);
03085 }
03086 else {
03087 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),opeval[i-1]->getValue());
03088 lineval[i] = new LinearOpEvaluation<Scalar>(opeval[i]->getDeriv(),lineval[i-1]->getValue());
03089 }
03090 }
03091 for (int i=lastlin;i<(int)opvec.size();i++) {
03092
03093 if (i==(int)opvec.size()-1)
03094 this->export_apply(*(opvec[i]),lineval[i-1]->getValue(),dy);
03095
03096 else if (i > 0)
03097 lineval[i]=new LinearOpEvaluation<Scalar>(*linop[i],lineval[i-1]->getValue());
03098
03099 else
03100 lineval[0] = new LinearOpEvaluation<Scalar>(*linop[0],dx);
03101 }
03102
03103
03104 for (int i=opvec.size()-1;i>-1;i--) {
03105 if (lineval[i]) delete lineval[i];
03106 if (opeval[i]) delete opeval[i];
03107 }
03108 }
03109 }
03110 catch (RVLException & e) {
03111 e<<"\ncalled from OpComp::applyDeriv\n";
03112 throw e;
03113 }
03114 }
03115
03119 void applyAdjDeriv(const Vector<Scalar> & x,
03120 const Vector<Scalar> & dy,
03121 Vector<Scalar> & dx) const {
03122 try {
03123
03124 if (opvec.size()<1) {
03125 RVLException e;
03126 e<<"Error: OpComp::applyAdjDeriv\n";
03127 e<<"object not initialized\n";
03128 throw e;
03129 }
03130
03131 applied = true;
03132
03133
03134
03135 if (opvec.size()==1)
03136 this->export_applyAdjDeriv(*(opvec[0]),x,dy,dx);
03137
03138
03139 else {
03140 std::vector<LinearOp<Scalar> *> linop(opvec.size(),NULL);
03141 std::vector<OperatorEvaluation<Scalar> *> opeval(opvec.size(),NULL);
03142 std::vector<LinearOpAdjEvaluation<Scalar> *> lineval(opvec.size(),NULL);
03143
03144
03145 int lastlin=opvec.size();
03146
03147 while ((lastlin > 0) && (linop[lastlin-1]=dynamic_cast<LinearOp<Scalar> *>(opvec[lastlin-1]))) {
03148 lastlin--;
03149 }
03150
03151 for (int i=0;i<lastlin;i++) {
03152 if (i==0) {
03153 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),x);
03154 }
03155 else {
03156 opeval[i] = new OperatorEvaluation<Scalar>(*(opvec[i]),opeval[i-1]->getValue());
03157 }
03158 }
03159
03160 for (int i=opvec.size()-1;i>lastlin-1;i--) {
03161
03162
03163 if (i==(int)opvec.size()-1)
03164 lineval[i]=new LinearOpAdjEvaluation<Scalar>(*(linop[i]),dy);
03165
03166 else if (i>0)
03167 lineval[i]=new LinearOpAdjEvaluation<Scalar>(*(linop[i]),lineval[i+1]->getValue());
03168
03169 else
03170 linop[0]->applyAdjOp(lineval[1]->getValue(),dx);
03171 }
03172 for (int i=lastlin-1;i>-1;i--) {
03173
03174 if (i==0) {
03175 opeval[i]->getDeriv().applyAdjOp(lineval[i+1]->getValue(),dx);
03176 }
03177
03178 else if (i==(int)opvec.size()-1) {
03179 lineval[i] = new LinearOpAdjEvaluation<Scalar>(opeval[i]->getDeriv(),dy);
03180 }
03181
03182 else {
03183 lineval[i] = new LinearOpAdjEvaluation<Scalar>(opeval[i]->getDeriv(),lineval[i+1]->getValue());
03184 }
03185 }
03186
03187 for (int i=opvec.size()-1;i>-1;i--) if (opeval[i]) delete opeval[i];
03188 for (int i=0;i<(int)opvec.size();i++) if (lineval[i]) delete lineval[i];
03189
03190 }
03191 }
03192 catch (RVLException & e) {
03193 e<<"\ncalled from OpComp::applyAdjDeriv\n";
03194 throw e;
03195 }
03196 }
03197
03199 void applyDeriv2(const Vector<Scalar> & x,
03200 const Vector<Scalar> & dx0,
03201 const Vector<Scalar> & dx1,
03202 Vector<Scalar> & dy) const {
03203 try {
03204
03205 if (opvec.size()<1) {
03206 RVLException e;
03207 e<<"Error: OpComp::applyDeriv2\n";
03208 e<<"object not initialized\n";
03209 throw e;
03210 }
03211
03212 applied = true;
03213
03214
03215
03216 if (opvec.size()==1)
03217 this->export_applyDeriv2(*(opvec[0]),x,dx0,dx1,dy);
03218 else if(opvec.size()==2){
03219 std::vector<OperatorEvaluation<Scalar> *> opeval(opvec.size(), NULL);
03220 opeval[0] = new OperatorEvaluation<Scalar>(*(opvec[0]),x);
03221 opeval[1] = new OperatorEvaluation<Scalar>(*(opvec[1]),opeval[0]->getValue());
03222 Vector<Scalar> tmp(opvec[1]->getRange());
03223 Vector<Scalar> dgx0(opvec[1]->getDomain());
03224 Vector<Scalar> dgx1(opvec[1]->getDomain());
03225 Vector<Scalar> d2gx(opvec[1]->getDomain());
03226
03227 opeval[0]->getDeriv().applyOp(dx0,dgx0);
03228 opeval[0]->getDeriv().applyOp(dx1,dgx1);
03229 opeval[0]->getDeriv2().applyOp(dx0,dx1,d2gx);
03230 opeval[1]->getDeriv2().applyOp(dgx0,dgx1,tmp);
03231 opeval[1]->getDeriv().applyOp(d2gx,dy);
03232 dy.linComb(1.0, tmp);
03233 for (int i=opvec.size()-1;i>-1;i--) if (opeval[i]) delete opeval[i];
03234
03235 }
03236
03237 else {
03238 RVLException e;
03239 e<<"Error: OpComp::applyDeriv2\n";
03240 e<<"deriv2 for more than two operators has not been implemented\n";
03241 throw e;
03242
03243 }
03244 }
03245 catch (RVLException & e) {
03246 e<<"\ncalled from OpComp::applyDeriv2\n";
03247 throw e;
03248 }
03249 }
03250
03251 void applyAdjDeriv2(const Vector<Scalar> & x,
03252 const Vector<Scalar> & dx0,
03253 const Vector<Scalar> & dy,
03254 Vector<Scalar> & dx1) const {
03255 try {
03256 if (opvec.size()<1) {
03257 RVLException e;
03258 e<<"Error: OpComp::applyAdjDeriv2\n";
03259 e<<"object not initialized\n";
03260 throw e;
03261 }
03262
03263 applied = true;
03264 if (opvec.size()==1)
03265 this->export_applyAdjDeriv2(*(opvec[0]),x,dx0,dy,dx1);
03266 else if(opvec.size()==2){
03267 std::vector<OperatorEvaluation<Scalar> *> opeval(opvec.size(), NULL);
03268 opeval[0] = new OperatorEvaluation<Scalar>(*(opvec[0]),x);
03269 opeval[1] = new OperatorEvaluation<Scalar>(*(opvec[1]),opeval[0]->getValue());
03270 Vector<Scalar> tmp(opvec[0]->getDomain());
03271 Vector<Scalar> tmp0(opvec[1]->getDomain());
03272 Vector<Scalar> dftdy(opvec[1]->getDomain());
03273 Vector<Scalar> dgx0(opvec[1]->getDomain());
03274
03275 opeval[0]->getDeriv().applyOp(dx0,dgx0);
03276 opeval[1]->getDeriv2().applyAdjOp(dgx0,dy,tmp0);
03277 opeval[0]->getDeriv().applyAdjOp(tmp0,tmp);
03278
03279 opeval[1]->getDeriv().applyAdjOp(dy,dftdy);
03280 opeval[0]->getDeriv2().applyAdjOp(dx0,dftdy,dx1);
03281 dx1.linComb(1.0, tmp);
03282 for (int i=opvec.size()-1;i>-1;i--) if (opeval[i]) delete opeval[i];
03283
03284 }
03285
03286 else {
03287 RVLException e;
03288 e<<"Error: OpComp::applyAdjDeriv2\n";
03289 e<<"deriv2 for more than two operators has not been implemented\n";
03290 throw e;
03291 }
03292 }
03293 catch (RVLException & e) {
03294 e<<"\ncalled from OpComp::applyAdjDeriv2\n";
03295 throw e;
03296 }
03297 }
03298
03304 Operator<Scalar> * clone() const { return new OpComp<Scalar>(*this); }
03305
03306 public:
03307
03308 OpComp(): opvec(0), applied(false) {}
03309
03310 OpComp(OpComp<Scalar> const & oc)
03311 : opvec(oc.opvec.size()), applied(false) {
03312 for (int i=0;i<(int)opvec.size(); i++) {
03313 opvec[i]=RVL::Operator<Scalar>::export_clone(*(oc.opvec[i]));
03314 }
03315 }
03316
03319 void setNext(Operator<Scalar> const & opref) {
03320 try {
03321 if (applied) {
03322 RVLException e;
03323 e<<"Error: OpComp::setNext (Operator)\n";
03324 e<<"operator composition already initialized, may not alter\n";
03325 throw e;
03326 }
03327 if (opvec.size() > 0) {
03328
03329 if (opvec[opvec.size()-1]->getRange() != opref.getDomain()) {
03330 RVLException e;
03331 e<<"Error: OpComp::setNext \n";
03332 e<<"domain of next operator differs from range of previous\n";
03333 e<<"\nnext:\n";
03334 opref.write(e);
03335 e<<"\nprevious:\n";
03336 opvec[opvec.size()-1]->write(e);
03337 throw e;
03338 }
03339 }
03340 opvec.push_back(RVL::Operator<Scalar>::export_clone(opref));
03341 }
03342 catch (RVLException & e) {
03343 e<<"\ncalled from OpComp::setNext(Operator)\n";
03344 throw e;
03345 }
03346 }
03347
03348
03350 OpComp(Operator<Scalar> const & op1ref,
03351 Operator<Scalar> const & op2ref)
03352 : opvec(0), applied(false) {
03353 try {
03354 this->setNext(op1ref);
03355 this->setNext(op2ref);
03356 }
03357 catch (RVLException & e) {
03358 e<<"Error: OpComp pair constructor from setNext\n";
03359 throw e;
03360 }
03361 }
03362
03364 OpComp(Operator<Scalar> const & op1ref,
03365 Operator<Scalar> const & op2ref,
03366 Operator<Scalar> const & op3ref)
03367 : opvec(0), applied(false) {
03368 try {
03369 this->setNext(op1ref);
03370 this->setNext(op2ref);
03371 this->setNext(op3ref);
03372 }
03373 catch (RVLException & e) {
03374 e<<"Error: OpComp triple constructor from setNext\n";
03375 throw e;
03376 }
03377 }
03378
03380 OpComp(Operator<Scalar> const & op1ref,
03381 Operator<Scalar> const & op2ref,
03382 Operator<Scalar> const & op3ref,
03383 Operator<Scalar> const & op4ref)
03384 : opvec(0), applied(false) {
03385 try {
03386 this->setNext(op1ref);
03387 this->setNext(op2ref);
03388 this->setNext(op3ref);
03389 this->setNext(op4ref);
03390 }
03391 catch (RVLException & e) {
03392 e<<"Error: OpComp quadruple constructor from setNext\n";
03393 throw e;
03394 }
03395 }
03396
03398 OpComp(Operator<Scalar> const & op1ref,
03399 Operator<Scalar> const & op2ref,
03400 Operator<Scalar> const & op3ref,
03401 Operator<Scalar> const & op4ref,
03402 Operator<Scalar> const & op5ref)
03403 : opvec(0), applied(false) {
03404 try {
03405 this->setNext(op1ref);
03406 this->setNext(op2ref);
03407 this->setNext(op3ref);
03408 this->setNext(op4ref);
03409 this->setNext(op5ref);
03410 }
03411 catch (RVLException & e) {
03412 e<<"Error: OpComp quintuple constructor from setNext\n";
03413 throw e;
03414 }
03415 }
03416
03417 ~OpComp() {
03418 for (int i=0;i<(int)opvec.size();i++) { delete opvec[i]; }
03419 }
03420
03422 const Space<Scalar> & getDomain() const {
03423 try {
03424 if (opvec.size() > 0) {
03425 applied = true;
03426 return opvec[0]->getDomain();
03427 }
03428 RVLException e;
03429 e<<"Error: OpComp::getDomain\n";
03430 e<<"not initialized - no factors specified\n";
03431 throw e;
03432 }
03433
03434 catch (RVLException & e) {
03435 e<<"\ncalled from OpComp::getDomain\n";
03436 throw e;
03437 }
03438 }
03439
03440 const Space<Scalar> & getRange() const {
03441 try {
03442 if (opvec.size() > 0) {
03443 applied = true;
03444 return opvec[opvec.size()-1]->getRange();
03445 }
03446 RVLException e;
03447 e<<"Error: OpComp::getRange\n";
03448 e<<"not initialized - no factors specified\n";
03449 throw e;
03450 }
03451 catch (RVLException & e) {
03452 e<<"\ncalled from OpComp::getRange\n";
03453 throw e;
03454 }
03455 }
03456
03457 ostream & write(ostream & str) const {
03458 try {
03459 if (opvec.size() > 0) {
03460 applied = true;
03461 str<<"OpComp: Operator composition\n";
03462 str<<"-- number of factors = "<<opvec.size()<<"\n";
03463 for (int i=0;i<(int)opvec.size(); i++) {
03464 str<<"\nfactor "<<i<<":\n";
03465 opvec[i]->write(str);
03466 }
03467 return str;
03468 }
03469 else {
03470 RVLException e;
03471 e<<"Error: OpComp::write\n";
03472 e<<"not initialized - no factors specified\n";
03473 throw e;
03474 }
03475 }
03476 catch (RVLException & e) {
03477 e<<"\ncalled from OpComp::write\n";
03478 throw e;
03479 }
03480 }
03481
03482 };
03483
03484 template<class Scalar>
03485 DerivEvaluation<Scalar> *
03486 OperatorWithInvertibleDeriv<Scalar>::createDerivEvaluation
03487 (OperatorEvaluation<Scalar> & opeval) const {
03488 return new InvertibleDerivEvaluation<Scalar>(opeval);
03489 }
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03521 template<class Scalar>
03522 class IdentityOp: public Operator<Scalar> {
03523
03524 private:
03525
03526 Space<Scalar> const & dom;
03527 Space<Scalar> const & rng;
03528
03529 IdentityOp();
03530
03531 protected:
03532
03533 void apply(const Vector<Scalar> & x,
03534 Vector<Scalar> & val) const {
03535 try {
03536 SpaceTest(this->getDomain(),x,"RVL::IdentityOp::apply (dom test)");
03537 SpaceTest(this->getRange(),val,"RVL::IdentityOp::apply (rng test)");
03538
03539 val.copy(x);
03540 }
03541 catch (RVLException & e) {
03542 e<<"\ncalled from IdentityOp::apply\n";
03543 throw e;
03544 }
03545 }
03546
03547 void applyDeriv(const Vector<Scalar> & x,
03548 const Vector<Scalar> & dx,
03549 Vector<Scalar> & dy) const {
03550 try {
03551 SpaceTest(this->getDomain(),x,"RVL::IdentityOp::applyDeriv (dom test x)");
03552 SpaceTest(this->getDomain(),dx,"RVL::IdentityOp::applyDeriv (dom test dx)");
03553 SpaceTest(this->getRange(),dy,"RVL::IdentityOp::applyDeriv (rng test)");
03554 dy.copy(dx);
03555 }
03556 catch (RVLException & e) {
03557 e<<"\ncalled from IdentityOp::applyDeriv\n";
03558 throw e;
03559 }
03560 }
03561
03562 void applyAdjDeriv(const Vector<Scalar> & x,
03563 const Vector<Scalar> & dy,
03564 Vector<Scalar> & dx) const {
03565 try {
03566 SpaceTest(this->getDomain(),x,"RVL::IdentityOp::applyAdjDeriv (dom test x)");
03567 SpaceTest(this->getDomain(),dx,"RVL::IdentityOp::applyAdjDeriv (dom test dx)");
03568 SpaceTest(this->getRange(),dy,"RVL::IdentityOp::applyAdjDeriv (rng test)");
03569 dx.copy(dy);
03570 }
03571 catch (RVLException & e) {
03572 e<<"\ncalled from IdentityOp::applyAdjDeriv\n";
03573 throw e;
03574 }
03575 }
03576
03577 Operator<Scalar> * clone() const { return new IdentityOp<Scalar>(*this); }
03578
03579 public:
03580
03581 IdentityOp(const Space<Scalar> & sp)
03582 :dom(sp), rng(sp) {}
03583
03584 IdentityOp(const IdentityOp<Scalar> & c)
03585 : dom(c.getDomain()), rng(c.getRange()){}
03586
03587 ~IdentityOp() {}
03588
03590 const Space<Scalar> & getDomain() const {
03591 return dom;
03592 }
03593
03594 const Space<Scalar> & getRange() const {
03595 return rng;
03596 }
03597
03598 ostream & write(ostream & str) const {
03599 str<<"IdentityOp: Identity Operator\n";
03600 return str;
03601 }
03602
03603 };
03604
03605
03606
03607
03608
03609 }
03610 #endif
03611