最近研究一个项目遇到需要使用插值,插值方法当然首选三次样条插值。此项目涉及到的插值包括内插值和外插值,所以对于插值的要求还是挺高的,需要尽可能的平滑。
首先我在github上面找到一段源代码GitHub - glentner/CubicSplineLib: C++ facility for natural cubic spline interpolation in 1D, 2D, and 3D.,基本能符合插值要求,但是外插值的时候跟Python结果差异较大,经过改进之后,完全与python的CubicSpline方法的
bc_type="natural"
保持一致。
部分代码展示如下:python代码
freq = np.array([250, 500, 1000, 2000, 4000])
gain = np.array([30, 30, 30, 30, 45])
gain_x = np.array([125, 250, 500, 1000, 2000, 4000, 8000])
full_freq = CubicSpline(freq, gain, bc_type="natural")
gain_y = full_freq(gain_x)
C++代码:
vector<double> AdjustCubicSpline(vector<double>& vecSrcX, vector<double>& vecConstX, vector<double>& vecConstY)
{
assert(!vecSrcX.empty());
assert(!vecConstX.empty());
assert(!vecConstY.empty());
assert(vecConstX.size() == vecConstY.size());
std::vector<double> create_temp_y;
try {
CubicSpline<double> my_data(vecConstX, vecConstY, 2); // the 2 says omp_set_num_threads(2)
create_temp_y = my_data.interpolate(vecSrcX);
}
catch (std::exception& error) {
std::cerr << error.what() << std::endl;
create_temp_y.resize(0);
vecSrcX.resize(0);
return create_temp_y;
}
return create_temp_y;
}
int main() {
vector<double> _X = { 250, 500, 1000, 2000, 4000};//must be strictly increasing sequence 必须严格增长
vector<double> _Y = { 30, 30, 30, 30, 45 };
vector<double> _X2 = { 125, 250, 500, 1000, 2000, 4000, 8000 };//must be strictly increasing sequence 必须严格增长
vector<double> vecAdd = AdjustCubicSpline(_X2, _X, _Y);//根据提供的x轴插值,灵活性较大
//vecAdd 就是最后得到的插值结果
}
有需求请联系qq:295282563