Skip to content
Snippets Groups Projects
Commit cfc686b5 authored by Tom Fischer's avatar Tom Fischer
Browse files

Fixed a problem in PiecewiseLinearInterpolation.

If the point to interpolate the value on is not located in any interval we choose either the first or the last interval and extrapolate the data. The algorithm for the determination of the interval is corrected.
parent 0afd2972
No related branches found
No related tags found
No related merge requests found
...@@ -11,57 +11,59 @@ ...@@ -11,57 +11,59 @@
* http://www.opengeosys.org/project/license * http://www.opengeosys.org/project/license
* *
*/ */
#include <cmath>
#include <limits>
#include "PiecewiseLinearInterpolation.h" #include "PiecewiseLinearInterpolation.h"
#include <iostream>
namespace MathLib namespace MathLib
{ {
PiecewiseLinearInterpolation::PiecewiseLinearInterpolation(const std::vector<double>& supporting_points, PiecewiseLinearInterpolation::PiecewiseLinearInterpolation(const std::vector<double>& supporting_points,
const std::vector<double>& values_at_supp_pnts) const std::vector<double>& values_at_supp_pnts)
: _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts) : _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts)
{} {}
PiecewiseLinearInterpolation::PiecewiseLinearInterpolation(const std::vector<double>& supporting_points, PiecewiseLinearInterpolation::PiecewiseLinearInterpolation(
const std::vector<double>& values_at_supp_pnts, const std::vector<double>& supporting_points,
const std::vector<double>& points_to_interpolate, const std::vector<double>&
std::vector<double>& values_at_interpol_pnts) values_at_supp_pnts,
const std::vector<double>&
points_to_interpolate,
std::vector<double>&
values_at_interpol_pnts)
: _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts) : _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts)
{ {
// std::cout << "PiecewiseLinearInterpolation::PiecewiseLinearInterpolation support_points, values_at_supp_pnts: " << std::endl;
// for (size_t k(0); k<supporting_points.size(); k++) {
// std::cout << supporting_points[k] << " " << values_at_supp_pnts[k] << std::endl;
// }
// std::cout << std::endl;
values_at_interpol_pnts.clear(); values_at_interpol_pnts.clear();
for (size_t k(0); k < points_to_interpolate.size(); k++) for (std::size_t k(0); k < points_to_interpolate.size(); k++)
values_at_interpol_pnts.push_back (this->getValue (points_to_interpolate[k])); values_at_interpol_pnts.push_back (this->getValue (points_to_interpolate[k]));
} }
PiecewiseLinearInterpolation::~PiecewiseLinearInterpolation() PiecewiseLinearInterpolation::~PiecewiseLinearInterpolation()
{} {}
double PiecewiseLinearInterpolation::getValue ( double pnt_to_interpolate ) double PiecewiseLinearInterpolation::getValue(double pnt_to_interpolate)
{ {
// search interval that has the point inside // search interval that has the point inside
size_t interval_idx (std::numeric_limits<size_t>::max()); std::size_t interval_idx(std::numeric_limits<std::size_t>::max());
for (size_t k(1); for (std::size_t k(1); k < _supporting_points.size()
k < _supporting_points.size() && interval_idx == std::numeric_limits<size_t>::max(); && interval_idx == std::numeric_limits<std::size_t>::max(); k++)
k++) if (_supporting_points[k - 1] <= pnt_to_interpolate
if (_supporting_points[k - 1] <= pnt_to_interpolate && pnt_to_interpolate <= && pnt_to_interpolate <= _supporting_points[k])
_supporting_points[k])
interval_idx = k - 1; interval_idx = k - 1;
if (interval_idx == std::numeric_limits<std::size_t>::max()) {
const double dist_first(fabs(_supporting_points[0] - pnt_to_interpolate));
const double dist_last(fabs(_supporting_points[_supporting_points.size() - 1] - pnt_to_interpolate));
if (dist_first < dist_last)
interval_idx = 0;
else
interval_idx = _supporting_points.size() - 2;
}
// compute linear interpolation polynom: y = m * x + n // compute linear interpolation polynom: y = m * x + n
long double m ( long double m((_values_at_supp_pnts[interval_idx + 1] - _values_at_supp_pnts[interval_idx])
(_values_at_supp_pnts[interval_idx + / (_supporting_points[interval_idx + 1] - _supporting_points[interval_idx]));
1] - long double n(_values_at_supp_pnts[interval_idx] - m * _supporting_points[interval_idx]);
_values_at_supp_pnts[interval_idx]) /
(_supporting_points[interval_idx + 1] - _supporting_points[interval_idx]));
// double m ((_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx+1]) / (_supporting_points[interval_idx] - _supporting_points[interval_idx+1]));
// double n (_values_at_supp_pnts[interval_idx+1] - m * _supporting_points[interval_idx+1]);
long double n (_values_at_supp_pnts[interval_idx] - m * _supporting_points[interval_idx]);
return m * pnt_to_interpolate + n; return m * pnt_to_interpolate + n;
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#ifndef PIECEWISELINEARINTERPOLATION_H_ #ifndef PIECEWISELINEARINTERPOLATION_H_
#define PIECEWISELINEARINTERPOLATION_H_ #define PIECEWISELINEARINTERPOLATION_H_
#include <limits>
#include <vector> #include <vector>
namespace MathLib namespace MathLib
...@@ -24,14 +23,14 @@ class PiecewiseLinearInterpolation ...@@ -24,14 +23,14 @@ class PiecewiseLinearInterpolation
{ {
public: public:
PiecewiseLinearInterpolation(const std::vector<double>& supporting_points, PiecewiseLinearInterpolation(const std::vector<double>& supporting_points,
const std::vector<double>& values_at_supp_pnts); const std::vector<double>& values_at_supp_pnts);
PiecewiseLinearInterpolation(const std::vector<double>& supporting_points, PiecewiseLinearInterpolation(const std::vector<double>& supporting_points,
const std::vector<double>& values_at_supp_pnts, const std::vector<double>& values_at_supp_pnts,
const std::vector<double>& points_to_interpolate, const std::vector<double>& points_to_interpolate,
std::vector<double>& values_at_interpol_pnts); std::vector<double>& values_at_interpol_pnts);
virtual ~PiecewiseLinearInterpolation(); virtual ~PiecewiseLinearInterpolation();
double getValue ( double pnt_to_interpolate ); double getValue(double pnt_to_interpolate);
private: private:
const std::vector<double>& _supporting_points; const std::vector<double>& _supporting_points;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment