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.

Reply via email to