4

Python で 2 つの関数 (任意) がある興味深い問題があり、それらの間の共通接線と、共通接線が各関数に接する x 軸上の点を見つけたいと思います。理想的には、すべての座標を与える関数が存在します(複数の解を持つ非常に複雑な関数のセットを想像してください)。

それで、私はうまくいくものを持っていますが、それは非常に粗雑です。私が行ったことは、各関数を行列に入れM[h,0]、x 値、M[h,1]function1 y 値、M[h,2]function2 y 値を含むことです。次に、導関数を見つけて、これを新しい行列D[h,1]に配置しD[h,2]ます (スパンは よりも 1 小さいですM[h,:]。私の考えは、基本的に x 軸に勾配を、y 軸に切片を「プロット」し、これらすべての点を検索することでした。最も近いペアの場合、値を指定します。

ここで 2 つの問題:

  1. プログラムは、最も近いペアが解であるかどうかを知りません。

  2. 痛々しいほど遅いです (numb_of_points^2 検索)。いくつかの最適化ライブラリが役立つ可能性があることは理解していますが、それらが 1 つのソリューションに焦点を合わせて残りを無視するのではないかと心配しています。

これを行うための最良の方法を考えている人はいますか?私の「コード」はここにあります:

def common_tangent(T):
    x_points = 600
    x_start = 0.0001 
    x_end = 0.9999
    M = zeros(((x_points+1),5) )
    for h in range(M.shape[0]):
        M[h,0] = x_start + ((x_end-x_start)/x_points)*(h) # populate matrix
        """ Some function 1 """
        M[h,1] = T*M[h,0]**2 + 56 + log(M[h,0])
        """ Some function 2 """
        M[h,2] = 5*T*M[h,0]**3 + T*M[h,0]**2 - log(M[h,0])
    der1 = ediff1d(M[:,1])*x_points # derivative of the first function
    der2 = ediff1d(M[:,2])*x_points # derivative of the second function
    D = zeros(((x_points),9) )
    for h in range(D.shape[0]):
        D[h,0] = (M[h,0]+M[h+1,0])/2 # for the der matric, find the point between
        D[h,1] = der1[h] # slope m_1 at this point
        D[h,2] = der2[h] # slope m_2 at this point
        D[h,3] = (M[h,1]+M[h+1,1])/2# average y_1 here
        D[h,4] = (M[h,2]+M[h+1,2])/2# average y_2 here
        D[h,5] = D[h,3] - D[h,1]*D[h,0] # y-intercept 1
        D[h,6] = D[h,4] - D[h,2]*D[h,0] # y-intercept 2
    monitor_distance = 5000 # some starting number
    for h in range(D.shape[0]):
        for w in range(D.shape[0]):
            distance = sqrt( #in "slope intercept space" find distance
                (D[w,6] - D[h,5])**2 +
                (D[w,2] - D[h,1])**2
                )
            if distance < monitor_distance: # do until the closest is found
                monitor_distance = distance
                fraction1 = D[h,0]
                fraction2 = D[w,0]
                slope_02 = D[w,2]
                slope_01 = D[h,1]
                intercept_01 = D[h,5]
                intercept_02 = D[w,6]
    return (fraction1, fraction2)

これは、相図を計算するための複数のギブ関数間の共通接線を見つける際に、材料科学で多くの用途があります。すべての人が使用できる堅牢な機能があればいいのですが...

4

2 に答える 2

1

曲線Aの点を通過し、各点で接線を描画して、曲線Bと交差する回数を計算できます。交差の数が2つ上下にジャンプする場合は、相互を通過したことがわかります。正接。これはまだかなり大雑把ですが、曲線が特定の接線と交差する回数を計算するために曲線Bのサンプルポイントをあまり必要としないため、元の提案よりもいくらか高速になると思います。(曲線Bが線より上と下の間で切り替わる回数を数えるだけです。)

(確かに、サンプルが少なすぎると、二重接線の近くで1対の交差を見逃す可能性がありますが、それでも問題ありません。それでも、二重接線に近づくことになります。別の推定値を追加できます。真のダブルタンジェントに非常に近づいたら、リファインメントアルゴリズム。ニュートン法、再帰的二分法などに類似したものを使用できます。)

あなたがもっと真剣なら、私はこのより洗練された議論を見つけました。

于 2012-04-22T19:11:42.283 に答える