dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Polynomial/Interpolator.h

127 lines
3.3 KiB
C
Raw Normal View History

// Copyright (c) 2008 Max-Planck-Institute Saarbruecken (Germany)
//
2020-10-13 12:44:25 +00:00
// This file is part of CGAL (www.cgal.org)
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Polynomial/include/CGAL/Polynomial/Interpolator.h $
// $Id: Interpolator.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
2020-10-13 12:44:25 +00:00
// Author(s) : Michael Hemmer <hemmer@informatik.uni-mainz.de>
#ifndef CGAL_POLYNOMIAL_INTERPOLATE_H
#define CGAL_POLYNOMIAL_INTERPOLATE_H
namespace CGAL {
namespace internal {
2020-10-13 12:44:25 +00:00
// Class for interpolation of univariate or multivariate polynomials.
// The template argument must be a model of concept Polynomial_d
2020-10-13 12:44:25 +00:00
//
//
template <class Polynomial_d_>
class Interpolator{
typedef CGAL::Polynomial_traits_d<Polynomial_d_> PT;
2020-10-13 12:44:25 +00:00
public:
2020-10-13 12:44:25 +00:00
typedef typename PT::Polynomial_d Polynomial_d;
typedef typename PT::Coefficient_type Coeff;
typedef typename PT::Innermost_coefficient_type IC;
2020-10-13 12:44:25 +00:00
private:
typedef typename CGAL::Coercion_traits<Coeff,IC>::Cast IC2Coeff;
typedef typename PT::Construct_polynomial Construct;
2020-10-13 12:44:25 +00:00
std::vector<IC> xvals;
std::vector<Coeff> yvals;
std::vector<Coeff> b;
bool valid;
Polynomial_d interpolant;
Coeff eval_newton(int n, IC z)
{
Coeff p(b[n]);
for (int i = n-1; i >=0; i--){
Coeff tmp(IC2Coeff()((z - xvals[i])));
p = p * tmp + b[i];
}
return p;
}
Polynomial_d eval_newton_poly(int n)
2020-10-13 12:44:25 +00:00
{
CGAL_precondition(n >=0);
Polynomial_d p(Construct()(b[n]));
for (int i = n-1; i >=0; i--) {
Polynomial_d tmp = Construct()(IC2Coeff()(-xvals[i]),Coeff(1));
p = (p * tmp) + b[i];
}
return p;
}
2020-10-13 12:44:25 +00:00
public:
Interpolator(){};
2020-10-13 12:44:25 +00:00
// constructor from an InputIterator range with value type std::pair<IC,Coeff>
template<class InputIterator>
Interpolator(InputIterator begin, InputIterator end){
for(InputIterator it = begin; it != end; it++){
add_interpolation_point(*it);
}
}
2020-10-13 12:44:25 +00:00
/*
Interpolator(std::vector<IC> xvals_, std::vector<Coeff> yvals_)
: valid(false) {
CGAL_precondition(xvals_.size() != 0);
CGAL_precondition(xvals_.size() == yvals_.size());
for(unsigned i = 0; i < xvals_.size(); i++){
add_interpolation_point(xvals_[i],yvals_[i]);
}
}
*/
2020-10-13 12:44:25 +00:00
// void add_interpolation_point(std::pair<IC,Coeff> point){
// add_interpolation_point(point.first, point.second);
// }
2020-10-13 12:44:25 +00:00
// void add_interpolation_point(IC xval, Coeff yval){
void add_interpolation_point(std::pair<IC,Coeff> point){
valid = false;
// CGAL_precondition(0 == std::count(xval, xvals.begin(), yvals.end()));
xvals.push_back(point.first);
yvals.push_back(point.second);
2020-10-13 12:44:25 +00:00
Coeff num, den;
2020-10-13 12:44:25 +00:00
int k = static_cast<int>(xvals.size()) - 1;
if(k == 0){
b.push_back(yvals[0]);
}else{
2020-10-13 12:44:25 +00:00
num = yvals[k] - eval_newton(k-1,xvals[k]);
den = Coeff(1);
for (int j = 0; j < k; j++) {
// (k-j) if xvals's are sequential
den *= (xvals[k] - xvals[j]);
}
b.push_back(num / den);
}
}
2020-10-13 12:44:25 +00:00
Polynomial_d get_interpolant(){
if (xvals.size() == 0) return Polynomial_d(0);
// TODO: compute new interpolant from old interpolant ?
if(!valid)
interpolant = eval_newton_poly(static_cast<int>(xvals.size())-1);
2020-10-13 12:44:25 +00:00
return interpolant;
}
2020-10-13 12:44:25 +00:00
};
} // namespace internal
} //namespace CGAL
2020-10-13 12:44:25 +00:00
#endif // CGAL_POLYNOMIAL_INTERPOLATE_H