39 std::vector<std::vector<Real>> x,
41 Size maxIterMultiplier)
42 : y_(
std::move(
y)),
x_(
std::move(x)), relTol_(relTol), maxIterMultiplier_(maxIterMultiplier) {
46 std::vector<Size> dim;
48 for (
Size i = 0; i <
x_.size(); ++i) {
51 dim.push_back(
x_[i].size());
60 QL_REQUIRE(!dim.empty(),
"LaplaceInterpolation: singular point or no points given");
62 layout_ = ext::make_shared<FdmLinearOpLayout>(dim);
64 std::vector<ext::shared_ptr<Fdm1dMesher>> meshers;
67 meshers.push_back(ext::make_shared<Predefined1dMesher>(i));
70 auto mesher = ext::make_shared<FdmMesherComposite>(
layout_, meshers);
75 explicit LaplaceOp(
const ext::shared_ptr<FdmMesher>& mesher) {
76 for (
Size direction = 0; direction < mesher->layout()->dim().size(); ++direction) {
77 if (mesher->layout()->dim()[direction] > 1)
81 std::vector<TripleBandLinearOp> map_;
85 Array apply(
const array_type&
r)
const override {
QL_FAIL(
"no impl"); }
94 std::vector<SparseMatrix> toMatrixDecomp()
const override {
95 std::vector<SparseMatrix> decomp;
96 decomp.reserve(map_.size());
97for (
auto const& m : map_)
98 decomp.push_back(m.toMatrix());
110 Array rhs(N, 0.0), guess(N, 0.0);
119 auto rowit = op.begin1();
121 std::vector<Real> corner_h(dim.size());
122 std::vector<Size> corner_neighbour_index(dim.size());
123 for (
auto const& pos : *
layout_) {
124 auto coord = pos.coordinates();
127 QL_REQUIRE(rowit != op.end1() && rowit.index1() == count,
128 "LaplaceInterpolation: op matrix row iterator ("
129 << (rowit != op.end1() ? std::to_string(rowit.index1()) :
"na")
130 <<
") does not match expected row count (" << count <<
")");
132 bool isCorner =
true;
133 for (
Size d = 0;
d < dim.size() && isCorner; ++
d) {
135 corner_h[
d] = meshers[
d]->dplus(0);
136 corner_neighbour_index[
d] = 1;
137 }
else if (coord[
d] ==
layout_->dim()[
d] - 1) {
138 corner_h[
d] = meshers[
d]->dminus(dim[
d] - 1);
139 corner_neighbour_index[
d] = dim[
d] - 2;
148 std::accumulate(corner_h.begin(), corner_h.end(),
Real(0.0), std::plus<Real>());
149 for (
Size j = 0; j < dim.size(); ++j) {
150 std::vector<Size> coord_j(coord);
151 coord_j[j] = corner_neighbour_index[j];
153 for (
Size i = 0; i < dim.size(); ++i) {
155 weight += corner_h[i];
157 weight = dim.size() == 1 ?
Real(1.0) :
Real(weight / sum_corner_h);
158 g(count,
layout_->index(coord_j)) = -weight;
160 g(count, count) = 1.0;
163 for (
auto colit = rowit.begin(); colit != rowit.end(); ++colit)
164 g(count, colit.index2()) = *colit;
167 guess[count] = guessTmp;
171 guess[count] = guessTmp = val;
182 std::vector<Size> tmp;
183 for (
Size i = 0; i < coordinates.size(); ++i) {
185 tmp.push_back(coordinates[i]);
201 QL_REQUIRE(coordinates.size() ==
x_.size(),
"LaplaceInterpolation::operator(): expected "
202 <<
x_.size() <<
" coordinates, got "
203 << coordinates.size());
205 Real val =
y_(coordinates);
215 const std::vector<Real>& x,
216 const std::vector<Real>&
y,
218 Size maxIterMultiplier) {
220 std::vector<std::vector<Real>> tmp;
225 tmp[0].resize(A.
rows());
226 std::iota(tmp[0].begin(), tmp[0].end(), 0.0);
231 std::iota(tmp[1].begin(), tmp[1].end(), 0.0);
235 [&A](
const std::vector<Size>& coordinates) {
236 return A(coordinates[0], coordinates[1]);
238 tmp, relTol, maxIterMultiplier);
240 for (
Size i = 0; i < A.
rows(); ++i) {
243 A(i, j) = interpolation({i, j});
Biconjugate gradient stabilized method.
1-D array used in linear algebra.
BiCGStabResult solve(const Array &b, const Array &x0=Array()) const
std::vector< Size > fullCoordinates(const std::vector< Size > &projectedCoordinates) const
ext::shared_ptr< FdmLinearOpLayout > layout_
LaplaceInterpolation(std::function< Real(const std::vector< Size > &)> y, std::vector< std::vector< Real > > x, Real relTol=1E-6, Size maxIterMultiplier=10)
Array interpolatedValues_
std::vector< bool > coordinateIncluded_
std::vector< Size > projectedCoordinates(const std::vector< Size > &coordinates) const
Size numberOfCoordinatesIncluded_
std::function< Real(const std::vector< Size > &)> y_
std::vector< std::vector< Real > > x_
Real operator()(const std::vector< Size > &coordinates) const
Matrix used in linear algebra.
template class providing a null value for a given type.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
One-dimensional simple FDM mesher object working on an index.
composite pattern for linear operators
memory layout of a fdm linear operator
FdmMesher which is a composite of Fdm1dMesher.
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
Laplace interpolation of missing values.
matrix used in linear algebra.
Array prod(const SparseMatrix &A, const Array &x)
void laplaceInterpolation(Matrix &A, const std::vector< Real > &x, const std::vector< Real > &y, Real relTol, Size maxIterMultiplier)
boost::numeric::ublas::compressed_matrix< Real > SparseMatrix
ext::shared_ptr< YieldTermStructure > r
One-dimensional mesher build from a given set of points.
second derivative operator
typedef for boost sparse matrix class
general triple band linear operator