北航数值分析作业三
2016-11-17 23:06
134 查看
from math import * t_table = [0, 0.2, 0.4, 0.6, 0.8, 1.0] th = 0.2 u_table = [0, 0.4, 0.8, 1.2, 1.6, 2] uh = 0.4 z_table = [[-0.5, -0.34, 0.14, 0.94, 2.06, 3.5], [-0.42, -0.5, -0.26, 0.3, 1.18, 2.38], [-0.18, -0.5, -0.5, -0.18, 0.46, 1.42], [0.22, -0.34, -0.58, -0.5, -0.1, 0.62], [0.78, -0.02, -0.5, -0.66, -0.5, -0.02], [1.5, 0.46, -0.26, -0.66, -0.74, -0.5] ] table_x = [0.08 * i for i in range(11)] table_y = [0.5 + 0.05 * i for i in range(21)] table_z = [[0 for i in range(len(table_y))] for j in range(len(table_x))] epsilon = 1e-12 sigma_limit = 1e-7 # 向量的无穷范数 vector_norm = lambda *x: max([abs(x[i]) for i in range(len(x))]) # 列主元高斯消去法求解线性方程组 def gauss(a, b): for i in range(len(b)): maxrow = i for j in range(i + 1, len(b)): if abs(a[j][i]) > abs(a[maxrow][i]): maxrow = j # 换行 a[maxrow], a[i] = a[i], a[maxrow] b[maxrow], b[i] = b[i], b[maxrow] for j in range(i + 1, len(b)): k = a[j][i] / a[i][i] for col in range(i, len(a[0])): a[j][col] -= k * a[i][col] b[j] -= k * b[i] # 回代过程 for i in range(len(b) - 1, -1, -1): for col in range(i + 1, len(a[0])): b[i] -= a[i][col] * b[col] b[i] /= a[i][i] return b # 矩阵转置 def transform(x): row_cnt, col_cnt = len(x), len(x[0]) y = [[0 for i in range(row_cnt)] for j in range(col_cnt)] for i in range(row_cnt): for j in range(col_cnt): y[j][i] = x[i][j] return y # 矩阵相乘 def matrix_mul_matrix(x, y): row_cnt, col_cnt = len(x), len(y[0]) z = [[0 for i in range(col_cnt)] for j in range(row_cnt)] for i in range(row_cnt): for j in range(col_cnt): for k in range(len(x[0])): z[i][j] += x[i][k] * y[k][j] return z #牛顿迭代法 def newton_iterate(t, u, v, w, b): f = [0.5 * cos(t) + u + v + w - b[0], t + 0.5 * sin(u) + v + w - b[1], 0.5 * t + u + cos(v) + w - b[2], t + 0.5 * u + v + sin(w) - b[3]] f = [-1 * i for i in f] ff = [[-0.5 * sin(t), 1, 1, 1], [1, 0.5 * cos(u), 1, 1], [0.5, 1, -sin(v), 1], [1, 0.5, 1, cos(w)]] delta = gauss(ff, f) t, u, v, w = t + delta[0], u + delta[1], v + delta[2], w + delta[3] return t, u, v, w # 迭代法求解非线性方程组 def solve(x, y): t, u, v, w = 1, 2, 1, 2 b = [2.67 + x, 1.07 + y, 3.74 + x, 0.79 + y] while 1: tt, uu, vv, ww = newton_iterate(t, u, v, w, b) if vector_norm(tt - t, uu - u, vv - v, ww - w) / vector_norm(tt, uu, vv, ww) < epsilon: return tt, uu, vv, ww t, u, v, w = tt, uu, vv, ww # 二次分片插值查表根据t,u插值求出z def interpolate(t, u): ti = round(t / th) ui = round(u / uh) ti = min(len(t_table) - 2, max(1, ti)) ui = min(len(u_table) - 2, max(1, ui)) ans = 0 for i in range(ti - 1, ti + 2): for j in range(ui - 1, ui + 2): l = 1 for k in range(ti - 1, ti + 2): if k != i: l *= t - t_table[k] l /= t_table[i] - t_table[k] for k in range(ui - 1, ui + 2): if k != j: l *= u - u_table[k] l /= u_table[j] - u_table[k] ans += z_table[i][j] * l return ans #根据x,y求z def getZ(): for xi, x in enumerate(table_x): for yi, y in enumerate(table_y): t, u, v, w = solve(x, y) z = interpolate(t, u) table_z[xi][yi] = z # 列主元高斯消去法求逆矩阵 def inverse(x): n = len(x) I = [[int(i == j) for i in range(n)] for j in range(n)] # 增广矩阵 ex = [x[i] + I[i] for i in range(n)] for i in range(n): max_row = i for j in range(i + 1, n): if abs(ex[j][i]) > abs(ex[max_row][i]): max_row = j ex[i], ex[max_row] = ex[max_row], ex[i] for j in range(i + 1, n): k = ex[j][i] / ex[i][i] for col in range(n * 2): ex[j][col] -= k * ex[i][col] # 将当前行第一个数字变为1 k = ex[i][i] for j in range(i, 2 * n): ex[i][j] /= k # 开始回溯 for i in range(n - 1, -1, -1): for j in range(i + 1, n): # 倍数ex[i][j] for k in range(n, 2 * n): ex[i][k] -= ex[i][j] * ex[j][k] ex[i][j] = 0 # 后半部分变为逆矩阵 ans = [[ex[i][j + n] for j in range(n)] for i in range(n)] return ans # 为了让矩阵乘法可读性更强 class Matrix: def __init__(self, matrix): self.matrix = matrix def mul(self, x): return Matrix(matrix_mul_matrix(self.matrix, x)) def get_sigma(k, C, cout=False): s = 0 for xi, x in enumerate(table_x): for yi, y in enumerate(table_y): fxy = table_z[xi][yi] x_vector = [[table_x[xi] ** i for i in range(k + 1)]] # 行向量 y_vector = [[table_y[yi] ** i] for i in range(k + 1)] # 列向量 pxy = Matrix(x_vector).mul(C).mul(y_vector).matrix[0][0] s += (fxy - pxy) ** 2 if cout: print(x, y, fxy, pxy) return s #最小二乘法曲面拟合 def least_square(): k = 1 while 1: B = [[table_x[j] ** i for i in range(k + 1)] for j in range(len(table_x))] G = [[table_y[j] ** i for i in range(k + 1)] for j in range(len(table_y))] C = Matrix(inverse(matrix_mul_matrix(transform(B), B))) \ .mul(transform(B)) \ .mul(table_z) \ .mul(G) \ .mul(inverse(matrix_mul_matrix(transform(G), G))).matrix sigma = get_sigma(k, C) print(k, sigma) if sigma < sigma_limit: return k, sigma, C else: k += 1 getZ() print("打印x,y,z") for xi, x in enumerate(table_x): for yi, y in enumerate(table_y): print(x, y, (table_z[xi][yi])) print("开始选择k并计算sigma") ans_k, ans_sigma, ans_C = least_square() print("最终选择的k,sigma,和系数矩阵为") print(ans_k, ans_sigma, ans_C) print("打印x,y,f(x,y),p(x,y)") get_sigma(ans_k, ans_C, cout=True)
相关文章推荐
- 北航数值分析作业三
- 截获数据分析--第一次作业
- 一个.NET编程的作业(Shop & Products) (2-分析篇(类图与Trousers类的设计))
- Hadoop作业提交分析(三)
- Hadoop作业提交分析(一)
- Hadoop0.21.0源码流程分析(1)-客户端提交作业
- 用Python实现一个细粒度hadoop作业监控分析工具
- 动态规划;多边形游戏;类似圈型石头合并;算法设计分析作业;
- 网站分析快速作业:十三个网站数据分析的问题及答案
- 2010.11 Linux内核分析第三次作业
- SqlServer链接服务器配置及其在作业更新时出现 [SQLSTATE 42000](错误 7410)的分析处理
- 作业及复习1:公共政策分析
- &lt;&lt;深入理解计算机系统&gt;&gt;家庭作业3.38, 分析全过程
- Hadoop作业提交分析(二)
- 《Java数据结构和算法(第二版)》第2章编程作业2.6中noDup方法错误分析及纠正方法
- 党性分析&作业
- 数据库作业001:范式分析
- 从yacc,Lex到手工的语法分析与词法分析,编译的作业牢骚
- Hadoop作业提交分析(四)
- 算法分析与设计的作业:“基于FMM的分词系统”