分段二次插值——用Python進行數值計算


  事實上在實際使用中,高次插值顯然是很不適合的,高次插值將所有樣點包涵進一個插值函數中,這是次冪高的原因。高次計算復雜,而且剛開始的一點誤差會被方的很大。因此將整個區間分為若干個小區間,在每一個小區間進行插值這樣更好,實現容易,也方便在一些嵌入式設備上使用。有不少需要插值方法的場景是在嵌入式的應用中。

  我以等距節點的二次插值為例,以每三個節點為一個子區間。

  等距節點二次插值很好寫,由於每個區間只有三個插值節點,計算差商也不必使用拉格朗日插值中使用的遞歸,直接列表達式也很簡單(實際上等距節點二次插值就是只有三個節點的拉格朗日插值,只是此時在定義域內,有很多個拉格朗日插值函數,每個子區間對應一個)。遞歸的副作用相當的明顯,盡管寫成尾遞歸可以減小副作用,但是能避免遞歸還是避免吧。

 

  分段插值函數可以表示為:

  

  每一個插值函數表達式:

  

 

  如上,不需要用遞歸求差商,方便很多。一個函數即可搞定。

  

"""
@brief: 獲得分段二次插值函數
@param: x       插值節點的橫坐標集合
@param: fx      插值節點的縱坐標集合  
@return: 參數所指定的插值節點集合對應的插值函數
"""    
def get_sub_two_interpolation_func(x = [], fx = []):
      
    def sub_two_interpolation_func(Lx):
        result = 0
        for index in range(len(x)-2):
            if Lx >= x[index] and Lx <= x[index+2]:
                result = fx[index]*(Lx-x[index+1])*(Lx-x[index+2])/(x[index]-x[index+1])/(x[index]-x[index+2]) + \
                         fx[index+1]*(Lx-x[index])*(Lx-x[index+2])/(x[index+1]-x[index])/(x[index+1]-x[index+2]) + \
                         fx[index+2]*(Lx-x[index])*(Lx-x[index+1])/(x[index+2]-x[index])/(x[index+2]-x[index+1])
        return result
            
    return sub_two_interpolation_func
    

  

     
"""
demo:
"""
if __name__ == '__main__':   

    ''' 插值節點, 這里用二次函數生成插值節點,每兩個節點x軸距離位10 '''
    sr_x = [i for i in range(-50, 51, 10)]
    sr_fx = [i**2 for i in sr_x]
    
    Lx = get_sub_two_interpolation_func(sr_x, sr_fx)            # 獲得插值函數
    tmp_x = [i for i in range(-45, 45)]     # 測試用例
    tmp_y = [Lx(i) for i in tmp_x]          # 根據插值函數獲得測試用例的縱坐標
        
    ''' 畫圖 '''
    import matplotlib.pyplot as plt
    plt.figure("play")
    ax1 = plt.subplot(111)
    plt.sca(ax1)
    plt.plot(sr_x, sr_fx, linestyle = ' ', marker='o', color='b')
    plt.plot(tmp_x, tmp_y, linestyle = '--', color='r')
    plt.show()

    插值函數圖像:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM