我需要插入一个tabled函数s.t.得到的样条曲线在间隔结束时具有零导数。我使用InterpolateWithDerivatives
函数编写了示例,但生成的样条曲线并没有跨越给定的点:
typedef Eigen::Spline<double,1> Spline1d;
typedef Eigen::SplineFitting<Spline1d> Spline1dFitting;
void test_spline()
{
Eigen::VectorXd x(5);
Eigen::VectorXd y(5);
x << 0.0, 0.25, 0.5, 0.75, 1.0;
y << 0.0, 0.5, 1.0, 0.5, 0.0;
Eigen::VectorXd derivatives(2);
derivatives << 0., 0.;
Eigen::VectorXi indices(2);
indices << 0, x.size() - 1;
Spline1d const& spline = Spline1dFitting::InterpolateWithDerivatives(
y.transpose(), derivatives.transpose(), indices, 3, x);
for (int i = 0; i < 5; ++ i)
std::cout << "must be 0: " << spline(x(i)) - y(i) << std::endl;
}
虽然没有固定衍生品,但效果很好:
void test_spline_2()
{
Eigen::VectorXd x(5);
Eigen::VectorXd y(5);
x << 0.0, 0.25, 0.5, 0.75, 1.0;
y << 0.0, 0.5, 1.0, 0.5, 0.0;
Spline1d const& spline2 = Spline1dFitting::Interpolate(y.transpose(), 3, x);
for (int i = 0; i < 5; ++ i)
std::cout << "must be 0: " << spline2(x(i)) - y(i) << std::endl;
}
这里有什么不对吗?
答案 0 :(得分:0)
偶然发现了同一问题。本征似乎存在一个错误。
第一个示例:
must be 0: 0
must be 0: 7.54792e+168
must be 0: 1.90459e+185
must be 0: 7.54792e+168
must be 0: 0
第二个示例:
must be 0: 0
must be 0: 0
must be 0: 0
must be 0: 0
must be 0: 0
在b
(SplineFitting.h)中,右侧向量InterpolateWithDerivatives
没有正确填充。
在您的示例中调用lu.solve
时,b
是
0.0
0.0
1.0
1.90459157797e+185
2.06587336741e+161
0.0
0.0
答案 1 :(得分:0)
昨天我遇到了同样的问题。不幸的是,本征确实存在一个错误。正如Andreas指出的那样,向量b没有正确初始化。
由于我没有时间跟踪本征中的错误,因此我将补丁发布在这里,以便在有人遇到相同问题时提供帮助。
--- /original/eigen3/unsupported/Eigen/src/Splines/SplineFitting.h 2018-09-24 10:13:26.281178488 +0200
+++ /new/eigen3/unsupported/Eigen/src/Splines/SplineFitting.h 2018-09-26 14:59:13.737373531 +0200
@@ -381,11 +381,12 @@
DenseIndex row = startRow;
DenseIndex derivativeIndex = derivativeStart;
+
for (DenseIndex i = 1; i < parameters.size() - 1; ++i)
{
const DenseIndex span = SplineType::Span(parameters[i], degree, knots);
- if (derivativeIndices[derivativeIndex] == i)
+ if (derivativeIndex < derivativeIndices.size() && derivativeIndices[derivativeIndex] == i)
{
A.block(row, span - degree, 2, degree + 1)
= SplineType::BasisFunctionDerivatives(parameters[i], 1, degree, knots);
@@ -395,8 +396,9 @@
}
else
{
- A.row(row++).segment(span - degree, degree + 1)
+ A.row(row).segment(span - degree, degree + 1)
= SplineType::BasisFunctions(parameters[i], degree, knots);
+ b.col(row++) = points.col(i);
}
}
b.col(0) = points.col(0);