Анализ размеров в SymPy - PullRequest
       17

Анализ размеров в SymPy

0 голосов
/ 11 января 2019

Я пытаюсь использовать SymPy для выполнения следующих задач:

  1. Упростим некоторые алгебраические уравнения физических величин и физических констант.
  2. Выполните анализ размеров, чтобы убедиться, что мои уравнения верны
  3. Оцените уравнения, добавив значения для физических величин.

Мой MCVE для этой задачи приведен ниже, где я хочу найти количество массы, эквивалентное данной энергии, используя эквивалент массы-энергии . (Я запускаю это в Jupyter, так как это может сделать уравнения красивыми.)

Начиная с E=m*c**2 Я хочу решить для m:

from sympy import *
E, m, c = symbols('E m c') # symbols, for energy, mass, and speed of light
eq_E = Eq(E, m*c**2) # define equation for E in terms of m and c
eq_m = Eq(m,solve(eq_E,m)[0]) # solve equation for m
display(eq_m)

m = \frac{E}{c^2}

Отлично! Теперь пришло время провести анализ размеров. Я определю свою энергию E в джоулях, и мне не нужно определять единицы измерения c, поскольку это физическая константа, и я работаю в единицах СИ (что, по-видимому, является значением по умолчанию для SymPy). Я хочу узнать, сколько массы находится в 1 Джоулях энергии, и я хочу узнать единицы этой массы. Я определю свои переменные, используя Quantity(), а затем снова установлю их в уравнении чтобы SymPy мог ее решить:

from sympy.physics.units import Quantity, energy, joule, speed_of_light
from sympy import Eq, solve
m = Quantity('m')                    # Define unknown mass 'm' as a quantity
E = Quantity('E')                    # Define known energy 'E' as a quantity
E.set_dimension(energy)              # E is a quantity of energy
E.set_scale_factor(1.0*joule, 'SI')  # set energy to 1.0 Joules
eq_E = Eq(E,m*speed_of_light**2)     # define E = mc^2
eq_m = Eq(m,solve(eq_E,m)[0])        # Solve E = mc^2 for m
display(eq_m)

Quantity(m,m)=\frac{Quantity(E,E)}{Quantity(speed_{oflight},c)^2}

Это не выглядит красиво, но выражение правильное. Теперь я хочу посмотреть, каково значение m и какие единицы m имеет. Сначала я сохраню решение для m в m_solve:

m_solve = solve(eq_E,m)[0]
display(m_solve)

\frac{Quantity(E,E)}{Quantity(speed_{oflight},c)^2}

Теперь можно посмотреть, какие единицы m_solve имеет?

print(m_solve.dimension)

AttributeError: 'Mul' object has no attribute 'dimension'

А как насчет значения m_solve?

print(m_solve.scale_factor)

AttributeError: 'Mul' object has no attribute 'scale_factor'

Что такое Mul? Как мне получить Quantity? В более общем смысле, есть ли в SymPy хороший рабочий процесс для манипулирования символьными уравнениями и проверки единиц измерения на этом пути, а затем, наконец, для оценки этих уравнений? Если не SymPy, есть ли хорошие альтернативы? (Я пробовал несколько альтернатив, наиболее многообещающе пинта , но, похоже, не хватает символической поддержки.)

1 Ответ

0 голосов
/ 15 января 2019

Я сделал пакет Python под названием SymDim ( Sym bolic Dim ensional analysis), чтобы сделать это, используя SymPy и astropy.units.

Установите SymDim (который также установит SymPy, Astropy и num2tex) с

pip install SymDim

Следующий пример можно запустить в записной книжке Jupyter. Первый вариант использования: я знаю скорость света, но пока не знаю, сколько энергии мне нужно, просто хочу посмотреть, в каких единицах m:

E = S('E', u.J) # energy in Joules ('J')
c = S('c', u.m/u.s, 3.0e8) # speed of light: 3.0e8 m/s
m = S('m') # I don't know the units yet!
E.equals(m*c**2)
m = E.solve_for(m)[0]  # solve returns a list of possible solutions
display(m)

enter image description here

m в килограммах! Теперь я хочу увидеть, сколько массы эквивалентно 9000 Дж энергии:

E = S('E', u.J, 9000) # energy
m = S('m') # I don't know the units or the value
E.equals(m*c**2)
m = E.solve_for(m)[0]
display(m)

enter image description here

И это то, что я хотел! Вы также можете делать сумасшедшие вещи, как:

x = S('x', u.m, 5.0)
L = S('L', u.m, 3.0)
Zw = S('Z_w')
T0 = S('T_0', u.K, 300.0)
T0.equals(Zw**(x/L-S(1)/S(2))) # enclose '1' and '2' in Sympint so python doesn't evaluate them 1/2 as 0.5
display(T0)
# now solve for Zw, whatever that is
Zw = T0.solve_for(Zw)[0]
display(Zw) # good to know that Zw has units of Kelvin^(6/7)!

enter image description here

Отказ от ответственности:

  1. Некоторые части клудги
  2. Иногда вы не можете повторно использовать переменную, и вам нужно переопределить ее, как только она выполнила свой метод equals().
  3. Мне все еще нужно обновить документацию по GitHub.

Пожалуйста, отправляйте сообщения об ошибках на 1053 *https://github.com/AndrewChap/symdim

...