21#include <ql/errors.hpp>
22#include <ql/math/comparison.hpp>
48struct IsDet :
public boost::static_visitor<bool> {
50 bool operator()(
const Filter& v)
const {
return v.deterministic(); }
51 template <
typename C>
bool operator()(
const C& c)
const {
return true; }
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; }
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");
66 const std::function<RandomVariable(
const RandomVariable&,
const RandomVariable&)>
op_;
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_;
76struct Assignment :
public boost::static_visitor<ValueType> {
77 ValueType operator()(RandomVariable& x,
const RandomVariable& y)
const {
81 template <
typename T>
ValueType operator()(T& x,
const T& y)
const {
85 template <
typename T,
typename U>
ValueType operator()(T& x,
const U& y)
const {
86 QL_FAIL(
"invalid assignment between incompatible types");
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");
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;
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");
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;
145Size
size(
const ValueType& v) {
return boost::apply_visitor(SizeGetter(), v); }
153 return boost::apply_visitor(
158 return boost::apply_visitor(
163 return boost::apply_visitor(
168 return boost::apply_visitor(
173 return boost::apply_visitor(
178 return boost::apply_visitor(
183 return boost::apply_visitor(
216 return boost::apply_visitor(
220 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
221 return Filter(x.size, x.value == y.value);
224 QL_REQUIRE(x.size == y.size,
"inconsistent size IndexVec (" << x.size <<
", " << y.size <<
")");
225 return Filter(x.size, x.value == y.value);
228 QL_REQUIRE(x.size == y.size,
"inconsistent size CurrencyVec (" << x.size <<
", " << y.size <<
")");
229 return Filter(x.size, x.value == y.value);
232 QL_REQUIRE(x.size == y.size,
"inconsistent size DaycounterVec (" << x.size <<
", " << y.size <<
")");
233 return Filter(x.size, x.value == y.value);
240 return boost::apply_visitor(
244 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
245 return Filter(x.size, x.value != y.value);
248 QL_REQUIRE(x.size == y.size,
"inconsistent size IndexVec (" << x.size <<
", " << y.size <<
")");
249 return Filter(x.size, x.value != y.value);
252 QL_REQUIRE(x.size == y.size,
"inconsistent size CurrencyVec (" << x.size <<
", " << y.size <<
")");
253 return Filter(x.size, x.value != y.value);
256 QL_REQUIRE(x.size == y.size,
"inconsistent size DaycounterVec (" << x.size <<
", " << y.size <<
")");
257 return Filter(x.size, x.value != y.value);
264 return boost::apply_visitor(
268 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
269 return Filter(x.size, x.value < y.value);
273 QL_FAIL(
"invalid comparison lt for CurrencyVec");
276 QL_FAIL(
"invalid comparison lt for DaycounterVec");
278 [](
const Filter& x,
const Filter& y) ->
Filter { QL_FAIL(
"invalid comparison lt for Filter"); }),
283 return boost::apply_visitor(
287 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
288 return Filter(x.size, x.value > y.value);
292 QL_FAIL(
"invalid comparison gt for CurrencyVec");
295 QL_FAIL(
"invalid comparison gt for DaycounterVec");
297 [](
const Filter& x,
const Filter& y) ->
Filter { QL_FAIL(
"invalid comparison gt for Filter"); }),
302 return boost::apply_visitor(
306 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
307 return Filter(x.size, x.value <= y.value);
311 QL_FAIL(
"invalid comparison leq for CurrencyVec");
314 QL_FAIL(
"invalid comparison leq for DaycounterVec");
316 [](
const Filter& x,
const Filter& y) ->
Filter { QL_FAIL(
"invalid comparison leq for Filter"); }),
322 return boost::apply_visitor(
326 QL_REQUIRE(x.size == y.size,
"inconsistent size EventVec (" << x.size <<
", " << y.size <<
")");
327 return Filter(x.size, x.value >= y.value);
331 QL_FAIL(
"invalid comparison geq for CurrencyVec");
334 QL_FAIL(
"invalid comparison geq for DaycounterVec");
336 [](
const Filter& x,
const Filter& y) ->
Filter { QL_FAIL(
"invalid comparison geq for Filter"); }),
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"); },
353 return boost::apply_visitor(
356 QL_FAIL(
"invalid logicalAnd for RandomVariable");
362 QL_FAIL(
"invalid logicalAnd for DaycounterVec");
369 return boost::apply_visitor(
372 QL_FAIL(
"invalid logicalOr for RandomVariable");
378 QL_FAIL(
"invalid logicalOr for DaycounterVec");
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)
bool deterministic(const ValueType &v)
Filter notequal(const ValueType &x, const ValueType &y)
Filter gt(const ValueType &x, const ValueType &y)
ValueType typeSafeAssign(ValueType &x, const ValueType &y)
Filter logicalAnd(const ValueType &x, const ValueType &y)
Size size(const ValueType &v)
Filter logicalOr(const ValueType &x, const ValueType &y)
Filter leq(const ValueType &x, const ValueType &y)
Filter geq(const ValueType &x, const ValueType &y)
boost::variant< RandomVariable, EventVec, CurrencyVec, IndexVec, DaycounterVec, Filter > ValueType
Filter logicalNot(const ValueType &x)
Serializable Credit Default Swap.
const std::function< Filter(const IndexVec &, const IndexVec &)> op_index
const std::function< Filter(const Filter &, const Filter &)> op_filter
const std::function< Filter(const RandomVariable &, const RandomVariable &)> op_rv
const std::function< Filter(const CurrencyVec &, const CurrencyVec &)> op_currency
const std::function< Filter(const DaycounterVec &, const DaycounterVec &)> op_daycounter
const std::function< RandomVariable(const RandomVariable &, const RandomVariable &)> op_
const std::function< Filter(const EventVec &, const EventVec &)> op_event
bool deterministic() const
value type and operations