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;
00032 Vector<Scalar> const & d;
00033 mutable Vector<Scalar> dx;
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
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
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
00069 if(!applied){
00070 Scalar val;
00071 this->apply(x,val);
00072 }
00073
00074
00075 LinearRestrictOp<Scalar> lop(op,x);
00076
00077
00078 Vector<Scalar> dd(lop.getRange());
00079 lop.applyOp(dx,dd);
00080 dd.linComb(-1.0,d);
00081
00082
00083
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
00090 OperatorEvaluation<Scalar> ropeval(rop,x);
00091
00092
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