On Mon, Jun 8, 2009 at 5:24 PM, Ben Goodrich<[email protected]> wrote:
>
> Can someone tell me if there is a subtle reason why the jacobian
> function in matrices.py is restricted to only work when the Jacobian
> is square?
>
> The example in the documentation is
>
> from sympy import symbols, sin, cos
> rho, phi = symbols("rho phi")
> X = Matrix([rho*cos(phi), rho*sin(phi)])
> Y = Matrix([rho, phi])
> X.jacobian(Y)
>
> which correctly yields the 2x2 matrix
>
>         [cos(phi), -rho*sin(phi)]
>         [sin(phi),  rho*cos(phi)]
>
> Suppose instead that
>
> X = Matrix([rho*cos(phi), rho*sin(phi), rho**2])
>
> I would hope that
>
> X.jacobian(Y)
>
> would now yield the 3x2 matrix
>
>        [cos(phi), -rho*sin(phi)]
>        [sin(phi),  rho*cos(phi)]
>        [   2*rho,             0]
>
> but the code is restricted to the square Jacobian case so it instead
> yields an assertion
>
> ---------------------------------------------------------------------------
> AssertionError                            Traceback (most recent call
> last)
>
> /usr/lib/pymodules/python2.5/sympy/matrices/<ipython console> in
> <module>()
>
> /usr/lib/pymodules/python2.5/sympy/matrices/matrices.pyc in jacobian
> (self, X)
>    943             assert X.shape[1] == n
>    944         else:
> --> 945             assert X.shape[0] == n
>    946
>    947         # n is the dimension of the matrix, computing the
> Jacobian is now easy:
>
> AssertionError:
>
> Would it break something I don't know about if the jacobian function
> handled the nonsquare case? It appears as if the following modified

This should definitely be fixed.

> function yields the behavior I expected in the 3x2 case without
> causing any tests to fail.
>
>        if not isinstance(X, Matrix):
>            X = Matrix(X)
>        # Both X and self can be a row or a column matrix, so we need
> to make
>        # sure all valid combinations work, but everything else fails:
>        assert len(self.shape) == 2
>        assert len(X.shape) == 2
>        if self.shape[0] == 1:
>            m = self.shape[1]
>        else:
>            m = self.shape[0]
>        if X.shape[0] == 1:
>            n = X.shape[1]
>        else:
>            n = X.shape[0]
>
>        # m is the number of functions and n is the number of
> variables
>        # computing the Jacobian is now easy:
>        return Matrix(m, n, lambda j, i: self[j].diff(X[i]))

Just run the tests, like:

$ bin/test sympy/matrices/
============================= test process starts ==============================
executable:   /usr/bin/python  (2.6.2-final-0)

sympy/matrices/tests/test_matrices.py[39] ......................................
.                                                                           [OK]

================== tests finished: 39 passed in 0.52 seconds ==================


As long as all tests pass, it's fine. Could you please send it as a
patch? Just follow the git howto here:

http://docs.sympy.org/sympy-patches-tutorial.html#quick-start

Make sure to also write tests for the new functionality too, just
create a new function at the end of
sympy/matrices/tests/test_matrices.py.

If you have any questions, just ask.

Thanks a lot,
Ondrej

--~--~---------~--~----~------------~-------~--~----~
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