【问题标题】:Nan values when using np.linspace() as input使用 np.linspace() 作为输入时的 Nan 值
【发布时间】:2018-04-18 03:44:16
【问题描述】:

我正在尝试计算电子通过一系列势阱的传输概率。当使用 np.linspace() 遍历能量值时,对于 15 以下的任何值,我都会返回 nan。对于 0 和 15 的值,我理解这一点,因为它们在 k 和 q 值的分母中返回零值。例如,如果我简单地调用 getT(5),我会得到一个真正的值。但是,当使用 np.linspace(0,30,2001) 从循环中调用 getT(5) 时,它会返回 nan。它不应该在这两种情况下都返回 nan 或 value 吗?

import numpy as np
import matplotlib.pyplot as plt

def getT(Ein):
    #constants
    hbar=1.055e-34 #J-s
    m=9.109e-31 #mass of electron kg
    N=10 #number of cells
    a=1e-10 #meters
    b=2e-10 #meters

    #convert energy and potential to Joules
    conv_J=1.602e-19
    E_eV=Ein
    V_eV=15
    E=conv_J*E_eV
    V=conv_J*V_eV

    #calculate values for k and q
    k=(2*m*E/hbar**2)**.5
    q=(2*m*(E-V)/hbar**2)**.5

    #create M1, M2 Matrices
    M1=np.matrix([[((q+k)/(2*q))*np.exp(1j*k*b),((q-k)/(2*q))*np.exp(-1j*k*b)], \
                  [((q-k)/(2*q))*np.exp(1j*k*b),((q+k)/(2*q))*np.exp(-1j*k*b)]])
    M2=np.matrix([[((q+k)/(2*k))*np.exp(1j*q*a),((k-q)/(2*k))*np.exp(-1j*q*a)], \
                  [((k-q)/(2*k))*np.exp(1j*q*a),((q+k)/(2*k))*np.exp(-1j*q*a)]])

    #calculate M_Cell
    M_Cell=M1*M2

    #calculate M for N cells
    M=M_Cell**N

    #get items in M_Cell
    M11=M.item(0,0)
    M12=M.item(0,1)
    M21=M.item(1,0)
    M22=M.item(1,1)

    #calculate r and t values
    r=-M21/M22
    t=M11-M12*M21/M22

    #calculate final T value
    T=abs(t)**2

    return Ein,T

#create empty array for data to plot
data=[]

#Calculate T for 500 values of E in between 0 and 30 eV
for i in np.linspace(0,30,2001):
    data.append(getT(i))
data=np.transpose(data)

#generate plot
fig, (ax1)=plt.subplots(1)
ax1.set_xlim([0,30])
ax1.set_xlabel('Energy (eV)',fontsize=32)
ax1.set_ylabel('T',fontsize=32)
ax1.grid()
plt.tick_params(labelsize=32)
plt.plot(data[0],data[1],lw=6)
plt.draw()
plt.show()

【问题讨论】:

  • 因为在q=(2*m*(E-V)/hbar**2)**.5 中,E-V 的差是负数,Python 会返回 NaN 而不是复数。这就是为什么 15 是临界点:V_eV=15
  • 如果您向linspace 询问复数,即np.linspace(0,30,2001,dtype=np.complex128),那么您只会得到两个NaNs。
  • @AhmedFasih:“Python 将返回 NaN”——更准确地说:NumPy 会这样做。 ;)
  • @Falko 是绝对正确的,Python 做的很聪明(-1.5 ** 0.5 很好)但是 linspace 的内容默认是 numpy.float64,而 np.float64(-1.5)**0.5 是 NaN ????。 Numpy 通常希望保留内存格式。
  • @AhmedFasih 很好的答案!谢谢

标签: python numpy matrix matrix-multiplication


【解决方案1】:

我认为差异来自于行

q=(2*m*(E-V)/hbar**2)**.5

使用 0 到 15 之间的单个值进行测试时,您基本上是在取负数的根(因为 E-V 是负数),这是不合理的,例如:

(-2)**0.5
>> (8.659560562354934e-17+1.4142135623730951j)

但是当使用np.linspace 时,你会取一个带有负值的 NumPy 数组的根,这会导致nan(和一个警告):

np.array(-2)**0.5
>> RuntimeWarning: invalid value encountered in power
>> nan

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-07
    • 2016-11-19
    • 2019-07-14
    • 2023-04-09
    • 2023-04-03
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    相关资源
    最近更新 更多