23#ifndef quantlib_fdm_n_dim_solver_hpp
24#define quantlib_fdm_n_dim_solver_hpp
46 ext::shared_ptr<FdmLinearOpComposite> op);
56 const std::vector<Size>& x,
Real value);
61 const ext::shared_ptr<FdmLinearOpComposite>
op_;
66 std::vector<std::vector<Real> >
x_;
70 mutable ext::shared_ptr<data_table>
f_;
71 mutable ext::shared_ptr<MultiCubicSpline<N> >
interp_;
78 ext::shared_ptr<FdmLinearOpComposite> op)
79 : solverDesc_(solverDesc), schemeDesc_(schemeDesc), op_(
std::move(op)),
81 0.99 *
std::min(1.0 / 365.0,
82 solverDesc.condition->stoppingTimes().empty() ?
84 solverDesc.condition->stoppingTimes().front()))),
86 x_(solverDesc.mesher->layout()->dim().size()),
87 initialValues_(solverDesc.mesher->layout()->size()),
88 extrapolation_(
std::vector<
bool>(N, false)) {
90 QL_REQUIRE(solverDesc.
mesher->layout()->dim().size() == N,
"solver dim " << N
91 <<
"does not fit to layout dim " << solverDesc.
mesher->layout()->size());
93 for (
Size i=0; i < N; ++i) {
94 x_[i].reserve(solverDesc.
mesher->layout()->dim()[i]);
97 for (
const auto& iter : *solverDesc.
mesher->layout()) {
99 ->avgInnerValue(iter, solverDesc.
maturity);
101 const std::vector<Size>& c = iter.coordinates();
102 for (
Size i=0; i < N; ++i) {
103 if ((std::accumulate(c.begin(), c.end(), 0UL) - c[i]) == 0U) {
104 x_[i].push_back(solverDesc.
mesher->location(iter, i));
113 template <Size N>
inline
115 Array rhs(initialValues_.size());
116 std::copy(initialValues_.begin(), initialValues_.end(), rhs.
begin());
119 .
rollback(rhs, solverDesc_.maturity, 0.0,
120 solverDesc_.timeSteps, solverDesc_.dampingSteps);
122 for (
const auto& iter : *solverDesc_.mesher->layout()) {
123 setValue(*
f_, iter.coordinates(), rhs[iter.index()]);
126 interp_ = ext::shared_ptr<MultiCubicSpline<N> >(
131 template <Size N>
inline
133 if (conditions_->stoppingTimes().front() == 0.0)
137 const Array& rhs = thetaCondition_->getValues();
141 for (
const auto& iter : *solverDesc_.mesher->layout()) {
142 setValue(
f, iter.coordinates(), rhs[iter.index()]);
146 - interpolateAt(x)) / thetaCondition_->getTime();
149 template <Size N>
inline
153 return (*interp_)(x);
156 template <Size N>
inline
158 const std::vector<Size>& x,
Real value) {
164 const std::vector<Size>& x,
Real value) {
1-D array used in linear algebra.
const_iterator begin() const
void rollback(array_type &a, Time from, Time to, Size steps, Size dampingSteps)
void performCalculations() const override
std::vector< Real > initialValues_
static void setValue(data_table &f, const std::vector< Size > &x, Real value)
const ext::shared_ptr< FdmStepConditionComposite > conditions_
MultiCubicSpline< N >::data_table data_table
const ext::shared_ptr< FdmSnapshotCondition > thetaCondition_
ext::shared_ptr< data_table > f_
const FdmSolverDesc solverDesc_
Real interpolateAt(const std::vector< Real > &x) const
FdmNdimSolver(const FdmSolverDesc &solverDesc, const FdmSchemeDesc &schemeDesc, ext::shared_ptr< FdmLinearOpComposite > op)
Real thetaAt(const std::vector< Real > &x) const
std::vector< std::vector< Real > > x_
const std::vector< bool > extrapolation_
ext::shared_ptr< MultiCubicSpline< N > > interp_
const ext::shared_ptr< FdmLinearOpComposite > op_
const FdmSchemeDesc schemeDesc_
Framework for calculation on demand and result caching.
N-dimensional cubic spline interpolation between discrete points.
template class providing a null value for a given type.
ext::function< Real(Real)> f_
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
layer of abstraction to calculate the inner value
memory layout of a fdm linear operator
step condition for value inspection
composite of fdm step conditions
generic finite difference model
std::size_t Size
size of a container
framework for calculation on demand and result caching
N-dimensional cubic spline interpolation between discrete points.
const ext::shared_ptr< FdmInnerValueCalculator > calculator
const ext::shared_ptr< FdmMesher > mesher