Since there have been many discussions on this - can I just say thankyou for writing such a detailed answer.
I initially tried the third recommendation which worked a treat - except for when it came to printing. It would always print out noevalsin instead of sin. So I tried the first way you mentioned. Though it is a lengthy expression, it does things exactly how I want it to: self.derivative.replace(sympy.sin(a), sympy.sin(self.x_value, evaluate=False)).replace(sympy.cos(a), sympy.cos(self.x_value, evaluate=False)) PERFECT. I imagine there would be some way to modify noevalsin so that it prints as sin, but alas I am but a simple noob at object-oriented in Python. Thankyou!!! On Saturday, 1 June 2013 14:08:53 UTC+10, 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.
