I think the real question here is, do we want most functions in sympy
to automatically vectorize over matrices (or similar objects)?  And I
think the answer is no.  Consider for example if we had an unevaluated
Matrix type that didn't multiply through by default (what
ImmutableMatrix used to be).  We might want something like
simplify(A*B + A*C) to give A*(B + C), where A, B, and C are all
explicit unevaluated matrices.

It's similar to the reason that solve() does not automatically call
dsolve() on ODEs.  It's useful to be able solve for the function
algebraically, i.e., both

>>> dsolve(f(x).diff(x, x) + f(x) - 1, f(x))
f(x) == C1*sin(x) + C2*cos(x) + 1

and

>>> solve(f(x).diff(x, x) + f(x) - 1, f(x))
[-Derivative(f(x), x, x) + 1]

can be useful.

Another good argument for matrices is exp().  We want exp(Matrix) to
give the exponential of a Matrix, which is not the matrix of
exponentials. And actually you can define f(Matrix) for any analytic
f.  Won't it be a little confusing if math_function(Matrix) works
different from simplify_function(Matrix)?  And again, what if you have
simplify_function(combination_of_math_functions(unevaluated_matrices))?

And aside from that, automatic vectorization would be a mess, because
only the most popular functions would support it, and the rest
wouldn't.  So we would end up with a situation where function `a`
works as expected, but very similar function `b` doesn't, and it's not
clear why (and even if `b` doesn't support it, it doesn't mean that
Matrix defines `_b`).  It's similar to automatic sympification of
strings that some but not all SymPy functions support.

Aaron Meurer

On Mon, Oct 15, 2012 at 1:42 PM, Matthew Rocklin <[email protected]> wrote:
>
>
> On Mon, Oct 15, 2012 at 2:16 PM, Julien Rioux <[email protected]>
> wrote:
>>
>> Hi,
>>
>> I certainly think I should be able to simplify(m) for m a matrix type. As
>> I use sympy I expect that all objects interact together naturally. I should
>> be able to combine objects (as long as they make mathematical sense) and be
>> able to use the same functions on all objects.
>
> This is a good ideal. Unfortunately most of the Expr code was written to
> only work with scalars. I.e. people often use 0 when they mean "additive
> identity" (I use this example a lot, please forgive me). I don't think that
> incremental bug fixes will solve this problem.
>
>> It used to be that simplify wasn't built to deal very well with
>> noncommutative symbols, so e.g. simplify(A*B - B*A) would return 0. Those
>> were considered bugs and were eventually fixed. I think the same approach
>> should be taken about simplifying matrices, any issue should be considered a
>> bug and fixed.
>>
>> I stopped using Matrix and have since used ImmutableMatrix because I could
>> use most regular sympy functions on it. By the way, I wish I could do
>> factor(m), too. Although it doesn't do anything useful at the moment, we
>> should improve upon it.
>
> I think that the easiest way to improve upon it is to have factor call
> ImmutableMatrix._factor. Trying to make one giant function to do factoring
> for all classes sounds difficult to me. It's hard to write a single function
> that factors all sorts of things.
>
>> I think the inheritance on Expr ensures that a lot of functions such as
>> simplify will work (possibly for free) or at least they won't error out.
>
> This is not my experience. It is very easy to stress the system and get into
> very weird states; or at least it was until I monkey patched some things.
> Now it is only moderately easy :) In these cases I would rather error out at
> a higher level than at a very low level. My experience is that the
> MatrixExpr(Expr) inheritance is very hard to reason about and has high
> potential for bugs. I've duct-taped things together so that they appear to
> usually work. It's very hard to develop new functionality with this though.
> I always end up running into Expr trouble. MatrixExpr can't grow effectively
> and will have many more bugs while it is still connected to Expr.
>
>> It doesn't bother me too much how it's implemented as long as it's not
>> overly complicated and it works.
> I think the easiest way to make it work is to remove the Expr dependence and
> use classes for polymorphism (i.e. put `if hasattr(expr, '_simplify'):
> return expr._simplify()` in the publicly visible simplify funciton. )
>
> --
> 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