Sympy中如何将表达式内2D IndexedBase变量替换为numpy数组
实现方案
首先明确结论:无法直接使用sympy.subs()或sympy.evalf(subs=)方法完成IndexedBase到NumPy数组的替换计算。SymPy的符号替换逻辑仅支持符号对象之间的映射,无法自动识别NumPy数组结构、完成索引匹配与广播计算,你可以使用sympy.lambdify()工具将符号表达式编译为支持NumPy数组输入的可调用函数实现需求。
完整实现代码示例
import sympy as sp import numpy as np # 定义符号与表达式(和你的示例一致) i, j, m, n = sp.symbols('i j m n', integer=True) x = sp.IndexedBase('x') a = sp.IndexedBase('a') b = sp.IndexedBase('b') f = sp.ln(sp.Sum(sp.exp(sp.Sum(a[i, j]*x[j]+b[i], (j, 1, n))), (i, 1, m))) # 将符号表达式编译为支持NumPy输入的可调用函数 f_np = sp.lambdify((a, b, x, m, n), f, modules="numpy") # 定义常量、生成测试数组 MIN = 0 MAX = 1 M = 3 N = 2 A = np.random.uniform(MIN, MAX, (M+1, N+1)) # 补第0位适配SymPy 1起始索引 B = np.random.uniform(MIN, MAX, M+1) x_val = np.array([0, 1, 5]) # 补第0位,x[1]=1、x[2]=5 # 调用函数计算结果 result = f_np(A, B, x_val, M, N) print(result)
注意事项
- SymPy的
IndexedBase默认从1开始索引,而NumPy数组默认从0开始索引,所以上面的示例中对数组做了补位处理,如果你想直接用原生0起始的NumPy数组,可以把求和式的上下界修改为(j, 0, n-1)、(i, 0, m-1),不需要额外补位。 lambdify的modules参数指定为numpy,会自动把SymPy的Sum、exp、ln等操作映射为NumPy对应的向量化操作,计算效率远高于逐点符号计算。
内容的提问来源于stack exchange,提问作者Ian Roberts
相关产品推荐
相关产品推荐

