数値計算のための二分法の使用方法

数値計算の二分法の使用方法

根の求め方の二分法とその動作の理解

Andrewによる写真、Unsplashから

以下で連絡を取ることができます:| LINKEDIN | TWITTER | VoAGI | SUBSTACK |

コンピュータサイエンスと数学の一部である数値計算は、数学の問題を解析的に解くことが困難または不可能な数学パズルの答えの近似値を求めるために、コンピュータを利用した数値的な手法とアルゴリズムを使用することに焦点を当てています。シミュレーションと計算を実行して、数学的な問題の近似解を得ることを目指しています。

数学には多くの方程式があります。これらの方程式を現実の問題に適用するためには、それらの方程式を解く必要があります。方程式の根を見つけることができれば、方程式はゼロになります。簡単な例を見てみましょう。

f(x) = x * x — 1

x * x — 1 = 0

f(1) = (1) * (1) –1 = 0

f(-1) = (-1) * (-1) –1=0

したがって、上記の方程式の根は1-1です。

これはどのように理解されたのでしょうか?

方程式にxの値を代入してみることで、これらの方程式を解くことができます。しかし、現実の問題では、方程式を解くのはそれほど簡単ではありません。

現実の問題を解くためには、「根の求め方の方法」と呼ばれる多くの方法があります。これらの方法は、数値計算、最適化、補間、曲線フィッティング、数値解析など、さまざまなフィールドで非常に有用です。

進化について話し始めると、ブログ全体が必要になりますが、テクニックの実装から直接始めましょう。

二分法

二分法は、数値の根を求めるための数学的な簡単なアプローチです。 二分法は超越的な問題を解決するための最も単純な数値計算法です。この記事では、二分法のアプローチと解決された問題について詳しく説明します。

多項式の問題の根を求めるためには、二分法を使用します。この方法では、方程式の根が存在する区間を分割し分離します。連続関数の中間値の定理がこの方法の基本原理となります。正と負の区間の距離を縮めていき、正しい解に近づけます。変数の間の距離を平均化することで、この技術は変数間の距離を縮めます。

簡単なプロセスですが、進行が遅いです。二分法は時々二分法法、バイナリサーチ法、区間半分法、根の求め方法とも呼ばれます。

出典:Wikipedia

二分法アルゴリズム

任意の連続関数f(x)に対して [出典]

a < b かつ f(a)* f(b) < 0 となる二つの点aとbを見つける

aとbの中間点である”c”を見つける

f(c) = 0ならばcは与えられた関数の根であり、そうでなければ次のステップに進む

区間[a, b]を分割する — もしf(c)*f(a) <0ならば、cとaの間に根が存在する – そうでなければf(c) *f (b) < 0ならば、cとbの間に根が存在する

f(c) = 0となるまで上記の三つのステップを繰り返す。

二分法は、与えられた方程式の根を求めるための近似手法であり、区間を繰り返し分割することによって結果の区間を見つけるまで区間を分割します。この手法は、極めて小さな区間が見つかるまで区間を分割します。

コード:

免責事項/警告:このコードは、Pythonで基本的な二分法コードを作成する方法を示すためのものです。コードの最適化を主張するものではなく、具体的な問題文に応じてさらなる改善が必要です。

単純な関数を取りましょう。

F(x) = x * x – 3

def fun(x):    return x * x - 3

二分法コードのための非常に基本的なパイプラインを作成するための非常に基本的なコードを書いてみましょう。

a = 1    #近似的な最初のルートb = 2    #近似的な2番目のルート #関数の定義def fun(x):    return x*x - 3a_original = fun(a)b_original = fun(b)i = 0while i < 50 :        #これを50回繰り返す     c = (a + b)/2    c_original = fun(c)    if c_original < 0:        a = c    else:        b = c#     plt.plot(a)    print("aは{}".format(a))    print("bは{}".format(b))    i+=1

上記は非常に基本的ですが、力技レベルで二分法を表している基本的なコードです。

出力を見てみましょう

aは1.5bは2aは1.5bは1.75aは1.625bは1.75aは1.6875bは1.75aは1.71875bは1.75aは1.71875bは1.734375aは1.7265625bは1.734375aは1.73046875bは1.734375aは1.73046875bは1.732421875aは1.7314453125bは1.732421875aは1.73193359375bは1.732421875aは1.73193359375bは1.732177734375aは1.73193359375bは1.7320556640625aは1.73199462890625bは1.7320556640625aは1.732025146484375bは1.7320556640625aは1.7320404052734375bは1.7320556640625aは1.7320480346679688bは1.7320556640625aは1.7320480346679688bは1.7320518493652344aは1.7320499420166016bは1.7320518493652344aは1.7320499420166016bは1.732050895690918aは1.7320504188537598bは1.732050895690918aは1.7320506572723389bは1.732050895690918aは1.7320507764816284bは1.732050895690918aは1.7320507764816284bは1.7320508360862732aは1.7320508062839508bは1.7320508360862732aは1.7320508062839508bは1.732050821185112aは1.7320508062839508bは1.7320508137345314aは1.7320508062839508bは1.732050810009241aは1.7320508062839508bは1.732050808146596aは1.7320508072152734bは1.732050808146596aは1.7320508072152734bは1.7320508076809347aは1.732050807448104bは1.7320508076809347aは1.7320508075645193bは1.7320508076809347aは1.7320508075645193bは1.732050807622727aは1.7320508075645193bは1.7320508075936232aは1.7320508075645193bは1.7320508075790713aは1.7320508075645193bは1.7320508075717953aは1.7320508075681573bは1.7320508075717953aは1.7320508075681573bは1.7320508075699763aは1.7320508075681573bは1.7320508075690668aは1.732050807568612bは1.7320508075690668aは1.7320508075688394bは1.7320508075690668aは1.7320508075688394bは1.7320508075689531aは1.7320508075688394bは1.7320508075688963aは1.7320508075688679bは1.7320508075688963aは1.7320508075688679bは1.732050807568882aは1.732050807568875bは1.732050807568882aは1.732050807568875bは1.7320508075688785aは1.7320508075688767bは1.7320508075688785aは1.7320508075688767bは1.7320508075688776

上記の出力は、aとbを50回の反復で操作した結果です。システムは、制限により16桁以上の数値の処理に問題が発生する可能性があります。しかし、ルートの値が次第に近づいていることがわかります。

最後のa1.73205080です

最後のb1.73205080です

これらの最新の値を方程式に代入すると、

F(a) = -0.000176000…..

F(b) = 0.000176000…..

非常に0に近いです!

これでこのロジックが動作することがわかりました。コードを最適化し、出力を視覚化して理解しやすくします。

import matplotlib.pyplot as pltdef Bisection_method(a, b, iterations):    def fun(x):        return x * x - 3    # グラフのための図と軸を作成    plt.figure()    plt.xlabel('x')    plt.ylabel('y')    plt.title('方程式 y = x^2 - 3 の可視化')    # 範囲[a, b]で方程式 y = x^2 - 3 をプロット    x_values = [x / 100.0 for x in range(int(a * 100), int(b * 100) + 1)]    y_values = [fun(x) for x in x_values]    plt.plot(x_values, y_values, color='orange', label='y = x^2 - 3')    # グラフ上に初期点aとbをプロット    plt.plot(a, fun(a), 'ro', label='f(a)')    plt.plot(b, fun(b), 'go', label='f(b)')    # x軸をプロット    plt.axhline(linewidth=2, y=0, color='brown', linestyle='dashdot')    plt.axhline(y=fun(a), color='blue', linestyle='dashdot')    plt.axhline(y=fun(b), color='blue', linestyle='dashdot')    plt.legend()    plt.grid()    # グラフを更新して表示    plt.pause(1)    a_vals = [a]    b_vals = [b]    i = 0    while i < iterations:        c = (a + b) / 2        c_original = fun(c)        if c_original < 0:            a = c        else:            b = c        i += 1        a_vals.append(a)        b_vals.append(b)    # aとbのすべての値を異なる色でプロット    plt.plot([fun(a_val) for a_val in a_vals], 'mo', label='f(a)',color='orange')    plt.axhline(y=0, color='brown', linestyle='dashdot')    plt.plot([fun(b_val) for b_val in b_vals], 'co', label='f(b)')    plt.axhline(y=0, color='brown', linestyle='dashdot')    plt.legend()    plt.grid()    # グラフを更新して表示    plt.pause(1)    plt.show()

# 初期値a、b、反復回数を指定して関数を呼び出すa_initial = 1b_initial = 2iterations = 50Bisection_method(a_initial, b_initial, iterations)

このコードを変更し、入力を受け取り、ルートのグラフを表示するようにしました。

コードの出力

上の図では、始点とそのF(x)の値を見ることができます。赤いハイライトされた線は、初期ルートを達成したいものです。

上の図では、50点のうち最後の10点の出力をプロットしました。値が0に収束し、最後の数点はほぼ0です。これは、ルートを取得したことを示すサインです。反復は、全体の実行を制御するために設定できる制限です。パラメータは、関数の閾値値です。したがって、一定の反復回数を完了した後に停止するか、一定の閾値値を達成した場合に停止する必要があります。

このコードを使用して、関数を変更して自分の方程式の根を見つけることもできます。または、以下のリンクを直接使用することもできます。これにより、二分法オンライン計算機に移動します。

二分法オンライン計算機

二分法オンライン計算機は、非線形方程式の実根を見つけるためのシンプルで信頼性のあるツールです…

www.codesansar.com

二分法の利点:

収束性: 根を含む区間が与えられれば、アプローチが解を見つけることを保証します。

簡単さ: この方法は理論的に簡単で使いやすいです。

堅牢性: 他の特定の根探索技術と比較して、二分法は元の予測に対して感度が低いです。

区間の改良: 各改良により、解はより正確になります。

導関数の不要性: これにより、導関数が利用できないか、計算が困難な関数に適しています。

グローバル収束: この方法は最終的に区間内に根が存在する場合、根を見つけます。

二分法の制限事項:

収束の遅さ: 他の収束速度の速い根探索アルゴリズムと比較して、特に急峻な勾配の関数に対して、この方法は遅くなることがあります。

区間の要件: 区間が不明または特定するのが難しい場合、この手順は適切ではないかもしれません。

1つの根しか見つからない: 二分法は、提供された範囲[a, b]内の1つの根のみを見つけるように設計されています。もし範囲内に複数の根がある場合、手順は関数の1つの根に到達します。

複雑な方程式への限定的な適用性: 二分法は、指定された範囲内に単一の実根を持つ方程式に最も適しています。

これらの制限を克服するために、根の見つけ方のメカニズムが異なる高度なレベルの多くの他の方法があります。次のシリーズのブログでそれらをカバーします。

もしこの記事が有益だと思われた場合

「寛大さはあなたを幸せにする」ということ実証されています。したがって、この記事が気に入った場合は、拍手を送ってください。この記事が有益だと思った場合は、LinkedinVoAGIでフォローしてください。また、記事の公開時に通知を受け取るために購読することもできます。コミュニティを作りましょう!ご支援いただきありがとうございます!

ここをクリックしてコーヒーをご馳走してください

LangChainの理解🦜️🔗:パート1

LangChainのチェーン、プロンプト、およびその他の重要なモジュールの理論的理解

pub.towardsai.net

コンピュータビジョンアプリケーションのためのCNNアーキテクチャの選択に関する実践的なガイド

LeNetからEfficientNetまで:プロジェクトに最適なCNNアーキテクチャの選択

levelup.gitconnected.com

包括的なガイド:コンピュータビジョンに関するトップリソースがすべて1つのブログに

コンピュータビジョンに関する包括的なリソースのために、このブログを保存してください

VoAGI.com

データサイエンス、ML、およびCVプロジェクトを強化するための効果的なプロジェクト管理のための必須ツール

これらのツールを使用して、ビルドとプロジェクトをより速くする

pub.towardsai.net

署名をしています、

チンメイ

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI研究

黄さんの法則に留意する:エンジニアたちがどのように速度向上を進めているかを示すビデオ

話の中で、NVIDIAのチーフサイエンティストであるビル・ダリー氏が、モーアの法則時代後のコンピュータパフォーマンスの提供...