Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
interpolation.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//interpolation.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//interpolation.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with interpolation.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
25
26#pragma once
27
29
30namespace bertini{
31 namespace endgame{
32
59template<typename ComplexT>
60 Vec<ComplexT> HermiteInterpolateAndSolve(ComplexT const& target_time, const unsigned int num_sample_points, const TimeCont<ComplexT> & times, const SampCont<ComplexT> & samples, const SampCont<ComplexT> & derivatives, ContStart shift_from = ContStart::Back)
61{
62 assert((times.size() >= num_sample_points) && "must have sufficient number of sample times");
63 assert((samples.size() >= num_sample_points) && "must have sufficient number of sample points");
64 assert((derivatives.size() >= num_sample_points) && "must have sufficient number of derivatives");
65
66
67 unsigned num_t, num_s, num_d;
68 if (shift_from == ContStart::Back)
69 {
70 num_t = static_cast<unsigned>(times.size()-1);
71 num_s = static_cast<unsigned>(samples.size()-1);
72 num_d = static_cast<unsigned>(derivatives.size()-1);
73 }
74 else
75 {
76 num_t = num_s = num_d = num_sample_points-1;
77 }
78
79 Mat< Vec<ComplexT> > space_differences(2*num_sample_points,2*num_sample_points);
80 Vec<ComplexT> time_differences(2*num_sample_points);
81
82
83 for(unsigned int ii=0; ii<num_sample_points; ++ii)
84 {
85 space_differences(2*ii,0) = samples[ num_s-ii]; /* F[2*i][0] = samples[i]; */
86 space_differences(2*ii+1,0) = samples[ num_s-ii]; /* F[2*i+1][0] = samples[i]; */
87 space_differences(2*ii+1,1) = derivatives[num_d-ii]; /* F[2*i+1][1] = derivatives[i]; */
88 time_differences(2*ii) = times[ num_t-ii]; /* z[2*i] = times[i]; */
89 time_differences(2*ii+1) = times[ num_t-ii]; /* z[2*i+1] = times[i]; */
90 }
91
92 //Add first round of finite differences to fill out rest of matrix.
93 for(unsigned int ii=1; ii< num_sample_points; ++ii)
94 {
95 space_differences(2*ii,1) = (space_differences(2*ii,0) - space_differences(2*ii-1,0)) / (time_differences(2*ii) - time_differences(2*ii-1));
96
97 }
98
99 //Filling out finite difference matrix to get the diagonal for hermite interpolation polyonomial.
100 for(unsigned int ii=2; ii < 2*num_sample_points; ++ii)
101 {
102 for(unsigned int jj=2; jj <=ii; ++jj)
103 {
104 space_differences(ii,jj) =
105 (space_differences(ii,jj-1) - space_differences(ii-1,jj-1))
106 /
107 (time_differences(ii) - time_differences(ii-jj));
108 }
109 }
110
111 //The interpolant in Newton form is P(x) = sum_k a_k prod_{j<k}(x - z_j), with a_k the
112 //divided-difference diagonal and z the DOUBLED node list (each time appears twice).
113 //Horner from the top: multiply by (x - z_k) before adding a_k, for k = 2n-2 down to 0.
114 //
115 //This loop previously indexed the doubled node list at half speed (z_ii paired with
116 //a_{2*ii}), evaluating a polynomial that is NOT the Hermite interpolant: it failed to
117 //reproduce even a cubic exactly. The limit as the sample window slides to the target was
118 //unaffected, so the endgame still converged -- but at a degraded order, costing extra
119 //iterations and delivering poorer approximations than the samples support.
120 Vec<ComplexT> Result = space_differences(2*num_sample_points - 1,2*num_sample_points - 1);
121 for (int k = 2*static_cast<int>(num_sample_points) - 2; k >= 0; --k)
122 Result = (Result*(target_time - time_differences(k)) + space_differences(k,k)).eval();
123 return Result;
124} //re: HermiteInterpolateAndSolve
125
126}} // re: namespaces
Definition endgames.hpp:44
Vec< ComplexT > HermiteInterpolateAndSolve(ComplexT const &target_time, const unsigned int num_sample_points, const TimeCont< ComplexT > &times, const SampCont< ComplexT > &samples, const SampCont< ComplexT > &derivatives, ContStart shift_from=ContStart::Back)
Estimates the root to interpolating polynomial.
Definition interpolation.hpp:60
Definition algorithm_builder.hpp:36
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
std::deque< Vec< T > > SampCont
Definition config.hpp:33
ContStart
Definition config.hpp:36
@ Back
Definition config.hpp:38
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
std::deque< T > TimeCont
Definition config.hpp:34