スプライン補間(3次)
スプライン補間をやってみた。隣り合う2点を3次式で結ぶやつ。詳しくは次のサイトが参考になる。
・http://next1.cc.it-hiroshima.ac.jp/MULTIMEDIA/numeanal1/node16.html
・http://www.akita-nct.ac.jp/~yamamoto/lecture/2004/5E/interpolation/text/html/node3.html
def spline(x, y, a): l = len(x) matrix = [] p = [] #まず最初に連立方程式を解くための行列を作る for i in range(l + 1): if i == 0: p.append(1.0) else: p.append(0.0) matrix.append(p) for i in range(1, l - 1): p = [] for j in range(l + 1): p.append(0.0) p[i - 1] = x[i] - x[i - 1] p[i] = 2 * (x[i + 1] - x[i - 1]) p[i + 1] = x[i + 1] - x[i] p[l] = 6*((y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1])) matrix.append(p) p = [] for i in range(l + 1): if i == l - 1: p.append(1.0) else: p.append(0.0) matrix.append(p) hakidashi(matrix, l) #連立方程式を解く for i in range(l + 1): #aがどの区間にあるかを調べる if a >= x[i] and a <= x[i + 1]: break h = x[i + 1] - x[i] s = (matrix[i+1][l]*(a-x[i])**3 - matrix[i][l]*(a-x[i+1])**3)/(6*h)+(y[i+1]/h - h*matrix[i+1][l]/6)*(a-x[i])-(y[i]/h - h*matrix[i][l]/6)*(a-x[i+1]) return s def hakidashi(matrix, dim): for i in range(dim): num = matrix[i][i] for j in range(dim + 1): matrix[i][j] = matrix[i][j] / num for j in range(dim): if i == j: pass else: a = matrix[j][i] for k in range(i, dim + 1): matrix[j][k] = matrix[j][k]- a * matrix[i][k] def main(): x = [0.9,1.3,1.9,2.1,2.6,3.0,3.9,4.4,4.7,5.0,6.0,7.0,8.0,9.2] y = [1.3,1.5,1.85,2.1,2.6,2.7,2.4,2.15,2.05,2.1,2.25,2.3,2.25,1.95] f = open('data.dat', 'w') i = x[0] #開始地点 while i <= x[-1]: res = spline(x, y, i) #iに対する補間値を求める f.write('%f %f\n' % (i, res)) i += 0.01 #刻み幅 f.close() if __name__ == '__main__': main()
これで作られたdata.datをgnuplotで描いてみるとこんな感じになる。
赤い線がdata.datで描かれたもの。青い円形の点は元々のデータを表す。