曲线拟合

1. 最小二乘直线拟合(曲线拟合)

【问题描述】根据N个数据点构造最小二乘拟合直线y=ax+b。

【输入形式】在屏幕上依次输入数据点的个数N,和N对数据点的x和y坐标。

【输出形式】输出最小二乘拟合直线y=ax+b和误差(N对数据点的y坐标,与由拟合直线得到的对应N个x坐标的y值,之间的欧式距离)。

【样例1输入】

8
-1 10
0 9
1 7
2 5
3 4
4 3
5 0
6 -1

【样例1输出】

y=-1.6071429x+8.6428571

1.1801937

【样例1说明】输入:有8对数据点,后续每行是一对数据点的x和y坐标。输出:最小二乘拟合直线为y=-1.6071429x+8.6428571,误差(norm2范数,即欧式距离)为1.1801937(保留小数点后7位有效数字)

【评分标准】根据输入得到的输出准确

import numpy as np
# 最小二乘拟合直线
def f(n, x, y):
    # 求x,y的平均值
    xm = np.mean(x)
    ym = np.mean(y)
    # 求C
    sumx = (x - xm) @ (x - xm)
    # 求A
    sumxy = (y - ym) @ (x - xm)
    a = sumxy / sumx
    # 求B
    b = ym - a * xm
    print("y=%.7fx+%.7f" % (a, b))
    # 求误差
    f_y = np.poly1d([a, b])
    f_x = np.polyval(f_y, x)
    norm2 = np.linalg.norm(f_x - y)
    print('%.7f' %norm2)
    """
    sum = 0
    z = x * a + b - y
    for i in range(n):
        sum += z[i] ** 2
    ans = np.sqrt(sum)
    print('%.7f' % ans)
    """
def main():
    n = int(input())
    x = np.zeros(n, dtype=np.int)
    y = np.zeros(n, dtype=np.int)
    for i in range(n):
        xx,yy = input().split()
        x[i] = xx
        y[i] = yy
    f(n, x, y)
if __name__ == '__main__':
    main()
2. 最小二乘多项式拟合(曲线拟合)

【问题描述】根据N个数据点构造最小二乘多项式拟合。

【输入形式】在屏幕上依次输入多项式的次数m,数据点的个数N,和N对数据点的x和y坐标。

【输出形式】输出最小二乘多项式和误差。

【样例1输入】

2
4
-3 3
0 1
2 1
4 3

【样例1输出】

[ 0.17846248 -0.19249542 0.85051861]

0.2445252

【样例1说明】输入:多项式的次数m为2,有4对数据点,后续每行是一对数据点的x和y坐标。

输出:最小二乘多项式为y=0.17846248x**2-0.19249542x+0.85051861,误差(norm2范数,即欧式距离)为0.2445252(保留小数点后7位有效数字)

【评分标准】根据输入得到的输出准确

import numpy as np
def nihe(m, n, x, y):
    f = np.zeros((n, m+1), dtype=np.double)
    # b = np.zeros((1, m+1), dtype=np.double)
    # 一列一列的赋值
    for k in range(m+1):
        f[:, k] = x ** k
    # 矩阵的转置np.transpose(f)
    a = np.transpose(f) @ f
    b = np.transpose(f) @ y
    # a @ c = b
    c = np.linalg.inv(a) @ b
    # c为c1——c(m+1),为了对应多项式计算,需用np.flipud(c)翻转
    c = np.flipud(c)
    print(c)
    # 求误差
    f_x = np.polyval(c, x)
    norm2 = np.linalg.norm(f_x - y)
    print('%.7f' % norm2)
def main():
    # m为次数,有0——m,即m+1列
    m = int(input())
    # n为点数,有0——n-1,即n行
    n = int(input())
    x = np.zeros(n, dtype=np.double)
    y = np.zeros(n, dtype=np.double)
    for i in range(n):
        xx, yy = map(float, input().split())
        x[i] = xx
        y[i] = yy
    nihe(m, n, x, y)
if __name__ == '__main__':
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值