Is there some reason not to do this? (except for the way it prints)
hold = Function("Hold")
def release(expr):
return expr.replace(hold, Id)
print sin(pi), sin(hold(pi)), release(sin(hold(pi)))
:L
On Saturday, 1 June 2013 05:08:53 UTC+1, Aaron Meurer wrote:
>
> There have been many discussions on this sort of thing. There is a
> semi-standard way to do things by passing evaluate=False, like
>
> In [6]: sin(pi, evaluate=False)
> Out[6]: sin(π)
>
> Not all SymPy classes support this though, and it's not easy to use it
> with things like xreplace.
>
> Another way is to bypass the constructor of the class, like
>
> In [7]: Basic.__new__(sin, pi)
> Out[7]: sin(π)
>
> You can write an algorithm that walks the expression tree and replaces
> sin(x) with Basic.__new__(sin, pi) farily easily.
>
> But probably the best way is to just subclass sin and disable evaluation
>
> In [1]: class noevalsin(sin):
> ...: @classmethod
> ...: def eval(cls, arg):
> ...: return
> ...:
>
> In [2]: noevalsin(pi)
> Out[2]: noevalsin(π)
>
> In [4]: noevalsin(x).diff(x)
> Out[4]: cos(x)
>
> (the diff shows that it does indeed act like sin otherwise). You can
> change the printing by adding some more methods to the class.
>
> You can then use replace to replace instances of sin with noevalsin
>
> In [8]: sin(x).replace(sin, noevalsin)
> Out[8]: noevalsin(x)
>
> In [9]: sin(x).replace(sin, noevalsin).subs(x, pi)
> Out[9]: noevalsin(π)
>
> This third option is better because any function that rebuilds the
> object will keep it as it is. With the other two, the rebuilding will
> do sin(pi) and it will go to 0. With this, the rebuild will do
> noevalsin(pi) and it will stay unevaluated.
>
> You could also abstract this logic into a helper function (or class or
> metaclass).
>
> One issue with all of these is that many algorithms come to rely on
> the invariants satisfied by the classes---in this case, that sin(pi)
> is never an object---and so they might fail on such expressions. An
> easy way to check this is to disable it in the SymPy source and run
> the tests.
>
> Finally, we often don't use best practices so that classes are
> subclassable (see
> https://code.google.com/p/sympy/issues/detail?id=3652). If you come
> across something that converts noevalsin back into regular sin, that's
> probably a bug, or it might mean that you need to define more methods
> on the class. For example, noevalsin(x).diff(x, x) will be -sin(x),
> not -noevalsin(x), because cos(x).diff(x) remains unchanged.
>
> Aaron Meurer
>
> On Fri, May 31, 2013 at 8:31 PM, Ben Lucato <[email protected]<javascript:>>
> wrote:
> > So in my ever growing quest to work with sympy, I have expressions like:
> >
> > y = 2*(x*sin(x) - sin(x) + cos(x))/cos(x)**2
> >
> > with x values like pi/6
> >
> > How do I substitute x into y without having evaluate automatically
> happen.
> >
> > i.e. I would like to be able to do something like:
> >
> > y.xreplace({x: pi/6})
> >>>> 2*((pi/6)*sin(pi/6) - sin(pi/6) + cos(pi/6))/cos(pi/6)**2
> >
> >
> > It doesn't need to be with xreplace, that's just what I've used here for
> > explaining my goal.
> >
> > Thanks!
> >
> > --
> > 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 [email protected] <javascript:>.
> > To post to this group, send email to [email protected]<javascript:>.
>
> > Visit this group at http://groups.google.com/group/sympy?hl=en-US.
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> >
>
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.