18 const std::vector<std::vector<Real>> & base_points,
const MultiIndex<Real> & data)
21 setData(base_points, data);
35 _degenerate_interpolation =
false;
36 _setup_complete =
false;
39 _original_dim = data.
dim();
40 _degenerate_index.resize(_original_dim,
false);
43 if (data.
dim() != base_points.size())
45 std::ostringstream oss;
46 oss <<
"Leading dimension of base_points " << base_points.size() <<
" and data dimensionality " 47 << data.
dim() <<
" are inconsistent.";
48 throw std::domain_error(oss.str());
58 std::vector<std::vector<Real>> modified_base_points;
59 for (
unsigned int j = 0; j < data.
dim(); ++j)
62 slice_dimensions.push_back(j);
63 slice_indices.push_back(0);
64 _degenerate_index[j] =
true;
67 modified_base_points.push_back(base_points[j]);
74 if (modified_base_points.size() == 0)
76 _degenerate_interpolation =
true;
77 _base_points = base_points;
83 _base_points = modified_base_points;
84 _data = data.
slice(slice_dimensions, slice_indices);
93 if (_base_points.size() != _data.dim())
94 throw std::domain_error(
"Size of the leading dimension of base points must be equal to " 95 "dimensionality of data array");
98 for (
unsigned int j = 0; j < _data.dim(); ++j)
100 if (shape[j] != _base_points[j].size())
102 std::ostringstream oss;
103 oss <<
"Dimension " << j <<
" has " << _base_points[j].size()
104 <<
" base points but dimension of data array is " << shape[j];
105 throw std::domain_error(oss.str());
108 for (
unsigned int i = 1; i < _base_points[j].size(); ++i)
110 if (_base_points[j][i - 1] >= _base_points[j][i])
112 std::ostringstream oss;
113 oss <<
"Base point values for dimension " << j <<
" are not strictly increasing: bp[" 114 << i - 1 <<
"]: " << _base_points[j][i - 1] <<
" bc[" << i
115 <<
"]: " << _base_points[j][i];
116 throw std::domain_error(oss.str());
122 _setup_complete =
true;
125 template <
typename T>
130 assert(values.size() == _data.dim());
132 indices.
resize(_data.dim());
133 for (
unsigned int d = 0; d < _data.dim(); ++d)
134 indices[d] = linearSearchHelper(values[d], _base_points[d]);
137 template <
typename T>
140 const std::vector<Real> & vector)
const 144 for (
unsigned int i = 1; i < vector.size(); ++i)
146 if (vector[i - 1] >= vector[i])
148 std::ostringstream oss;
149 oss <<
"In linearSearchHelper vector is not strictly increasing: vector[" << i - 1
150 <<
"]: " << vector[i - 1] <<
" vector[" << i <<
"]: " << vector[i];
151 throw std::domain_error(oss.str());
162 else if (x >= vector.back())
171 return vector.size() - 2;
174 for (
unsigned int j = 0; j < vector.size() - 2; ++j)
175 if (x >= vector[j] && x < vector[j + 1])
177 return vector.size() - 2;
180 template <
typename T>
185 if (!_setup_complete)
186 throw std::domain_error(
187 "Object has been constructed properly. This happens when the empty constructor is called " 188 "and setData is not called before interpolation.");
192 if (x.size() != _original_dim)
194 std::ostringstream oss;
195 oss <<
"In sample the parameter x has size " << x.size() <<
" but data has dimension " 197 throw std::domain_error(oss.str());
201 if (_degenerate_interpolation)
206 std::vector<T> y(_data.dim());
208 for (
unsigned int j = 0; j < _original_dim; ++j)
209 if (!_degenerate_index[j])
217 linearSearch(y, indices);
221 std::vector<std::vector<T>> weights(_data.dim());
222 for (
unsigned int j = 0; j < _data.dim(); ++j)
224 volume *= _base_points[j][indices[j] + 1] - _base_points[j][indices[j]];
231 weights[j].resize(2);
232 weights[j][0] = _base_points[j][indices[j] + 1] - y[j];
233 weights[j][1] = y[j] - _base_points[j][indices[j]];
237 unsigned int flat_index = _data.flatIndex(indices);
246 T interpolated_value = 0;
247 for (
const auto & p : hypercube)
253 unsigned int index = flat_index;
255 for (
unsigned int j = 0; j < p.first.size(); ++j)
257 index += stride[j] * p.first[j];
258 w *= weights[j][p.first[j]];
262 interpolated_value += w * _data[index];
265 return interpolated_value /
volume;
unsigned int linearSearchHelper(T &x, const std::vector< Real > &vector) const
linear search helper for a single std::vector; note that argument is non-const to handle smaller/larg...
T multiLinearInterpolation(const std::vector< T > &x) const
This function will take an independent variable input and will return the dependent variable based on...
void linearSearch(std::vector< T > &values, MultiIndex< Real >::size_type &indices) const
linearSearch finds the indices i_k of the base point such that base_point[d][i_k] <= values[d] < base...
void setData(const std::vector< std::vector< Real >> &base_points, const MultiIndex< Real > &data)
sets data but also fixes degenerate dimensions in data
unsigned int dim() const
dimension of the container
void resize(const size_type &shape)
Resize container. Must keep dimensionality constant.
const size_type & size() const
container size as dim dimensional vector
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int stride(unsigned int j) const
access the stride
This class interpolates multi-dimensional data sets.
MultiIndex< T > slice(unsigned int dimension, unsigned int index) const
accesses a slice of the multi index object
MultiDimensionalInterpolationTempl()
void errorCheck()
checks consistency of the data