【问题标题】:How to substitute a SymPy symbol with an array of values?如何用一组值替换 SymPy 符号?
【发布时间】:2020-09-01 21:44:17
【问题描述】:

我目前有一个具有积分边界的数组(bounds_symbolic)。我正在尝试用一组值替换符号边界。

在高层次上,我要做的是解决以下积分(这里使用变量名):

integral_variables

这是一个例子:

example_integral

到目前为止,这是我的代码:

import sympy
import numpy as np
a, b, x, y = sympy.symbols("a b x y")


# Equation of the ellipse solved for y
ellipse = sympy.sqrt((b ** 2) * (1 - ((x ** 2) / (a ** 2))))

# Functions to be tested
test_functions = [(a * b * x), (((a * b) ** 2) * x), (((a * b) ** 3) * x), (((a * b) ** 4) * x), (((a * b) ** 5) * x)]


# Equating ellipse and test_functions so their intersection can be symbolically solved for
equate = [sympy.Eq(ellipse, test_functions[0]), sympy.Eq(ellipse, test_functions[1]), sympy.Eq(ellipse, test_functions[2]), sympy.Eq(ellipse, test_functions[3]), sympy.Eq(ellipse, test_functions[4])]


# Calculating the intersection points of the ellipse and the testing functions

# Array that holds the bounds of the integral solved symbolically
bounds_symbolic = []
for i in range(0, 3):
    bounds_symbolic.append(sympy.solve(equate[i], x))

# Array of a-values to plug into the bounds of the integral
a_values = np.linspace(-10, 10, 201)

# Setting b equal to a constant of 1
b = 1

integrand = []
for j in range(0, 3):
    integrand.append(ellipse - test_functions[j])

# New array with a-values substituted into the bounds

bounds_a = bounds_symbolic
for j in range(0, 201):
    bounds_a.subs(a, a_values[j])

当我运行它时,当我尝试执行bounds_a.subs(a, a_values[j]) 操作时出现错误:

AttributeError: 'list' object has no attribute 'subs'

我想要发生的是bounds_a 数组具有我在上面解决的相同边界,但所有的“a”值都被替换了,而不是只有一个符号“a” .我还希望能够将“b”值替换为 1。

我该怎么做呢?如果我使用 NumPy 数组而不是列表会更好吗?

谢谢!

【问题讨论】:

  • bounds_symbolic 是一个列表。元素可能是sympy 对象,带有subs 方法。如果要应用 subs 方法,则必须迭代列表的元素。列表本身不进行任何类型的迭代。
  • 有一个sympy.lambdify函数可以从sympy表达式创建一个numpy兼容函数。
  • @hpaulj 在我的新版本程序中,我已将所有内容都转换为 NumPy 数组而不是列表。这似乎解决了问题!

标签: python arrays numpy python-3.7 sympy


【解决方案1】:

isympy 会话中,x 定义为变量:

In [51]: x                                                                                           
Out[51]: x

我可以列出表达式:

In [52]: alist = [2*x, 3*x, 4+x]                                                                     

并对它们中的每一个执行subs

In [53]: [expr.subs({x:12}) for expr in alist]                                                       
Out[53]: [24, 36, 16]

和多个潜艇:

In [54]: [[expr.subs({x:val}) for expr in alist] for val in [1,2,3]]                                 
Out[54]: [[2, 3, 5], [4, 6, 6], [6, 9, 7]]

使用lambdify,我可以创建一个以numpy 数组作为输入的函数(默认为numpy 模式):

In [61]: f = lambdify(x, alist)                                                                      

In [62]: print(f.__doc__)                                                                            
Created with lambdify. Signature:

func(x)

Expression:

[2*x, 3*x, x + 4]

Source code:

def _lambdifygenerated(x):
    return ([2*x, 3*x, x + 4])

我可以给f一个号码:

In [63]: [f(i) for i in [1,2,3]]                                                                     
Out[63]: [[2, 3, 5], [4, 6, 6], [6, 9, 7]]

或数组:

In [64]: f(np.array([1,2,3]))                                                                        
Out[64]: [array([2, 4, 6]), array([3, 6, 9]), array([5, 6, 7])]

【讨论】:

  • 我已经尝试过这样做,我想我正在取得进展。我做了以下事情:bounds_ab = bounds_symbolicbounds_ab = sympy.lambdify(a, test_functions)bounds_new = bounds_ab(a_values)。 Python 抛出一个错误,指出“x”未定义。我在想我需要创建一个实际的(即 def)函数来解决这个问题,但我对该函数的实际外观有点困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 2018-06-10
  • 2016-01-02
  • 1970-01-01
  • 2016-01-01
相关资源
最近更新 更多