By the way, as far as you work on 1D and 2D arrays, you don't need numpy,
sympy can already handle those things. Greater dimensions are not yet
supported in sympy, unless you use tensor products in the diffgeom module,
but the representation of n-dim arrays is very strange there. As pointed
out by Aaron in a PR, you don't get a real advantage on dtype=object in
numpy over a possible pure python implementation.
Indexed derivatives are an urgent need for modern physics, otherwise it is
really hard to transcribe formulae to a CAS. We need them in the tensor
module.
There is already some stuff in the diffgeom module, which provides
differential and covariant derivatives for its field objects. I think it
only works within the diffgeom module.
Concerning derivatives by a vector, the diffgeom module handles them in a
clean way. I mean, you define a manifold, then a patch on the manifold, and
finally a coordinate system on the patch. The coordinate system specifies
the basis symbols, which you can use on scalar, vector, and tensor fields
defined on that patch. As an example:
>>> from sympy import Function
>>> from sympy.diffgeom.rn import R2
>>> from sympy.diffgeom import Differential
>>> from sympy import pprint
>>> g = Function('g')
>>> s_field = R2.x**2 * R2.y
>>> e_x, e_y, = R2.e_x, R2.e_y
>>> dg = Differential(s_field)
>>> pprint(dg(e_x))
2*x*y
>>> pprint(dg(e_y))
2
x
That is, the diffgeom already handles a far more general case. It would be
nice to have the diffgeom module interact with other parts of sympy, rather
than implementing everything separately.
By the way, there is a problem associated with derivatives by a vector: how
do you handle non-single-symbol expression in the derivative? I.e., if *v =
[a, b, a**2 + sin(b)]*, how do you handle a derivation of a matrix by v? In
the diffgeom module you define the coordinate system, the coordinate
symbols are instances of BaseScalarField, not generic expressions.
In any case, indexed derivations are a special case of the more general
tools already implemented in diffgeom, I mean, by your method you are
assuming:
1. a flat space.
2. a single patch on the flat space.
3. an ill-defined coordinate system, (you put it every time inside the
derivation).
4. Euclidean metric (i.e. no difference between covariant and
contravariant components of the objects to be derived).
I think that what is really worth, is to make diffgeom interact with
matrices and vectors, and maybe simplify its usage when the 4 points here
above are verified.
On Thursday, October 31, 2013 8:52:45 PM UTC+1, Aaron Meurer wrote:
>
> Ideally, we would implement these rules symbolically, so that they work
> even for something like MatrixSymbol('x', n, n). See
> https://code.google.com/p/sympy/issues/detail?id=2759. Getting this
> working would be a really nice feature for SymPy.
>
> Aaron Meurer
>
>
> On Thu, Oct 31, 2013 at 4:09 AM, Saullo Castro
> <[email protected]<javascript:>
> > wrote:
>
>> I have the functional:
>>
>>
>> <https://lh5.googleusercontent.com/-YyVcmvfWlB8/UnIq_SuBdjI/AAAAAAAABYE/NkiWxG35LS8/s1600/fig1.png>
>>
>> Where A is a function of "v". The non-linear system of equations
>> necessary to find "v" is obtained doing:
>>
>>
>> <https://lh5.googleusercontent.com/-SElccyNi1xo/UnIrNKzuKxI/AAAAAAAABYM/xd6tHk0SJT0/s1600/fig2.png>
>>
>> According to the differentiation rules, this system could be written in
>> matrix form as:
>>
>>
>> <https://lh6.googleusercontent.com/-Qm0cHaMnEAA/UnIrYLIfs5I/AAAAAAAABYU/ocDPAfGA4ic/s1600/fig3.png>
>>
>> So I've implemented in Sympy, with the help of NumPy "ndarray" the
>> differentiation about a vector. In this case the shape of (\partial A /
>> \partial v is (n X n X n), where "n" is the length of vector "v".
>>
>> The function is simple:
>> def vdiff(x, vector):
>> x = np.array(x)
>> shape = x.shape
>> ans = [np.array([e.diff(vi) for e in x.ravel()]) for vi in vector]
>> ans = [a.reshape(shape) for a in ans]
>> return np.array(ans).swapaxes(0, 1)
>>
>>
>>
>> And I've tested with two different cases:
>>
>> def test_00():
>> from sympy.abc import a, b, c, x
>> A11 = x*a*c**2
>> A12 = x**2*a*b*c
>> A13 = x**2*a**3*b**5
>> A21 = x**3*a**2*b*c
>> A22 = x**4*a*b**2*c**5
>> A23 = 5*x**4*a*b**2*c
>> A31 = x**4*a*b**2*c**4
>> A32 = 4*x**4*a*b**2*c**2
>> A33 = 4*x**4*a**5*b**2*c
>> A = np.array([[A11, A12, A13],
>> [A21, A22, A23],
>> [A31, A32, A33]])
>> v = np.array([a, b, c])
>> F = (v.T.dot(A)).dot(v)
>> Av = vdiff(A, v)
>> p1 = v.dot(A)
>> p2 = A.dot(v)
>> p3 = v.dot(Av.dot(v))
>> new = p1 + p2 + p3
>> ref = np.array([F.diff(a), F.diff(b), F.diff(c)])
>> print sympy.simplify(Matrix(ref-new))
>>
>> def test_01():
>> from sympy.abc import a, b, c, x
>> sympy.var('c1, c2')
>> A11 = x*a*c**2
>> A12 = x**2*a*b*c
>> A13 = x**2*a**3*b**5
>> A21 = x**3*a**2*b*c
>> A22 = x**4*a*b**2*c**5
>> A23 = 5*x**4*a*b**2*c
>> A = np.array([[A11, A12, A13],
>> [A21, A22, A23]])
>> v = np.array([a, b, c])
>> cc = np.array([c1, c2])
>> F = cc.dot(A.dot(v))
>> ref = np.array([F.diff(a), F.diff(b), F.diff(c)])
>> Av = vdiff(A, v)
>> p1 = cc.dot(A)
>> p2 = cc.dot(Av.dot(v))
>> new = p1 + p2
>> print sympy.simplify(Matrix(ref-new))
>>
>>
>> I'd like to share here and get some feedback in case someone has a more
>> straightforward way to implement this...
>>
>>
>> Thank you!
>>
>> Saullo
>>
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "sympy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected] <javascript:>
>> .
>> Visit this group at http://groups.google.com/group/sympy.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.