This has been helpful. Thanks all. On Mon, Jun 6, 2011 at 8:26 PM, Aaron Meurer <[email protected]> wrote:
> 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. > > -- 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.
