Hi,

there is a long discussion in the following two threads:

http://groups.google.com/group/sympy-patches/browse_thread/thread/83c33c0aa8560475/
http://groups.google.com/group/sympy-patches/browse_thread/thread/628ebc799ee57ec1

(don't forget to click next at the bottom of the page to get to the next pages).

First note, that our current .subs() is verstile enough to support
almost all kinds of syntax. For example:

In [1]: e = x**y+3*x+sin(y)

In [2]: e
Out[2]:
                y
3⋅x + sin(y) + x

In [3]: e.subs(x, z)
Out[3]:
                y
3⋅z + sin(y) + z

In [4]: e.subs({x: z})
Out[4]:
                y
3⋅z + sin(y) + z

In [5]: e.subs(dict(x=z))
Out[5]:
                y
3⋅z + sin(y) + z

In [6]: e.subs({x: 1, y: 2})
Out[6]: 4 + sin(2)

In [7]: e.subs(dict(x=1, y=2))
Out[7]: 4 + sin(2)


However, it may be useful to allow f(x=1, y=2) directly instead of the
equivalent e.subs(dict(x=1, y=2)).
There are pros and cons of each approach, so let me summarize it:

1) do not allow the e(x=1) syntax, i.e. raise an exception in e.__call__

this doesn't cause any problems

2) implement e.__call__ along these lines:

def __call__(self, *args, **kwargs):
    return self.subs(kwargs)

so now e(x=1, y=2) will be possible. A huge disadvantage is that the
following code will fail:

x = Symbol("a")
f = x*y

f(x=3)

This is because .subs() will try to substitute for Symbol("x"), but
there is no Symbol("x") in the expression, only Symbol("a").

Another problem is that what if your Symbol contains characters that
cannot be in a Python variable, like "\", "-", ..., then it will not
work.

3) implement e.__call__ along these lines (nice trick by Riccardo):

    def __call__(self, *args, **kwargs):
        import inspect
        frame = inspect.currentframe().f_back.f_globals
        nkwargs = {}
        try:
            for k, v in kwargs.iteritems():
                nkwargs[eval(k, frame)] = v
        finally:
            del frame
        return self._subs_dict(nkwargs)

In [1]: t = Symbol("theta")

In [2]: f = x+t**2

In [3]: f(x=10,t=3)
Out[3]: 19

Now it correctly finds the right variable to substitute for. However,
I and Brian don't like this, because playing with frames is a messy
stuff.


Read also the threads for more opinions. For comparison, here is what Sage does:

sage: t = var("theta")
sage: t
theta
sage: f = x+t**2
sage: f(x=10,t=3)
theta^2 + 10


So Sage chose the option 2).

So which option should we choose?

Ondrej

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to