私はそこに提案されたアルゴリズムの 1 つを使用していましたが、結果は非常に悪いです。
ウィキアルゴリズムを実装しました
Javaで(以下のコード)。x(0)
はpoints.get(0)
、y(0)
はvalues[points.get(0)]
、α
はalfa
およびμ
はmi
。あとはwikiの疑似コードと同じです。
public void createSpline(double[] values, ArrayList<Integer> points){
a = new double[points.size()+1];
for (int i=0; i <points.size();i++)
{
a[i] = values[points.get(i)];
}
b = new double[points.size()];
d = new double[points.size()];
h = new double[points.size()];
for (int i=0; i<points.size()-1; i++){
h[i] = points.get(i+1) - points.get(i);
}
alfa = new double[points.size()];
for (int i=1; i <points.size()-1; i++){
alfa[i] = (double)3 / h[i] * (a[i+1] - a[i]) - (double)3 / h[i-1] *(a[i+1] - a[i]);
}
c = new double[points.size()+1];
l = new double[points.size()+1];
mi = new double[points.size()+1];
z = new double[points.size()+1];
l[0] = 1; mi[0] = z[0] = 0;
for (int i =1; i<points.size()-1;i++){
l[i] = 2 * (points.get(i+1) - points.get(i-1)) - h[i-1]*mi[i-1];
mi[i] = h[i]/l[i];
z[i] = (alfa[i] - h[i-1]*z[i-1])/l[i];
}
l[points.size()] = 1;
z[points.size()] = c[points.size()] = 0;
for (int j=points.size()-1; j >0; j--)
{
c[j] = z[j] - mi[j]*c[j-1];
b[j] = (a[j+1]-a[j]) - (h[j] * (c[j+1] + 2*c[j])/(double)3) ;
d[j] = (c[j+1]-c[j])/((double)3*h[j]);
}
for (int i=0; i<points.size()-1;i++){
for (int j = points.get(i); j<points.get(i+1);j++){
// fk[j] = values[points.get(i)];
functionResult[j] = a[i] + b[i] * (j - points.get(i))
+ c[i] * Math.pow((j - points.get(i)),2)
+ d[i] * Math.pow((j - points.get(i)),3);
}
}
}
私が得る結果は次のとおりです。
しかし、これは次のようになります。
また、http: //www.geos.ed.ac.uk/~yliu23/docs/lect_spline.pdfに従って、別の方法でアルゴリズムを実装しようとしています。
最初に、線形スプラインを行う方法を示しますが、それは非常に簡単です。A
およびB
係数を計算する関数を作成します。次に、二次導関数を追加して線形スプラインを拡張します。係数も簡単に計算できますC
。D
しかし、二次導関数を計算しようとすると問題が発生します。彼らがそれらをどのように計算するかわかりません。
そこで、線形補間のみを実装しました。結果は次のとおりです。
最初のアルゴリズムを修正する方法を知っている人や、2 番目のアルゴリズムで 2 次導関数を計算する方法を説明してくれる人はいますか?