URI: 
       tIPDesignVariableParameterization.hh - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
  HTML git clone git://src.adamsgaard.dk/pism
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       tIPDesignVariableParameterization.hh (6174B)
       ---
            1 // Copyright (C) 2011, 2012, 2013, 2014, 2015  David Maxwell
            2 //
            3 // This file is part of PISM.
            4 //
            5 // PISM is free software; you can redistribute it and/or modify it under the
            6 // terms of the GNU General Public License as published by the Free Software
            7 // Foundation; either version 3 of the License, or (at your option) any later
            8 // version.
            9 //
           10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
           11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
           12 // FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
           13 // details.
           14 //
           15 // You should have received a copy of the GNU General Public License
           16 // along with PISM; if not, write to the Free Software
           17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
           18 
           19 
           20 #ifndef IPTAUCPARAMETERIZATION_HH_7ZRETI1S
           21 #define IPTAUCPARAMETERIZATION_HH_7ZRETI1S
           22 
           23 #include <string>
           24 
           25 namespace pism {
           26 
           27 class Config;
           28 class IceModelVec2S;
           29 
           30 namespace inverse {
           31 
           32 //! Encapsulates a parameterization of a design variable (e.g. \f$\tau_c\f$ for SSA inversions)
           33 //! as a function of a different parameter \f$\zeta\f$.
           34 /*!
           35   When solving an inverse problem for a design variable \f$d\f$ (think of
           36   \f$\tau_c\f$ or hardness for SSA inversions), one frequently does
           37   not work with \f$d\f$ directly but with a different
           38   variable \f$\zeta\f$, and a relationship \f$d=g(\zeta)\f$.
           39   A common choice in the glaciology literature for \f$\tau_c\f$
           40   is \f$\tau_c=g(\zeta)=\zeta^2\f$, which ensures that \f$\tau_c\f$ is 
           41   non-negative, but has the disadvantage that it is a 2-1 parameterization.  A potentially
           42   more satisfactory choice is \f$g(\zeta)=e^\zeta\f$, which ensures
           43   positivitiy, is 1-1, and respects the wide scale variations of \f$\tau_c\f$.
           44 
           45   An IPDesignVariableParameterization implements such a parameterization map.
           46 
           47   This method of encoding mathematical expressions is flexible and convenient,
           48   but is also slow; it has the overhead that many virtual function calls are
           49   needed if the expression is being called over and over again.  If this
           50   proves to be a significant source of slowness, we could look at 
           51   using the Expression Template idiom, http://drdobbs.com/184401627.
           52 
           53   For certain Tikhonov inversions, it is important to mainain well-scaled
           54   variables.  If the design parameter name is 'foo', internally the parameterizations 
           55   use units of \f$d\f$ such that  the config parameter \a design_param_foo_scale equals one. I.e.
           56   if 'foo' is 'tauc', then  for a conversion function \f$g(\zeta)=\zeta^2\f$, 
           57   \f[
           58   \frac{d} = d_{\rm scale}g(\zeta^2).
           59   \f]
           60   where \f$d_{\rm scale}={\tt design_param_tauc_scale}\f$.
           61 */
           62 class IPDesignVariableParameterization 
           63 {
           64 public:
           65   
           66   IPDesignVariableParameterization() {};
           67   
           68   virtual ~IPDesignVariableParameterization() {};
           69 
           70   virtual void set_scales(const Config &config, const std::string &design_var_name);
           71 
           72   //! Converts from parameterization value \f$\zeta\f$ to \f$d=g(\zeta)\f$.
           73   /*!
           74     \param[in] zeta The parameter value.
           75     \param[out] value The value \f$g(\zeta)\f$.
           76     \param[out] derivative The value \f$g'(\zeta)\f$. */
           77   virtual void toDesignVariable(double zeta, double *value, double *derivative) = 0;
           78   
           79   //! Converts from \f$d\f$ to a parameterization value \f$\zeta\f$ such that \f$d=g(\zeta)\f$.  
           80   /*! More than one such \f$\zeta\f$ may exist; only one is returned. */
           81   virtual void fromDesignVariable(double d, double *OUTPUT) = 0;
           82 
           83   virtual void convertToDesignVariable(IceModelVec2S &zeta, IceModelVec2S &d, bool communicate = true);
           84 
           85   virtual void convertFromDesignVariable(IceModelVec2S &d, IceModelVec2S &zeta,  bool communicate = true);
           86 protected:
           87   
           88   double m_d_scale;  ///< Value of \f$d\f$ in PISM units that equals 1 for IPDesignVariableParameterization's units.
           89 };
           90 
           91 //! Parameterization \f$d=d_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\zeta\f$.
           92 class IPDesignVariableParamIdent: public IPDesignVariableParameterization
           93 {
           94 public:
           95   IPDesignVariableParamIdent() { /*do nothing*/ };
           96 
           97   virtual ~IPDesignVariableParamIdent() {};
           98 
           99   virtual void toDesignVariable(double p, double *value, double *derivative);
          100 
          101   virtual void fromDesignVariable(double tauc, double *OUTPUT);
          102 };
          103 
          104 //! Parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\zeta^2\f$.
          105 class IPDesignVariableParamSquare: public IPDesignVariableParameterization
          106 {
          107 public:
          108   IPDesignVariableParamSquare() { /*do nothing*/ };
          109 
          110   virtual ~IPDesignVariableParamSquare() {};
          111 
          112   virtual void toDesignVariable(double p, double *value, double *derivative);
          113 
          114   virtual void fromDesignVariable(double tauc, double *OUTPUT);
          115 };
          116 
          117 //! Parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\exp(\zeta)\f$.
          118 class IPDesignVariableParamExp: public IPDesignVariableParameterization
          119 {
          120 public:
          121   IPDesignVariableParamExp() { /*do nothing*/ };
          122 
          123   virtual ~IPDesignVariableParamExp() {};
          124 
          125   virtual void set_scales(const Config &config, const std::string &design_var_name);
          126 
          127   virtual void toDesignVariable(double p, double *value, double *derivative);
          128 
          129   virtual void fromDesignVariable(double tauc, double *OUTPUT);
          130 
          131 private:
          132   double m_d_eps;
          133 };
          134 
          135 
          136 //! A monotone non-negative parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ that is approximately the identity away from small values of  \f$\tau_c\f$
          137 /*! More specifically, \f$g(\zeta)\rightarrow 0\f$ as \f$\zeta\rightarrow-\infty\f$ and \f$g(\zeta)\approx p\f$ 
          138   for large values of \f$\zeta\f$.  The transition from a nonlinear to an approximately linear 
          139   function occurs in the neighbourhood of the parameter \f$d_0\f$. */
          140 class IPDesignVariableParamTruncatedIdent: public IPDesignVariableParameterization
          141 {
          142 public:
          143   IPDesignVariableParamTruncatedIdent() {};
          144 
          145   virtual ~IPDesignVariableParamTruncatedIdent() {};
          146 
          147   virtual void set_scales(const Config &config, const std::string &design_var_name);
          148 
          149   virtual void toDesignVariable(double p, double *value, double *derivative);
          150 
          151   virtual void fromDesignVariable(double d, double *OUTPUT);
          152 
          153 private:
          154   double m_d0_sq;
          155   double m_d_eps;
          156 };
          157 
          158 } // end of namespace inverse
          159 } // end of namespace pism
          160 
          161 #endif /* end of include guard: IPTAUCPARAMETERIZATION_HH_7ZRETI1S */