Search code examples
pythontypeerrorsympylambdify

pure sympy: "loop of ufunc does not support argument 0 of type Mul which has no callable log method"


I am confused by sympy. First some setup. I entered the following into a python console

>>> import sympy as smp
>>> x, y = smp.symbols('x y', real=True)
>>> f = smp.log(x) + y

followed by

>>> smp.lambdify(x, f)(1)
y

which makes sense to me.

Then I went on to enter

>>> smp.lambdify(y, f)(1)
AttributeError: 'Symbol' object has no attribute 'log'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "\<stdin\>", line 1, in \<module\>
File "\<lambdifygenerated-9\>", line 2, in \_lambdifygenerated
TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable log method

I did not think much of it, because it is plausible to me that just entering 1 can break things. But then

>>> smp.lambdify(y, f)(smp.sympify(1))
AttributeError: 'Symbol' object has no attribute 'log'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "\<stdin\>", line 1, in \<module\>
File "\<lambdifygenerated-10\>", line 2, in \_lambdifygenerated
TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable log method

and now I am confused over why not evaluating the logarithm breaks things. I will have a good time for the next few days if I can successfully evaluate y at a number of my choosing and get a sympy object again, so advice from someone who resolved this / found an alternative way of achieving my goal would be much appreciated!


Solution

  • lambdify is mainly used to retrieve numerical data. Essentially, that error is telling you that you should always lambdify your expressions by specifying the appropriate amount of free symbols. So, your expressions contains two symbols, x, y, and you should generate a numerical function using both symbols: nf = lambdify([x, y], f), and then evaluate it as nf(x, 0). This, again will raise an error, because you asked lambdify to generate a numerical function to be evaluated with Numpy, which doesn't support symbolic objects, like x. One way to solve it is to request lambdify to use SymPy as the evaluation module: nf = lambdify([x, y], f, modules="sympy"), and then evaluate it as nf(x, 1) to get log(x) + 1.

    But, if you just want to get back a symbolic expression, then lambdify is overkill. Just substitute the numerical values into your symbolic expression. For example:

    f.subs(y, 1)
    # out: log(x) + 1