diff --git a/ql/methods/finitedifferences/americancondition.hpp b/ql/methods/finitedifferences/americancondition.hpp index 8b6077a5add..d69b5a1e627 100644 --- a/ql/methods/finitedifferences/americancondition.hpp +++ b/ql/methods/finitedifferences/americancondition.hpp @@ -32,19 +32,64 @@ namespace QuantLib { //! American exercise condition. - /*! \todo unify the intrinsicValues/Payoff thing */ class AmericanCondition : - public StandardCurveDependentStepCondition { - public: + public StandardStepCondition { + public: + explicit AmericanCondition(const Array& intrinsicValues) + : impl_(new ArrayImpl(intrinsicValues)) {} + + /*! \deprecated Use the other constructor. + Deprecated in version 1.19. + */ + QL_DEPRECATED AmericanCondition(Option::Type type, Real strike) - : StandardCurveDependentStepCondition(type, strike) {}; - AmericanCondition(const Array& intrinsicValues) - : StandardCurveDependentStepCondition(intrinsicValues) {}; - private: - Real applyToValue(Real current, Real intrinsic) const { - return std::max(current, intrinsic); + : impl_(new PayoffImpl(type, strike)) {} + + void applyTo(Array &a, Time) const { + //#pragma omp parallel for + for (Size i = 0; i < a.size(); i++) { + a[i] = std::max(a[i], impl_->getValue(a, i)); + } } + private: + // This part should be removed and the array-based implementation + // inlined once the payoff-based constructor is removed. + + class Impl; + + ext::shared_ptr impl_; + + class Impl { + public: + virtual ~Impl() {} + virtual Real getValue(const Array &a, + int i) = 0; + }; + + class ArrayImpl : public Impl { + private: + Array intrinsicValues_; + public: + explicit ArrayImpl(const Array &a) + : intrinsicValues_(a) {} + + Real getValue(const Array&, int i) { + return intrinsicValues_[i]; + } + }; + + class PayoffImpl : public Impl { + private: + ext::shared_ptr payoff_; + public: + PayoffImpl(Option::Type type, Real strike) + : payoff_(new PlainVanillaPayoff(type, strike)) {}; + Real getValue(const Array &a, + int i) { + return (*payoff_)(std::exp(a[i])); + } + }; }; } diff --git a/ql/methods/finitedifferences/fdtypedefs.hpp b/ql/methods/finitedifferences/fdtypedefs.hpp index c882ca2f1b4..24742527067 100644 --- a/ql/methods/finitedifferences/fdtypedefs.hpp +++ b/ql/methods/finitedifferences/fdtypedefs.hpp @@ -41,8 +41,36 @@ namespace QuantLib { //! default choice for step condition typedef StepCondition StandardStepCondition; + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif +#if defined(QL_PATCH_MSVC) +#pragma warning(push) +#pragma warning(disable:4996) +#endif + + /*! \deprecated Inherit from StandardStepCondition directly. + Deprecated in version 1.19. + */ + QL_DEPRECATED typedef CurveDependentStepCondition StandardCurveDependentStepCondition; +#if defined(QL_PATCH_MSVC) +#pragma warning(pop) +#endif +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } diff --git a/ql/methods/finitedifferences/shoutcondition.hpp b/ql/methods/finitedifferences/shoutcondition.hpp index 0f8e8434487..9b4dc9eace5 100644 --- a/ql/methods/finitedifferences/shoutcondition.hpp +++ b/ql/methods/finitedifferences/shoutcondition.hpp @@ -37,42 +37,77 @@ namespace QuantLib { during the option's life. The minimum value is the option's intrinsic value at the shout time. */ - class ShoutCondition : public StandardCurveDependentStepCondition { + class ShoutCondition : public StandardStepCondition { public: + ShoutCondition(const Array& intrinsicValues, + Time resTime, + Rate rate) + : resTime_(resTime), rate_(rate), + impl_(new ArrayImpl(intrinsicValues)) {} + + /*! \deprecated Use the other constructor. + Deprecated in version 1.19. + */ + QL_DEPRECATED ShoutCondition(Option::Type type, Real strike, Time resTime, - Rate rate); - ShoutCondition(const Array& intrinsicValues, - Time resTime, - Rate rate); + Rate rate) + : resTime_(resTime), rate_(rate), + impl_(new PayoffImpl(type, strike)) {} + void applyTo(Array& a, - Time t) const; - private: - virtual Real applyToValue(Real current, - Real intrinsic) const { - return std::max(current, disc_ * intrinsic ); + Time t) const { + DiscountFactor B = std::exp(-rate_ * (t - resTime_)); + //#pragma omp parallel for + for (Size i = 0; i < a.size(); i++) { + a[i] = std::max(a[i], B * impl_->getValue(a, i)); + } } + + private: Time resTime_; Rate rate_; - mutable DiscountFactor disc_; + + // This part should be removed and the array-based implementation + // inlined once the payoff-based constructor is removed. + + class Impl; + + ext::shared_ptr impl_; + + class Impl { + public: + virtual ~Impl() {} + virtual Real getValue(const Array &a, + int i) = 0; + }; + + class ArrayImpl : public Impl { + private: + Array intrinsicValues_; + public: + explicit ArrayImpl(const Array &a) + : intrinsicValues_(a) {} + + Real getValue(const Array&, int i) { + return intrinsicValues_[i]; + } + }; + + class PayoffImpl : public Impl { + private: + ext::shared_ptr payoff_; + public: + PayoffImpl(Option::Type type, Real strike) + : payoff_(new PlainVanillaPayoff(type, strike)) {}; + + Real getValue(const Array &a, int i) { + return (*payoff_)(std::exp(a[i])); + } + }; }; - inline ShoutCondition::ShoutCondition(Option::Type type, - Real strike, Time resTime, - Rate rate) - : StandardCurveDependentStepCondition(type, strike), - resTime_(resTime), rate_(rate) {} - - inline ShoutCondition::ShoutCondition(const Array& intrinsicValues, - Time resTime, Rate rate) - : StandardCurveDependentStepCondition(intrinsicValues), - resTime_(resTime), rate_(rate) {} - - inline void ShoutCondition::applyTo(Array& a, Time t) const { - disc_ = std::exp(-rate_ * (t - resTime_)); - StandardCurveDependentStepCondition::applyTo(a, t); - } } diff --git a/ql/methods/finitedifferences/stepcondition.hpp b/ql/methods/finitedifferences/stepcondition.hpp index fada5879045..58429860cd7 100644 --- a/ql/methods/finitedifferences/stepcondition.hpp +++ b/ql/methods/finitedifferences/stepcondition.hpp @@ -38,10 +38,15 @@ namespace QuantLib { virtual void applyTo(array_type& a, Time t) const = 0; }; - /* Abstract base class which allows step conditions to use both - payoff and array functions */ + /* */ + /*! Abstract base class which allows step conditions to use both + payoff and array functions. + + \deprecated Inherit from StepCondition directly instead. + Deprecated in version 1.19. + */ template - class CurveDependentStepCondition : + class QL_DEPRECATED CurveDependentStepCondition : public StepCondition { public: void applyTo(Array &a, Time) const { @@ -52,12 +57,23 @@ namespace QuantLib { } } protected: + +#if defined(QL_PATCH_MSVC) +#pragma warning(push) +#pragma warning(disable:4996) +#endif + CurveDependentStepCondition(Option::Type type, Real strike) : curveItem_(new PayoffWrapper(type, strike)) {}; CurveDependentStepCondition(const Payoff *p) : curveItem_(new PayoffWrapper(p)) {}; CurveDependentStepCondition(const array_type & a) : curveItem_(new ArrayWrapper(a)) {}; + +#if defined(QL_PATCH_MSVC) +#pragma warning(pop) +#endif + class CurveWrapper; ext::shared_ptr curveItem_;