dynare/dynare++/integ/cc/smolyak.hh

150 lines
4.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright © 2005 Ondra Kamenik
* Copyright © 2019 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
// Smolyak quadrature.
/* This file defines Smolyak (sparse grid) multidimensional quadrature for
non-nested underlying one dimensional quadrature. Let Q¹ₗ denote the one
dimensional quadrature of l level. Let nₗ denote a number of points in the l
level. Than the Smolyak quadrature can be defined as
⎛ d1 ⎞
Qᵈf = ∑ (1)^{l+d|k|1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
l≤|k|≤l+d1 ⎝|k|l⎠
where d is the dimension, k is d-dimensional sequence of integers, and |k|
denotes the sum of the sequence.
Here we define smolpit as Smolyak iterator and SmolyakQuadrature. */
#ifndef SMOLYAK_H
#define SMOLYAK_H
#include "int_sequence.hh"
#include "tl_static.hh"
#include "vector_function.hh"
#include "quadrature.hh"
#include "pascal_triangle.hh"
/* Here we define the Smolyak point iterator. The Smolyak formula can be broken
to a sum of product quadratures with various combinations of levels. The
iterator follows this pattern. It maintains an index to a summand and then a
point coordinates within the summand (product quadrature). The array of
summands to which the isummand points is maintained by the
SmolyakQuadrature class to which the object knows the pointer smolq.
We provide a constructor which points to the beginning of the given summand.
This constructor is used in SmolyakQuadrature::begin() method which
approximately divideds all the iterators to subsets of equal size. */
class SmolyakQuadrature;
class smolpit
{
protected:
const SmolyakQuadrature &smolq;
unsigned int isummand{0};
IntSequence jseq;
ParameterSignal sig;
Vector p;
double w;
public:
smolpit(const SmolyakQuadrature &q, unsigned int isum);
smolpit(const smolpit &spit) = default;
~smolpit() = default;
bool operator==(const smolpit &spit) const;
bool
operator!=(const smolpit &spit) const
{
return !operator==(spit);
}
smolpit &operator=(const smolpit &spit) = delete;
smolpit &operator++();
const ParameterSignal &
signal() const
{
return sig;
}
const Vector &
point() const
{
return p;
}
double
weight() const
{
return w;
}
void print() const;
protected:
void setPointAndWeight();
};
/* Here we define the class SmolyakQuadrature. It maintains an array of
summands of the Smolyak quadrature formula:
⎛ d1 ⎞
∑ (1)^{l+d|k|1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
l≤|k|≤l+d1 ⎝|k|l⎠
Each summand is fully specified by sequence k. The summands are here
represented (besides k) also by sequence of number of points in each level
selected by k, and also by a cummulative number of evaluations. The latter
two are added only for conveniency.
The summands in the code are given by levels, which is a vector of
k sequences, further by levpoints which is a vector of sequences
of nuber of points in each level, and by cumevals which is the
cumulative number of points, this is:
d
∑ ∏ n_kᵢ
ᵏ ⁱ⁼¹
where the sum is done through all k before the current.
The levels and levpoints vectors are used by smolpit. */
class SmolyakQuadrature : public QuadratureImpl<smolpit>
{
friend class smolpit;
int level;
const OneDQuadrature &uquad;
std::vector<IntSequence> levels;
std::vector<IntSequence> levpoints;
std::vector<int> cumevals;
public:
SmolyakQuadrature(int d, int l, const OneDQuadrature &uq);
~SmolyakQuadrature() override = default;
int numEvals(int level) const override;
void designLevelForEvals(int max_eval, int &lev, int &evals) const;
protected:
smolpit begin(int ti, int tn, int level) const override;
unsigned int
numSummands() const
{
return levels.size();
}
private:
int calcNumEvaluations(int level) const;
};
#endif