Yep.  Except you should just add the behavior to Function, so that it
does it for all subclasses.

Aaron Meurer

On Mon, Jun 6, 2011 at 8:32 PM, Matthew Rocklin <[email protected]> wrote:
> 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?
>
> 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 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?
>> >
>> > 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
>> [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