最小二乘法的正交多项拟合算法

最小二乘法的正交多项拟合算法

数学表达式

参考清华大学 李庆杨《数值分析》第五版 P69

构造正交多项式 p k ( x ) k = 0 n {p_k(x)}^n_{k=0} pk(x)k=0n
p 0 ( x ) = 1 p 1 ( x ) = ( x − A 1 ) p 0 ( x ) . . . p k + 1 ( x ) = ( x − A k + 1 ) p k ( x ) − B k p k − 1 ( x ) k = 1 , 2 , 3 , . . . , n − 1 p_0(x) = 1 \\ p_1(x) = (x-A_1)p_0(x) \\ ...\\ p_{k+1}(x) = (x-A_{k+1})p_k(x) - B_k p_{k-1}(x) \\ k =1,2,3,...,n-1 p0(x)=1p1(x)=(xA1)p0(x)...pk+1(x)=(xAk+1)pk(x)Bkpk1(x)k=1,2,3,...,n1
其中
A k + 1 = ( x p k , p k ) ( p k , p k ) = ∑ i = 0 m x i p k 2 ( x i ) ∑ i = 0 m p k 2 ( x i ) , k = 0 , 1 , 2 , . . . , n − 1 B k = ( p k , p k ) ( p k − 1 , p k − 1 ) = ∑ i = 0 m p k 2 ( x i ) ∑ i = 0 m p k − 1 2 ( x i ) , k = 1 , 2 , . . . , n − 1 A_{k+1} = \frac{(xp_k,p_k)}{(p_{k},p_{k})} = \frac{\sum_{i=0}^m x_ip^2_k(x_i)}{\sum_{i=0}^mp_k^2(x_i)},k=0,1,2,...,n-1 \\ B_k = \frac{(p_k,p_k)}{(p_{k-1},p_{k-1})}= \frac{\sum_{i=0}^m p^2_k(x_i)}{\sum_{i=0}^mp_{k-1}^2(x_i)},k=1,2,...,n-1 \\ Ak+1=(pk,pk)(xpk,pk)=i=0mpk2(xi)i=0mxipk2(xi),k=0,1,2,...,n1Bk=(pk1,pk1)(pk,pk)=i=0mpk12(xi)i=0mpk2(xi),k=1,2,...,n1
利用正交多项式构建 a ∗ a^* a
a k ∗ = ( f , p k ) ( p k , p k ) = ∑ i = 0 m f ( x i ) p k ( x i ) ∑ i = 0 m p k 2 ( x i ) a^*_k = \frac{(f,p_k)}{(p_k,p_k)}=\frac{\sum^m_{i=0}f(x_i)p_k(x_i)}{\sum^m_{i=0}p^2_k(x_i)} ak=(pk,pk)(f,pk)=i=0mpk2(xi)i=0mf(xi)pk(xi)
则待拟合曲线的正交多项式为
S ∗ = a 0 ∗ p 0 ( x ) + a 1 ∗ p 1 ( x ) + . . . + a n ∗ p n ( x ) S^* = a^*_0p_0(x) + a^*_1p_1(x) + ... + a^*_np_n(x) S=a0p0(x)+a1p1(x)+...+anpn(x)

计算示例

给定数据表,求二次最小二乘拟合多项式

x i x_i xi00.50.60.70.80.91.0
y i y_i yi1.01.751.962.192.442.713.0
  1. 求第一项 a 0 ∗ a^*_0 a0
    a 0 ∗ = ( f , p 0 ) ( p 0 , p 0 ) = ∑ i = 0 6 f ( x i ) p 0 ( x i ) ∑ i = 0 6 p 0 2 ( x i ) a^*_0 = \frac{(f,p_0)}{(p_0,p_0)}=\frac{\sum^6_{i=0}f(x_i)p_0(x_i)}{\sum^6_{i=0}p^2_0(x_i)} a0=(p0,p0)(f,p0)=i=06p02(xi)i=06f(xi)p0(xi)

p 0 ( x i ) = 1 ; p_0(x_i)=1; p0(xi)=1;

∑ 0 6 f ( x i ) = 15.05 ; \sum^6_0{f(x_i)}=15.05; 06f(xi)=15.05;

求得 a 0 ∗ = 15.05 / 7 = 2.15 a^*_0 = 15.05/7=2.15 a0=15.05/7=2.15

  1. 求第二项 a 1 ∗ a^*_1 a1
    a 1 ∗ = ( f , p 1 ) ( p 1 , p 1 ) = ∑ i = 0 6 f ( x i ) p 1 ( x i ) ∑ i = 0 6 p 1 2 ( x i ) a^*_1 = \frac{(f,p_1)}{(p_1,p_1)}=\frac{\sum^6_{i=0}f(x_i)p_1(x_i)}{\sum^6_{i=0}p^2_1(x_i)} a1=(p1,p1)(f,p1)=i=06p12(xi)i=06f(xi)p1(xi)

先确定 p 1 ( x i ) = x − A 1 p_1(x_i)=x-A_1 p1(xi)=xA1, 求 A 1 A_1 A1
A 1 = ( x p 0 , p 0 ) ( p 0 , p 0 ) = ∑ i = 0 6 x i ∑ i = 0 6 p 0 ∗ p 0 = 4.5 7 = 0.64 A_1 = \frac{(xp_0,p_0)}{(p_{0},p_{0})} =\frac{\sum^6_{i=0}x_i}{\sum^6_{i=0}p_0*p_0} = \frac{4.5}{7} = 0.64 A1=(p0,p0)(xp0,p0)=i=06p0p0i=06xi=74.5=0.64
p 1 ( x i ) = x − 0.64 p_1(x_i)= x- 0.64 p1(xi)=x0.64,求得
a 1 ∗ = 1.30 0.657 ≈ 1.98 a_1^*= \frac{1.30}{0.657} \approx 1.98 a1=0.6571.301.98

  1. 求第三项 a 2 ∗ a^*_2 a2
    a 2 ∗ = ( f , p 2 ) ( p 2 , p 2 ) = ∑ i = 0 6 f ( x i ) p 2 ( x i ) ∑ i = 0 6 p 2 2 ( x i ) a^*_2 = \frac{(f,p_2)}{(p_2,p_2)}=\frac{\sum^6_{i=0}f(x_i)p_2(x_i)}{\sum^6_{i=0}p^2_2(x_i)} a2=(p2,p2)(f,p2)=i=06p22(xi)i=06f(xi)p2(xi)
    p 2 ( x ) = ( x − A 2 ) p 1 ( x ) − B 1 p 0 ( x ) = ( x − A 2 ) ( x − A 1 ) − B 1 p_2(x) = (x-A_2)p_1(x)-B_1p_0(x) = (x-A_2)(x-A_1)-B_1 p2(x)=(xA2)p1(x)B1p0(x)=(xA2)(xA1)B1
    A 2 = ( x p 1 , p 1 ) ( p 1 , p 1 ) = ∑ i = 0 6 x i ∗ ( x i − 0.64 ) 2 ∑ i = 0 6 ( x i − 0.64 ) 2 = 0.2242 0.6572 = 0.34 A_2 = \frac{(xp_1,p_1)}{(p_{1},p_{1})} =\frac{\sum^6_{i=0}x_i*(x_i-0.64)^2}{\sum^6_{i=0}(x_i-0.64)^2} = \frac{0.2242}{0.6572} = 0.34 A2=(p1,p1)(xp1,p1)=i=06(xi0.64)2i=06xi(xi0.64)2=0.65720.2242=0.34

B 1 = ( p 1 , p 1 ) ( p 0 , p 0 ) = 0.6572 7 = 0.094 B_1 = \frac{(p_1,p_1)}{(p_0,p_0)}= \frac{0.6572}{7}=0.094 B1=(p0,p0)(p1,p1)=70.6572=0.094

p 2 ( x ) = x 2 − 0.98 x + 0.12 p_2(x) = x^2 - 0.98x +0.12 p2(x)=x20.98x+0.12

求得【此处需要高精度计算】
a 2 ∗ ≈ 0.0686 0.0686 ≈ 1 a^*_2 \approx \frac{0.0686}{0.0686} \approx 1 a20.06860.06861
最终
S ∗ = a 0 ∗ p 0 ( x ) + a 1 ∗ p 1 ( x ) + a 2 ∗ p 2 ( x ) = x 2 + x + 1 S^* = a^*_0p_0(x) + a^*_1p_1(x) +a^*_2p_2(x) =x^2+x+1 S=a0p0(x)+a1p1(x)+a2p2(x)=x2+x+1

正交多项式是目前为止多项式拟合最好的方法,不用解线性方程组,根据次数 n,只用递推公式方便地计算正交多项式;MATLAB 正交多项式最小二乘拟合函数 p = polyfit (x,y,n),输入参数 x = [ x 0 , x 1 , . . . x m ] ; y = [ y 0 , y 1 , . . . , y m ] x=[x_0,x_1,...x_m]; y=[y_0,y_1,...,y_m] x=[x0,x1,...xm];y=[y0,y1,...,ym],返回次数为 n 的多项式 p(x) 的系数,p 中的系数按降幂排列,p 的长度为 n + 1。

Python 代码

以拟合线性或二次曲线为例,由于1-2次曲线,最多只有 a 0 ∗ . . a 2 ∗ , p 0 . . p 2 a_0^*..a_2^*,p_0..p_2 a0..a2,p0..p2 需要计算,代码量比较小

def linearfit(xl: list, yl: list)->list:
    if len(xl) != len(yl) or len(xl) < 2:
        return []

    # 生成必要数据
    A = 0.0
    asl = [0, 0]

    # 定义p函数
    p = [lambda n:1, lambda n: n-A]
    # 定义x,y映射函数
    def f(i): return yl[xl.index(i)]

    # 计算第一项
    asl[0] = sum(map(f, xl))/sum(map(p[0], xl))

    # 计算第二项
    A = sum(map(lambda n: n, xl)) / sum(map(p[0], xl)) #确定p1函数的项
    asl[1] = sum(map(lambda n: f(n)*p[1](n), xl)) / sum(map(lambda n:p[1](n)**2, xl))

    # 计算返回系数
    cof = [asl[0]-A*asl[1],asl[1]]
    return cof


def QuadFit(xl: list, yl: list) -> list:
    if len(xl) != len(yl) or len(xl) < 3:
        return []

    # 定义x,y映射函数
    def f(i): return yl[xl.index(i)]

    # 生成必要数据
    A = [0.0, 0.0, 0.0]
    B = [0.0, 0.0, 0.0]
    asl = [0, 0, 0]
    # 定义p函数
    p = [lambda n:1, lambda n: n-A[1], lambda n:((n-A[2])*(n-A[1])-B[1])]

    # 计算第一项
    asl[0] = sum(map(f, xl))/sum(map(p[0], xl))

    # 计算第二项
    A[1] = sum(map(lambda n: n, xl)) / sum(map(p[0], xl))
    asl[1] = sum(map(lambda n: f(n)*p[1](n), xl)) / \
        sum(map(lambda n: p[1](n)**2, xl))

    # 计算第三项
    A[2] = sum(map(lambda n: n*p[1](n)**2, xl)) / \
        sum(map(lambda n: p[1](n)**2, xl))
    B[1] = sum(map(lambda n: p[1](n)**2, xl)) / \
        sum(map(lambda n: p[0](n)**2, xl))
    asl[2] = sum(map(lambda n: f(n)*p[2](n), xl)) / \
        sum(map(lambda n: p[2](n)**2, xl))

    def rst(n): return asl[0] + asl[1] * (n-A[1]) + \
        asl[2]*((n-A[2])*(n-A[1])-B[1])

    # 计算返回系数
    cof = [rst(0), asl[1]-asl[2]*(A[1]+A[2]), asl[2]]
    return cof

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Z@=

你的鼓励,换取更多的回报与惊喜

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

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

打赏作者

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

抵扣说明:

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

余额充值