存储符号和表达式的正确工作流程

问题描述 投票:0回答:1

我从我在 Github 上公开的讨论中重新发布了这篇文章,以接触更多的人,因为我的问题取决于个人喜好。

我想我的问题是由于 sympy 在 python(一般编程语言)中使用,而不是在特殊的数学语言中使用。我还是想听听你的建议。

目标

我已经使用 sympy 一段时间了。我的目标是仅通过输出创建尽可能可重复的计算。

问题

我一直在努力解决的问题是如何构建我的代码/存储在变量中。

我在计算面积和体积的示例中提出的一些不同方法:

期望的输出是:

import sympy as sp
from sympy.abc import *
display(sp.Eq(A, a*b), sp.Eq(V, A*h), sp.Eq(V, a*b*h))

第一种方法

第一种方法是将它们存储在 sp.Eq 中:

import sympy as sp
from sympy.abc import *


eq_A = sp.Eq(A, a*b)
eq_V = sp.Eq(V, A*h)

display(eq_A, eq_V)

eq_V_subs = sp.Eq(V, A.subs(A, eq_A.rhs))

display(eq_V_subs)

这种方法似乎太乏味并且容易出错,因为我必须不断用其对应的方程重新替换符号。

第二种方法

我采取的下一个方法是覆盖符号:

A = a*b
V = A*h

display(sp.Eq(sp.Symbol('A'),A), sp.Eq(sp.Symbol('V'),V)) 

以这种方式进行计算感觉很自然。问题是,我覆盖了符号,这阻碍了我获得所需的

sp.Eq(V, A*h)
输出。特别是当变量中的计算量越来越大时,需要用简单的符号替换以保持概览:

第三种方法

我的最后一个方法是以某种方式为我的表情创建一个商店:

import sympy as sp
from sympy.abc import *

store={}

store[A] = a*b
store[V] = A*h


display(sp.Eq(A, A.subs(store)), sp.Eq(V, V.subs(store)), sp.Eq(V, V.subs(store).subs(store)))

效果还不错,但正如在显示功能中可以看到的那样:要获得最终显示的音量,需要 sub V 2 次。随着字典大小的增加以及彼此建立的方程,n-subs 增加,这不再是手工可行的(也许编写一个函数来 subs n 次,其中 n 是字典的长度)。

展望

如果有一个类似于 sp.symbols() 的类,我可以在其中存储符号和相应的表达式,那不是很好吗?该类能够对符号和表达式执行 sympy 中的所有操作。通过一些定义的函数,我可以仅使用符号来显示,使用不同的函数,我可以使用表达式来呈现它。一些伪代码来说明我的意思:

import sympy as sp
from sympy.abc import *

A = mock_class(sp.Symbol('A'), a*b)
V = mock_class(sp.Symbol('V'), A*h)

mock_display_Symbol(V, V)
moch_display_expression(A, A)

所以我的问题是,你如何处理这个问题?你有什么建议我可以实现我的目标?

python jupyter sympy workflow quarto
1个回答
0
投票

您可能想探索一个不错的软件包,Algebra with SymPy

它实现了您在学校可能熟悉的“方程”概念,其中可以对方程两边应用相同的数学运算,或对两个或多个方程应用数学运算。

我认为这是一个强大的扩展,可以让 SymPy 计算感觉更自然。但有一个问题:它不会执行任何检查来验证您输入的内容是好还是坏。因此,你必须小心你想要实现的目标。

我会给你一个非常简短的介绍:

from sympy import *
from algebra_with_sympy import solve, Equation as Eqn, algwsym_config
init_printing()

Eqn
是实现魔法的类。
solve
是 SymPy 的
solve
函数的包装器,它能够处理
Equation
类型的对象。

# by default, when an equation is shown on the screen, it also shows
# a label with a unique number. Usually, I hide them:
algwsym_config.output.label = False
# by default, the algebra_with_sympy's solve returns objects of type
# FiniteSet. I don't like that behavior: I prefer lists of solutions.
algwsym_config.output.solve_to_list = True

现在举个例子:

var("a, b, h, V, A")
eq_V = Eqn(V, A*h)
eq_A = Eqn(A, a*b)
eq_V.subs(eq_A)
# out: V = a*b*h

上面的

subs
命令相当于
eq_V.subs(eq_A.lhs, eq_A.rhs)
。从本质上讲,您大大减少了输入错误的机会。

可以在这里找到更深入的教程

© www.soinside.com 2019 - 2024. All rights reserved.