找到数值积分的根

时间:2013-02-22 15:24:38

标签: python numpy scipy physics numerical-integration

我试图用Python重现这个Mathematica程序:

Mathematica program

它找到了数值积分的根,并形成了这些值的图。但是,我不能试图逃跑。

目前的尝试:

来自scipy.integrate import quad 来自scipy import的整合 来自scipy.optimize import fsolve 将pylab导入为pl 导入numpy为np

# Variables.
boltzmann_const = 1.38e-23
planck_const = 6.62e-34
hbar = planck_const / ( 2 * np.pi )
transition_temp = 9.2
gap_energy_at_zero_kelvin = 3.528 / ( 2 * transition_temp * boltzmann_const )
debye_freq = ( 296 * boltzmann_const ) / hbar

# For subtracting from root_of_integral
a_const = np.log( ( 1.13 * hbar * debye_freq ) / ( boltzmann_const * transition_temp) )
# For simplifying function f.
b_const = ( hbar * debye_freq ) / ( 2 * boltzmann_const)


def f( coherence_length, temp ):
    # Defines the equation whose integral will have its roots found. Epsilon = coherence length. Delta = Gap energy.

    squareRoot = np.sqrt( coherence_length*coherence_length + gap_energy*gap_energy )
    return np.tanh( ( ( b_const / temp ) * squareRoot ) / squareRoot )


def integrate( coherence_length, temp ):
    # Integrates equation f with respect to E, between 0 and 1. 

    return integrate.quad( f, 0, 1, args = ( temp, ) )[0]


def root_of_integral( temp ):
    # Finds the roots of the integral with a guess of 0.01.

   return fsolve( integrate, 0.01, args = ( temp, ) )


def gap_energy_values( temp ):
    # Subtracts a_const from each root found, to obtain the gap_energy_values.

    return root_of_integral( temp ) - a_const

2 个答案:

答案 0 :(得分:2)

这一行:

integral = (integrate.quad(lambda E: np.tanh(1477.92*np.sqrt(E**2+x**2))/np.sqrt(E**2+x**2), 0, 1)

有不平衡的括号:

integral = integrate.quad(lambda E: np.tanh(1477.92*np.sqrt(E**2+x**2))/np.sqrt(E**2+x**2), 0, 1)

如果你打破它会更容易看到,例如。

x_values = arange(0.01, 0.1, 0.0001)

delta = []
for x in x_values:
    def fun(E):
        distance = np.sqrt(E * E + x * x)
        return np.tanh(1477.92 * distance) / distance

    integral = integrate.quad(fun, 0, 1)
    delta_val = fsolve(integral, 1e-23) - a
    delta.append(delta_val)

pl.plot(delta, x_values)

答案 1 :(得分:2)

正如已经在评论中提到的那样(由@Hristo Iliev和@Pavel Annosov撰写),quad returns a tuple of stuff。如果您假设集成没有问题,就像您在Mathematica中所做的那样(虽然这不是一个好主意),在这个元组之外,您只需要第一个元素,它应该是整合结果。

但这只会给你一个数字,而不是T的函数。要获得后者,您需要自己定义相应的功能,就像您在Mathematica中使用\Delta[T_]:=...

一样

以下是一些可以帮助您入门的内容:

def f(E, T):
    """To be integrated over T."""
    temp = np.sqrt(E * E + T * T)
    return np.tanh(1477.92 * temp) / temp


def gap(T):
    """Integration result: \Delta(T)"""
    return quad(f, 0, 1, args=(T, ))[0]  #NB: [0] select the 1st element of a tuple

请注意,您需要使用args=(T,)语法将T参数发送到正在集成的函数:quad集成在函数的第一个参数上,并且需要其他参数能够评估f(E, T)

现在,您可以将此gap(T)提供给fsolvewhich also expects a function(一个callable,以便更精确)。

在稍微更一般的层面上,你不应该使用玻尔兹曼常数,hbar等的数值(甚至Mathematica抱怨!)。你应该做什么,你应该用无量纲的形式写你的公式:用能量单位测量温度(因此k_B = 1)等,在积分中做适当的替换,这样你就可以处理无量纲参数的无量纲函数---和然后让电脑处理那些。