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.


Reply via email to