SymPy error running Python3

240 views
Skip to first unread message

Janwillem van Dijk

unread,
Jan 7, 2014, 5:04:30 AM1/7/14
to sy...@googlegroups.com
I have a SymPy script with a.o.

f_mean = lambdify([mu, sigma], mean, modules='numpy')


where mean is a function of mu and sigma and mu and sigma are both arrays

mu = symbols('mu_0:%d' % n, real=True, bounded=True)

sigma = symbols('sigma_0:%d' % n, positive=True, real=True, bounded=True)


Under Python 2.7.5+ SymPy 0.12.0 I can use:

y = f_mean(x_n, ux_n)

returning y as a numpy array of size n when x_n and ux_n are both numpy arrays of size n.

However, with Python 3.3.2+ and SymPy 0.7.4.1-git I get (for n=5):

y = f_mean(x_n, ux_n)
TypeError: <lambda>() missing 10 required positional arguments: 'mu_2', 'mu_3', 'mu_4', 'mu_5', 'sigma_0', 'sigma_1', 'sigma_2', 'sigma_3', 'sigma_4', and 'sigma_5'


Which is similar to what I got in Python 2.7 before I added the modules=numpy argument

All this on ubuntu 13.10


Have I missed something in the docs or did I stumble on a not yet implemented feature?

Any help very welcome.heers,

Cheers, Janwillem


Ondřej Čertík

unread,
Jan 7, 2014, 1:58:48 PM1/7/14
to sympy
Hi Janwillem,
Would you mind sending the whole script? So that I can debug it.
You can post it here for example: https://gist.github.com/

Ondrej

Aaron Meurer

unread,
Jan 7, 2014, 2:02:51 PM1/7/14
to sy...@googlegroups.com
I'm not sure if lambdify supports nested arguments like this. You may need to do

lambdify(mu + sigma, mean)

and then call it like

f_mean(*(x_n + ux_n))

If it is supposed to support that then it's a bug and we should fix
it. If it only doesn't work in Python 3 it may be related to the def
f((x, y)) syntax not being supported any more.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> For more options, visit https://groups.google.com/groups/opt_out.

Janwillem van Dijk

unread,
Jan 11, 2014, 2:49:16 AM1/11/14
to sy...@googlegroups.com
Ondřej, I did send you my complete 900 lines scripts to show the problem and did not think of making a very simple demo; here it is:


import sympy

import numpy

n = 2

formula = 'x_0 + x_1'

x = sympy.symbols('x_0:%d' % n, real=True, bounded=True)

y = sympy.sympify(formula)

fx = f_x = sympy.lambdify([x], y, modules='numpy')

X = numpy.ones(n)

print('function value=', fx(X))


Python 2.7 returns: 

('function value=', 2.0)

which is obviously the correct answer.


Python 3.3 returns:

    print('function value=', fx(X))

TypeError: <lambda>() missing 1 required positional argument: 'x_1'


Hope this helps to clearify the point.
Cheers, Janwillem

Aaron Meurer

unread,
Jan 11, 2014, 3:06:43 PM1/11/14
to sy...@googlegroups.com
On Sat, Jan 11, 2014 at 1:49 AM, Janwillem van Dijk
<jwe.va...@gmail.com> wrote:
> Ondřej, I did send you my complete 900 lines scripts to show the problem and
> did not think of making a very simple demo; here it is:

But it doesn't help the rest of us if you only send your script to Ondrej.

>
>
> import sympy
>
> import numpy
>
> n = 2
>
> formula = 'x_0 + x_1'
>
> x = sympy.symbols('x_0:%d' % n, real=True, bounded=True)
>
> y = sympy.sympify(formula)
>
> fx = f_x = sympy.lambdify([x], y, modules='numpy')
>
> X = numpy.ones(n)
>
> print('function value=', fx(X))
>
>
> Python 2.7 returns:
>
> ('function value=', 2.0)
>
> which is obviously the correct answer.
>
>
> Python 3.3 returns:
>
> print('function value=', fx(X))
>
> TypeError: <lambda>() missing 1 required positional argument: 'x_1'
>
>
> Hope this helps to clearify the point.
> Cheers, Janwillem

I get a TypeError in both. In Python 3 I get the same error as you,
and in Python 2 I get TypeError: <lambda>() takes exactly 2 arguments
(1 given).

If you use fx(*X), it works on both platforms.

Aaron Meurer

>
>
>
> On Tuesday, 7 January 2014 11:04:30 UTC+1, Janwillem van Dijk wrote:
>>
>> I have a SymPy script with a.o.
>>
>> f_mean = lambdify([mu, sigma], mean, modules='numpy')
>>
>>
>> where mean is a function of mu and sigma and mu and sigma are both arrays
>>
>> mu = symbols('mu_0:%d' % n, real=True, bounded=True)
>>
>> sigma = symbols('sigma_0:%d' % n, positive=True, real=True, bounded=True)
>>
>>
>> Under Python 2.7.5+ SymPy 0.12.0 I can use:
>>
>> y = f_mean(x_n, ux_n)
>>
>> returning y as a numpy array of size n when x_n and ux_n are both numpy
>> arrays of size n.
>>
>> However, with Python 3.3.2+ and SymPy 0.7.4.1-git I get (for n=5):
>>
>> y = f_mean(x_n, ux_n)
>> TypeError: <lambda>() missing 10 required positional arguments: 'mu_2',
>> 'mu_3', 'mu_4', 'mu_5', 'sigma_0', 'sigma_1', 'sigma_2', 'sigma_3',
>> 'sigma_4', and 'sigma_5'
>>
>>
>> Which is similar to what I got in Python 2.7 before I added the
>> modules=numpy argument
>>
>> All this on ubuntu 13.10
>>
>>
>> Have I missed something in the docs or did I stumble on a not yet
>> implemented feature?
>>
>> Any help very welcome.heers,
>>
>> Cheers, Janwillem
>>
>>

Janwillem van Dijk

unread,
Jan 12, 2014, 4:11:53 PM1/12/14
to sy...@googlegroups.com
Thanks for the comments.
You are right, that works. So that example was my lengthy scripts too far simplified. In my actual program the functions have two arrays as input (expectation and standard uncertainty in a measurement model) and than the * does not work anymore. I understood from the docs that the modules='numpy' option was meant to make this work and that is what I experienced a year or so ago working with 2.7. So here is a modified example that still works in 2.7 but not with me on 3.3:

import sympy

import numpy

n = 2

x = sympy.symbols('x_0:%d' % n, real=True, bounded=True)

formula = 'x_0 + x_1'

y = sympy.sympify(formula)

fx = f_x = sympy.lambdify(x, y, modules='numpy')

X = numpy.ones(n)

print('function value=', fx(*X))  # works on both pythons


a = sympy.symbols('a_0:%d' % n, real=True, bounded=True)

formula = 'a_0 * x_0 + a_1 * x_1'

y = sympy.sympify(formula)

fx = f_x = sympy.lambdify([x, a], y, modules='numpy')

a = numpy.linspace(0.5, 1.0, n)

print('function value=', fx(*[X, a]))  # does not work on 3.3


gives with 3.3

print('function value=', fx(*[X, a]))

TypeError: <lambda>() missing 2 required positional arguments: 'a_0' and 'a_1'


and the same for a variation without *

print('function value=', fx(X, a))
TypeError: <lambda>() missing 2 required positional arguments: 'a_0' and 'a_1'

So still all help and explanations welcome!
Cheers, Janwillem


On Tuesday, 7 January 2014 11:04:30 UTC+1, Janwillem van Dijk wrote:

Aaron Meurer

unread,
Jan 12, 2014, 5:04:42 PM1/12/14
to sy...@googlegroups.com
Your code still doesn't work for me in Python 2 either.

But the point has been received. This sort of thing (nested arguments)
should probably work.

You need to understand what the * does. It denestst the list into
arguments, so that

f(*[1, 2, 3])

is the same as

f(1, 2, 3)

You are basically calling the function as

f([1, 1], [0.5, 1])

in the version with the *, and as

f([[1, 1], [0.5, 1]])

in the version without. But it expects

f(1, 1, 0.5, 1)

I'm not sure what the best way to concatenate two numpy arrays is, but
the following does work:

fx(*(list(X) + list(a)))

(because + on lists concatenates).

Aaron Meurer

Jason Moore

unread,
Jan 12, 2014, 5:08:55 PM1/12/14
to sy...@googlegroups.com
numpy.hstack and numpy.vstack are typically used for concatenation of numpy arrays. I typically use it and the * for passing lots of args into lambdify.

Aaron Meurer

unread,
Jan 12, 2014, 6:23:42 PM1/12/14
to sy...@googlegroups.com
I still think we should fix this so that it just works out of the box.
Squashing everything into one array is more complicated than it needs
to be.

Aaron Meurer

Janwillem van Dijk

unread,
Jan 13, 2014, 3:28:57 AM1/13/14
to sy...@googlegroups.com
I would be very glad if that could be done. My little project is part of a discussion on uncertainty evaluation in radiation dose measurements. I try to convince my colleagues that the traditional method developed by Gauss in 1800 is not reliable in our field. The method of choice is Monte Carlo integration. So I want a script where the traditional (called LPU) functions look as much as possible to the Monte Carlo method (MCM) functions as possible. When starting this project I also tried the *-way but thought it ugly and not very convincing when comparing it with the numpy/scipy based MCM (and old people like me reminds it of pointers and crashing computers). So I was very glad discovering the numpy option in lambdify which worked as I understood it would. So again I would be very pleased to see it working with 3.3.
For your info please find the problem scripts and some background in the attached archive (comments very welcome).
Cheers, Janwillem

On Tuesday, 7 January 2014 11:04:30 UTC+1, Janwillem van Dijk wrote:
sympy_issues.tar.gz

Janwillem van Dijk

unread,
Jan 13, 2014, 10:58:15 AM1/13/14
to sy...@googlegroups.com
To add to the * solution discussion:
In the past I had hidden the * by defining something like

_f_x = sympy.lambdify([x, a], y)

def f_x(x, a):

    return _f_x(*numpy.hstack([x, a]))


This works on Python3.3 but now I get on Python2.7:

Traceback (most recent call last):

  File "sympy-numpy_2.py", line 39, in <module>

    print('function value=', f_x(X, a))

  File "sympy-numpy_2.py", line 36, in f_x

    return _f_x(*numpy.hstack([x, a]))

TypeError: <lambda>() takes exactly 2 arguments (4 given)


Whereas I seem to remember that this used to work with 2.7

By the way, my environment
linux:   Linux-3.11.0-12-generic-x86_64-with-Ubuntu-13.10-saucy
python:  3.3.2+ (default, Oct  9 2013, 14:50:09) [GCC 4.8.1]
sympy:   0.7.4.1-git
numpy:   1.7.1
or
python:  2.7.5+ (default, Sep 19 2013, 13:48:49) [GCC 4.8.1]

On Tuesday, 7 January 2014 11:04:30 UTC+1, Janwillem van Dijk wrote:

Ondřej Čertík

unread,
Jan 13, 2014, 11:56:22 AM1/13/14
to sympy
Janwillem, thanks for sending the script to the list.
That's the most efficient way to get things done.

Ondrej

Aaron Meurer

unread,
Jan 17, 2014, 7:08:02 PM1/17/14
to sy...@googlegroups.com
I opened https://github.com/sympy/sympy/issues/2790 for this issue so
it's not forgotten about. Let us know if you want to give it a shot
fixing it.

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages