I found this code online,它实现了三次样条插值:
#include <vector>
#include <iostream>
using namespace std;
/** Templated on type of X, Y. X and Y must have operator +, -, *, /. Y must have defined
* a constructor that takes a scalar. */
template <typename X, typename Y>
class Spline
{
public:
/** An empty, invalid spline */
Spline() {}
/** A spline with x and y values */
Spline(const vector<X>& x, const vector<Y>& y)
{
if (x.size() != y.size()) {cerr << "X and Y must be the same size " << endl; return;}
if (x.size() < 3) { cerr << "Must have at least three points for interpolation" << endl; return;}
typedef typename vector<X>::difference_type size_type;
size_type n = y.size() - 1;
vector<Y> b(n), d(n), a(n), c(n + 1), l(n + 1), u(n + 1), z(n + 1);
vector<X> h(n + 1);
l[0] = Y(1);
u[0] = Y(0);
z[0] = Y(0);
h[0] = x[1] - x[0];
for (size_type i = 1; i < n; i++)
{
h[i] = x[i + 1] - x[i];
l[i] = Y(2 * (x[i + 1] - x[i - 1])) - Y(h[i - 1]) * u[i - 1];
u[i] = Y(h[i]) / l[i];
a[i] = (Y(3) / Y(h[i])) * (y[i + 1] - y[i]) - (Y(3) / Y(h[i - 1])) * (y[i] - y[i - 1]);
z[i] = (a[i] - Y(h[i - 1]) * z[i - 1]) / l[i];
}
l[n] = Y(1);
z[n] = c[n] = Y(0);
for (size_type j = n - 1; j >= 0; j--)
{
c[j] = z[j] - u[j] * c[j + 1];
b[j] = (y[j + 1] - y[j]) / Y(h[j]) - (Y(h[j]) * (c[j + 1] + Y(2) * c[j])) / Y(3);
d[j] = (c[j + 1] - c[j]) / Y(3 * h[j]);
}
for (size_type i = 0; i < n; i++)
{
mElements.push_back(Element(x[i], y[i], b[i], c[i], d[i]));
}
}
virtual ~Spline() {}
Y operator[](const X& x) const {return interpolate(x);}
Y interpolate(const X&x) const
{
if (mElements.size() == 0) return Y();
typename std::vector<element_type>::const_iterator it;
it = lower_bound(mElements.begin(), mElements.end(), element_type(x));
if (it != mElements.begin()) {it--;}
return it->eval(x);
}
vector<Y> operator[](const vector<X>& xx) const {return interpolate(xx);}
/* Evaluate at multiple locations, assuming xx is sorted ascending */
vector<Y> interpolate(const vector<X>& xx) const {
if (mElements.size() == 0) return vector<Y>(xx.size());
typename vector<X>::const_iterator it;
typename vector<element_type>::const_iterator it2;
it2 = mElements.begin();
vector<Y> ys;
for (it = xx.begin(); it != xx.end(); it++)
{
it2 = lower_bound(it2, mElements.end(), element_type(*it));
if (it2 != mElements.begin()) {it2--;}
ys.push_back(it2->eval(*it));
}
return ys;
}
protected:
class Element {
public:
Element(X _x) : x(_x) {}
Element(X _x, Y _a, Y _b, Y _c, Y _d)
: x(_x), a(_a), b(_b), c(_c), d(_d) {}
Y eval(const X& xx) const
{
X xix(xx - x);
return a + b * xix + c * (xix * xix) + d * (xix * xix * xix);
}
bool operator<(const Element& e) const {return x < e.x;}
bool operator<(const X& xx) const {return x < xx;}
X x;
Y a, b, c, d;
};
typedef Element element_type;
vector<element_type> mElements;
};
我这样称呼它:
Spline<VecDoub, VecDoub> MySpline(VecDoub(t), VecDoub(x));
但是,虽然程序编译没有错误,但根本不调用该函数。怎么了?我不是OO C ++的专家......
答案 0 :(得分:2)
此
Spline<VecDoub, VecDoub> MySpline(VecDoub(t), VecDoub(x));
定义一个函数,它接受两个VecDoub
参数并返回Spline<VecDoub, VecDoub>
(VecDoub(t)
与在这种情况下编写VecDoub t
相同)
如果编译器支持统一初始化,则可以使用
Spline<VecDoub, VecDoub> MySpline{VecDoub(t), VecDoub(x)};
甚至可能
Spline<VecDoub, VecDoub> MySpline(t, x);
将根据t
和x
的类型而有效。
答案 1 :(得分:1)
Vector<VecDoub> v1;
Vector<VecDoub> v2;
Spline<VecDoub,VecDoub> mySpline(v1,v2);
或
Spline<VecDoub,VecDoub> mySpline(Vector<VecDoub>(),Vector<VecDoub>());
答案 2 :(得分:0)
首先,我假设VecDoub
是std::vector<double>
,但无论如何,你发布的是该类的构造函数。