2

おそらく、コードを示して後で説明するのが最も簡単な方法です。

sigma_aussen = 7.1
roh_aussen = 38
lambda_schreib = 532*10**-9
lambda_rek = 432*10**-9
sigma_aussen=radians(sigma_aussen)
roh_aussen=radians(roh_aussen)

def BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek):


    gw2, sig_innen, ref_innen, sig_din, ref_din, p2, sig, ref =var('gw2 sig_innen ref_innen sig_din ref_din p2 sig ref')

    sigma = asin(1/n_brech*sin(sigma_aussen))
    roh = asin(1/n_brech*sin(roh_aussen))
    gw = (sigma+roh)/2
    sigma_din =  (roh-sigma)/2
    roh_din =  (sigma-roh)/2


    gw2 = (asin(1/n_brech*sin(sig))+asin(1/n_brech*sin(ref))/2)
    print("gw2: ", gw2)

    sig_innen = asin(1/n_brech*sin(sig))
    ref_innen = asin(1/n_brech*sin(ref))
    print ("sig_innen: ", sig_innen)
    print ("ref_innen: ", ref_innen)


    sig_din = gw2-sig_innen
    ref_din = gw2-ref_innen
    print ("ref_din: ", ref_din)

    p = lambda_schreib/(n_brech*(sin(sigma_din)-sin(roh_din)))
    print ("p: ",p)
    p2 = lambda_rek/n_brech*(sin(sig_din)-sin(ref_din))
    print ("p2: ", p2)

    Winkel=nsolve([gw-gw2, p-p2],[sig,ref], [0,0])
    return Winkel    

Winkel = BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek)

ここで私の説明: BraggMatch はラジアンで 2 つの角度を返すメソッドです。

2 つの方程式は gw-gw2=0 と p-p2=0 です。gw と p は 2 つの既知の変数です。不明な変数は sig と ref の 2 つだけです。2 つの未知の変数を数値的に解決し、BraggMatch メソッドで返す必要があります。

その 2 つの方程式を解くソフトウェア Maple を使用すれば、問題はありません。解決策を示して、役立つかもしれません: sig=0.064 and ref=0.734

これはエラーです:「ValueError: 指定された許容範囲内でルートが見つかりませんでした。(0.0448851 > 2.1684e-19) 別の開始点を試すか、引数を微調整してください。」

この問題を解決するのを手伝ってくれて、とても感謝しています。それが私の修士論文の核心です。


まず、迅速な対応に感謝します。

しかし、私はこれが正しい方法だとは思いません。そうです、忘れてしまいましたn_brech=1.5gw-gw2今日、それが分析的な問題を解決できることがわかりました。だから私はの解決策だけが必要ですp-p2。との解は、 の変化によって PI と -PI の間にある可能性がありますref。これが、私が 0 で解を探し始める理由です。sigsigma_aussen, roh_aussen, lambda_rek

ここに私の新しいコードが表示されます:

n_brech = 1.5
sigma_aussen = 7.1
roh_aussnen = 38
lambda_schreib = 532*10**-9
lambda_rek = 432*10**-9
sigma_aussen=radians(sigma_aussen)
roh_aussen=radians(roh_aussen)

def BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek):

    gw2, sig_innen, ref_innen, sig_din, ref_din, p2, sig, ref =var('gw2 sig_innen ref_innen sig_din ref_din p2 sig ref')

    sigma = asin(1/n_brech*sin(sigma_aussen))
    roh = asin(1/n_brech*sin(roh_aussen))
    gw = (sigma+roh)/2
    sigma_din =  (roh-sigma)/2
    roh_din =  (sigma-roh)/2


    gw2 = (asin(1/n_brech*sin(sig))+asin(1/n_brech*sin(ref))/2)
    ref_list=solve(gw-gw2,ref)
    ref=ref_list[0]
    print("ref: ", ref)
    gw2 = (asin(1/n_brech*sin(sig))+asin(1/n_brech*sin(ref))/2)

    sig_innen = asin(1/n_brech*sin(sig))
    ref_innen = asin(1/n_brech*sin(ref))
    sig_din = gw2-sig_innen
    ref_din = gw2-ref_innen

    p = lambda_schreib/(n_brech*(sin(sigma_din)-sin(roh_din)))
    p2 = lambda_rek/(n_brech*(sin(sig_din)-sin(ref_din)))
    print ("p2: ", p2)
    print ("p-p2: ", p-p2)
    sig=fsolve(p-p2,0)
    Winkel=[sig, ref]
    return Winkel

Winkel=BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek)

Maple が得意なら、私がアップロードした画像で、私が Python で解決しなければならない問題を完全に見ることができます。なぜなら、ここでは VPython で視覚化できるからです。Maple コードは角度を度単位で返しますが、これは問題ありません。 ここに画像の説明を入力


ここで、Maple で行ったように、コードを記述しようとしました。私は今いくつかのエラーを取得します:

ZeroDivisionError

コードは次のとおりです。

n_brech = 1.5
sigma_aussen = 7.1
roh_aussen = 38
lambda_schreib = 532*10**-9
lambda_rek = 432*10**-9
sigma_aussen=radians(sigma_aussen)
roh_aussen=radians(roh_aussen)

def BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek):

    sig, ref =var('sig ref')

    def sigma(n_brech, sigma_aussen):
        return (asin(1/n_brech*sin(sigma_aussen)))
    def roh(n_brech, roh_aussen):
        return (asin(1/n_brech*sin(roh_aussen)))
    def gw(n_brech, sigma_aussen, roh_aussen):
        return ((sigma(n_brech, sigma_aussen)+roh(n_brech, roh_aussen))/2)
    def sigma_din(n_brech, sigma_aussen, roh_aussen):
        return (gw(n_brech, sigma_aussen, roh_aussen)-sigma(n_brech, sigma_aussen))
    def roh_din(n_brech, sigma_aussen, roh_aussen):
        return (gw(n_brech, sigma_aussen, roh_aussen)-roh(n_brech, roh_aussen))
    def p(n_brech, sigma_aussen, roh_aussen, lambda_schreib):
        return (lambda_schreib/(n_brech*(sin(sigma_din(n_brech, sigma_aussen, roh_aussen))-sin(roh_din(n_brech, sigma_aussen, roh_aussen)))))

    return (nsolve([gw(n_brech, sigma_aussen, roh_aussen)-gw(n_brech, sig, ref), p(n_brech, sigma_aussen, roh_aussen, lambda_rek)-p(n_brech, sig, ref, lambda_schreib)], [sig, ref], [0, 0]))

Winkel=BraggMatch(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek)

なぜ機能しないのか理解できません...

4

1 に答える 1

0

問題は数値的にも解決できます。たとえば、次のようにしscipy.optimize.minimize()ます。

from scipy.optimize import minimize;
from math import radians, asin, sin;

sigma_aussen = 7.1
roh_aussen = 38
lambda_schreib = 532*10**-9
lambda_rek = 432*10**-9
sigma_aussen=radians(sigma_aussen)
roh_aussen=radians(roh_aussen)

n_brech = 1

def BraggMatch(sig,ref,sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek):
    sigma = asin(1/n_brech*sin(sigma_aussen))
    roh = asin(1/n_brech*sin(roh_aussen))
    gw = (sigma+roh)/2
    sigma_din =  (roh-sigma)/2
    roh_din =  (sigma-roh)/2
    gw2 = (asin(1/n_brech*sin(sig))+asin(1/n_brech*sin(ref))/2)
    sig_innen = asin(1/n_brech*sin(sig))
    ref_innen = asin(1/n_brech*sin(ref))
    sig_din = gw2-sig_innen
    ref_din = gw2-ref_innen
    p = lambda_schreib/(n_brech*(sin(sigma_din)-sin(roh_din)))
    p2 = lambda_rek/n_brech*(sin(sig_din)-sin(ref_din))
    return (gw-gw2)**2 + (p-p2)**2  

def f(x,sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_re):
    return BraggMatch(x[0],x[1],sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_re)

print(minimize(f,[0,0],args=(sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek)).x)

n_brech = 1ただし、その値が質問に示されていなかったため、推測する必要がありました。scipy.optimize.minimize()実際、 は解 ( [ 0.3148574 0.1574287]) を見つけますが、それは Maple が見つけたものと同じ解ではありません。

方程式のソースとその意味を知らなければ、それらが正しく定式化されていると確信することはできません. ただし、複数のソリューションを確認できました。[0.064, 0.734]atの代わりに at で最適化を開始すると[0, 0]、結果が得られました[ 0.0340574 0.7190287]

したがって、これらの方程式には複数の解があり、(少なくとも のこの値についてはn_brech) 最適化が異なる点で開始されると、異なる解が見つかるようです。

(さらに編集)

複数のソリューションを調査するために、次のコードを使用しました。

from scipy.optimize import minimize;
from math import radians, asin, sin, log;

sigma_aussen = 7.1
roh_aussen = 38
lambda_schreib = 532*10**-9
lambda_rek = 432*10**-9
sigma_aussen=radians(sigma_aussen)
roh_aussen=radians(roh_aussen)

n_brech = 1.5

def BraggMatch(sig,ref,sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek):
    sigma = asin(1/n_brech*sin(sigma_aussen))
    roh = asin(1/n_brech*sin(roh_aussen))
    gw = (sigma+roh)/2
    sigma_din =  (roh-sigma)/2
    roh_din =  (sigma-roh)/2
    gw2 = (asin(1/n_brech*sin(sig))+asin(1/n_brech*sin(ref))/2)
    sig_innen = asin(1/n_brech*sin(sig))
    ref_innen = asin(1/n_brech*sin(ref))
    sig_din = gw2-sig_innen
    ref_din = gw2-ref_innen
    p = lambda_schreib/(n_brech*(sin(sigma_din)-sin(roh_din)))
    p2 = lambda_rek/n_brech*(sin(sig_din)-sin(ref_din))
    return log((gw-gw2)**2 + (p-p2)**2) 

import matplotlib
import itertools
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'

delta = 0.001
sig = np.arange(0, 1, delta)
ref = np.arange(0, 1, delta)
XY = [(x,y) for x in sig for y in ref]
Z = [ BraggMatch(x,y,sigma_aussen, roh_aussen, n_brech, lambda_schreib, lambda_rek) for x,y in XY]
X = [x for x,y in XY]
Y = [y for x,y in XY]
Z = np.reshape(Z,(len(sig),-1))

plt.figure()
CS = plt.contour(sig, ref, Z)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Contour plot')
plt.xlabel('sig')
plt.ylabel('ref')

plt.show()

... 次の出力が生成されます。

ここに画像の説明を入力

...ここから、関心のある範囲内の曲線に沿って多くの極小値があることがわかります。したがって、さまざまな方法 (およびさまざまなソフトウェア) がさまざまな最小値を見つけることは驚くことではありません。

于 2013-03-24T08:50:12.307 に答える