gpt4 book ai didi

python - 如何在 sympy 中使用 Lambdify 和 IndexedBase 计算导数

转载 作者:行者123 更新时间:2023-12-01 09:03:47 29 4
gpt4 key购买 nike

我正在调查 SymPy 对于我的一些项目的适用性,并遇到了lambdaify 和 IndexedBase 之间交互的问题。

简而言之,我的应用程序大量使用采用双倍求和数组结构的函数。我需要能够计算函数以及函数相对于数组元素的一阶到三阶导数。

我的问题是:

  1. 如何使lambdaify与diff一起工作?
  2. 如何创建一个lambdaify函数,在其中可以指定我想要导数的索引?
  3. 如何将上述内容扩展到具有不同索引的二阶导数(即相对于索引 i 和 j 的二阶导数)?

简化示例:

from sympy import IndexedBase, Idx, lambdify, Sum, diff
from numpy import array


i = Idx("i", range=(0,1))
j = Idx("j", range=(0,1))
n = IndexedBase("n")
coefficients = IndexedBase("C")

double_sum = Sum(Sum(n[i]*n[j]*coefficients[i,j],(i,i.lower,i.upper)),(j,j.lower,j.upper))
first_derivative = diff(double_sum, n[i])
second_derivative = diff(first_derivative, n[j])

test_function_1 = lambdify((n,coefficients),double_sum)
test_function_2 = lambdify((n,coefficients,i),first_derivative)
test_function_3 = lambdify((n,coefficients,i,j),second_derivative)

test_vector = array([1, 2])
test_coefficients = array([[1,1],[2,3]])

test_value_1 = test_function_1(test_vector,test_coefficients)
print(test_value_1)

test_value_2 = test_function_2(test_vector,test_coefficients,1)
print(test_value_2)

test_value_3 = test_function_3(test_vector,test_coefficients)
print(test_value_3)

执行此代码会产生错误:

File "<lambdifygenerated-2>", line 9, in _lambdifygenerated
File "<lambdifygenerated-2>", line 9, in <genexpr>
NameError: name 'KroneckerDelta' is not defined

最佳答案

索引表达式很有用,但它们的派生有时比应有的更复杂,并且它们往往会出现 lambdify 问题。以下是不使用 Indexed 的大致等效代码。不同之处在于数组的大小是预先声明的,这使得可以使用 symarray 创建普通(非索引)符号的显式数组,操作这些数组,并对表达式进行羔羊化。我以某种方式对它们进行了羔羊化,以便一阶导数作为 1 列矩阵返回,二阶导数作为方阵返回(另一种返回类型如下)。

from sympy import symarray, Add, lambdify, Matrix
from numpy import array

i_upper = 2
j_upper = 2
n = symarray("n", i_upper)
coefficients = symarray("C", (i_upper, j_upper))

double_sum = Add(*[n[i]*n[j]*coefficients[i, j] for i in range(i_upper) for j in range(j_upper)])
first_derivative = Matrix(i_upper, 1, lambda i, j: double_sum.diff(n[i]))
second_derivative = Matrix(i_upper, j_upper, lambda i, j: double_sum.diff(n[i], n[j]))

params = list(n) + list(coefficients.ravel())
test_function_1 = lambdify(params, double_sum)
test_function_2 = lambdify(params, first_derivative)
test_function_3 = lambdify(params, second_derivative)

test_vector = array([1, 2])
test_coefficients = array([[1, 1], [2, 3]])
test_params = list(test_vector) + list(test_coefficients.ravel())
test_value_1 = test_function_1(*test_params)
test_value_2 = test_function_2(*test_params)
test_value_3 = test_function_3(*test_params)

测试值为 19[[8], [15]][[2, 3], [3, 6]] 分别。

或者,函数可以返回嵌套列表:

first_derivative = [double_sum.diff(n[i]) for i in range(i_upper)]
second_derivative = [[double_sum.diff(n[i], n[j]) for j in range(i_upper)] for i in range(i_upper)]

或 NumPy 数组:

first_derivative = array([double_sum.diff(n[i]) for i in range(i_upper)])
second_derivative = array([[double_sum.diff(n[i], n[j]) for j in range(i_upper)] for i in range(i_upper)])

这种方法的局限性:(a) 必须知道形成表达式时的符号数量; (b) 不能接受索引 ij 作为羔羊化函数的参数。

关于python - 如何在 sympy 中使用 Lambdify 和 IndexedBase 计算导数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52243320/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com