获取错误“只能将'exp'函数应用于无量纲量”,不确定如何解决此问题

2024-10-01 19:31:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在为我的一位教授将一些MatLab代码转换成python(这不是一项仅仅是整理一些东西的作业),我被困在这一部分

当我运行代码时,我得到了UnitTypeError:“只能对无量纲量应用'exp'函数”,我尝试解决这个问题的所有方法都不起作用。我猜想这个错误是由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

Tags: 方法函数代码错误np作业整理t1
2条回答

astropy常量是类的实例。在将它们用作np.exp()的参数之前,请尝试提取每个的“值”:

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上为零

accepted answer很好,只要您确信所使用的裸值在正确的维度上,它就可以工作。但是一般来说,使用.value并丢弃单位信息可能会有潜在的危险,使用Quantitieswith units可以确保所有计算都是使用兼容的单位完成的

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

首先请注意,您从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中的热力学β,尽管你应该仔细检查这个值应该是什么单位)

因此,您可能需要使用适当的单位声明这些值(顺便说一句,您可以通过定义一些ε并将其用作范围的起点来避免恼人的除以零):

>>> 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。如果这不正确,那么您需要检查我关于单位的一些假设)

在任何情况下,这就是该库的使用方式,而您得到的错误是针对您的假设进行的故意安全检查

更新:我在your other question中看到您为您的问题提供了更多的上下文,特别是指定l是以米为单位的波长(这是我的第一个猜测,但根据您给出的等式我不确定)

实际上,通过利用等价性,您可以避免在普朗克方程中直接使用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]>

(这里它给出了一些接近低波长的无穷大,但是你可以通过剪切到一个更大的下限来避免)

相关问题 更多 >

    热门问题