54 const std::map<double, T> &
points = {})
60 const std::map<double, T> &
points() const noexcept
90 throw std::runtime_error(
"[CubicSpline] Invalid points size: " + std::to_string(n));
93 std::array<Eigen::MatrixXd, 4> coeffMatAll;
94 for(
auto & coeffMat : coeffMatAll)
96 coeffMat.resize(
dim_, n);
100 for(
int dimIdx = 0; dimIdx <
dim_; dimIdx++)
106 Eigen::MatrixXd tridiagonalSystem(n, 4);
107 Eigen::VectorXd y(n);
108 Eigen::VectorXd yd(n);
109 Eigen::VectorXd deltaT(n - 1);
110 Eigen::VectorXd deltaY(n - 1);
111 Eigen::VectorXd h(n - 1);
112 Eigen::VectorXd r(n - 1);
116 auto pointIt =
points_.begin();
117 for(
size_t k = 0; k < n; k++, pointIt++)
119 y(k) = pointIt->second(dimIdx);
122 deltaT(k) = std::next(pointIt)->first - pointIt->first;
123 deltaY(k) = std::next(pointIt)->second(dimIdx) - pointIt->second(dimIdx);
125 r(k) = deltaY(k) / deltaT(k);
131 for(
size_t k = 0; k < n - 2; k++)
134 tridiagonalSystem.row(k + 1) << h(k + 1), 2 * (h(k) + h(k + 1)), h(k), 3 * (r(k) * h(k + 1) + r(k + 1) * h(k));
140 tridiagonalSystem.row(0) << 0, 1, 0,
bcStart_.value(dimIdx);
144 tridiagonalSystem.row(0) << 0, 1, 0.5,
145 (3 * deltaY(0)) / (2 * deltaT(0)) -
bcStart_.value(dimIdx) / (4 * deltaT(0));
149 throw std::runtime_error(
"[CubicSpline] Unsupported type of boundary constraint: "
150 + std::to_string(
static_cast<int>(
bcStart_.type)));
154 tridiagonalSystem.row(n - 1) << 0, 1, 0,
bcEnd_.value(dimIdx);
158 tridiagonalSystem.row(n - 1) << 2, 4, 0,
159 (6 * deltaY(n - 2)) / deltaT(n - 2) +
bcEnd_.value(dimIdx) * deltaT(n - 2);
163 throw std::runtime_error(
"[CubicSpline] Unsupported type of boundary constraint: "
164 + std::to_string(
static_cast<int>(
bcEnd_.type)));
169 for(
size_t i = 1; i < n; i++)
171 double w = tridiagonalSystem(i, 0) / tridiagonalSystem(i - 1, 1);
172 tridiagonalSystem(i, 1) -= w * tridiagonalSystem(i - 1, 2);
173 tridiagonalSystem(i, 3) -= w * tridiagonalSystem(i - 1, 3);
175 yd(n - 1) = tridiagonalSystem(n - 1, 3) / tridiagonalSystem(n - 1, 1);
176 for(
int i =
static_cast<int>(n - 2); i >= 0; i--)
178 yd(i) = (tridiagonalSystem(i, 3) - tridiagonalSystem(i, 2) * yd(i + 1)) / tridiagonalSystem(i, 1);
182 for(
size_t k = 0; k < n - 1; k++)
184 coeffMatAll[0](dimIdx, k) = y(k);
185 coeffMatAll[1](dimIdx, k) = yd(k);
186 coeffMatAll[2](dimIdx, k) = (3 * deltaY(k) / deltaT(k) - 2 * yd(k) - yd(k + 1)) / deltaT(k);
187 coeffMatAll[3](dimIdx, k) = (-2 * deltaY(k) / deltaT(k) + yd(k) + yd(k + 1)) / (deltaT(k) * deltaT(k));
193 auto pointIt =
points_.begin();
194 for(
size_t k = 0; k < n - 1; k++, pointIt++)
196 double t0 = pointIt->first;
197 std::array<T, 4> coeff;
198 for(
size_t i = 0; i < coeffMatAll.size(); i++)
200 coeff[i] = coeffMatAll[i].col(k);
202 std::shared_ptr<CubicPolynomial<T>> cubicFunc = std::make_shared<CubicPolynomial<T>>(coeff, t0);
203 this->
funcs_.emplace(std::next(pointIt)->first, cubicFunc);