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_BLOCKOP
00034 #define __RVL_BLOCKOP
00035
00036 #include "op.hh"
00037
00038 namespace RVL {
00039
00047 template<class Scalar>
00048 class BlockOperator: public Operator<Scalar> {
00049
00050 friend class OperatorEvaluation<Scalar>;
00051
00052 protected:
00053
00054 virtual void applyComponent(int i,
00055 const Vector<Scalar> & x,
00056 Vector<Scalar> & yi) const = 0;
00057
00058 virtual void apply(Vector<Scalar> const & x,
00059 Vector<Scalar> & y) const {
00060 try {
00061 Components<Scalar> yc(y);
00062 for (int i=0;i<(int)yc.getSize();i++)
00063 applyComponent(i,x,yc[i]);
00064 }
00065 catch (RVLException & e) {
00066 e<<"\ncalled from BlockOperator::apply\n";
00067 throw e;
00068 }
00069 }
00070
00072 virtual void applyComponentDeriv(int i,
00073 const Vector<Scalar> & x,
00074 const Vector<Scalar> & dx,
00075 Vector<Scalar> & dyi) const = 0;
00076
00081 virtual void applyDeriv(const Vector<Scalar> & x,
00082 const Vector<Scalar> & dx,
00083 Vector<Scalar> & dy) const {
00084 try {
00085 Components<Scalar> dyc(dy);
00086 for (int i=0;i<(int)dyc.getSize();i++)
00087 applyComponentDeriv(i,x,dx,dyc[i]);
00088 }
00089 catch (RVLException & e) {
00090 e<<"\ncalled from BlockOperator::applyDeriv\n";
00091 throw e;
00092 }
00093 }
00094
00096 virtual void applyComponentAdjDeriv(int i,
00097 const Vector<Scalar> & x,
00098 const Vector<Scalar> & dyi,
00099 Vector<Scalar> & dx) const = 0;
00100
00104 virtual void applyAdjDeriv(const Vector<Scalar> & x,
00105 const Vector<Scalar> & dy,
00106 Vector<Scalar> & dx) const {
00107 try {
00108 Components<Scalar> dyc(dy);
00109 applyComponentAdjDeriv(0,x,dyc[0],dx);
00110 if (dyc.getSize()>0) {
00111 Vector<Scalar> tmp(this->getDomain(),true);
00112 for (int i=1; i<(int)dyc.getSize(); i++) {
00113 applyComponentAdjDeriv(i,x,dyc[i],tmp);
00114 dx.linComb(1.0,tmp);
00115 }
00116 }
00117 }
00118 catch (RVLException & e) {
00119 e<<"\ncalled from BlockOperator::applyAdjDeriv\n";
00120 throw e;
00121 }
00122 }
00123
00125 virtual void applyComponentDeriv2(int i,
00126 const Vector<Scalar> & x,
00127 const Vector<Scalar> & dx0,
00128 const Vector<Scalar> & dx1,
00129 Vector<Scalar> & dyi) const = 0;
00130
00135 virtual void applyDeriv2(const Vector<Scalar> & x,
00136 const Vector<Scalar> & dx0,
00137 const Vector<Scalar> & dx1,
00138 Vector<Scalar> & dy) const {
00139 try {
00140 Components<Scalar> dyc(dy);
00141 for (int i=0;i<(int)dyc.getSize();i++)
00142 applyComponentDeriv2(i,x,dx0,dx1,dyc[i]);
00143 }
00144 catch (RVLException & e) {
00145 e<<"\ncalled from BlockOperator::applyDeriv2\n";
00146 throw e;
00147 }
00148 }
00150 virtual void applyComponentAdjDeriv2(int i,
00151 const Vector<Scalar> & x,
00152 const Vector<Scalar> & dx0,
00153 const Vector<Scalar> & dyi,
00154 Vector<Scalar> & dx1) const = 0;
00155
00159 virtual void applyAdjDeriv2(const Vector<Scalar> & x,
00160 const Vector<Scalar> & dx0,
00161 const Vector<Scalar> & dy,
00162 Vector<Scalar> & dx1) const {
00163 try {
00164 Components<Scalar> dyc(dy);
00165 applyComponentAdjDeriv2(0,x,dx0,dyc[0],dx1);
00166 if (dyc.getSize()>0) {
00167 Vector<Scalar> tmp(this->getDomain(),true);
00168 for (int i=1; i<(int)dyc.getSize(); i++) {
00169 applyComponentAdjDeriv2(i,x,dx0,dyc[i],tmp);
00170 dx1.linComb(1.0,tmp);
00171 }
00172 }
00173 }
00174 catch (RVLException & e) {
00175 e<<"\ncalled from BlockOperator::applyAdjDeriv2\n";
00176 throw e;
00177 }
00178 }
00181 virtual BlockOperator<Scalar> * cloneBlockOp() const = 0;
00182 Operator<Scalar> * clone() const { return cloneBlockOp(); }
00183
00184 public:
00185
00186 BlockOperator() {}
00187 BlockOperator(const BlockOperator<Scalar> &) {}
00188 virtual ~BlockOperator() {}
00189
00191 virtual const ProductSpace<Scalar> & getProductRange() const = 0;
00193 const Space<Scalar> & getRange() const {
00194 return getProductRange();
00195 }
00196
00197 };
00198
00201 template<typename Scalar>
00202 class TensorOp: public BlockOperator<Scalar> {
00203
00204 private:
00205
00206 Operator<Scalar> const & op1;
00207 Operator<Scalar> const & op2;
00208 StdProductSpace<Scalar> rng;
00209
00210 TensorOp();
00211
00212 protected:
00213
00214 void applyComponent(int i,
00215 const Vector<Scalar> & x,
00216 Vector<Scalar> & yi) const {
00217 try {
00218 if (i==0) this->export_apply(op1,x,yi);
00219 else if (i==1) this->export_apply(op2,x,yi);
00220 else {
00221 RVLException e;
00222 e<<"Error: TensorOp::applyComponent\n";
00223 e<<"index "<<i<<" out of range [0,1]\n";
00224 throw e;
00225 }
00226 }
00227 catch (RVLException & e) {
00228 e<<"\ncalled from TensorOp::applyComponent\n";
00229 throw e;
00230 }
00231 }
00232
00233 void applyComponentDeriv(int i,
00234 const Vector<Scalar> & x,
00235 const Vector<Scalar> & dx,
00236 Vector<Scalar> & dyi) const {
00237 try {
00238 if (i==0) this->export_applyDeriv(op1,x,dx,dyi);
00239 else if (i==1) this->export_applyDeriv(op2,x,dx,dyi);
00240 else {
00241 RVLException e;
00242 e<<"Error: TensorOp::applyComponentDeriv\n";
00243 e<<"index "<<i<<" out of range [0,1]\n";
00244 throw e;
00245 }
00246 }
00247 catch (RVLException & e) {
00248 e<<"\ncalled from TensorOp::applyComponentDeriv\n";
00249 throw e;
00250 }
00251 }
00252
00253 void applyComponentAdjDeriv(int i,
00254 const Vector<Scalar> & x,
00255 const Vector<Scalar> & dyi,
00256 Vector<Scalar> & dx) const {
00257 try {
00258 if (i==0) this->export_applyAdjDeriv(op1,x,dyi,dx);
00259 else if (i==1) this->export_applyAdjDeriv(op2,x,dyi,dx);
00260 else {
00261 RVLException e;
00262 e<<"Error: TensorOp::applyComponentAdjDeriv\n";
00263 e<<"index "<<i<<" out of range [0,1]\n";
00264 throw e;
00265 }
00266 }
00267 catch (RVLException & e) {
00268 e<<"\ncalled from TensorOp::applyComponentAdjDeriv\n";
00269 throw e;
00270 }
00271 }
00272
00273 void applyComponentDeriv2(int i,
00274 const Vector<Scalar> & x,
00275 const Vector<Scalar> & dx0,
00276 const Vector<Scalar> & dx1,
00277 Vector<Scalar> & dyi) const {
00278 try {
00279 if (i==0) this->export_applyDeriv2(op1,x,dx0,dx1,dyi);
00280 else if (i==1) this->export_applyDeriv2(op2,x,dx0,dx1,dyi);
00281 else {
00282 RVLException e;
00283 e<<"Error: TensorOp::applyComponentDeriv2\n";
00284 e<<"index "<<i<<" out of range [0,1]\n";
00285 throw e;
00286 }
00287 }
00288 catch (RVLException & e) {
00289 e<<"\ncalled from TensorOp::applyComponentDeriv2\n";
00290 throw e;
00291 }
00292 }
00293
00294 void applyComponentAdjDeriv2(int i,
00295 const Vector<Scalar> & x,
00296 const Vector<Scalar> & dx0,
00297 const Vector<Scalar> & dyi,
00298 Vector<Scalar> & dx1) const{
00299 try {
00300 if (i==0) this->export_applyAdjDeriv2(op1,x,dx0,dyi,dx1);
00301 else if (i==1) this->export_applyAdjDeriv2(op2,x,dx0,dyi,dx1);
00302 else {
00303 RVLException e;
00304 e<<"Error: TensorOp::applyComponentAdjDeriv2\n";
00305 e<<"index "<<i<<" out of range [0,1]\n";
00306 throw e;
00307 }
00308 }
00309 catch (RVLException & e) {
00310 e<<"\ncalled from TensorOp::applyComponentAdjDeriv2\n";
00311 throw e;
00312 }
00313 }
00314
00315 TensorOp<Scalar> * cloneTensorOp() const { return new TensorOp(*this); }
00316 BlockOperator<Scalar> * cloneBlockOp() const { return cloneTensorOp(); }
00317
00318 public:
00319
00320 TensorOp(Operator<Scalar> const & _op1,
00321 Operator<Scalar> const & _op2)
00322 : op1(_op1), op2(_op2), rng(op1.getRange(),op2.getRange()) {
00323 try {
00324 if (op1.getDomain() != op2.getDomain()) {
00325 RVLException e;
00326 e<<"Error: TensorOp constructor\n";
00327 e<<"input operators do not have same domain\n";
00328 throw e;
00329 }
00330 }
00331 catch (RVLException & e) {
00332 e<<"\ncalled from TensorOp constructor\n";
00333 throw e;
00334 }
00335 }
00336
00337 TensorOp(TensorOp<Scalar> const & op)
00338 : op1(op.op1), op2(op.op2), rng(op1.getRange(),op2.getRange()) {}
00339
00340 ~TensorOp() {}
00341
00342 Space<Scalar> const & getDomain() const { return op1.getDomain(); }
00343 ProductSpace<Scalar> const & getProductRange() const { return rng; }
00344
00345 ostream & write(ostream & str) const {
00346 str<<"TensorOp: 2x1 block operator\n";
00347 str<<"*** operator[0,0]:\n";
00348 op1.write(str);
00349 str<<"*** operator[1,0]:\n";
00350 op2.write(str);
00351 return str;
00352 }
00353 };
00354
00360 template<typename Scalar>
00361 class DiagOp: public Operator<Scalar> {
00362
00363 private:
00364
00365 std::vector<Operator<Scalar> const * > op;
00366 StdProductSpace<Scalar> dom;
00367 StdProductSpace<Scalar> rng;
00368
00369 bool init() const {
00370 for (int i=0; i<op.size(); i++)
00371 if (!(op[i])) return false;
00372 return true;
00373 }
00374
00375 DiagOp();
00376
00377 protected:
00378
00379 void apply(const Vector<Scalar> & x,
00380 Vector<Scalar> & y) const {
00381 try {
00382 if (!init()) {
00383 RVLException e;
00384 e<<"ERROR: DiagOp::apply\n";
00385 e<<" not initialized\n";
00386 throw e;
00387 }
00388
00389
00390 Components<Scalar> cx(x);
00391 Components<Scalar> cy(y);
00392 if ((cx.getSize() != op.size()) ||
00393 (cy.getSize() != op.size())) {
00394 RVLException e;
00395 e<<"ERROR: DiagOp::apply\n";
00396 e<<" input or output vector has wrong number of args\n";
00397 throw e;
00398 }
00399 for (int i=0;i<op.size();i++)
00400 RVL::Operator<Scalar>::export_apply(*(op[i]),cx[i],cy[i]);
00401 }
00402 catch (RVLException & e) {
00403 e<<"\ncalled from DiagOp::apply\n";
00404 throw e;
00405 }
00406 }
00407
00408 void applyDeriv(const Vector<Scalar> & x,
00409 const Vector<Scalar> & dx,
00410 Vector<Scalar> & dy) const {
00411 try {
00412 if (!init()) {
00413 RVLException e;
00414 e<<"ERROR: DiagOp::applyDeriv\n";
00415 e<<" not initialized\n";
00416 throw e;
00417 }
00418 Components<Scalar> cx(x);
00419 Components<Scalar> cdx(dx);
00420 Components<Scalar> cdy(dy);
00421 if ((cx.getSize() != op.size()) ||
00422 (cdx.getSize() != op.size()) ||
00423 (cdy.getSize() != op.size())) {
00424 RVLException e;
00425 e<<"ERROR: DiagOp::applyDeriv\n";
00426 e<<" input or output vector has wrong number of args\n";
00427 throw e;
00428 }
00429 for (int i=0; i<op.size(); i++)
00430 RVL::Operator<Scalar>::export_applyDeriv(*(op[i]),cx[i],cdx[i],cdy[i]);
00431 }
00432 catch (RVLException & e) {
00433 e<<"\ncalled from DiagOp::applyDeriv\n";
00434 throw e;
00435 }
00436 }
00437
00438 void applyAdjDeriv(const Vector<Scalar> & x,
00439 const Vector<Scalar> & dy,
00440 Vector<Scalar> & dx) const {
00441 try {
00442 if (!init()) {
00443 RVLException e;
00444 e<<"ERROR: DiagOp::applyAdjDeriv\n";
00445 e<<" not initialized\n";
00446 throw e;
00447 }
00448
00449 Components<Scalar> cx(x);
00450 Components<Scalar> cdx(dx);
00451 Components<Scalar> cdy(dy);
00452 if ((cx.getSize() != op.size()) ||
00453 (cdx.getSize() != op.size()) ||
00454 (cdy.getSize() != op.size())) {
00455 RVLException e;
00456 e<<"ERROR: DiagOp::applyAdjDeriv\n";
00457 e<<" input or output vector has wrong number of args\n";
00458 throw e;
00459 }
00460 for (int i=0; i<op.size(); i++)
00461 RVL::Operator<Scalar>::export_applyAdjDeriv(*(op[i]),cx[i],cdy[i],cdx[i]);
00462 }
00463 catch (RVLException & e) {
00464 e<<"\ncalled from DiagOp::applyAdjDeriv\n";
00465 throw e;
00466 }
00467 }
00468
00469 void applyDeriv2(const Vector<Scalar> & x,
00470 const Vector<Scalar> & dx0,
00471 const Vector<Scalar> & dx1,
00472 Vector<Scalar> & dy) const {
00473 try {
00474 if (!init()) {
00475 RVLException e;
00476 e<<"ERROR: DiagOp::applyDeriv2\n";
00477 e<<" not initialized\n";
00478 throw e;
00479 }
00480
00481 Components<Scalar> cx(x);
00482 Components<Scalar> cdx0(dx0);
00483 Components<Scalar> cdx1(dx1);
00484 Components<Scalar> cdy(dy);
00485 if ((cx.getSize() != op.size()) ||
00486 (cdx0.getSize() != op.size()) ||
00487 (cdx1.getSize() != op.size()) ||
00488 (cdy.getSize() != op.size())) {
00489 RVLException e;
00490 e<<"ERROR: DiagOp::applyDeriv2\n";
00491 e<<" input or output vector has wrong number of args\n";
00492 throw e;
00493 }
00494 for (int i=0; i<op.size(); i++)
00495 RVL::Operator<Scalar>::export_applyDeriv2(*(op[i]),cx[i],cdx0[i],cdx1[i],cdy[i]);
00496 }
00497 catch (RVLException & e) {
00498 e<<"\ncalled from DiagOp::applyDeriv2\n";
00499 throw e;
00500 }
00501 }
00502
00503 void applyAdjDeriv2(const Vector<Scalar> & x,
00504 const Vector<Scalar> & dx0,
00505 const Vector<Scalar> & dy,
00506 Vector<Scalar> & dx1) const {
00507 try {
00508 if (!init()) {
00509 RVLException e;
00510 e<<"ERROR: DiagOp::applyAdjDeriv2\n";
00511 e<<" not initialized\n";
00512 throw e;
00513 }
00514
00515 Components<Scalar> cx(x);
00516 Components<Scalar> cdx0(dx0);
00517 Components<Scalar> cdx1(dx1);
00518 Components<Scalar> cdy(dy);
00519 if ((cx.getSize() != op.size()) ||
00520 (cdx0.getSize() != op.size()) ||
00521 (cdx1.getSize() != op.size()) ||
00522 (cdy.getSize() != op.size())) {
00523 RVLException e;
00524 e<<"ERROR: DiagOp::applyAdjDeriv2\n";
00525 e<<" input or output vector has wrong number of args\n";
00526 throw e;
00527 }
00528 for (int i=0; i<op.size(); i++)
00529 RVL::Operator<Scalar>::export_applyAdjDeriv2(*(op[i]),cx[i],cdx0[i],cdy[i],cdx1[i]);
00530
00531 }
00532 catch (RVLException & e) {
00533 e<<"\ncalled from DiagOp::applyAdjDeriv2\n";
00534 throw e;
00535 }
00536 }
00537
00538 Operator<Scalar> * clone() const { return new DiagOp(*this); }
00539
00540 public:
00541
00542 DiagOp(size_t nfac)
00543 : op(nfac, NULL), dom(nfac), rng(nfac) {}
00544
00545 DiagOp(DiagOp<Scalar> const & x)
00546 : op(x.op), dom(x.dom), rng(x.rng) {}
00547
00548 ~DiagOp() {}
00549
00550 void set(Operator<Scalar> const & a, size_t i) {
00551 if (op[i]) {
00552 RVLException e;
00553 e<<"ERROR: DiagOp::set\n";
00554 e<<" entry "<<i<<" already set\n";
00555 throw e;
00556 }
00557 op[i] = RVL::Operator<Scalar>::export_clone(a);
00558 dom.set(a.getDomain(),i);
00559 rng.set(a.getRange(),i);
00560 }
00561
00562 Space<Scalar> const & getDomain() const { return dom; }
00563 Space<Scalar> const & getRange() const { return rng; }
00564
00565 ostream & write(ostream & str) const {
00566 str<<"DiagOp: diagonal block operator\n";
00567 if (this->init()) {
00568 for (int i=0; i<op.size(); i++) {
00569 str<<"*** operator["<<i<<","<<i<<"]:\n";
00570 op[i]->write(str);
00571 }
00572 }
00573 else {
00574 str<<" incompletely initialized\n";
00575 }
00576 return str;
00577 }
00578 };
00579
00580
00581 template<typename Scalar>
00582 class BlockLinearOpBlock;
00583
00589 template<class Scalar>
00590 class BlockLinearOp: public LinearOp<Scalar> {
00591
00592 friend class BlockLinearOpBlock<Scalar>;
00593
00594 protected:
00595
00597 virtual void apply(int i, int j,
00598 const Vector<Scalar> & xj,
00599 Vector<Scalar> & yi) const = 0;
00600
00601 virtual void apply(Vector<Scalar> const & x,
00602 Vector<Scalar> & y) const {
00603 try {
00604 Components<Scalar> yc(y);
00605 Components<Scalar> xc(x);
00606 for (int i=0;i<(int)yc.getSize();i++) {
00607 yc[i].zero();
00608 Vector<Scalar> tmp(yc[i].getSpace());
00609 for (int j=0; j< (int)xc.getSize(); j++) {
00610 apply(i,j,xc[j],tmp);
00611 yc[i].linComb(ScalarFieldTraits<Scalar>::One(),tmp);
00612 }
00613 }
00614 }
00615 catch (RVLException & e) {
00616 e<<"\ncalled from BlockLinearOp::apply\n";
00617 throw e;
00618 }
00619 }
00620
00622 virtual void applyAdj(int i, int j,
00623 const Vector<Scalar> & yi,
00624 Vector<Scalar> & xj) const = 0;
00625
00629 virtual void applyAdj(const Vector<Scalar> & y,
00630 Vector<Scalar> & x) const {
00631 try {
00632 Components<Scalar> xc(x);
00633 Components<Scalar> yc(y);
00634 for (int j=0; j<(int)xc.getSize();j++) {
00635 xc[j].zero();
00636 Vector<Scalar> tmp(xc[j].getSpace());
00637 for (int i=0; i<(int)yc.getSize(); i++) {
00638 applyAdj(i,j,yc[i],tmp);
00639 xc[j].linComb(ScalarFieldTraits<Scalar>::One(),tmp);
00640 }
00641 }
00642 }
00643 catch (RVLException & e) {
00644 e<<"\ncalled from BlockLinearOp::applyAdjDeriv\n";
00645 throw e;
00646 }
00647 }
00648
00651 virtual BlockLinearOp<Scalar> * cloneBlockLinearOp() const = 0;
00652 LinearOp<Scalar> * clone() const { return cloneBlockLinearOp(); }
00653
00654 public:
00655
00656 BlockLinearOp() {}
00657 BlockLinearOp(const BlockLinearOp<Scalar> &) {}
00658 virtual ~BlockLinearOp() {}
00659
00661 virtual const ProductSpace<Scalar> & getProductDomain() const = 0;
00663 const Space<Scalar> & getDomain() const {
00664 return getProductDomain();
00665 }
00667 virtual const ProductSpace<Scalar> & getProductRange() const = 0;
00669 const Space<Scalar> & getRange() const {
00670 return getProductRange();
00671 }
00672
00673 };
00674
00677 template<class Scalar>
00678 class BlockLinearOpBlock: public LinearOp<Scalar> {
00679
00680 private:
00681
00682 BlockLinearOp<Scalar> const & blk;
00683 int row;
00684 int col;
00685
00686 protected:
00687
00688 virtual void apply(const Vector<Scalar> & xj,
00689 Vector<Scalar> & yi) const {
00690 try {
00691 blk.apply(row, col, xj, yi);
00692 }
00693 catch (RVLException & e) {
00694 e<<"\ncalled from BlockLinearOpBlock::apply\n";
00695 throw e;
00696 }
00697 }
00698
00699 virtual void applyAdj(const Vector<Scalar> & yi,
00700 Vector<Scalar> & xj) const {
00701 try {
00702 blk.applyAdj(row, col, yi, xj);
00703 }
00704 catch (RVLException & e) {
00705 e<<"\ncalled from BlockLinearOpBlock::applyAdj\n";
00706 throw e;
00707 }
00708 }
00709
00710 LinearOp<Scalar> * clone() const { return BlockLinearOpBlock(*this); }
00711
00712 public:
00713
00714 BlockLinearOpBlock(BlockLinearOp<Scalar> const & _blk, int _row, int _col): blk(_blk), row(_row), col(_col) {}
00715 BlockLinearOpBlock(const BlockLinearOpBlock<Scalar> & b): blk(b.blk), row(b.row), col(b.col) {}
00716 ~BlockLinearOpBlock() {}
00717
00719 const Space<Scalar> & getDomain() const {
00720 return blk.getProductDomain()[col];
00721 }
00723 const Space<Scalar> & getRange() const {
00724 return blk.getProductRange()[row];
00725 }
00726
00727 };
00728
00733 template<class Scalar>
00734 class ColumnLinearOp: public LinearOp<Scalar> {
00735
00736 friend class OperatorEvaluation<Scalar>;
00737
00738 protected:
00739
00740 virtual void applyComponent(int i,
00741 const Vector<Scalar> & x,
00742 Vector<Scalar> & yi) const = 0;
00743
00744 virtual void apply(Vector<Scalar> const & x,
00745 Vector<Scalar> & y) const {
00746 try {
00747 Components<Scalar> yc(y);
00748 for (int i=0;i<(int)yc.getSize();i++)
00749 applyComponent(i,x,yc[i]);
00750 }
00751 catch (RVLException & e) {
00752 e<<"\ncalled from ColumnLinearOp::apply\n";
00753 throw e;
00754 }
00755 }
00756
00757
00759 virtual void applyComponentAdj(int i,
00760 const Vector<Scalar> & yi,
00761 Vector<Scalar> & x) const = 0;
00762
00766 virtual void applyAdj(const Vector<Scalar> & x,
00767 Vector<Scalar> & y) const {
00768 try {
00769 Components<Scalar> xc(x);
00770 applyComponentAdj(0,xc[0],y);
00771 if (xc.getSize()>0) {
00772 Vector<Scalar> tmp(this->getDomain(),true);
00773 for (int i=1; i<(int)xc.getSize(); i++) {
00774 applyComponentAdj(i,xc[i],tmp);
00775 y.linComb(1.0,tmp);
00776 }
00777 }
00778 }
00779 catch (RVLException & e) {
00780 e<<"\ncalled from ColumnLinearOp::applyAdjDeriv\n";
00781 throw e;
00782 }
00783 }
00784
00787 virtual ColumnLinearOp<Scalar> * cloneColumnLinearOp() const = 0;
00788 LinearOp<Scalar> * clone() const { return cloneColumnLinearOp(); }
00789
00790 public:
00791
00792 ColumnLinearOp() {}
00793 ColumnLinearOp(const ColumnLinearOp<Scalar> &) {}
00794 virtual ~ColumnLinearOp() {}
00795
00797 virtual const ProductSpace<Scalar> & getProductRange() const = 0;
00799 const Space<Scalar> & getRange() const {
00800 return getProductRange();
00801 }
00802
00803 };
00804
00809 template<typename Scalar>
00810 class TensorLinearOp: public ColumnLinearOp<Scalar> {
00811
00812 private:
00813
00814 LinearOp<Scalar> const & op1;
00815 LinearOp<Scalar> const & op2;
00816 StdProductSpace<Scalar> rng;
00817
00818 TensorLinearOp();
00819
00820 protected:
00821
00822 void applyComponent(int i,
00823 const Vector<Scalar> & x,
00824 Vector<Scalar> & yi) const {
00825 try {
00826 if (i==0) this->export_apply(op1,x,yi);
00827 else if (i==1) this->export_apply(op2,x,yi);
00828 else {
00829 RVLException e;
00830 e<<"Error: TensorLinearOp::applyComponent\n";
00831 e<<"index "<<i<<" out of range [0,1]\n";
00832 throw e;
00833 }
00834 }
00835 catch (RVLException & e) {
00836 e<<"\ncalled from TensorLinearOp::applyComponent\n";
00837 throw e;
00838 }
00839 }
00840
00841 void applyComponentAdj(int i,
00842 const Vector<Scalar> & yi,
00843 Vector<Scalar> & x) const {
00844 try {
00845 if (i==0) op1.applyAdjOp(yi,x);
00846 else if (i==1) op2.applyAdjOp(yi,x);
00847 else {
00848 RVLException e;
00849 e<<"Error: TensorLinearOp::applyComponentAdj\n";
00850 e<<"index "<<i<<" out of range [0,1]\n";
00851 throw e;
00852 }
00853 }
00854 catch (RVLException & e) {
00855 e<<"\ncalled from TensorLinearOp::applyComponentAdj\n";
00856 throw e;
00857 }
00858 }
00859
00860 TensorLinearOp<Scalar> * cloneTensorLinearOp() const { return new TensorLinearOp(*this); }
00861 ColumnLinearOp<Scalar> * cloneColumnLinearOp() const { return cloneTensorLinearOp(); }
00862
00863 public:
00864
00865 TensorLinearOp(LinearOp<Scalar> const & _op1,
00866 LinearOp<Scalar> const & _op2)
00867 : op1(_op1), op2(_op2), rng(op1.getRange(),op2.getRange()) {
00868 try {
00869 if (op1.getDomain() != op2.getDomain()) {
00870 RVLException e;
00871 e<<"Error: TensorLinearOp constructor\n";
00872 e<<"input operators do not have same domain\n";
00873 throw e;
00874 }
00875 }
00876 catch (RVLException & e) {
00877 e<<"\ncalled from TensorLinearOp constructor\n";
00878 throw e;
00879 }
00880 }
00881
00882 TensorLinearOp(TensorLinearOp<Scalar> const & op)
00883 : op1(op.op1), op2(op.op2), rng(op1.getRange(),op2.getRange()) {}
00884
00885 ~TensorLinearOp() {}
00886
00887 Space<Scalar> const & getDomain() const { return op1.getDomain(); }
00888 ProductSpace<Scalar> const & getProductRange() const { return rng; }
00889
00890 ostream & write(ostream & str) const {
00891 str<<"TensorLinearOp: 2x1 block operator\n";
00892 str<<"*** LinearOp[0,0]:\n";
00893 op1.write(str);
00894 str<<"*** LinearOp[1,0]:\n";
00895 op2.write(str);
00896 return str;
00897 }
00898 };
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01136 template<typename Scalar>
01137 class InjectOp: public Operator<Scalar> {
01138
01139 private:
01140
01141 std::shared_ptr<Vector<Scalar> > ref;
01142 Components<Scalar> cref;
01143 StdProductSpace<Scalar> dom;
01144 std::vector<int> icvec;
01145
01146 protected:
01147
01148 void apply(Vector<Scalar> const & x,
01149 Vector<Scalar> & y) const {
01150
01151 try {
01152
01153 y.copy(*ref);
01154 Components<Scalar> cy(y);
01155 Components<Scalar> cx(x);
01156 for (int i=0; i<icvec.size(); i++)
01157 cy[icvec[i]].copy(cx[i]);
01158 }
01159 catch (RVLException &e) {
01160 e<<"\ncalled from InjectOp::apply\n";
01161 throw e;
01162 }
01163 }
01164
01165 void applyDeriv(Vector<Scalar> const & x,
01166 Vector<Scalar> const & dx,
01167 Vector<Scalar> & dy) const {
01168 try {
01169 dy.zero();
01170 Components<Scalar> cx(dx);
01171 Components<Scalar> cy(dy);
01172 for (int i=0; i<icvec.size(); i++)
01173 cy[icvec[i]].copy(cx[i]);
01174 }
01175 catch (RVLException &e) {
01176 e<<"\ncalled from InjectOp::applyDeriv\n";
01177 throw e;
01178 }
01179 }
01180
01181 void applyAdjDeriv(Vector<Scalar> const & x,
01182 Vector<Scalar> const & dy,
01183 Vector<Scalar> & dx) const {
01184 try {
01185 Components<Scalar> cy(dy);
01186 Components<Scalar> cx(dx);
01187 for (int i=0; i<icvec.size(); i++)
01188 cx[i].copy(cy[icvec[i]]);
01189 }
01190 catch (RVLException &e) {
01191 e<<"\ncalled from InjectOp::applyAdjDeriv\n";
01192 throw e;
01193 }
01194 }
01195
01196 Operator<Scalar> * clone() const { return new InjectOp(*this); }
01197
01198 public:
01199
01200 InjectOp(std::shared_ptr<Vector<Scalar> > _ref,
01201 int _icomp)
01202 : ref(_ref), cref(*ref),
01203 dom(cref[_icomp].getSpace()),
01204 icvec(1,_icomp) {}
01205
01206 InjectOp(std::shared_ptr<Vector<Scalar> > _ref,
01207 std::vector<int> _icvec)
01208 : ref(_ref), cref(*ref), icvec(_icvec), dom(_icvec.size()) {
01209 for (int i=0; i<icvec.size(); i++)
01210 dom.set(cref[i].getSpace(),i);
01211 }
01212
01213 InjectOp(InjectOp<Scalar> const & f)
01214 : ref(f.ref), cref(*ref), dom(f.dom), icvec(f.icvec) {}
01215
01216 ~InjectOp() {}
01217
01218 Space<Scalar> const & getDomain() const { return dom; }
01219 Space<Scalar> const & getRange() const {
01220 return ref->getSpace();
01221 }
01222
01223 ostream & write(ostream & str) const {
01224 str<<"InjectOp object\n";
01225 str<<"components = \n";
01226 for (int i=0; i<icvec.size(); i++) str<<" index = "<<i<<" value = "<<icvec[i]<<"\n";
01227 str<<"reference vector in output product space:\n";
01228 ref->write(str);
01229 return str;
01230 }
01231 };
01232 }
01233
01234 #endif