I have just been playing with sympy, and I find that the feeling of the
library is still a bit clunky, compared to maple.
For instance if I want to define a function as a solution of an equation,
using sympy to solve the equation symbolicaly, but afterwards doing
numerical work with the solution, I have to do something like:
++++++++++++++++++++++++++++++++++++++
from sympy import solve, Symbol
x = Symbol('x')
y = Symbol('y')
f = solve(x+y+1, x) # f gives you the symbolic result
F = lambda v: f.subs(y, v)
++++++++++++++++++++++++++++++++++++++
The last line feels clunky. I understand why it is there, but let my
propose a synthax the I think is easier on the user. For this let me give
some code, demoing this syntax (by monky patching sympy, I hope you do
not mind):
++++++++++++++++++++++++++++++++++++++
# Do the monky patching
from sympy.core.basic import Basic
from sympy import Symbol
def func_call(self, **substitutions):
replacement = {}
for key, value in substitutions.iteritems():
replacement[Symbol(key)] = value
return self.subs_dict(replacement)
Basic.__call__ = func_call
# And now the
from sympy import solve, Symbol
x = Symbol('x')
y = Symbol('y')
f = solve(x+y, x)
F = lamdba y: f(y=y)
++++++++++++++++++++++++++++++++++++++
So the subs has been been replaced by a call to the expression. Of course
the exat same process are going on in both cases, but I think the second
option is easier on the beginner. Moreover, with the second option I
would not feel the need to define a lambda in most cases, as the syntax
is light-enough for me.
This trick of using keyword arguments to do the sustitution could also be
added to eval, evalf and evalc, making for a nicer syntax.
What do you think ?
Cheers,
Gaël
SymPy has a function Lambda that you should be able to use like this:
F = Lambda(f[0], y)
F(3)
It doesn't seem to work with my copy of SymPy; not sure why. It does
work in the sympycore (http://code.google.com/p/sympycore/) branch,
though there the syntax has been changed to
F = Lambda(y, expr)
to match the argument order of Python's lambda.
Fredrik
> SymPy has a function Lambda that you should be able to use like this:
> F = Lambda(f[0], y)
> F(3)
Ah, OK, I was looking for something like this, but managed to miss it.
That does look good.
Cheers,
Gaël
Hi Gael,
as Fredrik said, you can use Lambda. It's true that those things are
currently a little broken in SymPy, since it's a new feature. Those
implemented in sympycore should now be ported back to SymPy.
However, the general idea of using keywords for things like
.subs(x=y), or limit(sin(x)/x, x=0), is not bad, but I personally find
it confusing and unpythonic. I, speaking for myself, prefer to use
limit(sin(x)/x, x, 0), or .subs(x, y). But maybe there is a
solution, using a method similar to that you just shown, to actually
allow both possibilities.
Ondrej
On Wed, Nov 07, 2007 at 03:50:51PM +0100, Ondrej Certik wrote:
> However, the general idea of using keywords for things like
> .subs(x=y), or limit(sin(x)/x, x=0), is not bad, but I personally find
> it confusing and unpythonic. I, speaking for myself, prefer to use
> limit(sin(x)/x, x, 0), or .subs(x, y). But maybe there is a
> solution, using a method similar to that you just shown, to actually
> allow both possibilities.
I definitely like the syntax I proposed because, althought it is a bit
unpythonic, "f(x=1, y=2)" looks a lot like the kind of things you are going
to write on a blackboard.
I thing the Lambda is pretty good from a language design point of view, I
just don't expect somebody not into computers to guess what it means easy
(experience has shown that the "lambda" in Python confuses my physicists
colleagues).
Gaël
(exp(1+x)).subs(1+x,y) -> exp(y)
So, the `x=y` usage can only be optional.
Btw, we have subs_dict method that can be
used to get `x=y` effect, though, much more
in verbose way:
(exp(1+x).subs_dict(dict(x=y)))
Pearu
Yes.
It's the consequence of the fact, that subs(x=y) is unpythonic and
thus doesn't always work.
That's why I prefer to stick to Python way of doing things when possible.
Ondrej