21#include <ql/math/comparison.hpp>
23#include <boost/math/distributions/normal.hpp>
28 QuantLib::LsmBasisSystem::PolynomialType polynomType,
29 const double eps, QuantLib::Real regressionVarianceCutoff) {
30 std::vector<RandomVariableOp> ops;
33 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return RandomVariable(); });
36 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return *args[0] + (*args[1]); });
39 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return *args[0] - (*args[1]); });
42 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return -(*args[0]); });
45 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return *args[0] * (*args[1]); });
48 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return *args[0] / (*args[1]); });
51 ops.push_back([size, regressionOrder, polynomType,
52 regressionVarianceCutoff](
const std::vector<const RandomVariable*>& args) {
53 std::vector<const RandomVariable*> regressor;
54 for (
auto r = std::next(args.begin(), 2); r != args.end(); ++r) {
55 if ((*r)->initialised() && !(*r)->deterministic())
56 regressor.push_back(*r);
58 std::vector<RandomVariable> transformedRegressor;
59 Matrix coordinateTransform;
60 if (regressionVarianceCutoff != Null<Real>()) {
65 if (regressor.empty())
74 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return indicatorEq(*args[0], *args[1]); });
77 ops.push_back([eps](
const std::vector<const RandomVariable*>& args) {
78 return indicatorGt(*args[0], *args[1], 1.0, 0.0, eps);
82 ops.push_back([eps](
const std::vector<const RandomVariable*>& args) {
89 [](
const std::vector<const RandomVariable*>& args) {
return QuantExt::min(*args[0], *args[1]); });
91 ops.push_back([eps](
const std::vector<const RandomVariable*>& args) {
92 return indicatorGt(*args[0], *args[1], 1.0, 0.0, eps) * (*args[1] - *args[0]) + *args[0];
99 [](
const std::vector<const RandomVariable*>& args) {
return QuantExt::max(*args[0], *args[1]); });
101 ops.push_back([eps](
const std::vector<const RandomVariable*>& args) {
102 return indicatorGt(*args[0], *args[1], 1.0, 0.0, eps) * (*args[0] - *args[1]) + *args[1];
107 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::abs(*args[0]); });
110 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::exp(*args[0]); });
113 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::sqrt(*args[0]); });
116 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::log(*args[0]); });
119 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::pow(*args[0], *args[1]); });
122 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::normalCdf(*args[0]); });
125 ops.push_back([](
const std::vector<const RandomVariable*>& args) {
return QuantExt::normalPdf(*args[0]); });
131 const QuantLib::LsmBasisSystem::PolynomialType polynomType,
132 const double eps,
const Real regressionVarianceCutoff) {
134 std::vector<RandomVariableGrad> grads;
137 grads.push_back([](
const std::vector<const RandomVariable*>& args,
142 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
148 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
154 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
160 [](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
161 return {*args[1], *args[0]};
166 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
167 return {
RandomVariable(size, 1.0) / *args[1], -*args[0] / (*args[1] * *args[1])};
172 [](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
173 QL_FAIL(
"gradient of conditional expectation not implemented");
178 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
184 [eps](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
190 grads.push_back(grads.back());
193 grads.push_back([eps](
const std::vector<const RandomVariable*>& args,
201 grads.push_back([eps](
const std::vector<const RandomVariable*>& args,
210 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
215 grads.push_back([](
const std::vector<const RandomVariable*>& args,
216 const RandomVariable* v) -> std::vector<RandomVariable> {
return {*v}; });
220 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
226 [size](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
232 [](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
233 return {*args[1] / *args[0] * (*v),
QuantExt::log(*args[0]) * (*v)};
238 [](
const std::vector<const RandomVariable*>& args,
const RandomVariable* v) -> std::vector<RandomVariable> {
243 grads.push_back([](
const std::vector<const RandomVariable*>& args,
244 const RandomVariable* v) -> std::vector<RandomVariable> {
return {-(*args[0]) * *v}; });
250 std::vector<RandomVariableOpNodeRequirements> res;
253 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
false); });
256 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
false); });
259 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
false); });
262 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
false); });
265 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
268 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
271 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
true); });
274 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
false); });
277 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
280 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
283 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
286 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
289 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
292 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
true); });
295 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
false),
true); });
298 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
301 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
true); });
304 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
false); });
307 res.push_back([](
const std::size_t nArgs) {
return std::make_pair(std::vector<bool>(nArgs,
true),
true); });
std::vector< RandomVariableGrad > getRandomVariableGradients(const Size size, const Size regressionOrder, const QuantLib::LsmBasisSystem::PolynomialType polynomType, const double eps, const Real regressionVarianceCutoff)
std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > multiPathBasisSystem(Size dim, Size order, QuantLib::LsmBasisSystem::PolynomialType type, Size basisSystemSizeBound)
RandomVariable sqrt(RandomVariable x)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
CompiledFormula exp(CompiledFormula x)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
RandomVariable indicatorDerivative(const RandomVariable &x, const double eps)
std::vector< RandomVariableOpNodeRequirements > getRandomVariableOpNodeRequirements()
CompiledFormula pow(CompiledFormula x, const CompiledFormula &y)
std::vector< const RandomVariable * > vec2vecptr(const std::vector< RandomVariable > &values)
RandomVariable expectation(const RandomVariable &r)
RandomVariable normalCdf(RandomVariable x)
RandomVariable conditionalExpectation(const std::vector< const RandomVariable * > ®ressor, const std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > &basisFn, const Array &coefficients)
RandomVariable indicatorGeq(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal, const Real eps)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
CompiledFormula abs(CompiledFormula x)
RandomVariable indicatorEq(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal)
RandomVariable normalPdf(RandomVariable x)
Matrix pcaCoordinateTransform(const std::vector< const RandomVariable * > ®ressor, const Real varianceCutoff)
CompiledFormula log(CompiledFormula x)
std::vector< RandomVariableOp > getRandomVariableOps(const Size size, const Size regressionOrder, QuantLib::LsmBasisSystem::PolynomialType polynomType, const double eps, QuantLib::Real regressionVarianceCutoff)
RandomVariable indicatorGt(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal, const Real eps)
std::vector< RandomVariable > applyCoordinateTransform(const std::vector< const RandomVariable * > ®ressor, const Matrix &transform)
ops for type randomvariable