2

I'd like to create a sympy expression that lambdify's to numpy.maximum(). How can I do this? Attempt:

import numpy as np
import sympy
x = sympy.Symbol('x')
expr = sympy.Max(2, x)
f = sympy.lambdify(x, expr)
f(np.arange(5))

This leads to:

ValueError: setting an array element with a sequence.

Looks like a sympy.Maximum() analogy to np.maximum() was proposed in sympy issue 11027 but never implemented.

A clunky workaround:

maximum = sympy.Function('maximum')
expr2 = maximum(2, x)
f2 = lambda c: sympy.lambdify((maximum, x), expr2)(np.maximum, c)
f2(np.arange(5))

But I'd really prefer an expression that directly lambdify's to what I want.

dshin
  • 2,354
  • 19
  • 29
  • Have you tried the `numpy` parameter in the `lambdify` call? https://stackoverflow.com/questions/41315237/lambdifyed-expression-raises-typeerror-when-used-with-arrays-if-the-expression/41316842#41316842 – hpaulj Aug 01 '17 at 18:33
  • @hpaulj How would I tell `sympy` to match `sympy.Max` with `np.maximum`? – dshin Aug 01 '17 at 18:36
  • So looking more at the error message, it appears that `sympy.Max` translates to `numpy.amax`. `np.maximum` on the other hand is a `ufunc`, designed to work with 2 arrays. – hpaulj Aug 01 '17 at 19:52
  • Yes, the link I provided gives some details. – dshin Aug 01 '17 at 19:53
  • The example you gave is more like [numpy.clip](https://docs.scipy.org/doc/numpy/reference/generated/numpy.clip.html) because an array is being compared with a scalar. Is this the goal? –  Aug 01 '17 at 19:59
  • @Alex Thanks, never knew clip existed, that is in fact what I want. – dshin Aug 01 '17 at 20:09

1 Answers1

2

The maximum of two numbers x, y is the same as (x+y+abs(x-y))/2. And abs lambdifies easily:

expr = (x + 2 + sympy.Abs(x-2))/2
f = sympy.lambdify(x, expr)
f(np.arange(5))  # prints [ 2.  2.  2.  3.  4.]
  • Actually, this doesn't work so well after all. I ultimately need to convert the expr into optimized c++ code, and it is difficult to automatically identify that the `sympy.Expr` generated by your trick can be transformed into a c++ `max()` call. – dshin Aug 02 '17 at 20:45
  • Then I don't know why you asked about `lambdify`, as [SymPy code generation](http://docs.sympy.org/latest/modules/utilities/codegen.html) works with a SymPy expression, not with a lambda. I suggest asking a new question specifically about C code generation. –  Aug 02 '17 at 21:28
  • I need the sympy expression for two distinct purposes: to evaluate in-python on numpy arrays, and also to convert into custom c++ code by traversing the expression tree. – dshin Aug 04 '17 at 16:04