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