VPM.hh

Go to the documentation of this file.
00001 #ifndef __RVLALG_LINFIT_L2_H
00002 #define __RVLALG_LINFIT_L2_H
00003 
00004 #include "op.hh"
00005 #include "alg.hh"
00006 #include "cgalg.hh"
00007 #include "cgnealg.hh"
00008 #include "terminator.hh"
00009 #include "table.hh"
00010 
00011 using namespace RVLAlg;
00012 
00013 namespace RVLUmin {
00014     
00015   using namespace RVL;
00016   using namespace RVLAlg;
00017     
00024   template<typename Scalar, typename LSPolicy, typename LSPolicyData>
00025   class VPM: public Functional<Scalar>, public LSPolicy {
00026         
00027     typedef typename ScalarFieldTraits<Scalar>::AbsType atype;
00028         
00029   private:
00030       
00031     LinOpValOp<Scalar> const & op;      // operator
00032     Vector<Scalar> const & d;           // data
00033     mutable Vector<Scalar> dx;         // linear solution
00034     mutable bool applied;
00035     ostream & str;
00036         
00037   protected:
00038         
00039     void apply(const Vector<Scalar> & x,
00040            Scalar & val) const {
00041       try {
00042     atype rnorm;
00043     atype nrnorm;
00044     // access linear part
00045     LinearRestrictOp<Scalar> lop(op,x);
00046     dx.zero();
00047           
00048     Algorithm * solver
00049       = LSPolicy::build(dx,lop,d,rnorm,nrnorm,str);
00050       
00051     solver->run();
00052           
00053     // get the value of objective function
00054     val = 0.5*rnorm*rnorm;
00055 
00056     applied = true;
00057     delete solver;
00058       }
00059       catch (RVLException & e) {
00060     e<<"\ncalled from VPM::apply\n";
00061     throw e;
00062       }
00063     }
00064         
00065     void applyGradient(const Vector<Scalar> & x,
00066                Vector<Scalar> & g) const {
00067       try {
00068     // compute dx, value
00069     if(!applied){
00070       Scalar val;
00071       this->apply(x,val);
00072     }
00073 
00074     // access linear part
00075     LinearRestrictOp<Scalar> lop(op,x);
00076 
00077     // compute residual dd = F(x)dx-d
00078     Vector<Scalar> dd(lop.getRange());
00079     lop.applyOp(dx,dd);   
00080     dd.linComb(-1.0,d);
00081 
00082     // access nonlinear part - input product vector with linear
00083     // part set
00084     Vector<Scalar> xx(op.getDomain());
00085     Components<Scalar> cxx(xx);
00086     cxx[1].copy(dx);
00087     RestrictOp<Scalar> rop(op,xx,0);
00088 
00089     // access evaluation, linearization
00090     OperatorEvaluation<Scalar> ropeval(rop,x);
00091 
00092     // naive computation of gradient
00093     ropeval.getDeriv().applyAdjOp(dd,g);
00094       }
00095       catch (RVLException & e) {
00096     e<<"\ncalled from VPM::applyGradient\n";
00097     throw e;
00098       }   
00099     }
00100         
00101     void applyHessian(const Vector<Scalar> & x,
00102               const Vector<Scalar> & dx,
00103               Vector<Scalar> & dy) const {
00104       RVLException e;
00105       e<<"ERROR: VPM::applyHessian\n";
00106       e<<"  Hessian not defined\n";
00107       throw e;
00108     }
00109         
00110     Functional<Scalar> * clone() const {
00111       return new VPM<Scalar,LSPolicy,LSPolicyData>(*this);
00112     }
00113         
00114   public:
00115       
00116     VPM(LinOpValOp<Scalar> const & _op,
00117     Vector<Scalar> const & _d,
00118     LSPolicyData const & s,
00119     ostream & _str=cerr)
00120       : LSPolicy(), op(_op), d(_d),
00121         dx(op.getProductDomain()[1]),
00122         applied(false), str(_str) {
00123       try{
00124     dx.zero();
00125     LSPolicy::assign(s);
00126     if (s.verbose) {
00127       str<<"\n";
00128       str<<"==============================================\n";
00129       str<<"VPM constructor - ls policy data = \n";
00130       s.write(str);
00131     }
00132       }
00133       catch (RVLException & e) {
00134     e<<"\ncalled from VPM::Constructor\n";
00135     throw e;
00136       }
00137     }
00138       
00139     VPM(VPM<Scalar,LSPolicy,LSPolicyData> const & f) 
00140       : LSPolicy(f), op(f.op), d(f.d), dx(f.dx),
00141     applied(f.applied), str(f.str) {}
00142         
00143     const Space<Scalar> & getDomain() const { 
00144       return (op.getProductDomain())[0];
00145     }
00146       
00147     Scalar getMaxStep(const Vector<Scalar> & x,
00148               const Vector<Scalar> & dx) const {
00149       try {
00150     return op.getMaxStep(x,dx);
00151       }
00152       catch (RVLException & e) {
00153     e<<"\ncalled from VPM::getMaxStep\n";
00154     throw e;
00155       }
00156     }
00157       
00158     Vector<Scalar> const & getLSSoln() const { return dx; }
00159       
00160     ostream & write(ostream & str) const {
00161       str<<"VPM: \n";
00162       str<<"*** LinearOp valued operator:\n";
00163       op.write(str);
00164       str<<"*** data vector:\n";
00165       d.write(str);
00166       str<<"*** linear LS solution dx:\n";
00167       dx.write(str);
00168       str<<"*** applied = " << applied << "\n";
00169       return str;
00170     }
00171   };
00172 
00173 }
00174 #endif

Generated on 5 Jan 2017 for RvlUmin by  doxygen 1.4.7