Here is commented version of my "square_root_of_expr" function. The functions determines if the input expression is a perfect square and if it is returns the positive square root of the perfect square. The other cases for the input expression are now documented in the code. I assume the expression is real and if the expression is a number and negative you want the square root of the absolute value of the expression. This is done for the case of normalizing the basis vectors in a Minkowski space. That is if the square of a basis vector is negative then the square of the normalized basis vector should be -1. This only works for basis vectors whose squares are numbers and not functions of the coordinates since in general sympy cannot determine if a function is positive or negative over
a given range.

def square_root_of_expr(expr):
    """
    If expression is product of even powers then every power is divided
    by two and the product is returned.  If some terms in product are
    not even powers the sqrt of the absolute value of the expression is
    returned.  If the expression is a number the sqrt of the absolute
    value of the number is returned.
    """
    if expr.is_number:
        if expr > 0:
            return(sqrt(expr))
        else:
            return(sqrt(-expr))
    else:
        expr = trigsimp(expr)
        (coef, pow_lst) = sqf_list(expr)
        if coef != S(1):
            if coef.is_number:
                coef = square_root_of_expr(coef)
            else:
                coef = sqrt(abs(coef))  # Product coefficient not a number
        for p in pow_lst:
            (f, n) = p
            if n % 2 != 0:
                return(sqrt(abs(expr)))  # Product not all even powers
            else:
coef *= f ** (n / 2) # Positive sqrt of the square of an expression
        return coef



On 12/06/2014 09:58 AM, Francesco Bonazzi wrote:
I published a gist on how to get the gradient in any coordinate system, given the backward transformation to rectangular coordinates.

I was also trying to write the code to get the divergence, but I ran into problems with sympy's simplify( ) function.

https://gist.github.com/Upabjojr/34f75ce115f1cf5a6afc

This gist defines a function *get_grad( ... )* which returns the gradient, it requires as an input a lambda function (backwards transformation).

Example:
|
from_spherical =lambdar,theta,phi:(r*sin(theta)*cos(phi),r*sin(theta)*sin(phi),r*cos(theta))
grad =get_grad(from_spherical)
|

Notice that the function /from_spherical/ is simply the easiest way to define the spherical coordinates.

I get the following output:

|
⎡∂_θ│sin(θ)│⋅∂ᵩ⎤
⎢∂ᵣ,───,───────────⎥
⎢    r 2⎥
⎣         r⋅sin (θ)⎦
|

SymPy doesn't know that in /theta/'s range of values its /sin(theta)/ is always positive, this is the reason why it does not get simplified.

I have only tried the spherical coordinates, but this should work with any coordinate transformation in three dimensions. It should not be too complicated to generalize this to any dimension.

That's why I would like coordinate systems to be instances of a class, and not classes themselves. It is really uncomfortable to define a new class for every new coordinate system.

On Thursday, November 27, 2014 7:17:49 AM UTC+1, Aaron Meurer wrote:

    On Tue, Nov 25, 2014 at 1:58 AM, Francesco Bonazzi
    <franz....@gmail.com <javascript:>> wrote:
    >
    >
    > On Wednesday, November 19, 2014 11:17:24 PM UTC+1, Jason Moore
    wrote:
    >>
    >> Sachin Joglekar developed the vector package this past summer.
    I was his
    >> GSoC mentor on the project. You can check out this implemented
    of the
    >> Cartesian coordinate system:
    >>
    >>
    https://github.com/sympy/sympy/blob/master/sympy/vector/coordsysrect.py
    <https://github.com/sympy/sympy/blob/master/sympy/vector/coordsysrect.py>

    >
    >
    > In sympy.diffgeom coordinate systems are defined as instances of
    the
    > CoordSystem class, once more coordinate systems are defined, the
    > transformation rules are set using the connect_to method:
    >
    > In [1]: from sympy.diffgeom import *
    >
    > In [2]: r, theta, phi = symbols('r theta phi', positive=True)
    >
    > In [4]: M = Manifold('M', 3)
    >
    > In [5]: P = Patch('P', M)
    >
    > In [7]: rect = CoordSystem('rect', P, ['x', 'y', 'z'])
    >
    > In [8]: spherical = CoordSystem('spherical', P, ['r', 'theta',
    'phi'])
    >
    > In [9]: spherical.connect_to(rect, [r, theta, phi],
    [r*sin(phi)*cos(theta),
    > r*sin(phi)*sin(theta), r*cos(phi)], inverse=False)
    >
    >
    > I put inverse=False in the last line, because SymPy's solvers
    are unable to
    > reverse the spherical-to-rect transformation.
    >
    > Manifold and Patch are some boilerplate, Manifold specifies the
    space you're
    > considering, while Patch is a connected subspace of the
    manifold. Patch is
    > used because on some manifolds there does not exist a
    homeomorphism to a
    > coordinate system (e.g. on the sphere).
    >
    > I think that some algorithmic code could be shared between the
    vector and
    > the diffgeom modules.

    +1 to that, especially if we can avoid hard-coding things and just
    let
    solve() compute things (similar to how sympy.stats works).

    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+un...@googlegroups.com <javascript:>.
    > To post to this group, send email to sy...@googlegroups.com
    <javascript:>.
    > Visit this group at http://groups.google.com/group/sympy
    <http://groups.google.com/group/sympy>.
    > To view this discussion on the web visit
    >
    
https://groups.google.com/d/msgid/sympy/7341823f-1172-4ecb-b322-f52f115d44f4%40googlegroups.com
    
<https://groups.google.com/d/msgid/sympy/7341823f-1172-4ecb-b322-f52f115d44f4%40googlegroups.com>.

    >
    > For more options, visit https://groups.google.com/d/optout
    <https://groups.google.com/d/optout>.

--
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+unsubscr...@googlegroups.com <mailto:sympy+unsubscr...@googlegroups.com>. To post to this group, send email to sympy@googlegroups.com <mailto:sympy@googlegroups.com>.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/14ce54ae-897d-41bd-9a35-36e9a0b11822%40googlegroups.com <https://groups.google.com/d/msgid/sympy/14ce54ae-897d-41bd-9a35-36e9a0b11822%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
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+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/54848AD2.8020306%40verizon.net.
For more options, visit https://groups.google.com/d/optout.

Reply via email to