小能豆

如何使用 sympy.lambdify 和 Max 函数来替代 numpy.maximum 而不是 numpy.amax?

py

我正在尝试使用 sp.Max(x, 0) 对大型解析表达式进行 lambdify。我想使用 numpy 来矢量化我的计算,因此 x 将是一个数组。我需要 x 和 0 的元素最大值。不过,sympy 默认将 sp.Max 更改为 np.amax。它沿轴找到最大值,这不是我需要的。lambdify 中的“modules”关键字无法按预期工作。我试过:

import numpy as np
import sympy as sp

arr = np.array([1, 2, 3])
expr = sp.sin(x) + sp.Max(x, 0)
f = sp.lambdify(x, expr, modules=[{'Max': np.maximum}, 'numpy'])  # docs say, priority of modules matters
help(f)

它给出:

Help on function _lambdifygenerated:
_lambdifygenerated(x)
    Created with lambdify. Signature:

    func(x)

    Expression:

    sin(x) + Max(0, x)

    Source code:

    def _lambdifygenerated(x):
        return (sin(x) + amax((0,x)))


    Imported modules:

由于某种原因,sp.Max 更改为 amax。

如果“numpy”未包含在“模块”列表中,它将跳过所有其他函数。我也尝试过在列表中交换 dict 和“numpy”,但没有帮助。请澄清一下,出了什么问题?这是 sympy 中的错误吗?


阅读 7

收藏
2024-12-23

共1个答案

小能豆

当使用lambdify创建用于矢量化的 numpy 函数时,经常会出现一些细微的问题,尤其是当变量(x)和常量(0)混合在一起时。

在这种情况下,sp.max假设其所有可能的参数都是单个值。np.amax获取一个扁平数组的最大值。np.maximum获取两个数组的元素最大值。这里的问题是常量0不会自动扩展为 numpy 数组。

我的解决方法是sp.max使用基于的自定义函数进行替换sp.Piecewise。请注意,如果 有超过 2 个参数,则需要一个单独的函数sp.max

import numpy as np
import sympy as sp
from sympy.abc import x

def sympy_max2(a, b):
    return sp.Piecewise((b, a < b), (a, True))

arr = np.array([11, 22, 33, -1, -2])
expr = sp.sin(x) + sympy_max2(0, x)
f = sp.lambdify(x, expr, modules=['numpy'])

print(f(arr)) # [10.00000979 21.99114869 33.99991186 -0.84147098 -0.90929743]
2024-12-23