【问题标题】:How can I evaluate pre-defined symbolic variables array in Python?如何在 Python 中评估预定义的符号变量数组?
【发布时间】:2021-07-25 05:27:07
【问题描述】:

我有一个 MATLAB 代码,我正在尝试将其转换为 Python。我使用 eval() 在 MATLAB 中评估我的符号数组。但我找不到如何在 Python 中解决这个问题。这是一个简单的例子:

MATLAB 代码:


%values to be assigned
input = [10 20 30; ...
         15 25 20; ...
         20 20 10]

%decision variables     
x_1_1 = input(1)    
x_2_1 = input(2)    
x_3_1 = input(3)    
x_1_2 = input(4)
x_2_2 = input(5)    
x_3_2 = input(6)
x_1_3 = input(7)    
x_2_3 = input(8)    
x_3_3 = input(9)

%symbolic arrray
symbolic_eq  = sym('x_',[3,3])

%any math operation    
m  =  [-1  0  0 ; ...
        0 -1  0 ; ...
        0  1 -1 ]

% new equations for symbolic array    
multp_eq  = m*symbolic_eq

% get results
results   = eval(multp_eq)

Python 代码:

from sympy import *
import numpy as np

#values to be assigned
input = np.array([[10, 20, 30, 15, 25, 20, 20, 20, 10]])

#decision variables
x_1_1 = input[0]
x_2_1 = input[1]
x_3_1 = input[2]
x_1_2 = input[3]
x_2_2 = input[4]
x_3_2 = input[5]
x_1_3 = input[6]
x_2_3 = input[7]
x_3_3 = input[8]

#symbolic array (edited)
symbolic_eq = symarray('x', (4, 4))
symbolic_eq = np.array(symbolic_eq [1:, 1:])

#any math operation
m  =  np.array([[-1,  0,  0 ],
                [ 0, -1,  0 ],
                [ 0,  1, -1 ]])

#new equations for symbolic array
multp_eq  = m*symbolic_eq

# get results
results   = eval(multp_eq)

另外,对于 MATLAB 和 Python,如何轻松定义我的 input() 变量?

【问题讨论】:

  • symarray 的第一个索引是 0 而不是 1。
  • 我修改了python symarray函数代码。我曾在我的代码中考虑过这种情况,但在这里忘记了。谢谢@Corralien

标签: python matlab eval sympy code-conversion


【解决方案1】:

您的代码的主要问题是您需要进行替换(使用方法.subs(),然后才能评估您的表达式。这是通过提供包含变量及其值的列表元组来完成的。在这里我构建了这个列表在 for 循环中。

关于您的代码的一些额外信息。一般来说,避免使用像 from sympy import * 这样的命令。它无缘无故地填充您的命名空间。最后,我认为没有“好的”理由从 1 而不是 0 开始索引。我建议考虑切换到本机索引,因为它通常会使代码更清晰。

import sympy as sp
import numpy as np

#values to be assigned
aninput = np.array([[10, 20, 30],
                    [15, 25, 20],
                    [20, 20, 10]])

#symbolic array (edited)
symbolic_eq = sp.symarray('x', (4, 4))
symbolic_eq = symbolic_eq [1:, 1:]

thesubs = []
for index, theinput in np.ndenumerate(aninput):
    thesubs.append((symbolic_eq[index], aninput[index]))
print(thesubs)

#any math operation
m  =  sp.Matrix([[-1,  0,  0 ],
                [ 0, -1,  0 ],
                [ 0,  1, -1 ]])

#new equations for symbolic array
multp_eq  = m*symbolic_eq

# get results
results   = multp_eq.subs(thesubs)
results

最后,这段代码不会运行得很快。如果要对大量输入数组值进行此操作,则应考虑使用sympy.lambdify 而不是.subs

function = sp.lambdify(np.array(symbolic_eq).flatten(), multp_eq, modules="numpy" )

那么你只需要调用函数就可以得到答案:

result = function(*aninput.flatten())

在我的机器上,对于这个简单的例子,最后一行比使用 subs 的那一行快了近 400 倍。但是,如果您的输入数组的大小可以增加,那么这个解决方案可能会遇到一些限制(如果我记得的话,可以达到 256 个值)。

【讨论】:

  • 非常有用的功能@Romain Laugier。虽然第二个更有效,但在某些地方我也会使用第一个。我会考虑您对 import* 和本机索引的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2013-12-10
  • 2011-03-30
相关资源
最近更新 更多