[数値解析] Python実装ラグランジュ補間

今日は何の関係も、程度のコードでこれらの補間式を達成しようとされている、してみてくださいしてみてください。

ラグランジュ補間開始の最も単純でスタート!ラグランジュ補間式の基本は、詳細に入る、Baiduの上で多くのことを検索しません。

基本的な考え方は、第一の所望の入力と予測点の数、ベースの機能を取得し、最終的な演算結果に応じて適切なサンプル点X補間部を選択するために、与えられたサンプルポイントにファイルから読み出されます。コードで直接見て!(注:サンプルは非常に正確ではないことをここでのポイント、本当に困惑し、より良い説明を見つけることができませんでした...)

関数str2double

そのため、それがあるべき - 小さな問題は結局、私たちはサンプル点を与え、必ずしも常に整数であること、また、このような複数の+以上のように、いくつかのフォールトトレラント処理を行う必要がなく、フロートへのSTR型のpythonを変換する方法であります正しい番号を識別します。だから、関数str2doubleメソッドを実装します。

import re
def str2double(str_num):
    pattern = re.compile(r'^((\+*)|(\-*))?(\d+)(.(\d+))?$')
    m = pattern.match(str_num)
    if m is None:
        return m
    else:
        sign = 1 if str_num[0] == '+' or '0' <= str_num[0] <= '9' else -1
        num = re.sub(r'(\++)|(\-+)', "", m.group(0))
        matchObj = re.match(r'^\d+$', num)
        if matchObj is not None:
            num = sign * int(matchObj.group(0))
        else:
            matchObj = re.match(r'^(\d+).(\d+)$', num)
            if matchObj is not None:
                integer = int(matchObj.group(1))
                fraction = int(matchObj.group(2)) * pow(10, -1*(len(matchObj.group(2))))
                num = sign * (integer + fraction)
        return num

私は、達成するために正規表現を使用pattern = re.compile(r'^((\+*)|(\-*))?(\d+)(.(\d+))?$')する整数と私は上記の浮動小数点のすべてのタイプを一致させることができ、彼らは整数、直接リターンの整数部分がある場合は、試合後、試合はこれで、成功している(int)キャストすることができ、それが浮いている場合点は、次に使用する(\d+)整数部の上記処理と同様再びマッチングこの正規表現、それぞれ整数部と小数部を、小数部分を用いて乗算されるpow(10, -小数位数)添加があってもよい直接後、得られました。ここで+又は複数のサポートするために-の符号は確定申告で乗算することができる場合には、除去されたシンボルを用いre.sub法、私たちはデジタルサインを記録する必要が正または負です。

def binary_search(point_set, n, x):
    first = 0
    length = len(point_set)
    last = length
    while first < last:
        mid = (first + last) // 2
        if point_set[mid][0] < x:
            first = mid + 1
        elif point_set[mid][0] == x:
            return mid
        else:
            last = mid
    last =  last if last != length else last-1

    head = last - 1
    tail = last
    while n > 0:
        if head != -1:
            n -= 1
            head -= 1
        if tail != length:
            n -= 1
            tail += 1
    return [head+1, tail-1] if n == 0 else [head+1, tail-2]

ここで全てのサンプル点point_setの集合であり、nは補間入力の数であり、xは入力予測点です。パケットxの内側、即ち、可能な限り適切な補間間隔を返します。

それは知識を求めることを含むので、入力に応じた適切な補間間隔を取得するため。本明細書で使用する場合、二分探索、最初のサンプル点セットは、point_set最初のサンプル点を見つけるために、(昇順で)ソートされ、両方の拡張間隔の補間満たす要件の数まで、予測された点のニーズよりも大きいです。ここで私はいくつかの問題が発生する可能性がありますことに気づいn=-1によるtail複数回の支払い、およびwhile、外側のループは、裁判官を実施したn=-1際にtail-2、この実装は確かに良いではありません、バグがあるかもしれません。

最後に、残りのコンテンツをよりよく理解されて、直接、すべてのコードを置きます。

import re
import matplotlib.pyplot as plt
import numpy as np

def str2double(str_num):
    pattern = re.compile(r'^((\+*)|(\-*))?(\d+)(.(\d+))?$')
    m = pattern.match(str_num)
    if m is None:
        return m
    else:
        sign = 1 if str_num[0] == '+' or '0' <= str_num[0] <= '9' else -1
        num = re.sub(r'(\++)|(\-+)', "", m.group(0))
        matchObj = re.match(r'^\d+$', num)
        if matchObj is not None:
            num = sign * int(matchObj.group(0))
        else:
            matchObj = re.match(r'^(\d+).(\d+)$', num)
            if matchObj is not None:
                integer = int(matchObj.group(1))
                fraction = int(matchObj.group(2)) * pow(10, -1*(len(matchObj.group(2))))
                num = sign * (integer + fraction)
        return num

def preprocess():
    f = open("input.txt", "r")
    lines = f.readlines()
    lines = [line.strip('\n') for line in lines]
    point_set = list()
    for line in lines:
        point = list(filter(None, line.split(" ")))
        point = [str2double(pos) for pos in point]
        point_set.append(point)
    return point_set

def lagrangeFit(point_set, x):
    res = 0
    for i in range(len(point_set)):
        L = 1
        for j in range(len(point_set)):
            if i == j:
                continue
            else:
                L = L * (x - point_set[j][0]) / (point_set[i][0] - point_set[j][0])
        L = L * point_set[i][1]
        res += L
    return res

def showbasis(point_set):
    print("Lagrange Basis Function:\n")
    for i in range(len(point_set)):
        top = ""
        buttom = ""
        for j in range(len(point_set)):
            if i == j:
                continue
            else:
                top += "(x-{})".format(point_set[j][0])
                buttom += "({}-{})".format(point_set[i][0], point_set[j][0])
        print("Basis function{}:".format(i))
        print("\t\t{}".format(top))
        print("\t\t{}".format(buttom))

def binary_search(point_set, n, x):
    first = 0
    length = len(point_set)
    last = length
    while first < last:
        mid = (first + last) // 2
        if point_set[mid][0] < x:
            first = mid + 1
        elif point_set[mid][0] == x:
            return mid
        else:
            last = mid
    last =  last if last != length else last-1

    head = last - 1
    tail = last
    while n > 0:
        if head != -1:
            n -= 1
            head -= 1
        if tail != length:
            n -= 1
            tail += 1
    return [head+1, tail-1] if n == 0 else [head+1, tail-2]

if __name__ == '__main__':
    pred_x = input("Predict x:")
    pred_x = float(pred_x)
    n = input("Interpolation times:")
    n = int(n)
    point_set = preprocess()
    point_set = sorted(point_set, key=lambda a: a[0])
    span = binary_search(point_set, n+1, pred_x)
    print("Chosen points: {}".format(point_set[span[0]:span[1]+1]))
    showbasis(point_set[span[0]:span[1]+1])

    X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
    S = np.sin(X)
    L = [lagrangeFit(point_set, x) for x in X]
    L1 = [lagrangeFit(point_set[span[0]:span[1]+1], x) for x in X]
    
    plt.figure(figsize=(8, 4))
    plt.plot(X, S, label="$sin(x)$", color="red", linewidth=2)
    plt.plot(X, L, label="$LagrangeFit-all$", color="blue", linewidth=2)
    plt.plot(X, L1, label="$LagrangeFit-special$", color="green", linewidth=2)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title("$sin(x)$ and Lagrange Fit")
    plt.legend()
    plt.show()

入力について

行、真ん中の空間の各点について、読み出しに使用されるサンプル点INPUT.TXT。

結果

HHHかなり良い楽しさを感じ、ニュートンの補間は、数日してみてください!白白!

おすすめ

転載: www.cnblogs.com/LuoboLiam/p/11706151.html