3次スプラインのバリエーションをまとめました。
準備
はじめに、3次スプラインの基本を整理します。
3次スプラインの定義
データ点 を、次の区分多項式 で補間します。
ただし、 は以下の条件を満たします。
条件1. 区間の右側の端点でデータ点に一致。
条件2. 区間の左側の端点でデータ点に一致。
条件3. 隣接する区間の境界点で1階微分が一致。
条件4. 隣接する区間の境界点で2階微分が一致。
図1にイメージを示します。
解くべき式の導出
上の4つの条件式を係数の組 について解けば良いですが、これらを直接 の式で表すことは困難です。
そこで先ず を使って、 を の式で表します。その次に、 が満たすべき式を導きます。
[ の表式 ]
条件1.より
よって
[ の表式 ]
の定義式より
よって
[ の表式 ]
条件4.より
よって
ただし、 は1つ前の項との差分を表します()。
[ の表式 ]
条件2.より
すでに求めた係数 の表式を代入すると
よって
ただし、
としました。添字は、後の式の見栄えを良くするため、あえて1つずらしました。
[ の表式 ]
続けて が満たすべき式を導きます。条件3.より
式を整理して
係数 の表式を代入すると
最終的に、 の隣接3項間漸化式の形に整理できます。
行列の形で書けば
です(横線はただの仕切り線です)。
式 (5) に示した上下2つの空白 ( ) の行に適当な の条件式を入れると、すべての が定まり、式 (1)-(4) から係数の組 が求まります。このとき加える の条件式により、3次スプラインには複数のバリエーションが存在します。
3次スプラインのバリエーションと計算法
3次スプラインのバリエーションを挙げます。なお、周期的スプライン以外は、左端と右端とで異なるバリエーションを組み合わせることも可能です。
自然スプライン (natural spline)
最端点 で2階微分がゼロとなるように を決めます。自然スプライン曲線は、区間 ] の外で直線(=2階微分がゼロ)に滑らかにつながります。
[ の条件式]
[ 解くべき式 ]
このような、係数行列が3重対角行列で与えられる線形連立方程式は、3重対角行列アルゴリズム(Tri-Diagonal Matrix Algorithm, TDMA)により効率的に解かれます。プログラムの実装は極めて簡単です。
固定スプライン (clamped spline)
日本語訳が見当たらなかったので、ここでは仮に固定スプラインと呼びます。固定スプラインでは、最端点 での1階微分の値を与えます。
の値は任意です。 の条件式は、式(2)-(4)を代入して直ちに求まります。
[ の条件式]
[ 解くべき式 ]
ここでも係数行列が3重対角行列になっており、3重対角行列アルゴリズムが有効です。
ノットなしスプライン (not-a-knot spline)
ノット(節点)とは、隣接する区間の曲線が互いに結合する点(データ点)のことです。ノットなしスプラインでは、 で3階微分が連続になるように を決めます。自然スプラインや固定スプラインと異なり、最端点 での1階、2階微分の値を指定しません。
最端点での1階、2階微分の値が不明な場合、ノットなしスプラインが有用です。
ノットなしスプラインでは、 で0~3階微分がすべて連続になるため、 と 、 と はそれぞれ全く同じ関数になります。つまり、見かけ上 のノットが消失します。 の条件式は、式(3)を代入して直ちに求まります。
[ の条件式]
[ 解くべき式 ]
[ ] で囲った要素により、係数行列が3重対角行列になっていません。第2行の 倍を第1行から引き、第 行の 倍を第 行から引くことで、[ ] で囲った要素を消去します。適当に定数倍して式を整えると、
を得ます。これで、3重対角行列アルゴリズムを使える形になりました。
<注意>
または の場合、3重対角行列アルゴリズムをそのまま適用するとゼロ除算が起きます。この場合は、 についてそれぞれ独立に解けますので、これらを消去してから適用します。
上記の場合以外で、 または が に近い場合は、計算が不安定になると思われます。この場合は、ガウスの掃き出し法など、別のアルゴリズムを使った方が良いかもしれません。
周期的スプライン (periodic spline)
周期的スプラインでは、両最端点 での1階、2階微分の値が互いに一致するように を決めます。 であれば、スプライン曲線は区間 ] の外に周期的に繋がります。
の条件式は、式(2)-(4)を代入して直ちに求まります。
[ の条件式]
[ 解くべき式 ]
3重対角行列アルゴリズムを適用するために変形を行います。第 行の 倍を第 行、 倍を第 行に加えます。このとき、第 行の式 を別に書くと、解くべき式は次の通りになります。
右上と左下の角に非ゼロの要素([ ] で囲った要素)がありますが、これも3重対角行列アルゴリズムを適用できる形です。例えば、次のWikipediaのページ ("Variants") を参照。
en.wikipedia.org
各バリエーションの比較テスト
自然スプライン、固定スプライン、ノットなしスプライン
FORTRANで即席のプログラムを作成しました。SPLINE_INT() を呼び出して係数を決定したのち、SPLINE() を呼び出して区間 ] の任意の点を計算します。また、SPLINE_INT() では、左端と右端とで別々に3次スプラインの種類を指定します。
PROGRAM MAIN
IMPLICIT REAL*8(A-H, O-Z)
ALLOCATABLE XJ(:), YJ(:),
$ X(:), YN(:), YC(:), YK(:)
C ファイルからデータを読み込む
NDATA = 0 ! データ点の数
OPEN(UNIT=10, FILE="input1.txt", STATUS="OLD", ACTION="READ")
DO
READ(UNIT=10, FMT=*, END=10) DUMMY
NDATA = NDATA + 1
ENDDO
10 N = NDATA - 1
ALLOCATE(XJ(0:N), YJ(0:N))
REWIND(UNIT=10)
DO J=0, N
READ(UNIT=10, FMT=*) XJ(J), YJ(J)
ENDDO
CLOSE(UNIT=10)
C スプライン補間を実行
C 元のデータ点数の100倍の数の等間隔点で補間
KMAX = NDATA * 100 - 1
DX = (XJ(N) - XJ(0)) / KMAX
ALLOCATE(X(0:KMAX), YN(0:KMAX), YC(0:KMAX), YK(0:KMAX))
C 固定スプラインの両端での傾き
ALPHA = -1.D0
BETA = 1.D0
C 自然スプライン
C 'N'は自然(NATURAL)
C ALPHA, BETA はダミー
CALL SPLINE_INI('N', ALPHA, 'N', BETA, XJ, YJ, N)
XTMP = XJ(0) - DX
DO K=0, KMAX
XTMP = XTMP + DX
CALL SPLINE(XJ, N, XTMP, Y)
X(K) = XTMP
YN(K) = Y
ENDDO
C 固定スプライン
C 'C'は固定(CLAMPED)
CALL SPLINE_INI('C', ALPHA, 'C', BETA, XJ, YJ, N)
DO K=0, KMAX
CALL SPLINE(XJ, N, X(K), Y)
YC(K) = Y
ENDDO
C ノットなしスプライン
C 'K'はノット(KNOT)
C ALPHA, BETA はダミー
CALL SPLINE_INI('K', ALPHA, 'K', BETA, XJ, YJ, N)
DO K=0, KMAX
CALL SPLINE(XJ, N, X(K), Y)
YK(K) = Y
ENDDO
OPEN(UNIT=20, FILE="spline.txt", STATUS="REPLACE", ACTION="WRITE")
DO K=0, KMAX
WRITE(UNIT=20, FMT=*)X(K), YN(K), YC(K), YK(K)
ENDDO
CLOSE(UNIT=20)
DEALLOCATE(XJ, YJ, X, YN, YC, YK)
STOP
END
C 係数を決定、保存
SUBROUTINE SPLINE_INI(KEY0, ALPHA, KEY1, BETA, XJ, YJ, N)
IMPLICIT REAL*8(A-H, O-Z)
INTENT(IN) KEY0, KEY1, XJ, YJ, N
CHARACTER*1 KEY0, KEY1
C スプラインの種類 (N/C/K)
C KEY0: 左端
C KEY1: 右端
DIMENSION XJ(0:N), YJ(0:N),
$ UJ(0:N), SJ(0:N-1), DXJ(1:N), DSJ(1:N-1),
$ TDMA_A(1:N), TDMA_B(0:N), TDMA_C(0:N-1), TDMA_D(0:N)
ALLOCATABLE COEFF(:, :)
SAVE COEFF
IF(.NOT.(KEY0.EQ.'N'.OR.KEY0.EQ.'C'.OR.KEY0.EQ.'K').OR.
$ .NOT.(KEY1.EQ.'N'.OR.KEY1.EQ.'C'.OR.KEY1.EQ.'K'))
$ STOP "! KEY ERROR"
IF(ALLOCATED(COEFF)) DEALLOCATE(COEFF)
DXJ(1) = XJ(1) - XJ(0)
SJ(0) = (YJ(1) - YJ(0)) / DXJ(1)
DO J=1, N-1
DXJ(J+1) = XJ(J+1) - XJ(J)
SJ(J) = (YJ(J+1) - YJ(J)) / DXJ(J+1)
DSJ(J) = SJ(J) - SJ(J-1)
ENDDO
C 式(5)を作る。
C TDMA は TriDiagonal Matrix Algorithm (3重対角行列アルゴリズム)。
C
C [ TDMA_B(0) TDMA_C(0) ] [UJ(0)] [TDMA_D(0)]
C [ TDMA_A(1) TDMA_B(1) TDMA_C(1) 0 ] [ ] [ ]
C [ TDMA_A(2) TDMA_B(2) ... ] [ ... ] = [ ... ]
C [ ... ... ] [ ] [ ]
C [ 0 TDMA_C(N-1) ] [ ] [ ]
C [ TDMA_A(N) TDMA_B(N) ] [UJ(N)] [TDMA_D(N)]
DO J=1, N-1
TDMA_A(J) = DXJ(J)
TDMA_B(J) = DXJ(J) + DXJ(J+1)
TDMA_C(J) = DXJ(J+1)
TDMA_D(J) = DSJ(J)
ENDDO
TDMA_B = 2.D0 * TDMA_B
TDMA_D = 6.D0 * TDMA_D
C 左端
SELECT CASE (KEY0)
CASE ('N')
TDMA_B(0) = 1.D0
TDMA_C(0) = 0.D0
TDMA_D(0) = 0.D0
CASE ('C')
TDMA_B(0) = 2.D0 * DXJ(1)
TDMA_C(0) = DXJ(1)
TDMA_D(0) = 6.D0 * (SJ(0) - ALPHA)
CASE ('K')
TDMA_B(0) = DXJ(1) - DXJ(2)
TDMA_C(0) = 2.D0 * DXJ(1) + DXJ(2)
TDMA_D(0) = 6.D0 * DSJ(1) / (1.D0 + DXJ(2) / DXJ(1))
END SELECT
C 右端
SELECT CASE (KEY1)
CASE ('N')
TDMA_B(N) = 1.D0
TDMA_A(N) = 0.D0
TDMA_D(N) = 0.D0
CASE ('C')
TDMA_B(N) = 2.D0 * DXJ(N)
TDMA_A(N) = DXJ(N)
TDMA_D(N) = 6.D0 * (BETA - SJ(N-1))
CASE ('K')
TDMA_B(N) = DXJ(N) - DXJ(N-1)
TDMA_A(N) = 2.D0 * DXJ(N) + DXJ(N-1)
TDMA_D(N) = 6.D0 * DSJ(N-1) / (1.D0 + DXJ(N-1) / DXJ(N))
END SELECT
NMIN=0
NMAX=N
C ゼロ除算の回避
IF(TDMA_B(0).EQ.0.D0)THEN
UJ(1) = TDMA_D(0) / TDMA_C(0)
TDMA_D(1) = TDMA_D(1) - TDMA_B(1) * UJ(1)
TDMA_D(2) = TDMA_D(2) - TDMA_A(2) * UJ(1)
TDMA_B(1) = TDMA_A(1)
TDMA_A(2) = 0.D0
NMIN=1
ELSEIF(TDMA_B(N).EQ.0.D0)THEN
UJ(N-1) = TDMA_D(N) / TDMA_A(N)
TDMA_D(N-1) = TDMA_D(N-1) - TDMA_B(N-1) * UJ(N-1)
TDMA_D(N-2) = TDMA_D(N-2) - TDMA_C(N-2) * UJ(N-1)
TDMA_B(N-1) = TDMA_C(N-1)
TDMA_A(N-2) = 0.D0
NMAX=N-1
ENDIF
C TDMA を実行
DO J=NMIN+1, NMAX
W = TDMA_A(J) / TDMA_B(J-1)
TDMA_B(J) = TDMA_B(J) - W * TDMA_C(J-1)
TDMA_D(J) = TDMA_D(J) - W * TDMA_D(J-1)
ENDDO
UJ(NMAX) = TDMA_D(NMAX) / TDMA_B(NMAX)
DO J=NMAX-1, NMIN, -1
UJ(J) = (TDMA_D(J) - TDMA_C(J) * UJ(J+1)) / TDMA_B(J)
ENDDO
IF(NMIN.EQ.1)THEN
TMP = UJ(0)
UJ(0) = UJ(1)
UJ(1) = TMP
ENDIF
IF(NMAX.EQ.N-1)THEN
TMP = UJ(N)
UJ(N) = UJ(N-1)
UJ(N-1) = TMP
ENDIF
C 係数を計算
ALLOCATE(COEFF(4,N))
C COEFF(1, J): A_J
C COEFF(2, J): B_J
C COEFF(3, J): C_J
C COEFF(4, J): D_J
DO J=1, N
COEFF(1, J) = (UJ(J)-UJ(J-1)) / DXJ(J) / 6.D0
COEFF(2, J) = .5D0 * UJ(J)
COEFF(3, J) = SJ(J-1)
$ + DXJ(J) * (2.D0 * UJ(J) + UJ(J-1)) / 6.D0
COEFF(4, J) = YJ(J)
ENDDO
RETURN
C スプライン補間の計算
ENTRY SPLINE(XJ, N, X, Y)
C X がどの区間にあるか判断
JMIN = 0
JMAX = N
DO
IF(JMAX.EQ.JMIN+1) EXIT
JAVE = (JMIN + JMAX) / 2
IF(XJ(JAVE).LT.X)THEN
JMIN = JAVE
ELSE
JMAX = JAVE
ENDIF
ENDDO
J = JMAX
C 計算を実行
XDIF = X - XJ(J)
Y = COEFF(1, J)
DO NORD=2, 4
Y = Y * XDIF + COEFF(NORD, J)
ENDDO
RETURN
END
"input1.txt" からデータ点を読み取ってスプライン補間し、結果を "spline.txt" に出力します。ここでは次の適当なデータ点で試してみます。
"input1.txt"
0.2 0.4392
0.7 0.8638
1.6 0.5449
2.3 0.2019
3.0 0.0190
4.0 -0.0374
補間の結果を、下の図2に示します。
固定スプラインの結果は、最端点 でやや無理な傾きを指定しているため 、自然スプラインとノットなしスプラインの結果に比べて大きくたわんでいます。一方、自然スプラインとノットなしスプラインの結果の差は、図の左側で大きくなっているように見えます。最左端 の付近を拡大してみます。
図3では、 での接線を点線で描き加えました(係数が分かっているので、当然接線を求めることができます)。 が増加したときの接線との乖離の程度を見比べると、明らかに自然スプラインの方が直線に近い形をしていることが分かります。
図4では、 を点線で描き加えました。自然スプラインは で乖離していますが、一方でノットなしスプラインは で乖離しています。見かけ上 のノットが消失していることが分かります。
周期的スプライン
FORTRANで即席のプログラムを作成しました。SPLINE_INT() を呼び出して係数を決定したのち、SPLINE() を呼び出して区間 [x0,xN] の任意の点を計算します。
PROGRAM MAIN
IMPLICIT REAL*8(A-H, O-Z)
ALLOCATABLE XJ(:), YJ(:)
C ファイルからデータを読み込む
NDATA = 0 ! データ点の数
OPEN(UNIT=10, FILE="input2.txt", STATUS="OLD", ACTION="READ")
DO
READ(UNIT=10, FMT=*, END=10) DUMMY
NDATA = NDATA + 1
ENDDO
10 N = NDATA - 1
ALLOCATE(XJ(0:N), YJ(0:N))
REWIND(UNIT=10)
DO J=0, N
READ(UNIT=10, FMT=*) XJ(J), YJ(J)
ENDDO
CLOSE(UNIT=10)
C スプライン補間を実行
C 元のデータ点数の100倍の数の等間隔点で補間
KMAX = NDATA * 100 - 1
DX = (XJ(N) - XJ(0)) / KMAX
C 周期的スプライン
OPEN(UNIT=20, FILE="splineP.txt",
$ STATUS="REPLACE", ACTION="WRITE")
CALL SPLINE_INI(XJ, YJ, N)
XX = XJ(0) - DX
DO K=0, KMAX
XX = XX + DX
CALL SPLINE(XJ, N, XX, YY)
WRITE(UNIT=20, FMT=*)XX, YY
ENDDO
CLOSE(UNIT=20)
DEALLOCATE(XJ, YJ)
STOP
END
C 係数を決定、保存
SUBROUTINE SPLINE_INI(XJ, YJ, N)
IMPLICIT REAL*8(A-H, O-Z)
INTENT(IN) XJ, YJ, N
DIMENSION XJ(0:N), YJ(0:N),
$ UJ(0:N), SJ(0:N-1), DXJ(1:N), DSJ(1:N-1),
$ TDMA_A(0:N-1), TDMA_B(0:N-1),
$ TDMA_C(0:N-1), TDMA_D(0:N-1),
$ PJ(N-1), QJ(N-1), RJ(N-1)
ALLOCATABLE COEFF(:, :)
SAVE COEFF
IF(ALLOCATED(COEFF)) DEALLOCATE(COEFF)
DXJ(1) = XJ(1) - XJ(0)
SJ(0) = (YJ(1) - YJ(0)) / DXJ(1)
DO J=1, N-1
DXJ(J+1) = XJ(J+1) - XJ(J)
SJ(J) = (YJ(J+1) - YJ(J)) / DXJ(J+1)
DSJ(J) = SJ(J) - SJ(J-1)
ENDDO
C 解くべき式
C
C [ TDMA_B(0) TDMA_C(0) TDMA_A(0) ] [UJ(0) ] [TDMA_D(0) ]
C [ TDMA_A(1) TDMA_B(1) TDMA_C(1) 0 ] [ ] [ ]
C [ TDMA_A(2) TDMA_B(2) ... ] [ ... ] = [ ... ]
C [ ... ... ] [ ] [ ]
C [ 0 TDMA_C(N-2) ] [ ] [ ]
C [ TDMA_C(N-1) TDMA_A(N-1) TDMA_B(N-1) ] [UJ(N-1)] [TDMA_D(N-1)]
TDMA_A(0) = DXJ(N)
TDMA_B(0) = DXJ(N) + DXJ(1)
TDMA_C(0) = DXJ(1)
TDMA_D(0) = SJ(0) - SJ(N-1)
DO J=1, N-1
TDMA_A(J) = DXJ(J)
TDMA_B(J) = DXJ(J) + DXJ(J+1)
TDMA_C(J) = DXJ(J+1)
TDMA_D(J) = DSJ(J)
ENDDO
TDMA_B = 2.D0 * TDMA_B
TDMA_D = 6.D0 * TDMA_D
C 下記2つの線形連立方程式に TDMA (3重対角行列アルゴリズム) を適用。
C
C [ TDMA_B(1) TDMA_C(1) ] [PJ(1) ] [TDMA_D(1) ]
C [ TDMA_A(2) TDMA_B(2) TDMA_C(2) 0 ] [ ] [ ]
C [ TDMA_A(3) TDMA_B(3) ... ] [ ... ] = [ ... ]
C [ 0 ... ... TDMA_C(N-2) ] [ ] [ ]
C [ TDMA_A(N-1) TDMA_B(N-1) ] [PJ(N-1)] [TDMA_D(N-1)]
C
CALL TDMA(N-1, TDMA_A(1), TDMA_B(1), TDMA_C(1), TDMA_D(1), PJ)
C
C [ TDMA_B(1) TDMA_C(1) ] [QJ(1) ] [-TDMA_A(1) ]
C [ TDMA_A(2) TDMA_B(2) TDMA_C(2) 0 ] [ ] [ 0 ]
C [ TDMA_A(3) TDMA_B(3) ... ] [ ... ] = [ ... ]
C [ 0 ... ... TDMA_C(N-1) ] [ ] [ 0 ]
C [ TDMA_A(N-1) TDMA_B(N-1) ] [QJ(N-1)] [-TDMA_C(N-1)]
RJ = 0.D0
RJ(1) = -TDMA_A(1)
RJ(N-1) = -TDMA_C(N-1)
CALL TDMA(N-1, TDMA_A(1), TDMA_B(1), TDMA_C(1), RJ, QJ)
C UJが求まる
UJ(0) = (TDMA_D(0) - TDMA_A(0) * PJ(N-1) - TDMA_C(0) * PJ(1))
$ / (TDMA_B(0) + TDMA_A(0) * QJ(N-1) + TDMA_C(0) * QJ(1))
DO J=1, N-1
UJ(J) = PJ(J) + UJ(0) * QJ(J)
ENDDO
UJ(N) = UJ(0)
C 係数を計算
ALLOCATE(COEFF(4,N))
C COEFF(1, J): A_J
C COEFF(2, J): B_J
C COEFF(3, J): C_J
C COEFF(4, J): D_J
DO J=1, N
COEFF(1, J) = (UJ(J)-UJ(J-1)) / DXJ(J) / 6.D0
COEFF(2, J) = .5D0 * UJ(J)
COEFF(3, J) = SJ(J-1)
$ + DXJ(J) * (2.D0 * UJ(J) + UJ(J-1)) / 6.D0
COEFF(4, J) = YJ(J)
ENDDO
RETURN
C スプライン補間の計算
ENTRY SPLINE(XJ, N, X, Y)
C X がどの区間にあるか判断
JMIN = 0
JMAX = N
DO
IF(JMAX.EQ.JMIN+1) EXIT
JAVE = (JMIN + JMAX) / 2
IF(XJ(JAVE).LT.X)THEN
JMIN = JAVE
ELSE
JMAX = JAVE
ENDIF
ENDDO
J = JMAX
C 計算を実行
XDIF = X - XJ(J)
Y = COEFF(1, J)
DO NORD=2, 4
Y = Y * XDIF + COEFF(NORD, J)
ENDDO
RETURN
END
C TDMA
SUBROUTINE TDMA(M, A, B, C, D, X)
IMPLICIT REAL*8(A-H, O-Z)
DIMENSION A(M), B(M), C(M), D(M), X(M)
DO J=2, M
W = A(J) / B(J-1)
B(J) = B(J) - W * C(J-1)
D(J) = D(J) - W * D(J-1)
ENDDO
X(M) = D(M) / B(M)
DO J=M-1, 1, -1
X(J) = (D(J) - C(J) * X(J+1)) / B(J)
ENDDO
RETURN
END
"input2.txt" からデータ点を読み取ってスプライン補間し、結果を "splineP.txt" に出力します。ここでは次の適当なデータ点 で試してみます。
"input2.txt"
0.7854 0.7071
1.0472 0.8660
1.5708 1.0000
2.0944 0.8660
2.3562 0.7071
2.6180 0.5000
3.1416 -0.0004
3.6652 -0.5000
3.9270 -0.7071
4.1888 -0.8660
4.7124 -1.0000
5.2360 -0.8660
5.4978 -0.7071
5.7596 -0.5000
6.2832 0.0000
6.8068 0.5000
7.0686 0.7071
補間の結果を、下の図5に示します。
補間を行った区間は、中央の縦線 () より左側です。右側の曲線は、左側の補間の結果を1周期ずらしてプロットしたものです。1階微分を破線、2階微分を点線であわせて示しました。いずれも、縦線のところで滑らかにつながっています。
比較のため、自然スプライン、固定スプライン、ノットなしスプラインによる補間の結果を示します。
図6は自然スプラインの結果です。実線の結果は悪くないように見えますが、1階微分は明らかに不連続です。2階微分は、最端点でゼロになる条件に無理があり、縦線の付近で不自然な振る舞いをしています。
図7は固定スプラインの結果です。両最端点での1階微分は、どちらも としました。1階、2階微分とも滑らかにつながっているように見えます(実際に滑らかにつながっている訳ではありません)。最端点での1階微分の値が予め分かっているため、それらしい結果が得られました。
図8はノットなしスプラインの結果です。1階微分まで滑らかにつながっているように見えます(実際に滑らかにつながっている訳ではありません)。2階微分は明らかに不連続ですが、自然スプラインの結果と比べると、こちらの結果の方が無理がありません。
まとめ
3次スプラインの4つのバリエーションをまとめました。また、即席のプログラムで実際にスプライン補間を行い、それぞれの特徴を見ました(表1)。
表1 3次スプラインのバリエーション
周期的スプライン | 両最端点の1階、2階微分の値を互いに一致させる。 周期的なデータの補間に適する。 |
自然スプライン | 最端点での2階微分の値をゼロとする。 直線で無理なく補外できるデータの補間に適する。 |
固定スプライン | 最端点での1階微分の値を指定する。 最端点での傾きが分かっているデータの補間に適する。 |
ノットなしスプライン | 最端点での条件を指定しない。 一般的なデータの補間に用いられる。 |