Doubts about extending the API of the vector module

72 views
Skip to first unread message

Francesco Bonazzi

unread,
Aug 31, 2017, 4:09:37 PM8/31/17
to sympy
As part of the GSoC 2017, the vector module (sympy.vector) is being extended to support any kind of coordinate system transformation that preserves the orthogonality of base vectors.

The old code only supported rotations and translations. For example, to translate a coordinate system, there is the .locate_new( ... ) method:

C = CoordSysCartesian("C")
D
= C.locate_new("D", 3*C.i)

this means that D is the coordinate system C pushed three units (3*C.i) along the x-axis.

The x variable in D (that is D.x) expressed in the system C looks like:

In [8]: express(f(D.x), C, variables=True)
Out[8]: f(C.x - 3)

In [9]: express(f(C.x), D, variables=True)
Out[9]: f(D_x + 3)

which makes sense, f(D.x) == f(C.x - 3), that is, the x-axis point C.x == 2 will be D.x == -1, so to preserve the result of function f we need to translate backwards (inverse function).

The new API we have prepared supports generic lambda functions for the coordinate transformations. The question is, to what should .locate_new( ... , 3*C.i ) correspond?
  • lambda x, y, z: (x + 3, y, z)
  • lambda x, y, z: (x - 3, y, z)

So far we have assumed the first one (considering lambda as acting on the coordinate system). In that case we need defined transformation for express(f(C.x), D, ... ) and the inverse transformation for express(f(D.x), C, ...).


Considering the rectangular to spherical transformation:


              ______________         _________              
           
   2    2    2            2    2                
(x, y, z) ⎝╲╱  x  + y  + z  , atan2⎝╲╱  x  + y  , z⎠, atan2(y, x)⎠


At this point, if R is a rectangular coordinate system and I want to define a spherical one, it seems reasonable to call:


S = R.create_new("S", lambda x, y, z: ( ... defined as above ... ))

So when we call express, it would be reasonable to have express(x, S, ... ) == r*sin(theta)*cos(phi), and express(r, R, ... ) == sqrt(x**2 + y**2 + z**2).


Unfortunately if we maintain the transformation directions as defined above, we will have:


express(x, S, ... ) == sqrt(x**2 + y**2 + z**2)


and


express(r, R, ... ) == r*sin(theta)*cos(phi)


The inverse transformation functions should be used.


So the question is, should .locate_new( ... , 3*C.i ) rather correspond to .create_new( ... , lambda x, y, z: (x - 3, ... ) ) (rather than the lambda with x+3) ?


What do you think?

Aaron Meurer

unread,
Aug 31, 2017, 5:17:42 PM8/31/17
to sy...@googlegroups.com
My feeling is that the method names should be named in such a way that it's clear to anyone whether they correspond to the transformation C -> D or the inverse transformation C <- D. 

I think the confusion perhaps comes from the use of a lambda function, which makes the variables of the transformation bound, meaning they can have any name. So there's no obvious "type checking" to prevent you from applying C -> D on an element of D. Your express() example is clear because it shows C.x and D.x. This is especially important since both C and D are rectangular, so they both use x, y, and z. 

If you are creating D from C you can use the C variables C.x, C.y, C.z, but if you want to create D and use D.x how do you do that when D hasn't been created yet? Is this the core of the problem here? 

Aaron Meurer

--
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 sympy+unsubscribe@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/a0094783-3910-40db-99c9-f2d8313821b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages