簡體   English   中英

我的復方程上的Scipy.optimize.fsolve()

[英]Scipy.optimize.fsolve() on my complex equation

我試圖用scipy解決一個復雜的功能。 我讀到fsolve僅適用於實數。 因此,我對公式進行了一些更改,現在看起來像這樣:

import numpy as np
from scipy.optimize import fsolve

delta = 84.37228318652858 * np.pi / 180
psi = 55.2217535040673 * np.pi / 180
n_S = 2.6726 + 3.0375j
phi_i = 70 * np.pi / 180
d_L = 300  # thickness of layer in nm
n_air = 1  # refractive index of air


def snell(phi, n1, n2):
    phi_ref = np.arcsin((n1 / n2) * np.sin(phi))
    return phi_ref


def fresnel(n1, phi1, n2, phi2):
    rs = (n1 * np.cos(phi1) - n2 * np.cos(phi2)) / (
        n1 * np.cos(phi1) + n2 * np.cos(phi2))
    rp = (n2 * np.cos(phi1) - n1 * np.cos(phi2)) / (
        n2 * np.cos(phi1) + n1 * np.cos(phi2))
    return rs, rp


def calc_rho(n_k):
    n = n_k[0]
    k = n_k[1]
    n_L = n + 1j * k
    phi_L = snell(phi_i, n_air, n_L)
    phi_S = snell(phi_L, n_L, n_S)
    rs_al, rp_al = fresnel(n_air, phi_i, n_L, phi_L)
    rs_ls, rp_ls = fresnel(n_L, phi_L, n_S, phi_S)
    beta = 2 * np.pi * d_L * n_L * np.cos(phi_L) / lambda_vac
    rp_L = (rp_al + rp_ls * np.exp(-2 * 1j * beta)) / (
        1 + rp_al * rp_ls * np.exp(-2 * 1j * beta))
    rs_L = (rs_al + rs_ls * np.exp(-2 * 1j * beta)) / (
        1 + rs_al * rs_ls * np.exp(-2 * 1j * beta))
    rho_L = rp_L / rs_L
    return abs(rho_L - rho_given)


lambda_vac = 300
n_S = 2.6726 + 3.0375j
rho_given = np.tan(psi) * np.exp(
    1j * delta)  # should be 1.4399295435287844+0.011780279522394433j
initialGuess = [1.5, 0.1]
nsolve = fsolve(calc_rho, initialGuess)
print(nsolve)

這是我第一次使用求解器(和scipy),但是我認為這是使用它的正確方法。

上面的代碼給出以下錯誤:

TypeError: fsolve: there is a mismatch between the input and output shape of the 'func' argument 'calc_rho'.Shape should be (2,) but it is (1,).

我不知道如何解決此錯誤,以及如何獲得能解決我的方程式的復數n。

如評論中所述, minimize似乎更適合此類問題。 以下工作正常並成功終止:

import numpy as np
from scipy.optimize import minimize

delta = 84.37228318652858 * np.pi / 180
psi = 55.2217535040673 * np.pi / 180
n_S = 2.6726 + 3.0375j
phi_i = 70 * np.pi / 180
d_L = 300  # thickness of layer in nm
n_air = 1  # refractive index of air


def snell(phi, n1, n2):
    phi_ref = np.arcsin((n1 / n2) * np.sin(phi))
    return phi_ref


def fresnel(n1, phi1, n2, phi2):
    rs = (n1 * np.cos(phi1) - n2 * np.cos(phi2)) / (
        n1 * np.cos(phi1) + n2 * np.cos(phi2))
    rp = (n2 * np.cos(phi1) - n1 * np.cos(phi2)) / (
        n2 * np.cos(phi1) + n1 * np.cos(phi2))
    return rs, rp


def calc_rho(n_k):
    n = n_k[0]
    k = n_k[1]
    n_L = n + 1j * k
    phi_L = snell(phi_i, n_air, n_L)
    phi_S = snell(phi_L, n_L, n_S)
    rs_al, rp_al = fresnel(n_air, phi_i, n_L, phi_L)
    rs_ls, rp_ls = fresnel(n_L, phi_L, n_S, phi_S)
    beta = 2 * np.pi * d_L * n_L * np.cos(phi_L) / lambda_vac
    rp_L = (rp_al + rp_ls * np.exp(-2 * 1j * beta)) / (
        1 + rp_al * rp_ls * np.exp(-2 * 1j * beta))
    rs_L = (rs_al + rs_ls * np.exp(-2 * 1j * beta)) / (
        1 + rs_al * rs_ls * np.exp(-2 * 1j * beta))
    rho_L = rp_L / rs_L
    return abs(rho_L - rho_given)


lambda_vac = 300
n_S = 2.6726 + 3.0375j
rho_given = np.tan(psi) * np.exp(
    1j * delta)  # should be 1.4399295435287844+0.011780279522394433j
initialGuess = [1.5, 0.1]
nsolve = minimize(calc_rho, initialGuess, method='Nelder-Mead')
print(nsolve)

這將打印:

 final_simplex: (array([[1.50419259, 0.10077416],
       [1.50419591, 0.10076434],
       [1.50421181, 0.1007712 ]]), array([0.00015298, 0.00015507, 0.00022935]))
           fun: 0.00015297827023618208
       message: 'Optimization terminated successfully.'
          nfev: 48
           nit: 25
        status: 0
       success: True
             x: array([1.50419259, 0.10077416])

我們使用method='Nelder-Mead'因為這是一種無梯度優化方法,似乎是此類問題所必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM