出现错误 "Can only apply 'exp' function to dimensionless quantities",不知道如何解决这个问题

Getting error "Can only apply 'exp' function to dimensionless quantities", Not sure how to fix this

我一直在为我的一位教授将一些 MatLab 代码转换为 python(不是一项只是将一些东西放在一起的作业),我被困在这一部分上。

当我 运行 代码出现 UnitTypeError: "Can only apply 'exp' function to dimensionless quantities" 时,我尝试修复此问题的所有方法都不起作用。我想错误是由 linspace 命令引起的,但我不确定。任何帮助都会很棒。

这是行

IM0 = ((2*h*c**2)/(l**5))/(np.exp(h*c/( h*c/(k*T1*l)))-1)

常数来自 astropy

h = const.h;
c = const.c;
k = const.k_B;
l = np.linspace(0, 1.5e-6, 1500);
T1 = 3750

astropy 常量是 类 的实例。在将它们用作 np.exp():

的参数之前,尝试为每个提取 "value"
import astropy.constants as const
import numpy as np

h = const.h.value
c = const.c.value
k = const.k_B.value
l = np.linspace(0, 1.5e-6, 1500);
T1 = 3750
IM0 = ((2*h*c**2)/(l**5))/(np.exp(h*c/( h*c/(k*T1*l)))-1)

但是请注意 IM0 存在数值问题。所有 l.

的分母都为零

带单位的 is fine and works so far as you're confident that the bare values you're using are in the correct dimensions. But in general using .value and throwing away the units information can be potentially dangerous--using Quantities 可确保您的所有计算均使用兼容的单位进行。

让我们只看指数中的指数,它通常应该是无量纲的量。

首先请注意,您在 Astropy 中使用的所有常量都有单位:

>>> from astropy.constants import h, c, k_B                                     
>>> h                                                                           
<<class 'astropy.constants.codata2018.CODATA2018'> name='Planck constant' value=6.62607015e-34 uncertainty=0.0 unit='J s' reference='CODATA 2018'>
>>> c                                                                           
<<class 'astropy.constants.codata2018.CODATA2018'> name='Speed of light in vacuum' value=299792458.0 uncertainty=0.0 unit='m / s' reference='CODATA 2018'>
>>> k_B                                                                         
<<class 'astropy.constants.codata2018.CODATA2018'> name='Boltzmann constant' value=1.380649e-23 uncertainty=0.0 unit='J / K' reference='CODATA 2018'>

然后您声明了一些无单位值并将它们与这些值混合:

>>> T1 = 3750
>>> l = np.linspace(0, 1.5e-6, 1500)
>>> h*c/(h*c/(k_B*T1*l))                                                        
/home/embray/.virtualenvs/astropy/lib/python3.6/site-packages/astropy/units/quantity.py:481: RuntimeWarning: divide by zero encountered in true_divide
  result = super().__array_ufunc__(function, method, *arrays, **kwargs)
<Quantity [0.00000000e+00, 5.18088768e-29, 1.03617754e-28, ...,
           7.75578885e-26, 7.76096974e-26, 7.76615063e-26] J / K>

k_B 中得出以每开尔文焦耳为单位的结果,需要用正确单位的某些值进行抵消。我猜 T1 应该是开尔文温度(我不确定 l 但假设它是 J-1 中的热力学 beta你应该仔细检查这个值应该是什么单位)。

所以你可能想要做的是用适当的单位声明这些值(顺便说一句,你可以通过定义一些 epsilon 并将其用作你的范围的开始来避免烦人的除以零):

>>> from astropy import units as u
>>> eps = np.finfo(float).eps
>>> T1 = 3750 * u.K                                                             
>>> l = np.linspace(eps, 1.5e-6, 1500) * (u.J**-1)

现在你的指数是正确的无量纲量:

>>> h*c/(h*c/(k_B*T1*l))                                                        
<Quantity [1.14962123e-35, 5.18088882e-29, 1.03617765e-28, ...,
           7.75578885e-26, 7.76096974e-26, 7.76615063e-26]>
>>> np.exp(h*c/(h*c/(k_B*T1*l)))                                                
<Quantity [1., 1., 1., ..., 1., 1., 1.]>

(在这种情况下,无量纲值都非常接近于零,以至于指数四舍五入为 1——如果这不正确,那么您需要检查我对您的单位的一些假设)。

无论如何,这就是库的用途,您遇到的错误是针对您的假设的故意安全检查。

更新: 我在 中看到您为问题提供了更多背景信息,特别是指定 l 是以米为单位的波长(这是我的第一个猜测,但根据你给出的等式我不确定。

实际上,您可以利用 等效项 ,避免在 Plank 方程中直接使用 hc。在这里您可以将 l 定义为以米为单位的波长:

>>> l = np.linspace(eps, 1.5e-6, 1500) * u.m

并将其直接转换为光谱能量:

>>> E = l.to(u.J, equivalencies=u.spectral())                                   
>>> E                                                                           
<Quantity [8.94615682e-10, 1.98512112e-16, 9.92560670e-17, ...,
           1.32606651e-19, 1.32518128e-19, 1.32429724e-19] J>

然后在普朗克定律方程中写下指数,例如:

>>> np.exp(E / (k_B * T1))                                                      
/home/embray/.virtualenvs/astropy/lib/python3.6/site-packages/astropy/units/quantity.py:481: RuntimeWarning: overflow encountered in exp
  result = super().__array_ufunc__(function, method, *arrays, **kwargs)
<Quantity [        inf,         inf,         inf, ..., 12.95190431,
           12.92977839, 12.90771972]>

(这里它在低波长附近给出了一些无穷大,但您可以通过剪裁到更大的下限来避免这种情况)。