# -*- coding: UTF-8 -*- from math import * import numpy as np ############################################ # 線形連立方程式を解く(逆行列を求める) # w : 方程式の左辺及び右辺 # n : 方程式の数 # m : 方程式の右辺の列の数 # eps : 逆行列の存在を判定する規準 # return : =0 : 正常 # =1 : 逆行列が存在しない # coded by Y.Suganuma ############################################ def gauss(w, n, m, eps) : nm = n + m ind = 0 for i1 in range(0, n) : y1 = 0.0 m1 = i1 + 1 m2 = 0 # ピボット要素の選択 for i2 in range(i1, n) : y2 = abs(w[i2][i1]) if y1 < y2 : y1 = y2 m2 = i2 # 逆行列が存在しない if y1 < eps : ind = 1 break # 逆行列が存在する else : # 行の入れ替え for i2 in range(i1, nm) : y1 = w[i1][i2] w[i1][i2] = w[m2][i2] w[m2][i2] = y1 # 掃き出し操作 y1 = 1.0 / w[i1][i1] for i2 in range(m1, nm) : w[i1][i2] *= y1 for i2 in range(0, n) : if i2 != i1 : for i3 in range(m1, nm) : w[i2][i3] -= (w[i2][i1] * w[i1][i3]) return ind ######################################### # 最小二乗法 # m : 多項式の次数 # n : データの数 # x,y : データ # return : 多項式の係数(高次から) # エラーの場合はNULLを返す # coded by Y.Suganuma ######################################### def least(m, n, x, y) : m += 1 z = np.empty(m, np.float) w = np.empty((m, m+1), np.float) A = np.empty((n, m), np.float) for i1 in range(0, n) : A[i1][m-2] = x[i1] A[i1][m-1] = 1.0 x1 = A[i1][m-2] x2 = x1 for i2 in range(m-3, -1, -1) : x2 *= x1 A[i1][i2] = x2 for i1 in range(0, m) : for i2 in range(0, m) : w[i1][i2] = 0.0 for i3 in range(0, n) : w[i1][i2] += A[i3][i1] * A[i3][i2] for i1 in range(0, m) : w[i1][m] = 0.0 for i2 in range(0, n) : w[i1][m] += A[i2][i1] * y[i2] sw = gauss(w, m, 1, 1.0e-10) if sw == 0 : for i1 in range(0, m) : z[i1] = w[i1][m] else : z = np.empty(0, np.float) return z ---------------------------------- # -*- coding: UTF-8 -*- import numpy as np import sys from math import * from function import least ############################ # 最小二乗法(多項式近似) # coded by Y.Suganuma ############################ line = sys.stdin.readline() s = line.split() m = int(s[0]) # 多項式の次数 n = int(s[1]) # データの数 x = np.empty(n, np.float) y = np.empty(n, np.float) for i1 in range(0, n) : # データ line = sys.stdin.readline() s = line.split() x[i1] = float(s[0]) y[i1] = float(s[1]) z = least(m, n, x, y) if z.size > 0 : print("結果") for i1 in range(0, m+1) : print(" " + str(m-i1) + " 次の係数 " + str(z[i1])) else : print("***error 逆行列を求めることができませんでした") ------------データ例1(コメント部分を除いて下さい)-------- 1 10 // 多項式の次数とデータの数 0 2.450 // 以下,(x, y) 1 2.615 2 3.276 3 3.294 4 3.778 5 4.009 6 3.920 7 4.267 8 4.805 9 5.656 -------------------------データ例2------------------------- 2 6 10 28.2 15 47.0 20 44.4 26 32.8 32 20.8 40 0.8