Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
value.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20
21#include <ql/errors.hpp>
22#include <ql/math/comparison.hpp>
23
24namespace ore {
25namespace data {
26
27std::ostream& operator<<(std::ostream& out, const EventVec& a) {
28 out << a.value;
29 return out;
30}
31
32std::ostream& operator<<(std::ostream& out, const CurrencyVec& a) {
33 out << a.value;
34 return out;
35}
36
37std::ostream& operator<<(std::ostream& out, const IndexVec& a) {
38 out << a.value;
39 return out;
40}
41
42std::ostream& operator<<(std::ostream& out, const DaycounterVec& a) {
43 out << a.value;
44 return out;
45}
46
47namespace {
48struct IsDet : public boost::static_visitor<bool> {
49 bool operator()(const RandomVariable& v) const { return v.deterministic(); }
50 bool operator()(const Filter& v) const { return v.deterministic(); }
51 template <typename C> bool operator()(const C& c) const { return true; }
52};
53
54struct SizeGetter : public boost::static_visitor<Size> {
55 Size operator()(const RandomVariable& v) const { return v.size(); }
56 Size operator()(const Filter& v) const { return v.size(); }
57 template <typename C> Size operator()(const C& c) const { return c.size; }
58};
59
60struct BinaryOp : public boost::static_visitor<ValueType> {
61 BinaryOp(const std::function<RandomVariable(const RandomVariable&, const RandomVariable&)>& op) : op_(op) {}
62 ValueType operator()(const RandomVariable& x, const RandomVariable& y) const { return op_(x, y); }
63 template <typename T, typename U> ValueType operator()(const T&, const U&) const {
64 QL_FAIL("binary operation on invalid types");
65 }
66 const std::function<RandomVariable(const RandomVariable&, const RandomVariable&)> op_;
67};
68
69struct UnaryOp : public boost::static_visitor<ValueType> {
70 UnaryOp(const std::function<RandomVariable(const RandomVariable&)>& op) : op_(op) {}
71 ValueType operator()(const RandomVariable& x) const { return op_(x); }
72 template <typename T> ValueType operator()(const T&) const { QL_FAIL("unary operation on invalid type"); }
73 const std::function<RandomVariable(const RandomVariable&)> op_;
74};
75
76struct Assignment : public boost::static_visitor<ValueType> {
77 ValueType operator()(RandomVariable& x, const RandomVariable& y) const {
78 x = y;
79 return x;
80 }
81 template <typename T> ValueType operator()(T& x, const T& y) const {
82 x = y;
83 return x;
84 }
85 template <typename T, typename U> ValueType operator()(T& x, const U& y) const {
86 QL_FAIL("invalid assignment between incompatible types");
87 }
88};
89
90struct BinaryComp : public boost::static_visitor<Filter> {
91 BinaryComp(const std::function<Filter(const RandomVariable&, const RandomVariable&)>& op_rv,
92 const std::function<Filter(const EventVec&, const EventVec&)>& op_event,
93 const std::function<Filter(const IndexVec&, const IndexVec&)>& op_index,
94 const std::function<Filter(const CurrencyVec&, const CurrencyVec&)>& op_currency,
95 const std::function<Filter(const DaycounterVec&, const DaycounterVec&)>& op_daycounter,
96 const std::function<Filter(const Filter&, const Filter&)>& op_filter)
99 Filter operator()(const RandomVariable& x, const RandomVariable& y) const { return op_rv(x, y); }
100 Filter operator()(const EventVec& x, const EventVec& y) const { return op_event(x, y); }
101 Filter operator()(const IndexVec& x, const IndexVec& y) const { return op_index(x, y); }
102 Filter operator()(const CurrencyVec& x, const CurrencyVec& y) const { return op_currency(x, y); }
103 Filter operator()(const DaycounterVec& x, const DaycounterVec& y) const { return op_daycounter(x, y); }
104 Filter operator()(const Filter& x, const Filter& y) const { return op_filter(x, y); }
105 template <typename T, typename U> Filter operator()(const T&, const U&) const {
106 QL_FAIL("invalid comparison between incompatible types");
107 }
108 const std::function<Filter(const RandomVariable&, const RandomVariable&)> op_rv;
109 const std::function<Filter(const EventVec&, const EventVec&)> op_event;
110 const std::function<Filter(const IndexVec&, const IndexVec&)> op_index;
111 const std::function<Filter(const CurrencyVec&, const CurrencyVec&)> op_currency;
112 const std::function<Filter(const DaycounterVec&, const DaycounterVec&)> op_daycounter;
113 const std::function<Filter(const Filter&, const Filter&)> op_filter;
114};
115
116struct UnaryComp : public boost::static_visitor<Filter> {
117 UnaryComp(const std::function<Filter(const RandomVariable&)>& op_rv,
118 const std::function<Filter(const EventVec&)>& op_event,
119 const std::function<Filter(const IndexVec&)>& op_index,
120 const std::function<Filter(const CurrencyVec&)>& op_currency,
121 const std::function<Filter(const DaycounterVec&)>& op_daycounter,
122 const std::function<Filter(const Filter&)>& op_filter)
125 Filter operator()(const RandomVariable& x) const { return op_rv(x); }
126 Filter operator()(const EventVec& x) const { return op_event(x); }
127 Filter operator()(const IndexVec& x) const { return op_index(x); }
128 Filter operator()(const CurrencyVec& x) const { return op_currency(x); }
129 Filter operator()(const DaycounterVec& x) const { return op_daycounter(x); }
130 Filter operator()(const Filter& x) const { return op_filter(x); }
131 template <typename T, typename U> Filter operator()(const T&, const U&) const {
132 QL_FAIL("invalid comparison between incompatible types");
133 }
134 const std::function<Filter(const RandomVariable&)> op_rv;
135 const std::function<Filter(const EventVec&)> op_event;
136 const std::function<Filter(const IndexVec&)> op_index;
137 const std::function<Filter(const CurrencyVec&)> op_currency;
138 const std::function<Filter(const DaycounterVec&)> op_daycounter;
139 const std::function<Filter(const Filter&)> op_filter;
140};
141
142} // namespace
143
144bool deterministic(const ValueType& v) { return boost::apply_visitor(IsDet(), v); }
145Size size(const ValueType& v) { return boost::apply_visitor(SizeGetter(), v); }
146
147bool operator==(const EventVec& a, const EventVec& b) { return a.value == b.value && a.size == b.size; }
148bool operator==(const CurrencyVec& a, const CurrencyVec& b) { return a.value == b.value && a.size == b.size; }
149bool operator==(const IndexVec& a, const IndexVec& b) { return a.value == b.value && a.size == b.size; }
150bool operator==(const DaycounterVec& a, const DaycounterVec& b) { return a.value == b.value && a.size == b.size; }
151
153 return boost::apply_visitor(
154 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return x + y; }), x, y);
155}
156
158 return boost::apply_visitor(
159 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return x - y; }), x, y);
160}
161
163 return boost::apply_visitor(
164 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return x * y; }), x, y);
165}
166
168 return boost::apply_visitor(
169 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return x / y; }), x, y);
170}
171
172ValueType min(const ValueType& x, const ValueType& y) {
173 return boost::apply_visitor(
174 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return min(x, y); }), x, y);
175}
176
177ValueType max(const ValueType& x, const ValueType& y) {
178 return boost::apply_visitor(
179 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return max(x, y); }), x, y);
180}
181
182ValueType pow(const ValueType& x, const ValueType& y) {
183 return boost::apply_visitor(
184 BinaryOp([](const RandomVariable& x, const RandomVariable& y) -> RandomVariable { return pow(x, y); }), x, y);
185}
186
187ValueType operator-(const ValueType& x) { return boost::apply_visitor(UnaryOp(std::negate<RandomVariable>()), x); }
188
190 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return abs(x); }), x);
191}
192
194 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return exp(x); }), x);
195}
196
198 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return log(x); }), x);
199}
200
202 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return sqrt(x); }), x);
203}
204
206 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return normalCdf(x); }), x);
207}
208
210 return boost::apply_visitor(UnaryOp([](const RandomVariable& x) -> RandomVariable { return normalPdf(x); }), x);
211}
212
213ValueType typeSafeAssign(ValueType& x, const ValueType& y) { return boost::apply_visitor(Assignment(), x, y); }
214
215Filter equal(const ValueType& x, const ValueType& y) {
216 return boost::apply_visitor(
217 BinaryComp(
218 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return close_enough(x, y); },
219 [](const EventVec& x, const EventVec& y) -> Filter {
220 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
221 return Filter(x.size, x.value == y.value);
222 },
223 [](const IndexVec& x, const IndexVec& y) -> Filter {
224 QL_REQUIRE(x.size == y.size, "inconsistent size IndexVec (" << x.size << ", " << y.size << ")");
225 return Filter(x.size, x.value == y.value);
226 },
227 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
228 QL_REQUIRE(x.size == y.size, "inconsistent size CurrencyVec (" << x.size << ", " << y.size << ")");
229 return Filter(x.size, x.value == y.value);
230 },
231 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
232 QL_REQUIRE(x.size == y.size, "inconsistent size DaycounterVec (" << x.size << ", " << y.size << ")");
233 return Filter(x.size, x.value == y.value);
234 },
235 [](const Filter& x, const Filter& y) -> Filter { return equal(x, y); }),
236 x, y);
237}
238
239Filter notequal(const ValueType& x, const ValueType& y) {
240 return boost::apply_visitor(
241 BinaryComp(
242 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return !close_enough(x, y); },
243 [](const EventVec& x, const EventVec& y) -> Filter {
244 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
245 return Filter(x.size, x.value != y.value);
246 },
247 [](const IndexVec& x, const IndexVec& y) -> Filter {
248 QL_REQUIRE(x.size == y.size, "inconsistent size IndexVec (" << x.size << ", " << y.size << ")");
249 return Filter(x.size, x.value != y.value);
250 },
251 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
252 QL_REQUIRE(x.size == y.size, "inconsistent size CurrencyVec (" << x.size << ", " << y.size << ")");
253 return Filter(x.size, x.value != y.value);
254 },
255 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
256 QL_REQUIRE(x.size == y.size, "inconsistent size DaycounterVec (" << x.size << ", " << y.size << ")");
257 return Filter(x.size, x.value != y.value);
258 },
259 [](const Filter& x, const Filter& y) -> Filter { return !equal(x, y); }),
260 x, y);
261}
262
263Filter lt(const ValueType& x, const ValueType& y) {
264 return boost::apply_visitor(
265 BinaryComp(
266 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return x < y; },
267 [](const EventVec& x, const EventVec& y) -> Filter {
268 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
269 return Filter(x.size, x.value < y.value);
270 },
271 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid comparison lt for IndexVec"); },
272 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
273 QL_FAIL("invalid comparison lt for CurrencyVec");
274 },
275 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
276 QL_FAIL("invalid comparison lt for DaycounterVec");
277 },
278 [](const Filter& x, const Filter& y) -> Filter { QL_FAIL("invalid comparison lt for Filter"); }),
279 x, y);
280}
281
282Filter gt(const ValueType& x, const ValueType& y) {
283 return boost::apply_visitor(
284 BinaryComp(
285 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return x > y; },
286 [](const EventVec& x, const EventVec& y) -> Filter {
287 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
288 return Filter(x.size, x.value > y.value);
289 },
290 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid comparison gt for IndexVec"); },
291 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
292 QL_FAIL("invalid comparison gt for CurrencyVec");
293 },
294 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
295 QL_FAIL("invalid comparison gt for DaycounterVec");
296 },
297 [](const Filter& x, const Filter& y) -> Filter { QL_FAIL("invalid comparison gt for Filter"); }),
298 x, y);
299}
300
301Filter leq(const ValueType& x, const ValueType& y) {
302 return boost::apply_visitor(
303 BinaryComp(
304 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return x <= y; },
305 [](const EventVec& x, const EventVec& y) -> Filter {
306 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
307 return Filter(x.size, x.value <= y.value);
308 },
309 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid comparison leq for IndexVec"); },
310 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
311 QL_FAIL("invalid comparison leq for CurrencyVec");
312 },
313 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
314 QL_FAIL("invalid comparison leq for DaycounterVec");
315 },
316 [](const Filter& x, const Filter& y) -> Filter { QL_FAIL("invalid comparison leq for Filter"); }),
317
318 x, y);
319}
320
321Filter geq(const ValueType& x, const ValueType& y) {
322 return boost::apply_visitor(
323 BinaryComp(
324 [](const RandomVariable& x, const RandomVariable& y) -> Filter { return x >= y; },
325 [](const EventVec& x, const EventVec& y) -> Filter {
326 QL_REQUIRE(x.size == y.size, "inconsistent size EventVec (" << x.size << ", " << y.size << ")");
327 return Filter(x.size, x.value >= y.value);
328 },
329 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid comparison geq for IndexVec"); },
330 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter {
331 QL_FAIL("invalid comparison geq for CurrencyVec");
332 },
333 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
334 QL_FAIL("invalid comparison geq for DaycounterVec");
335 },
336 [](const Filter& x, const Filter& y) -> Filter { QL_FAIL("invalid comparison geq for Filter"); }),
337
338 x, y);
339}
340
342 return boost::apply_visitor(
343 UnaryComp([](const RandomVariable& x) -> Filter { QL_FAIL("invalid logicalNot for RandomVariable"); },
344 [](const EventVec& x) -> Filter { QL_FAIL("invalid logicalNot for EventVec"); },
345 [](const IndexVec& x) -> Filter { QL_FAIL("invalid logicalNot for IndexVec"); },
346 [](const CurrencyVec& x) -> Filter { QL_FAIL("invalid logicalNot for CurrencyVec"); },
347 [](const DaycounterVec& x) -> Filter { QL_FAIL("invalid logicalNot for DaycounterVec"); },
348 [](const Filter& x) -> Filter { return !x; }),
349 x);
350}
351
353 return boost::apply_visitor(
354 BinaryComp(
355 [](const RandomVariable& x, const RandomVariable& y) -> Filter {
356 QL_FAIL("invalid logicalAnd for RandomVariable");
357 },
358 [](const EventVec& x, const EventVec& y) -> Filter { QL_FAIL("invalid logicalAnd for EventVec"); },
359 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid logicalAnd for IndexVec"); },
360 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter { QL_FAIL("invalid logicalAnd for CurrencyVec"); },
361 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
362 QL_FAIL("invalid logicalAnd for DaycounterVec");
363 },
364 [](const Filter& x, const Filter& y) -> Filter { return x && y; }),
365 x, y);
366}
367
368Filter logicalOr(const ValueType& x, const ValueType& y) {
369 return boost::apply_visitor(
370 BinaryComp(
371 [](const RandomVariable& x, const RandomVariable& y) -> Filter {
372 QL_FAIL("invalid logicalOr for RandomVariable");
373 },
374 [](const EventVec& x, const EventVec& y) -> Filter { QL_FAIL("invalid logicalOr for EventVec"); },
375 [](const IndexVec& x, const IndexVec& y) -> Filter { QL_FAIL("invalid logicalOr for IndexVec"); },
376 [](const CurrencyVec& x, const CurrencyVec& y) -> Filter { QL_FAIL("invalid logicalOr for CurrencyVec"); },
377 [](const DaycounterVec& x, const DaycounterVec& y) -> Filter {
378 QL_FAIL("invalid logicalOr for DaycounterVec");
379 },
380 [](const Filter& x, const Filter& y) -> Filter { return x || y; }),
381 x, y);
382}
383
384} // namespace data
385} // namespace ore
@ data
Definition: log.hpp:77
RandomVariable max(RandomVariable x, const RandomVariable &y)
BucketedDistribution operator+(const BucketedDistribution &lhs, const BucketedDistribution &rhs)
RandomVariable exp(RandomVariable x)
RandomVariable sqrt(RandomVariable x)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
RandomVariable log(RandomVariable x)
RandomVariable pow(RandomVariable x, const RandomVariable &y)
RandomVariable operator/(RandomVariable x, const RandomVariable &y)
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
bool operator==(const Dividend &d1, const Dividend &d)
RandomVariable normalCdf(RandomVariable x)
RandomVariable abs(RandomVariable x)
RandomVariable normalPdf(RandomVariable x)
Filter equal(Filter x, const Filter &y)
RandomVariable operator-(RandomVariable x, const RandomVariable &y)
RandomVariable min(RandomVariable x, const RandomVariable &y)
BucketedDistribution operator*(Real factor, const BucketedDistribution &rhs)
Filter lt(const ValueType &x, const ValueType &y)
Definition: value.cpp:263
bool deterministic(const ValueType &v)
Definition: value.cpp:144
Filter notequal(const ValueType &x, const ValueType &y)
Definition: value.cpp:239
Filter gt(const ValueType &x, const ValueType &y)
Definition: value.cpp:282
ValueType typeSafeAssign(ValueType &x, const ValueType &y)
Definition: value.cpp:213
Filter logicalAnd(const ValueType &x, const ValueType &y)
Definition: value.cpp:352
Size size(const ValueType &v)
Definition: value.cpp:145
Filter logicalOr(const ValueType &x, const ValueType &y)
Definition: value.cpp:368
Filter leq(const ValueType &x, const ValueType &y)
Definition: value.cpp:301
Filter geq(const ValueType &x, const ValueType &y)
Definition: value.cpp:321
boost::variant< RandomVariable, EventVec, CurrencyVec, IndexVec, DaycounterVec, Filter > ValueType
Definition: value.hpp:60
Filter logicalNot(const ValueType &x)
Definition: value.cpp:341
Serializable Credit Default Swap.
Definition: namespaces.docs:23
const std::function< Filter(const IndexVec &, const IndexVec &)> op_index
Definition: value.cpp:110
const std::function< Filter(const Filter &, const Filter &)> op_filter
Definition: value.cpp:113
const std::function< Filter(const RandomVariable &, const RandomVariable &)> op_rv
Definition: value.cpp:108
const std::function< Filter(const CurrencyVec &, const CurrencyVec &)> op_currency
Definition: value.cpp:111
const std::function< Filter(const DaycounterVec &, const DaycounterVec &)> op_daycounter
Definition: value.cpp:112
const std::function< RandomVariable(const RandomVariable &, const RandomVariable &)> op_
Definition: value.cpp:66
const std::function< Filter(const EventVec &, const EventVec &)> op_event
Definition: value.cpp:109
bool deterministic() const
std::string value
Definition: value.hpp:47
std::string value
Definition: value.hpp:57
std::string value
Definition: value.hpp:52
value type and operations