On Mon, Jun 6, 2011 at 9:20 PM, Ronan Lamy <[email protected]> wrote: > Le lundi 06 juin 2011 à 19:32 -0700, Matthew Rocklin a écrit : >> So in each elementary SymPy function, call it foo, under the eval >> method I could add a test to see if the argument has an attribute, >> _eval_foo and if so call it? > > That doesn't sound like a good idea, there are just too many functions > for this to be practical. The object should have only one method, acting > like some kind of __rcall__, i.e. foo(X) calls X.__rcall__(foo). > > The method could perhaps just return a wrapper around the ordinary, not > random-aware, version of foo(X). The wrapper would handle the random > stuff and let foo handle the function stuff. >> >> On Mon, Jun 6, 2011 at 7:09 PM, Aaron Meurer <[email protected]> >> wrote: >> On Mon, Jun 6, 2011 at 7:19 PM, Matthew Rocklin >> <[email protected]> wrote: >> >> > In an ideal world the operand (in this case the random >> variable X) would >> >> > be >> >> > able to take control. This is the case for some functions >> like abs which >> >> > just call the object’s __abs__ method. I can’t find any >> evidence that >> >> > this >> >> > is possible generally in the Python language although I’d >> be thrilled to >> >> > find that I was incorrect. >> >> >> >> I'm not sure what you mean by "in the Python language." >> For this to >> >> work, it would have to be implemented in SymPy. So, for >> example, you >> >> would have to make sin(x) call x._eval_sin() or something >> like that. >> >> Quite a few functions in SymPy, like diff(), already do >> have a design >> >> like this. You would mainly just have to add it to >> Function. >> > >> > When Python sees fn(var) it talks to fn first and doesn't >> talk to var. A fun >> > exception that I like are operators like __radd__ . When >> you call a+b it >> > first calls a.__add__(b). If that raises a >> NotImplementedError it then calls >> > b.__radd__(a). This is how Matrices allow for syntactically >> clean scalar >> > operations like 5*eye(3) regardless of which side of the >> operator the matrix >> > is on. This is the sort of behavior I would like. sin(X) >> currently throws an >> > error, It'd be cool if X could pick that up and take things >> over. I don't >> > think this is possible in Python though other than the >> operator case >> > discussed above. I brought this up hoping that someone would >> tell me I was >> > wrong. >> >> >> This is exactly what I'm suggesting with _eval_sin(). sin() >> is a >> SymPy function (actually, a class), so of course it can do >> whatever >> you want. >> >> Aaron Meurer >> >> >> >> >> >> > To achieve minimal disruption of the core I could always >> do something >> >> > like >> >> > X.applyfunc(sin) but this seems unpleasant to write. I >> think that >> >> > matrices >> >> > use this solution. Another thought is to have elementary >> sympy >> >> > functions >> >> > check for an applyfunc method of their arguments and, if >> it exists, to >> >> > use >> >> > it. This would solve my problem and possibly be useful >> generally. >> >> >> >> Another option would be to create your own sin() class, >> which would be >> >> a RandomVariable. I'm not entirely sure what sorts of >> things f(X) >> >> would do, where f is some SymPy function and X is a >> RandomVariable, so >> >> I can't really say what the best design is. For example, >> does it make >> >> sense to do f(X) for any function f or just certain ones >> (like sin())? >> >> Do you need sin(X) to act like sin(x) in any way (for >> example, should >> >> diff(sin(X), X) work)? These are the sorts of questions >> whose answers >> >> will show what the best design for you is. >> > >> > What needs to happen in the common case: >> > For a continuous random variable X, described by PDF, p(x), >> the random >> > variable Y = f(X) is described by the pdf >> > q(y) = p(f^-1(y)) * | d f^-1(y) / dy | >> > This is an annoying but purely symbolic operation that is >> often (but not >> > always) doable. This is what has to happen when you call Y = >> f(X) for simple >> > f. The function is effectively just passed into an >> expression contained >> > within X. If f is sufficiently complex so that this >> calculation fails then >> > I'll probably just keep things as expressions like sin(X) >> for later >> > sampling. > > I think that calling sin(X) should not compute the distribution. If you > do it only when it's explicitly requested, you'll avoid unnecessary > calculations (stupid example: covariance(Y, sin(cos(X) + exp(X))). There > are certainly many interesting things you can do without ever knowing > the symbolic form of the distribution, like Monte-Carlo integrals, ...
+1. I actually started writing up a wiki page on my thoughts on automatic simplification/evaluation. See https://github.com/sympy/sympy/wiki/automatic-simplification (short summary: automatic simplification/evaluation is usually a bad idea). In fact, you might be able to do this without modifying the functions like sin() at all, just by making X an Expr, and having functions that do your various simplification routines for you. Aaron Meurer > >> > I hadn't thought much about the other aspects of what SymPy >> functions can do >> > (like derivatives) and I'll need to chew on this for a >> while. If it's not >> > possible to evaluate sin(X) then the expression will stay >> something like >> > sin(X) (or some variant) just like how sin objects stick >> around now if the >> > argument doesn't support easy evaluation. Mainly I'm just >> trying to >> > make redirections of the evaluate part of sin (and all other >> sympy >> > functions) possible. >> > If I can do this from within the function then that's ideal >> (for me). If it >> > ends up being too invasive then I'll do something like what >> you suggest, >> > creating my own sin function or creating something that >> turns a general >> > function into a random-friendly function. >> > I'll probably end up making some general form of this anyway >> so that >> > non-SymPy user-defined functions can be decorated. An >> interesting case is >> > like writing the value of a random variable to file. This >> should be a >> > "random action" or some such thing. >> >> >> >> P.S., I vaguely remember discussing this, or something like >> this, >> >> already. Did we discuss this prior to your acceptance into >> GSoC? > > That kind of idea must have already come up in the context of quantum > physics, tensors or matrices. The problems are basically the same there. > >> > I've written this down a couple of times on various SymPy >> application/wiki >> > documents but I don't have any specific memory of discussing >> it with anyone >> > other than briefly with my mentor. My memory however is that >> of a five year >> > old's so this definitely could have happened. >> > >> >> >> > -- >> > 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. >> > >> >> -- >> 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 sympy >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/sympy?hl=en. >> >> >> >> >> >> -- >> 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 sympy >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/sympy?hl=en. > > > -- > 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. > > -- 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.
