rnop.hh

Go to the documentation of this file.
00001 /*************************************************************************
00002 
00003 Copyright Rice University, 2011.
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
00030 
00031 **************************************************************************/
00032 
00033 #ifndef __RVL_RNOP
00034 #define __RVL_RNOP
00035 
00036 #include "op.hh"
00037 #include "rnmat.hh"
00038 
00051 namespace RVL {
00052 
00054   template<typename T, int f(int, int, T const *, T *)>
00055   class CFunction: public BinaryLocalFunctionObject<T> {
00056   public:
00057     void operator()(LocalDataContainer<T> & y,
00058             LocalDataContainer<T> const & x) {
00059       int err=0;
00060       if (err=f(y.getSize(), x.getSize(), x.getData(), y.getData())) {
00061     RVLException e;
00062     e<<"Error: CFunction::operator() - err="<<err<<"\n";
00063     throw e;
00064       } 
00065     }
00066     string getName() const { string tmp = "CFunction"; return tmp; }
00067   };
00068 
00081   template<typename T, int df(int, int, T const *, T *)>
00082   class CJacobian: public UnaryLocalFunctionObjectConstEval<T> {
00083   private:
00084     GenMat<T> & a;
00085     CJacobian();
00086     CJacobian(CJacobian<T, df> const &);
00087   public:
00088     CJacobian(GenMat<T> & _a): a(_a) {}
00089     void operator()(LocalDataContainer<T> const & x) {
00090       int err=0;
00091       if (err=df(a.getNRows(), a.getNCols(), x.getData(), a.getData())) {
00092     RVLException e;
00093     e<<"Error: CJacobian::operator() - err="<<err<<"\n";
00094     throw e;
00095       }
00096     }
00097     string getName() const { string tmp = "CJacobian"; return tmp; }
00098   };
00099 
00101   template<typename T> 
00102   class OpWithGenMatDeriv: public Operator<T> {
00103   public:
00104     virtual GenMat<T> const & getGenMat() const = 0;
00105   };
00106 
00111   template<typename T, int f(int, int, T const *, T *), int df(int, int, T const *, T *)>
00112   class GenOp: public OpWithGenMatDeriv<T> {
00113     
00114   private:
00115 
00116     // domain and range
00117     RnSpace<T> const & dom;
00118     RnSpace<T> const & rng;
00119 
00120     // GenMat matrix LinearOp object and intialization flag,
00121     // modifiable post-construction
00122     mutable GenMat<T> deriv;
00123     mutable bool init;
00124 
00125     // common code for intializing the Jacobian (GenMat object),
00126     // hoisted out. Note that initialization will be done only once,
00127     // per the design of Operator.
00128     void buildJacobian(Vector<T> const & x) const {
00129       try {
00130     if (!init) {
00131       CJacobian<T, df> j(deriv);
00132       x.eval(j);
00133       init=true;
00134     }
00135       }
00136       catch (RVLException & e) {
00137     e<<"\ncalled from GenOp::buildJacobian\n";
00138     throw e;
00139       }
00140     }
00141 
00142     GenOp();
00143 
00144   protected:
00145     
00147     virtual void apply(const Vector<T> & x, 
00148                Vector<T> & y) const {
00149       try {
00150     CFunction<T, f> ff;
00151     y.eval(ff,x);
00152     // why not
00153     buildJacobian(x);
00154       }
00155       catch (RVLException & e) {
00156     e<<"\ncalled from GenOp::apply\n";
00157     throw e;
00158       }
00159     }
00160       
00162     virtual void applyDeriv(const Vector<T> & x, 
00163                 const Vector<T> & dx,
00164                 Vector<T> & dy) const {
00165       try {
00166     buildJacobian(x);
00167     deriv.applyOp(dx,dy);
00168       }
00169       catch (RVLException & e) {
00170     e<<"\ncalled from GenOp::applyDeriv\n";
00171     throw e;
00172       }
00173     }
00174 
00176     virtual void applyAdjDeriv(const Vector<T> & x, 
00177                    const Vector<T> & dy,
00178                    Vector<T> & dx) const {
00179       try {
00180     buildJacobian(x);
00181     deriv.applyAdjOp(dy,dx);
00182       }
00183       catch (RVLException & e) {
00184     e<<"\ncalled from GenOp::applyAdjDeriv\n";
00185     throw e;
00186       }
00187     }    
00188 
00189     virtual Operator<T> * clone() const {
00190       return new GenOp<T, f, df>(dom,rng);
00191     }
00192 
00193   public:
00194 
00196     GenOp(RnSpace<T> const & _dom, RnSpace<T> const & _rng)
00197       : dom(_dom), rng(_rng), deriv(dom,rng), init(false) {}
00202     GenOp(GenOp<T, f, df> const & a)
00203       : dom(a.dom), rng(a.rng), deriv(dom,rng), init(false) {}
00204     
00205     Space<T> const & getDomain() const { return dom; }
00206     Space<T> const & getRange() const { return rng; }
00207 
00210     GenMat<T> const & getGenMat() const { 
00211       if (init) return deriv;
00212       RVLException e;
00213       e<<"Error: GenOp::getGenMat\n";
00214       e<<"Jacobian matrix not initialized - must evaluate somewhere first!\n";
00215       throw e;
00216     }
00217 
00218     ostream & write(ostream & str) const {
00219       str<<"GenOp instance\n";
00220       str<<"domain:\n";
00221       dom.write(str);
00222       str<<"range:\n";
00223       rng.write(str);
00224       return str; 
00225     }
00226   };
00227 
00228 }
00229 
00230 #endif

Generated on 5 Jan 2017 for LocalRVL by  doxygen 1.4.7