python实现最小二乘拟合函数(选择三种不同基函数,基函数可改变)

作业题目和要求:
在这里插入图片描述
在这里插入图片描述
解决思路:
在这里插入图片描述

分别使用基函数是fai_i(x) = x^i ,是勒让德正交基函数,是利用正交函数关系式构造出g0~g4实现拟合。

相关知识:在这里插入图片描述
计算结果如下:
在这里插入图片描述
计算拟合误差,使用2-范数:
也就是误差平方求和再开方(方差好像。。)

在这里插入图片描述

import numpy as np

def Linear_independence_functions(m,n,list_x,list_y): #选择线性无关函数fai(x)作为基函数,公式(5.2.14)
    #构造方程组参数G与G的转置
    G = np.zeros(shape=(m, n+1)) #构造正规方程组(方程组为GT*G*c=GT*y)
    for i in range (0,m): #i从0到m-1,共m行
        G_row = [] #每行重置空row
        for j in range (0,n+1): #n+1列
            G_row.append(list_x[i]**j)
        G[i] = G_row
    #print(G)
    GT = np.transpose(G) #GT是G的转置
    #构造方程组参数y的转置
    yT = np.transpose(list_y)
    # 系数c求解
    c = np.linalg.solve(np.dot(GT,G),np.dot(GT,yT))
    print(c)
    return c

def Legendre_Orthogonality_functions(m,n,list_x,list_y): #勒让德正交函数作为基函数
    """
    c(k) = (gk,f) / (gk,gk),所以需要g0~g4
    g0 = 1
    g1 = x
    g2 = 1/2(3x*x-1)
    g3 = 1/2(5x*x*x-3x)
    g4 = 1/8(35x*x*x*x-30x*x+3)
    """
    #存储gk每一项的系数
    list_b = [1,0,-1/2,0,3/8]
    list_1 = [0,1,0,-3/2,0]
    list_2 = [0,0,2/3,0,-30/8]
    list_3 = [0,0,0,5/2,0]
    list_4 = [0,0,0,0,35/8]
    c = []
    for i in range (0,n+1):#分别计算c0~c4
        #构造gi函数
        k1 = list_1[i]
        k2 = list_2[i]
        k3 = list_3[i]
        k4 = list_4[i]
        b = list_b[i]
        #计算(gi,f),(gi, gi)
        sum_up = 0
        sum_down = 0
        for j in range (0,len(list_y)):
            x = list_x[i]
            g = k1 * x + k2 * (x ** 2) + k3 * (x ** 3) + k4 * (x ** 4) + b
            sum_up += g*list_y[j]
            sum_down += g*g
        print(sum_up)
        print(sum_down)
        c.append(sum_up/sum_down)
    print(c)
    return c

def Orthogonality_functions(m,n,list_x,list_y): #递推关系式构造的正交函数作为基函数
    """
    c(k) = (gk,f) / (gk,gk),所以需要g0~g4
    g0 = 1
    g1 = x-1/2
    g2 = x*x-x+1/6
    g3 = x**3-3/2x**2+3/5x+1/20
    g4 = x**4-2x**3+7/9x**2-2/7x+1/70
    """
    #存储gk每一项的系数
    list_b = [1,-1/2,1/6,1/20,1/70]
    list_1 = [0,1,-1,3/5,-2/7]
    list_2 = [0,0,1,-3/2,9/7]
    list_3 = [0,0,0,1,-2]
    list_4 = [0,0,0,0,1]
    c = []
    for i in range (0,n+1):#分别计算c0~c4
        #构造gi函数
        k1 = list_1[i]
        k2 = list_2[i]
        k3 = list_3[i]
        k4 = list_4[i]
        b = list_b[i]
        #计算(gi,f),(gi, gi)
        sum_up = 0
        sum_down = 0
        for j in range (0,len(list_y)):
            x = list_x[i]
            g = k1 * x + k2 * (x ** 2) + k3 * (x ** 3) + k4 * (x ** 4) + b
            sum_up += g*list_y[j]
            sum_down += g*g
        print(sum_up)
        print(sum_down)
        c.append(sum_up/sum_down)
    print(c)
    return c

def Calculate_error(c,list_x,list_y): #计算误差的2—范数
    error = 0
    for i in range(0,len(list_x)):
        x = list_x[i]
        p = c[0]+c[1]*x+c[2]*(x**2)+c[3]*(x**3)+c[4]*(x**4) #拟合函数的计算结果
        error_each = (p-list_y[i])**2 #每一个x的误差的平方
        error += error_each
    error = error**0.5 #误差总和开方
    print(error)

if __name__ == '__main__':
    list_x = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
    list_y = [5.1234,5.3057,5.5687,5.9375,6.4370,7.0978,7.9493,9.0253,10.3627]
    m = len(list_x) #正规方程组的行数
    n = 4 #题目要求计算拟合四次多项式,正规方程组的列数是n+1=5
    #c = Linear_independence_functions(m, n, list_x, list_y)
    #Calculate_error(c, list_x, list_y)
    c = Orthogonality_functions(m, n, list_x, list_y)
    Calculate_error(c, list_x, list_y)

anyway ,不知道是代码问题还是基函数的选取问题,除了第一种方法以外,其余两种正交函数当基函数的误差都很大。
我看x的取值是0.1~0.9,勒让德的正交区间是[-1,1],应该是。。没问题的吧???
但是这两种方法算出的c0是正确的,c1~c4人工检验计算太麻烦了就没算。。
Attention:如果想使用其他的基函数,只需要改变g函数的参数列表list_b,list_1~4就行。

结果运算如下:
首先是使用线性无关基函数,误差很小
第一行是求出来的c0~c4

C:\Anaconda\envs\pythonProject\python.exe C:/Users/871674389/PycharmProjects/pythonProject/Ordinary_least_squares.py
[5.00097222 0.99268907 2.01064782 3.00333463 0.99096737]
0.000574429212322953

Process finished with exit code 0

勒让德:

C:\Anaconda\envs\pythonProject\python.exe C:/Users/871674389/PycharmProjects/pythonProject/Ordinary_least_squares.py
[6.9786, 34.89299999999999, -15.860454545454544, -15.860454545454546, -24.142183783783782]
25.705626617459462

Process finished with exit code 0

构造的正交函数:

C:\Anaconda\envs\pythonProject\python.exe C:/Users/871674389/PycharmProjects/pythonProject/Ordinary_least_squares.py
[6.9786, -23.262, -161.04461538461538, 61.21578947368423, 1302.6719999999923]
905.0385923940642

Process finished with exit code 0

误差突增,就。。离谱

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炖鹅小铁锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值