2

我正在尝试用 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' 未包含在 'modules' 列表中,它会简单地跳过所有其他功能。我也尝试在列表中交换 dict 和 'numpy',但没有帮助。请澄清一下,怎么了?这是同情的错误吗?

4

3 回答 3

2

lambdify用于创建旨在进行矢量化工作的 numpy 函数时,通常会出现一些微妙的问题,尤其是当变量 ( x) 和常量 ( 0) 混合在一起时。

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

我的解决方法是sp.max用基于sp.Piecewise. 请注意,如果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]
于 2020-03-17T15:18:00.690 回答
0

在 SymPy 的当前版本中,我得到return (sin(x) + amax((0,x), axis=0))了签名。这是你想要的吗?

于 2020-03-17T14:28:02.177 回答
0

要使用np.maximum函数而不是np.amax,我发现指定amax方法而不是Max工作。该np.maximum函数还需要进行一些调整,以接收用于该amax函数的参数。

import numpy as np
import sympy as sp

arr = np.array([11, 22, 33, -1, -2])
expr = sp.sin(x) + sp.Max(x, 0)
def custom_amax(x,**kwargs): 
    return np.maximum(x[0],x[1])
f = sp.lambdify(x, expr, modules=[{'amax': custom_amax}, 'numpy']) 
f(arr) # [10.00000979, 21.99114869, 33.99991186, -0.84147098, -0.90929743]
于 2021-02-17T21:43:30.043 回答