1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2003 RiskMap srl 5 6 This file is part of QuantLib, a free-software/open-source library 7 for financial quantitative analysts and developers - http://quantlib.org/ 8 9 QuantLib is free software: you can redistribute it and/or modify it 10 under the terms of the QuantLib license. You should have received a 11 copy of the license along with this program; if not, please email 12 <quantlib-dev@lists.sf.net>. The license is also available online at 13 <http://quantlib.org/license.shtml>. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the license for more details. 18 */ 19 20 /*! \file ql/math/functional.hpp 21 \brief functionals and combinators not included in the STL 22 */ 23 24 #ifndef quantlib_math_functional_hpp 25 #define quantlib_math_functional_hpp 26 27 #include <ql/types.hpp> 28 #include <ql/utilities/null.hpp> 29 #include <cmath> 30 31 namespace QuantLib { 32 33 // functions 34 35 template <class T, class U> 36 class constant { 37 public: 38 typedef T argument_type; 39 typedef U result_type; constant(const U & u)40 explicit constant(const U& u) : u_(u) {} operator ()(const T &) const41 U operator()(const T&) const { return u_; } 42 private: 43 U u_; 44 }; 45 46 template <class T> 47 class identity { 48 public: 49 typedef T argument_type; 50 typedef T result_type; operator ()(const T & t) const51 T operator()(const T& t) const { return t; } 52 }; 53 54 template <class T> 55 class square { 56 public: 57 typedef T argument_type; 58 typedef T result_type; operator ()(const T & t) const59 T operator()(const T& t) const { return t*t; } 60 }; 61 62 template <class T> 63 class cube { 64 public: 65 typedef T argument_type; 66 typedef T result_type; operator ()(const T & t) const67 T operator()(const T& t) const { return t*t*t; } 68 }; 69 70 template <class T> 71 class fourth_power { 72 public: 73 typedef T argument_type; 74 typedef T result_type; operator ()(const T & t) const75 T operator()(const T& t) const { T t2 = t*t; return t2*t2; } 76 }; 77 78 // a few shortcuts for common binders 79 80 template <class T> 81 class add { 82 T y; 83 public: 84 typedef T argument_type; 85 typedef Real result_type; 86 add(Real y)87 explicit add(Real y) : y(y) {} operator ()(T x) const88 Real operator()(T x) const { return x + y; } 89 }; 90 91 template <class T> 92 class subtract { 93 T y; 94 public: 95 typedef T argument_type; 96 typedef Real result_type; 97 subtract(Real y)98 explicit subtract(Real y) : y(y) {} operator ()(T x) const99 Real operator()(T x) const { return x - y; } 100 }; 101 102 template <class T> 103 class subtract_from { 104 T y; 105 public: 106 typedef T argument_type; 107 typedef Real result_type; 108 subtract_from(Real y)109 explicit subtract_from(Real y) : y(y) {} operator ()(T x) const110 Real operator()(T x) const { return y - x; } 111 }; 112 113 template <class T> 114 class multiply_by { 115 T y; 116 public: 117 typedef T argument_type; 118 typedef Real result_type; 119 multiply_by(Real y)120 explicit multiply_by(Real y) : y(y) {} operator ()(T x) const121 Real operator()(T x) const { return x * y; } 122 }; 123 124 template <class T> 125 class divide { 126 T y; 127 public: 128 typedef T argument_type; 129 typedef Real result_type; 130 divide(Real y)131 explicit divide(Real y) : y(y) {} operator ()(T x) const132 Real operator()(T x) const { return y / x; } 133 }; 134 135 template <class T> 136 class divide_by { 137 T y; 138 public: 139 typedef T argument_type; 140 typedef Real result_type; 141 divide_by(Real y)142 explicit divide_by(Real y) : y(y) {} operator ()(T x) const143 Real operator()(T x) const { return x / y; } 144 }; 145 146 template <class T> 147 class less_than { 148 T y; 149 public: 150 typedef T argument_type; 151 typedef bool result_type; 152 less_than(Real y)153 explicit less_than(Real y) : y(y) {} operator ()(T x) const154 bool operator()(T x) const { return x < y; } 155 }; 156 157 template <class T> 158 class greater_than { 159 T y; 160 public: 161 typedef T argument_type; 162 typedef bool result_type; 163 greater_than(Real y)164 explicit greater_than(Real y) : y(y) {} operator ()(T x) const165 bool operator()(T x) const { return x > y; } 166 }; 167 168 template <class T> 169 class greater_or_equal_to { 170 T y; 171 public: 172 typedef T argument_type; 173 typedef bool result_type; 174 greater_or_equal_to(Real y)175 explicit greater_or_equal_to(Real y) : y(y) {} operator ()(T x) const176 bool operator()(T x) const { return x >= y; } 177 }; 178 179 template <class T> 180 class not_zero { 181 public: 182 typedef T argument_type; 183 typedef bool result_type; operator ()(T x) const184 bool operator()(T x) const { return x != T(); } 185 }; 186 187 template <class T> 188 class not_null { 189 T null; 190 public: 191 typedef T argument_type; 192 typedef bool result_type; 193 not_null()194 not_null() : null(Null<T>()) {} operator ()(T x) const195 bool operator()(T x) const { return x != null; } 196 }; 197 198 // predicates 199 200 class everywhere : public constant<Real,bool> { 201 public: everywhere()202 everywhere() : constant<Real,bool>(true) {} 203 }; 204 205 class nowhere : public constant<Real,bool> { 206 public: nowhere()207 nowhere() : constant<Real,bool>(false) {} 208 }; 209 210 template <class T> 211 class equal_within { 212 public: 213 typedef T first_argument_type; 214 typedef T second_argument_type; 215 typedef bool result_type; 216 equal_within(const T & eps)217 explicit equal_within(const T& eps) : eps_(eps) {} operator ()(const T & a,const T & b) const218 bool operator()(const T& a, const T& b) const { 219 return std::fabs(a-b) <= eps_; 220 } 221 private: 222 const T eps_; 223 }; 224 225 // combinators 226 template <class F, class R> 227 class clipped_function { 228 public: 229 typedef typename F::argument_type argument_type; 230 typedef typename F::result_type result_type; clipped_function(const F & f,const R & r)231 clipped_function(const F& f, const R& r) : f_(f), r_(r) {} operator ()(const argument_type & x) const232 result_type operator()(const argument_type& x) const { 233 return r_(x) ? f_(x) : result_type(); 234 } 235 private: 236 F f_; 237 R r_; 238 }; 239 240 template <class F, class R> clip(const F & f,const R & r)241 clipped_function<F,R> clip(const F& f, const R& r) { 242 return clipped_function<F,R>(f,r); 243 } 244 245 246 template <class F, class G> 247 class composed_function { 248 public: 249 typedef typename G::argument_type argument_type; 250 typedef typename F::result_type result_type; composed_function(const F & f,const G & g)251 composed_function(const F& f, const G& g) : f_(f), g_(g) {} operator ()(const argument_type & x) const252 result_type operator()(const argument_type& x) const { 253 return f_(g_(x)); 254 } 255 private: 256 F f_; 257 G g_; 258 }; 259 260 template <class F, class G> compose(const F & f,const G & g)261 composed_function<F,G> compose(const F& f, const G& g) { 262 return composed_function<F,G>(f,g); 263 } 264 265 template <class F, class G, class H> 266 class binary_compose3_function { 267 public: 268 typedef typename G::argument_type first_argument_type; 269 typedef typename H::argument_type second_argument_type; 270 typedef typename F::result_type result_type; 271 binary_compose3_function(const F & f,const G & g,const H & h)272 binary_compose3_function(const F& f, const G& g, const H& h) 273 : f_(f), g_(g), h_(h) {} 274 operator ()(const first_argument_type & x,const second_argument_type & y) const275 result_type operator()(const first_argument_type& x, 276 const second_argument_type& y) const { 277 return f_(g_(x), h_(y)); 278 } 279 280 private: 281 F f_; 282 G g_; 283 H h_; 284 }; 285 286 template <class F, class G, class H> binary_compose3_function<F, G, H> compose3(const F & f,const G & g,const H & h)287 compose3(const F& f, const G& g, const H& h) { 288 return binary_compose3_function<F, G, H>(f, g, h); 289 } 290 } 291 292 293 #endif 294