| 1 | // | 
|---|
| 2 | // C++ Interface: itpp_ext | 
|---|
| 3 | // | 
|---|
| 4 | // Description: | 
|---|
| 5 | // | 
|---|
| 6 | // | 
|---|
| 7 | // Author: smidl <smidl@utia.cas.cz>, (C) 2008 | 
|---|
| 8 | // | 
|---|
| 9 | // Copyright: See COPYING file that comes with this distribution | 
|---|
| 10 | // | 
|---|
| 11 | // | 
|---|
| 12 | #ifndef FN_H | 
|---|
| 13 | #define FN_H | 
|---|
| 14 |  | 
|---|
| 15 | #include "../base/bdmbase.h" | 
|---|
| 16 |  | 
|---|
| 17 | namespace bdm { | 
|---|
| 18 |  | 
|---|
| 19 | //! class representing function \f$f(x) = a\f$, here \c rv is empty | 
|---|
| 20 | class constfn : public fnc { | 
|---|
| 21 |         //! value of the function | 
|---|
| 22 |         vec val; | 
|---|
| 23 |  | 
|---|
| 24 | public: | 
|---|
| 25 |         //vec eval() {return val;}; | 
|---|
| 26 |         //! inherited | 
|---|
| 27 |         vec eval ( const vec &cond ) { | 
|---|
| 28 |                 return val; | 
|---|
| 29 |         }; | 
|---|
| 30 |         //!Default constructor | 
|---|
| 31 |         constfn ( const vec &val0 ) : fnc(), val ( val0 ) { | 
|---|
| 32 |                 dimy = val.length(); | 
|---|
| 33 |         }; | 
|---|
| 34 | }; | 
|---|
| 35 |  | 
|---|
| 36 | //! Class representing function \f$f(x) = Ax+B\f$ | 
|---|
| 37 | class linfn: public fnc { | 
|---|
| 38 |         //! Identification of \f$x\f$ | 
|---|
| 39 |         RV rv; | 
|---|
| 40 |         //! Matrix A | 
|---|
| 41 |         mat A; | 
|---|
| 42 |         //! vector B | 
|---|
| 43 |         vec B; | 
|---|
| 44 | public : | 
|---|
| 45 |         vec eval ( const vec &cond ) { | 
|---|
| 46 |                 it_assert_debug ( cond.length() == A.cols(), "linfn::eval Wrong cond." ); | 
|---|
| 47 |                 return A*cond + B; | 
|---|
| 48 |         }; | 
|---|
| 49 |  | 
|---|
| 50 | //              linfn evalsome ( ivec &rvind ); | 
|---|
| 51 |         //!default constructor | 
|---|
| 52 |         linfn ( ) : fnc(), A ( ), B () { }; | 
|---|
| 53 |         //! Set values of \c A and \c B | 
|---|
| 54 |         void set_parameters ( const mat &A0 , const vec &B0 ) { | 
|---|
| 55 |                 A = A0; | 
|---|
| 56 |                 B = B0; | 
|---|
| 57 |                 dimy = A.rows(); | 
|---|
| 58 |         }; | 
|---|
| 59 | }; | 
|---|
| 60 |  | 
|---|
| 61 |  | 
|---|
| 62 | /*! | 
|---|
| 63 | \brief Class representing a differentiable function of two variables \f$f(x,u)\f$. | 
|---|
| 64 |  | 
|---|
| 65 | Function of two variables. | 
|---|
| 66 |  | 
|---|
| 67 | TODO: | 
|---|
| 68 | 1) Technically, it could have a common parent (e.g. \c fnc ) with other functions. For now, we keep it as it is. | 
|---|
| 69 | 2) It could be generalized into multivariate form, (which was original meaning of \c fnc ). | 
|---|
| 70 | */ | 
|---|
| 71 | class diffbifn: public fnc { | 
|---|
| 72 | protected: | 
|---|
| 73 |         //! Indentifier of the first rv. | 
|---|
| 74 |         RV rvx; | 
|---|
| 75 |         //! Indentifier of the second rv. | 
|---|
| 76 |         RV rvu; | 
|---|
| 77 |         //! cache for rvx.count() | 
|---|
| 78 |         int dimx; | 
|---|
| 79 |         //! cache for rvu.count() | 
|---|
| 80 |         int dimu; | 
|---|
| 81 | public: | 
|---|
| 82 |         //! Evaluates \f$f(x0,u0)\f$ (VS: Do we really need common eval? ) | 
|---|
| 83 |         vec eval ( const vec &cond ) { | 
|---|
| 84 |                 it_assert_debug ( cond.length() == ( dimx + dimu ), "linfn::eval Wrong cond." ); | 
|---|
| 85 |                 return eval ( cond ( 0, dimx - 1 ), cond ( dimx, dimx + dimu - 1 ) );//-1 = end (in matlab) | 
|---|
| 86 |         }; | 
|---|
| 87 |  | 
|---|
| 88 |         //! Evaluates \f$f(x0,u0)\f$ | 
|---|
| 89 |         virtual vec eval ( const vec &x0, const vec &u0 ) { | 
|---|
| 90 |                 return zeros ( dimy ); | 
|---|
| 91 |         }; | 
|---|
| 92 |         //! Evaluates \f$A=\frac{d}{dx}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed. @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. | 
|---|
| 93 |         virtual void dfdx_cond ( const vec &x0, const vec &u0, mat &A , bool full = true ) {}; | 
|---|
| 94 |         //! Evaluates \f$A=\frac{d}{du}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed.        @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. | 
|---|
| 95 |         virtual void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full = true ) {}; | 
|---|
| 96 |         //!Default constructor (dimy is not set!) | 
|---|
| 97 |         diffbifn () : fnc() {}; | 
|---|
| 98 |         //! access function | 
|---|
| 99 |         int _dimx() const { | 
|---|
| 100 |                 return dimx; | 
|---|
| 101 |         } | 
|---|
| 102 |         //! access function | 
|---|
| 103 |         int _dimu() const { | 
|---|
| 104 |                 return dimu; | 
|---|
| 105 |         } | 
|---|
| 106 | }; | 
|---|
| 107 |  | 
|---|
| 108 | //! Class representing function \f$f(x,u) = Ax+Bu\f$ | 
|---|
| 109 | //TODO can be generalized into multilinear form! | 
|---|
| 110 | class bilinfn: public diffbifn { | 
|---|
| 111 |         mat A; | 
|---|
| 112 |         mat B; | 
|---|
| 113 | public : | 
|---|
| 114 |         //!\name Constructors | 
|---|
| 115 |         //!@{ | 
|---|
| 116 |  | 
|---|
| 117 |         bilinfn () : diffbifn () , A() , B()    {}; | 
|---|
| 118 |         bilinfn ( const mat A0, const mat B0 ) { | 
|---|
| 119 |                 set_parameters ( A0, B0 ); | 
|---|
| 120 |         }; | 
|---|
| 121 |         //! Alternative constructor | 
|---|
| 122 |         void set_parameters ( const mat A0, const mat B0 ) { | 
|---|
| 123 |                 it_assert_debug ( A0.rows() == B0.rows(), "" ); | 
|---|
| 124 |                 A = A0; | 
|---|
| 125 |                 B = B0; | 
|---|
| 126 |                 dimy = A.rows(); | 
|---|
| 127 |                 dimx = A.cols(); | 
|---|
| 128 |                 dimu = B.cols(); | 
|---|
| 129 |         } | 
|---|
| 130 |         //!@} | 
|---|
| 131 |  | 
|---|
| 132 |         //!\name Mathematical operations | 
|---|
| 133 |         //!@{ | 
|---|
| 134 |         inline vec eval ( const  vec &x0, const vec &u0 ) { | 
|---|
| 135 |                 it_assert_debug ( x0.length() == dimx, "linfn::eval Wrong xcond." ); | 
|---|
| 136 |                 it_assert_debug ( u0.length() == dimu, "linfn::eval Wrong ucond." ); | 
|---|
| 137 |                 return A*x0 + B*u0; | 
|---|
| 138 |         } | 
|---|
| 139 |  | 
|---|
| 140 |         void dfdx_cond ( const vec &x0, const vec &u0, mat &F, bool full ) { | 
|---|
| 141 |                 it_assert_debug ( ( F.cols() == A.cols() ) & ( F.rows() == A.rows() ), "Allocated F is not compatible." ); | 
|---|
| 142 |                 if ( full ) F = A;      //else : nothing has changed no need to regenerate | 
|---|
| 143 |         } | 
|---|
| 144 |         //! | 
|---|
| 145 |         void dfdu_cond ( const vec &x0, const vec &u0, mat &F,  bool full = true ) { | 
|---|
| 146 |                 it_assert_debug ( ( F.cols() == B.cols() ) & ( F.rows() == B.rows() ), "Allocated F is not compatible." ); | 
|---|
| 147 |                 if ( full ) F = B;      //else : nothing has changed no need to regenerate | 
|---|
| 148 |         } | 
|---|
| 149 |         //!@} | 
|---|
| 150 | }; | 
|---|
| 151 |  | 
|---|
| 152 | } //namespace | 
|---|
| 153 | #endif // FN_H | 
|---|