mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
* Interpolate a uniform grid with a bilinear function. * Typo removal. * Invalid syntax in Jamfile. * Do domain verification before computation. * Fix OOB access on print. * pimpl the class so it can be shared between threads. * Add google/benchmark file to measure the performance of the bilinear interpolation. * Fix up docs. * Remove non-ASCII characters from print statements. Add a float128 test. * Improve the documentation of the bilinear uniform class. * Remove float128 as it doesn't support to_string. * Don't use decltype(fieldData.size()) as the indexer; that makes MSVC 14.2 choke. Use RandomAccessContainer::size_type. * Use ADL for to_string for compatibility with multiprecision. * Improve error message which rows*cols != fieldData.size().
95 lines
3.4 KiB
Plaintext
95 lines
3.4 KiB
Plaintext
[/
|
|
Copyright (c) 2021 Nick Thompson
|
|
Use, modification and distribution are subject to the
|
|
Boost Software License, Version 1.0. (See accompanying file
|
|
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
]
|
|
|
|
[section:bilinear_uniform Bilinear Uniform Interpolation]
|
|
|
|
[heading Synopsis]
|
|
|
|
``
|
|
#include <boost/math/interpolators/bilinear_uniform.hpp>
|
|
|
|
namespace boost::math::interpolators {
|
|
|
|
template <class RandomAccessContainer>
|
|
class bilinear_uniform
|
|
{
|
|
public:
|
|
using Real = typename RandomAccessContainer::value_type;
|
|
|
|
bilinear_uniform(RandomAccessContainer && fieldData, decltype(fieldData.size()) rows, decltype(fieldData.size()) cols, Real dx = 1, Real dy = 1, Real x0 = 0, Real y0 = 0)
|
|
|
|
Real operator()(Real x, Real y) const;
|
|
};
|
|
``
|
|
|
|
|
|
[heading Bilinear Uniform Interpolation]
|
|
|
|
The bilinear uniform interpolator takes a grid of data points specified by a linear index and interpolates between each segment using a bilinear function.
|
|
Note that "bilinear" does not mean linear-it is the product of two linear functions.
|
|
The interpolant is continuous and its evaluation is constant time.
|
|
An example usage is as follows:
|
|
|
|
std::vector<double> v{0.1, 0.2, 0.3,
|
|
0.4, 0.5, 0.5};
|
|
using boost::math::interpolators::bilinear_uniform;
|
|
int rows = 2;
|
|
int cols = 3;
|
|
double dx = 1;
|
|
double dy = 1;
|
|
auto bu = bilinear_uniform(std::move(v), rows, cols, dx, dy);
|
|
// evaluate at a point:
|
|
double z = bu(0.0, 0.0);
|
|
|
|
Periodically, it is helpful to see what data the interpolator has.
|
|
This can be achieved via
|
|
|
|
std::cout << ub << "\n";
|
|
|
|
Note that the interpolator is pimpl'd, so that copying the class is cheap, and hence it can be shared between threads.
|
|
(The call operator is threadsafe.)
|
|
|
|
Note that the layout of the field data follows the convention found in laying out images: The first value is associated with (x0, y0), and the last value is associate with (x0 + (cols - 1)dx, y0 + (rows - 1)dy).
|
|
This matches with how we think about laying out matrices in C order, but of course there is no canonical choice and conventions must be made.
|
|
For example, it is traditional in image processing the associate the first field value with the center of the pixel (which would be called a cell-centered field in VTK).
|
|
This interpolator is point-centered, in the sense that (x0,y0) is associated with value v[0], and (x0+dx, y0) associated with v[1].
|
|
If you have cell-centered data at (0,0), then just pass (x0,y0) = (0.5, 0.5) to this interpolator.
|
|
|
|
Note that this interpolator does not provide the option for a rotation.
|
|
We regarded that as too expensive to handle in this class.
|
|
Rotating the arguments must be performed by the user.
|
|
|
|
|
|
[heading Complexity and Performance]
|
|
|
|
The google/benchmark in `reporting/performance/bilinear_uniform_performance.cpp` demonstrates the cost of the call operator for this interpolator:
|
|
|
|
```
|
|
Run on (16 X 4300 MHz CPU s)
|
|
CPU Caches:
|
|
L1 Data 32K (x8)
|
|
L1 Instruction 32K (x8)
|
|
L2 Unified 1024K (x8)
|
|
L3 Unified 11264K (x1)
|
|
Load Average: 0.92, 0.64, 0.35
|
|
--------------------------------------
|
|
Benchmark Time
|
|
--------------------------------------
|
|
Bilinear<double>/64 13.6 ns
|
|
Bilinear<double>/128 13.3 ns
|
|
Bilinear<double>/256 13.9 ns
|
|
Bilinear<double>/512 13.7 ns
|
|
Bilinear<double>/1024 13.2 ns
|
|
Bilinear<double>/2048 13.1 ns
|
|
Bilinear<double>/4096 13.2 ns
|
|
Bilinear<double>/8192 13.2 ns
|
|
```
|
|
|
|
|
|
[endsect]
|
|
[/section:bilinear_uniform]
|