Получение ошибки «Может только применить функцию« exp »к безразмерным величинам», Не уверен, как это исправить - PullRequest
0 голосов
/ 29 апреля 2020

Я работал над преобразованием некоторого кода MatLab в python для одного из моих профессоров (не задание, просто работающее над сборкой некоторых вещей), и я застрял в этой одной части.

Когда я запускаю код, я получаю UnitTypeError: «Может применять функцию« exp »только к безразмерным величинам», все методы, которые я пытался исправить, не будут работать. Я предполагаю, что ошибка вызвана командой linspace, но я не уверен. Любая помощь в этом была бы хороша.

здесь есть строка

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

с константами из астропии

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

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Принятый ответ в порядке и работает, если вы уверены, что используемые вами значения имеют правильные размеры. Но в целом использование .value и отбрасывание информации о единицах может быть потенциально опасным - использование Количества с единицами гарантирует, что все ваши вычисления выполняются с совместимыми единицами.

Давайте посмотрим на только экспонента в вашей экспоненте, которая обычно должна быть безразмерной величиной.

Сначала обратите внимание, что все константы, которые вы используете из 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, но допустим, что это термодинамическая c бета в 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 - если это не правильно, тогда вы захотите проверить некоторые мои предположения о ваших единицах.)

В любом случае, именно так библиотека предназначена для использования , и ошибка, которую вы получаете, является преднамеренной проверкой ваших предположений.

Обновление: Я видел в ваш другой вопрос , что вы дали немного больше контекста для вашего пробл Эм, в частности, указав, что l - это длины волн в метрах (это было мое первое предположение, но я не был уверен, основываясь на приведенном вами уравнении).

На самом деле вы можете избежать непосредственного использования h и c в вашем уравнении Планка, используя эквивалентности . Здесь вы можете определить 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]>

(здесь он дает некоторые бесконечности вблизи низких длин волн, но вы можете избежать этого, обрезая большую нижнюю границу).

1 голос
/ 29 апреля 2020

Константы 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.

...