Python计算&绘图——曲线拟合问题

        题目来自老师的课后作业,如下所示。很多地方应该可以直接调用函数,但是初学Python,对里面的函数还不是很了解,顺便带着学习的态度,尽量自己动手code。

         


测试版代码,里面带有很多注释和测试代码:

# -*- coding: cp936 -*-
import math
import random
import matplotlib.pyplot as plt
import numpy as np


'''
在x=[0,1]上均匀采样10个点组成一个数据集D=[a,b]
'''
a = []
b = []
x=0
def func(x):
    mu=0
    sigma=0.1
    epsilon = random.gauss(mu,sigma) #高斯分布随机数
    return np.sin(2*np.pi*x)+epsilon
for i in range(0,10):
    x=x+1.0/11.0
    a.append(x)
    b.append(func(x))




#定义输出矩阵函数
def print_matrix( info, m ): 
    i = 0; j = 0; l = len(m)
    print info
    for i in range( 0, len( m ) ):
        for j in range( 0, len( m[i] ) ):
            if( j == l ):
                print ' |',
            print '%6.4f' % m[i][j],
        print
    print


#定义交换变量函数
def swap( a, b ):
    t = a; a = b; b = t
    
#定义线性方程函数,高斯消元法    
def solve( ma, b, n ):
    global m; m = ma # 这里主要是方便最后矩阵的显示
    global s;    
    i = 0; j = 0; row_pos = 0; col_pos = 0; ik = 0; jk = 0
    mik = 0.0; temp = 0.0  
    n = len( m )
# row_pos 变量标记行循环, col_pos 变量标记列循环
    while( ( row_pos < n ) and( col_pos < n ) ):
        # 选主元
        mik = - 1
        for i in range( row_pos, n ):
            if( abs( m[i][col_pos] ) > mik ):
                mik = abs( m[i][col_pos] )
                ik = i
        if( mik == 0.0 ):
            col_pos = col_pos + 1
            continue
        # 交换两行
        if( ik != row_pos ):
            for j in range( col_pos, n ):
                swap( m[row_pos][j], m[ik][j] )
                swap( m[row_pos][n], m[ik][n] );  
        try:
            # 消元
            m[row_pos][n] /= m[row_pos][col_pos]
        except ZeroDivisionError:
            # 除零异常 一般在无解或无穷多解的情况下出现……
            return 0;     
        j = n - 1
        while( j >= col_pos ):
            m[row_pos][j] /= m[row_pos][col_pos]
            j = j - 1
        for i in range( 0, n ):
            if( i == row_pos ):
                continue
            m[i][n] -= m[row_pos][n] * m[i][col_pos]
            j = n - 1
            while( j >= col_pos ):
                m[i][j] -= m[row_pos][j] * m[i][col_pos]
                j = j - 1
        row_pos = row_pos + 1; col_pos = col_pos + 1
    for i in range( row_pos, n ):
        if( abs( m[i][n] ) == 0.0 ):
            return 0
    return 1




matrix_A=[]         #将系数矩阵A的所有元素存到a[n-1][n-1]中
matrix_b=[]
X=a
Y=b
N=len(X)
M=3    #对于题目中要求的不同M[0,1,3,9]值,需要在这里更改,然后重新编译运行


#计算线性方程组矩阵A的第[i][j]个元素A[i][j]    
def matrix_element_A(x,i,j,n): 
    sum_a=0
    for k in range(0,n):   
        sum_a = sum_a+pow(x[k],i+j-2)   #x[0]到x[n-1],共n个元素求和
    return sum_a


for i in range(0,M+1):  
    matrix_A.append([])  
    for j in range(0,M+1):  
        matrix_A[i].append(0)
        matrix_A[i][j] = matrix_element_A(X,i+1,j+1,N)
#计算线性方程组矩阵b的第[i]行元素b[i]
def matrix_element_b(x,y,i,n): 
    sum_b=0
    for k in range(0,n):
        sum_b=sum_b+y[k]*pow(x[k],i-1)  #x[0]到x[n-1],共n个元素求和
    return sum_b
for i in range(0,M+1):
    matrix_b.append(matrix_element_b(X,Y,i+1,N))


#函数matrix_element_A_()用来求扩展矩阵A_,array_A表示系数矩阵A,array_b表示方程组右侧常数,A_row表示A的行秩
def matrix_element_A_(array_A,array_b,A_row):
    M=A_row  #局部变量M,与全局变量M无关
    matrix_A_= []
    for i in range(0,M+1):
        matrix_A_.append([])
        for j in range(0,M+2):
            matrix_A_[i].append(0)
            if j<M+1:
                matrix_A_[i][j] = array_A[i][j]
            elif j==M+1:     #如果不加这个控制条件,matrix_A_将被array_b刷新
                matrix_A_[i][j] = array_b[i]
    return matrix_A_
matrix_A_ = matrix_element_A_(matrix_A,matrix_b,M)


'''
多项式拟合函数
'''
#x为自变量,w为多项式系数,m为多项式的阶数
def poly_fit(x,wp,m):
    sumf = 0
    for j in range(0,m+1):
        sumf=sumf+wp[j]*pow(x,j)
    return sumf


'''
sin(2*pi*x)在x=0处的3阶泰勒展开式
'''
coef_taylor = [] #正弦函数的泰勒展开式系数
K=3  #展开到K阶
if K%2==0:
    print "K必须为正奇数"
s = 0
k=(K-1)/2+1  #小k为系数个数
#求K阶泰勒展开式的系数:
for i in range(0,k):
    s = pow(-1,i)*pow(2*np.pi,2*i+1)/math.factorial(2*i+1)
    coef_taylor.append(s)
print "%d阶泰勒级数展开式的系数为:" %K
print coef_taylor
#tx为泰勒展开式函数的自变量    
def sin_taylor(tx):
    sum_tay=0
    for i in range(0,k):
        sum_tay=sum_tay+coef_taylor[i]*pow(tx,2*k+1)
    return sum_tay
poly_taylor_a = []   #泰勒展开式函数的输入值
poly_taylor_b = []   #泰勒展开式函数的预测值
for i in range(0,N):
    poly_taylor_a.append(a[i])
    poly_taylor_b.append(sin_taylor(poly_taylor_a[i]))




'''
在x=[0,1]上生成100个点,作为测试集
'''
testa = []  #测试集的横坐标
testb = []  #测试集的纵坐标
x=0
for i in range(0,100):
    x=x+1.0/101.0
    testa.append(x)
    testb.append(np.sin(2*np.pi*x))
    
'''
计算泰勒展开式模型的训练误差和测试误差
'''
#定义误差函数:
#ly为真实值,fx为预测值
def Lfun(ly,fx):
    L=0
    for i in range(0,len(fx)):
        L=L+pow(ly[i]-fx[i],2)
    return L


'''
主程序
'''
if __name__ == '__main__':
# 求解方程组, 并输出方程组的可解信息
    ret = solve( matrix_A_, 0, 0 ) 
    if( ret== 0 ):
        print "方 程组无唯一解或无解\n"
   
    # 输出方程组及其解,解即为w[j]
    w = []
    for i in range( 0, len( m ) ):
        w.append(m[i][len( m )])
    print "M=%d时的系数w[j]:" %M
    print w
    
    #多项式拟合后的预测值:
    poly_a = []
    poly_b = []
    for i in range(0,N):
        poly_a.append(a[i])
        poly_b.append(poly_fit(poly_a[i],w,M))


    #fxtay为泰勒展开式的预测值,LCtaylor为测试误差:
    fxtay = []
    for i in range(0,100):
         fxtay.append(sin_taylor(testa[i]))
    LCtaylor = Lfun(testb,fxtay)/100
    print "三阶泰勒展开式的测试误差为:%f" %LCtaylor


    #fxpoly为M阶多项式拟合函数的预测值,LXpoly为训练误差:
    fxpoly = []
    for i in range(0,N):   #len(poly_b)=N=10
        fxpoly.append(poly_fit(a[i],w,M))
    LXpoly = Lfun(b,fxpoly)/len(poly_b)
    print "M=%d时多项式拟合函数的训练误差为:%f" % (M,LXpoly)


    #fxpolyc为M阶多项式拟合函数的预测值,LCpoly为测试误差:
    fxpolyc = []
    for i in range(0,100):
        fxpolyc.append(poly_fit(testa[i],w,M))
    LCpoly = Lfun(testb,fxpolyc)/100 
    print "M=%d时多项式拟合函数的测试误差为:%f" % (M,LCpoly)
    
    #多项式拟合的效果:
    fig1 = plt.figure(1)
    plt.plot(poly_a,poly_b,color='blue',linestyle='solid',marker='o') 
    #加入epsilon后的样本:
    plt.plot(a,b,color='red',linestyle='dashed',marker='x') 
    #泰勒展开式拟合效果:
    plt.plot(poly_taylor_a,poly_taylor_b,color='yellow',linestyle='dashed',marker='o')
    #figure(2)对比多项式拟合函数与训练数据:
    fig2 = plt.figure(2)
    plt.plot(poly_a,poly_b,color='blue',linestyle='solid',marker='o')
    plt.plot(a,b,color='red',linestyle='dashed',marker='x')
    plt.show()

M=3时的运行结果:

3阶泰勒级数展开式的系数为:
[6.283185307179586, -41.341702240399755]
M=3时的系数w[j]:
[-0.28492708632293295, 13.031310645420685, -37.730992850050448, 25.464782221275197]
三阶泰勒展开式的测试误差为:100.889335
M=3时多项式拟合函数的训练误差为:0.008933
M=3时多项式拟合函数的测试误差为:0.007886


Figure(1):


Figure(2):



         初次编写这么长的代码,思路不是有一点的混乱难过。其中有快哭了也有得意。以后会继续来优化这个程序,作为学习Python的入口。奋斗




        

### 回答1: Python 是一种强大的计算机编程语言,其中一个重要的应用就是数组计算和曲线绘制。常用的库有 Numpy 和 Matplotlib。Numpy 提供了高效的数组操作,可以帮助我们进行矩阵运算、统计分析等。Matplotlib 则提供了丰富的绘图工具,可以绘制各种图形,如线图、散点图、直方图等。这些工具可以帮助我们对数据进行可视化和分析。 ### 回答2: Python是一种非常优秀的编程语言,尤其是在科学计算和数据处理方面,Python可以帮助我们快速完成许多复杂的计算和分析任务。而在Python编程中,数组计算和曲线绘制也是非常重要的部分,可以帮助程序员更好地进行数据处理和数据可视化。 在Python中,数组计算是一种高效的数据处理方式。Python中的数组可以使用NumPy库来进行操作,NumPy库可以让我们更方便地进行向量和矩阵运算,也可以对整个数组进行快速的计算和处理。基于NumPy库,我们可以快速地进行数组计算,用简短的代码实现各种复杂的数学运算和数据处理任务。 例如,在Python中我们可以使用NumPy库来进行数组的加、减、乘、除等基本运算,也可以进行数组的切片、拼接、排序等操作。比如,对于两个数组a和b,我们可以使用以下代码来进行数组的加法运算: ```python import numpy as np a = np.array([1, 2, 3, 4]) b = np.array([5, 6, 7, 8]) c = a + b print(c) # [ 6 8 10 12] ``` 通过这种方式,我们可以快速地进行数组计算,完成复杂的数据处理和分析工作。 除了数组计算Python中的曲线绘制也是非常重要的技能。Python可以使用Matplotlib库来进行数据可视化,Matplotlib库可以帮助我们快速地绘制各种类型的图表,包括线性图、散点图、饼图、柱状图等等。 例如,我们可以使用Matplotlib库来绘制一条简单的折线图,代码如下: ```python import matplotlib.pyplot as plt x = np.arange(0, 10, 0.1) y = np.sin(x) plt.plot(x, y) plt.show() ``` 通过这种方式,我们就可以快速地绘制出一条正弦波曲线,这对于数据分析以及数据可视化非常有用。 综上所述,Python的数组计算和曲线绘制是非常重要的计算思维训练,这不仅可以帮助我们快速地完成数据处理和数据分析任务,还可以帮助我们更好地展示和交流计算结果。希望大家在学习Python的过程中,注重这些计算思维的训练,不断提高自己的编程技能和数据处理能力。 ### 回答3: 计算思维是指在计算问题解决中的思维方式和方法。Python是一个强大的计算机编程语言,其运用广泛,包括数据科学、Web开发、网络安全、人工智能等多个领域。Python计算思维训练主要围绕数组计算和曲线绘制展开,这些技能在数据分析和可视化中尤为重要。 数组是Python中最基本的数据类型之一,其优点是数据的存储和处理都十分方便。Python中有丰富的数组库,如NumPy、SciPy和pandas等,可以帮助开发者高效地处理大量数据。在数组计算的训练中,开发者需要学会如何使用数组进行各种常见的计算操作,如数组的加减乘除、索引和切片、排序和聚合等,以便在实际工作中可以快速准确地进行数据处理。 曲线绘制是Python中常用的数据可视化技术之一。Matplotlib和Seaborn等库可以帮助开发者绘制各种类型的图表,如折线图、散点图、柱状图、饼图等,这些图表能够直观地展示数据分布、趋势和关系。在曲线绘制的训练中,开发者需要学会如何使用不同的绘图库及其参数,选择合适的图表类型和设置图表风格,使其画出的图表更加美观、直观和有用。 总之,Python计算思维训练目标在于帮助开发者打造高效处理数据和优秀展示数据的能力。掌握数组计算和曲线绘制的技能不仅可以提高计算机编程的水平,更重要的是可以在数据科学领域中获取更多机会和晋升空间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值