Esempio n. 1
0
def test_coordinate_vars():
    """
    Tests the coordinate variables functionality with respect to
    reorientation of coordinate systems.
    """
    A = CoordSysCartesian('A')
    assert BaseScalar('Ax', 0, A, ' ', ' ') == A.x
    assert BaseScalar('Ay', 1, A, ' ', ' ') == A.y
    assert BaseScalar('Az', 2, A, ' ', ' ') == A.z
    assert BaseScalar('Ax', 0, A, ' ', ' ').__hash__() == A.x.__hash__()
    assert isinstance(A.x, BaseScalar) and \
           isinstance(A.y, BaseScalar) and \
           isinstance(A.z, BaseScalar)
    assert A.scalar_map(A) == {A.x: A.x, A.y: A.y, A.z: A.z}
    assert A.x.system == A
    B = A.orient_new_axis('B', q, A.k)
    assert B.scalar_map(A) == {B.z: A.z, B.y: -A.x*sin(q) + A.y*cos(q),
                                 B.x: A.x*cos(q) + A.y*sin(q)}
    assert A.scalar_map(B) == {A.x: B.x*cos(q) - B.y*sin(q),
                                 A.y: B.x*sin(q) + B.y*cos(q), A.z: B.z}
    assert express(B.x, A, variables=True) == A.x*cos(q) + A.y*sin(q)
    assert express(B.y, A, variables=True) == -A.x*sin(q) + A.y*cos(q)
    assert express(B.z, A, variables=True) == A.z
    assert express(B.x*B.y*B.z, A, variables=True) == \
           A.z*(-A.x*sin(q) + A.y*cos(q))*(A.x*cos(q) + A.y*sin(q))
    assert express(B.x*B.i + B.y*B.j + B.z*B.k, A) == \
           (B.x*cos(q) - B.y*sin(q))*A.i + (B.x*sin(q) + \
           B.y*cos(q))*A.j + B.z*A.k
    assert simplify(express(B.x*B.i + B.y*B.j + B.z*B.k, A, \
                            variables=True)) == \
           A.x*A.i + A.y*A.j + A.z*A.k
    assert express(A.x*A.i + A.y*A.j + A.z*A.k, B) == \
           (A.x*cos(q) + A.y*sin(q))*B.i + \
           (-A.x*sin(q) + A.y*cos(q))*B.j + A.z*B.k
    assert simplify(express(A.x*A.i + A.y*A.j + A.z*A.k, B, \
                            variables=True)) == \
           B.x*B.i + B.y*B.j + B.z*B.k
    N = B.orient_new_axis('N', -q, B.k)
    assert N.scalar_map(A) == \
           {N.x: A.x, N.z: A.z, N.y: A.y}
    C = A.orient_new_axis('C', q, A.i + A.j + A.k)
    mapping = A.scalar_map(C)
    assert mapping[A.x] == 2*C.x*cos(q)/3 + C.x/3 - \
           2*C.y*sin(q + pi/6)/3 + C.y/3 - 2*C.z*cos(q + pi/3)/3 + C.z/3
    assert mapping[A.y] == -2*C.x*cos(q + pi/3)/3 + \
           C.x/3 + 2*C.y*cos(q)/3 + C.y/3 - 2*C.z*sin(q + pi/6)/3 + C.z/3
    assert mapping[A.z] == -2*C.x*sin(q + pi/6)/3 + C.x/3 - \
           2*C.y*cos(q + pi/3)/3 + C.y/3 + 2*C.z*cos(q)/3 + C.z/3
    D = A.locate_new('D', a*A.i + b*A.j + c*A.k)
    assert D.scalar_map(A) == {D.z: A.z - c, D.x: A.x - a, D.y: A.y - b}
    E = A.orient_new_axis('E', a, A.k, a*A.i + b*A.j + c*A.k)
    assert A.scalar_map(E) == {A.z: E.z + c,
                               A.x: E.x*cos(a) - E.y*sin(a) + a,
                               A.y: E.x*sin(a) + E.y*cos(a) + b}
    assert E.scalar_map(A) == {E.x: (A.x - a)*cos(a) + (A.y - b)*sin(a),
                               E.y: (-A.x + a)*sin(a) + (A.y - b)*cos(a),
                               E.z: A.z - c}
    F = A.locate_new('F', Vector.zero)
    assert A.scalar_map(F) == {A.z: F.z, A.x: F.x, A.y: F.y}
def test_coordsyscartesian_equivalence():
    A = CoordSysCartesian("A")
    A1 = CoordSysCartesian("A")
    assert A1 == A
    B = CoordSysCartesian("B")
    assert A != B
    assert A.locate_new("C1", A.i) == A.locate_new("C2", A.i)
    assert A.orient_new_axis("C1", a, A.i) == A.orient_new_axis("C2", a, A.i)
def test_rotation_matrix():
    N = CoordSysCartesian('N')
    A = N.orient_new_axis('A', q1, N.k)
    B = A.orient_new_axis('B', q2, A.i)
    C = B.orient_new_axis('C', q3, B.j)
    D = N.orient_new_axis('D', q4, N.j)
    E = N.orient_new_space('E', q1, q2, q3, '123')
    F = N.orient_new_quaternion('F', q1, q2, q3, q4)
    G = N.orient_new_body('G', q1, q2, q3, '123')
    assert N.rotation_matrix(C) == Matrix([
        [- sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3), - sin(q1) *
        cos(q2), sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1)], \
        [sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), \
         cos(q1) * cos(q2), sin(q1) * sin(q3) - sin(q2) * cos(q1) * \
         cos(q3)], [- sin(q3) * cos(q2), sin(q2), cos(q2) * cos(q3)]])
    test_mat = D.rotation_matrix(C) - Matrix(
        [[cos(q1) * cos(q3) * cos(q4) - sin(q3) * (- sin(q4) * cos(q2) +
        sin(q1) * sin(q2) * cos(q4)), - sin(q2) * sin(q4) - sin(q1) *
            cos(q2) * cos(q4), sin(q3) * cos(q1) * cos(q4) + cos(q3) * \
          (- sin(q4) * cos(q2) + sin(q1) * sin(q2) * cos(q4))], \
         [sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), cos(q1) * \
          cos(q2), sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)], \
         [sin(q4) * cos(q1) * cos(q3) - sin(q3) * (cos(q2) * cos(q4) + \
                                                   sin(q1) * sin(q2) * \
                                                   sin(q4)), sin(q2) *
                cos(q4) - sin(q1) * sin(q4) * cos(q2), sin(q3) * \
          sin(q4) * cos(q1) + cos(q3) * (cos(q2) * cos(q4) + \
                                         sin(q1) * sin(q2) * sin(q4))]])
    assert test_mat.expand() == zeros(3, 3)
    assert E.rotation_matrix(N) == Matrix(
        [[cos(q2)*cos(q3), sin(q3)*cos(q2), -sin(q2)],
        [sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), \
         sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2)], \
         [sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), - \
          sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2)]])
    assert F.rotation_matrix(N) == Matrix([[
        q1**2 + q2**2 - q3**2 - q4**2,
        2*q1*q4 + 2*q2*q3, -2*q1*q3 + 2*q2*q4],[ -2*q1*q4 + 2*q2*q3,
            q1**2 - q2**2 + q3**2 - q4**2, 2*q1*q2 + 2*q3*q4],
                                           [2*q1*q3 + 2*q2*q4,
                                            -2*q1*q2 + 2*q3*q4,
                                q1**2 - q2**2 - q3**2 + q4**2]])
    assert G.rotation_matrix(N) == Matrix([[
        cos(q2)*cos(q3),  sin(q1)*sin(q2)*cos(q3) + sin(q3)*cos(q1),
        sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3)], [
            -sin(q3)*cos(q2), -sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3),
            sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],[
                sin(q2), -sin(q1)*cos(q2), cos(q1)*cos(q2)]])
Esempio n. 4
0
def test_rotation_matrix():
    N = CoordSysCartesian('N')
    A = N.orient_new_axis('A', q1, N.k)
    B = A.orient_new_axis('B', q2, A.i)
    C = B.orient_new_axis('C', q3, B.j)
    D = N.orient_new_axis('D', q4, N.j)
    E = N.orient_new_space('E', q1, q2, q3, '123')
    F = N.orient_new_quaternion('F', q1, q2, q3, q4)
    G = N.orient_new_body('G', q1, q2, q3, '123')
    assert N.rotation_matrix(C) == Matrix([
        [- sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3), - sin(q1) *
        cos(q2), sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1)], \
        [sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), \
         cos(q1) * cos(q2), sin(q1) * sin(q3) - sin(q2) * cos(q1) * \
         cos(q3)], [- sin(q3) * cos(q2), sin(q2), cos(q2) * cos(q3)]])
    test_mat = D.rotation_matrix(C) - Matrix(
        [[cos(q1) * cos(q3) * cos(q4) - sin(q3) * (- sin(q4) * cos(q2) +
        sin(q1) * sin(q2) * cos(q4)), - sin(q2) * sin(q4) - sin(q1) *
            cos(q2) * cos(q4), sin(q3) * cos(q1) * cos(q4) + cos(q3) * \
          (- sin(q4) * cos(q2) + sin(q1) * sin(q2) * cos(q4))], \
         [sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), cos(q1) * \
          cos(q2), sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)], \
         [sin(q4) * cos(q1) * cos(q3) - sin(q3) * (cos(q2) * cos(q4) + \
                                                   sin(q1) * sin(q2) * \
                                                   sin(q4)), sin(q2) *
                cos(q4) - sin(q1) * sin(q4) * cos(q2), sin(q3) * \
          sin(q4) * cos(q1) + cos(q3) * (cos(q2) * cos(q4) + \
                                         sin(q1) * sin(q2) * sin(q4))]])
    assert test_mat.expand() == zeros(3, 3)
    assert E.rotation_matrix(N) == Matrix(
        [[cos(q2)*cos(q3), sin(q3)*cos(q2), -sin(q2)],
        [sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), \
         sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2)], \
         [sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), - \
          sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2)]])
    assert F.rotation_matrix(N) == Matrix([[
        q1**2 + q2**2 - q3**2 - q4**2,
        2*q1*q4 + 2*q2*q3, -2*q1*q3 + 2*q2*q4],[ -2*q1*q4 + 2*q2*q3,
            q1**2 - q2**2 + q3**2 - q4**2, 2*q1*q2 + 2*q3*q4],
                                           [2*q1*q3 + 2*q2*q4,
                                            -2*q1*q2 + 2*q3*q4,
                                q1**2 - q2**2 - q3**2 + q4**2]])
    assert G.rotation_matrix(N) == Matrix([[
        cos(q2)*cos(q3),  sin(q1)*sin(q2)*cos(q3) + sin(q3)*cos(q1),
        sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3)], [
            -sin(q3)*cos(q2), -sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3),
            sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],[
                sin(q2), -sin(q1)*cos(q2), cos(q1)*cos(q2)]])
def test_vector():
    """
    Tests the effects of orientation of coordinate systems on
    basic vector operations.
    """
    N = CoordSysCartesian("N")
    A = N.orient_new_axis("A", q1, N.k)
    B = A.orient_new_axis("B", q2, A.i)
    C = B.orient_new_axis("C", q3, B.j)

    # Test to_matrix
    v1 = a * N.i + b * N.j + c * N.k
    assert v1.to_matrix(A) == Matrix([[a * cos(q1) + b * sin(q1)], [-a * sin(q1) + b * cos(q1)], [c]])

    # Test dot
    assert N.i.dot(A.i) == cos(q1)
    assert N.i.dot(A.j) == -sin(q1)
    assert N.i.dot(A.k) == 0
    assert N.j.dot(A.i) == sin(q1)
    assert N.j.dot(A.j) == cos(q1)
    assert N.j.dot(A.k) == 0
    assert N.k.dot(A.i) == 0
    assert N.k.dot(A.j) == 0
    assert N.k.dot(A.k) == 1

    assert N.i.dot(A.i + A.j) == -sin(q1) + cos(q1) == (A.i + A.j).dot(N.i)

    assert A.i.dot(C.i) == cos(q3)
    assert A.i.dot(C.j) == 0
    assert A.i.dot(C.k) == sin(q3)
    assert A.j.dot(C.i) == sin(q2) * sin(q3)
    assert A.j.dot(C.j) == cos(q2)
    assert A.j.dot(C.k) == -sin(q2) * cos(q3)
    assert A.k.dot(C.i) == -cos(q2) * sin(q3)
    assert A.k.dot(C.j) == sin(q2)
    assert A.k.dot(C.k) == cos(q2) * cos(q3)

    # Test cross
    assert N.i.cross(A.i) == sin(q1) * A.k
    assert N.i.cross(A.j) == cos(q1) * A.k
    assert N.i.cross(A.k) == -sin(q1) * A.i - cos(q1) * A.j
    assert N.j.cross(A.i) == -cos(q1) * A.k
    assert N.j.cross(A.j) == sin(q1) * A.k
    assert N.j.cross(A.k) == cos(q1) * A.i - sin(q1) * A.j
    assert N.k.cross(A.i) == A.j
    assert N.k.cross(A.j) == -A.i
    assert N.k.cross(A.k) == Vector.zero

    assert N.i.cross(A.i) == sin(q1) * A.k
    assert N.i.cross(A.j) == cos(q1) * A.k
    assert N.i.cross(A.i + A.j) == sin(q1) * A.k + cos(q1) * A.k
    assert (A.i + A.j).cross(N.i) == (-sin(q1) - cos(q1)) * N.k

    assert A.i.cross(C.i) == sin(q3) * C.j
    assert A.i.cross(C.j) == -sin(q3) * C.i + cos(q3) * C.k
    assert A.i.cross(C.k) == -cos(q3) * C.j
    assert C.i.cross(A.i) == (-sin(q3) * cos(q2)) * A.j + (-sin(q2) * sin(q3)) * A.k
    assert C.j.cross(A.i) == (sin(q2)) * A.j + (-cos(q2)) * A.k
    assert express(C.k.cross(A.i), C).trigsimp() == cos(q3) * C.j
Esempio n. 6
0
def test_coordsyscartesian_equivalence():
    A = CoordSysCartesian('A')
    A1 = CoordSysCartesian('A')
    assert A1 == A
    B = CoordSysCartesian('B')
    assert A != B
    assert A.locate_new('C1', A.i) == A.locate_new('C2', A.i)
    assert A.orient_new_axis('C1', a, A.i) == \
           A.orient_new_axis('C2', a, A.i)
Esempio n. 7
0
def test_coordsyscartesian_equivalence():
    A = CoordSysCartesian('A')
    A1 = CoordSysCartesian('A')
    assert A1 == A
    B = CoordSysCartesian('B')
    assert A != B
    assert A.locate_new('C1', A.i) == A.locate_new('C2', A.i)
    assert A.orient_new_axis('C1', a, A.i) == \
           A.orient_new_axis('C2', a, A.i)
Esempio n. 8
0
def test_orient_new_methods():
    N = CoordSysCartesian('N')
    D = N.orient_new('D', 'Axis', [q4, N.j])
    E = N.orient_new('E', 'Space', [q1, q2, q3], '123')
    F = N.orient_new('F', 'Quaternion', [q1, q2, q3, q4])
    G = N.orient_new('G', 'Body', [q1, q2, q3], '123')
    assert D == N.orient_new_axis('D', q4, N.j)
    assert E == N.orient_new_space('E', q1, q2, q3, '123')
    assert F == N.orient_new_quaternion('F', q1, q2, q3, q4)
    assert G == N.orient_new_body('G', q1, q2, q3, '123')
def test_orient_new_methods():
    N = CoordSysCartesian("N")
    orienter1 = AxisOrienter(q4, N.j)
    orienter2 = SpaceOrienter(q1, q2, q3, "123")
    orienter3 = QuaternionOrienter(q1, q2, q3, q4)
    orienter4 = BodyOrienter(q1, q2, q3, "123")
    D = N.orient_new("D", (orienter1,))
    E = N.orient_new("E", (orienter2,))
    F = N.orient_new("F", (orienter3,))
    G = N.orient_new("G", (orienter4,))
    assert D == N.orient_new_axis("D", q4, N.j)
    assert E == N.orient_new_space("E", q1, q2, q3, "123")
    assert F == N.orient_new_quaternion("F", q1, q2, q3, q4)
    assert G == N.orient_new_body("G", q1, q2, q3, "123")
Esempio n. 10
0
def test_orient_new_methods():
    N = CoordSysCartesian('N')
    orienter1 = AxisOrienter(q4, N.j)
    orienter2 = SpaceOrienter(q1, q2, q3, '123')
    orienter3 = QuaternionOrienter(q1, q2, q3, q4)
    orienter4 = BodyOrienter(q1, q2, q3, '123')
    D = N.orient_new('D', (orienter1, ))
    E = N.orient_new('E', (orienter2, ))
    F = N.orient_new('F', (orienter3, ))
    G = N.orient_new('G', (orienter4, ))
    assert D == N.orient_new_axis('D', q4, N.j)
    assert E == N.orient_new_space('E', q1, q2, q3, '123')
    assert F == N.orient_new_quaternion('F', q1, q2, q3, q4)
    assert G == N.orient_new_body('G', q1, q2, q3, '123')
Esempio n. 11
0
def test_orient_new_methods():
    N = CoordSysCartesian('N')
    orienter1 = AxisOrienter(q4, N.j)
    orienter2 = SpaceOrienter(q1, q2, q3, '123')
    orienter3 = QuaternionOrienter(q1, q2, q3, q4)
    orienter4 = BodyOrienter(q1, q2, q3, '123')
    D = N.orient_new('D', (orienter1, ))
    E = N.orient_new('E', (orienter2, ))
    F = N.orient_new('F', (orienter3, ))
    G = N.orient_new('G', (orienter4, ))
    assert D == N.orient_new_axis('D', q4, N.j)
    assert E == N.orient_new_space('E', q1, q2, q3, '123')
    assert F == N.orient_new_quaternion('F', q1, q2, q3, q4)
    assert G == N.orient_new_body('G', q1, q2, q3, '123')
Esempio n. 12
0
def test_vector():
    """
    Tests the effects of orientation of coordinate systems on
    basic vector operations.
    """
    N = CoordSysCartesian('N')
    A = N.orient_new_axis('A', q1, N.k)
    B = A.orient_new_axis('B', q2, A.i)
    C = B.orient_new_axis('C', q3, B.j)

    #Test to_matrix
    v1 = a * N.i + b * N.j + c * N.k
    assert v1.to_matrix(A) == Matrix([[a * cos(q1) + b * sin(q1)],
                                      [-a * sin(q1) + b * cos(q1)], [c]])

    #Test dot
    assert N.i.dot(A.i) == cos(q1)
    assert N.i.dot(A.j) == -sin(q1)
    assert N.i.dot(A.k) == 0
    assert N.j.dot(A.i) == sin(q1)
    assert N.j.dot(A.j) == cos(q1)
    assert N.j.dot(A.k) == 0
    assert N.k.dot(A.i) == 0
    assert N.k.dot(A.j) == 0
    assert N.k.dot(A.k) == 1

    assert N.i.dot(A.i + A.j) == -sin(q1) + cos(q1) == \
           (A.i + A.j).dot(N.i)

    assert A.i.dot(C.i) == cos(q3)
    assert A.i.dot(C.j) == 0
    assert A.i.dot(C.k) == sin(q3)
    assert A.j.dot(C.i) == sin(q2) * sin(q3)
    assert A.j.dot(C.j) == cos(q2)
    assert A.j.dot(C.k) == -sin(q2) * cos(q3)
    assert A.k.dot(C.i) == -cos(q2) * sin(q3)
    assert A.k.dot(C.j) == sin(q2)
    assert A.k.dot(C.k) == cos(q2) * cos(q3)

    #Test cross
    assert N.i.cross(A.i) == sin(q1) * A.k
    assert N.i.cross(A.j) == cos(q1) * A.k
    assert N.i.cross(A.k) == -sin(q1) * A.i - cos(q1) * A.j
    assert N.j.cross(A.i) == -cos(q1) * A.k
    assert N.j.cross(A.j) == sin(q1) * A.k
    assert N.j.cross(A.k) == cos(q1) * A.i - sin(q1) * A.j
    assert N.k.cross(A.i) == A.j
    assert N.k.cross(A.j) == -A.i
    assert N.k.cross(A.k) == Vector.zero

    assert N.i.cross(A.i) == sin(q1) * A.k
    assert N.i.cross(A.j) == cos(q1) * A.k
    assert N.i.cross(A.i + A.j) == sin(q1) * A.k + cos(q1) * A.k
    assert (A.i + A.j).cross(N.i) == (-sin(q1) - cos(q1)) * N.k

    assert A.i.cross(C.i) == sin(q3) * C.j
    assert A.i.cross(C.j) == -sin(q3) * C.i + cos(q3) * C.k
    assert A.i.cross(C.k) == -cos(q3) * C.j
    assert C.i.cross(A.i) == (-sin(q3)*cos(q2))*A.j + \
           (-sin(q2)*sin(q3))*A.k
    assert C.j.cross(A.i) == (sin(q2)) * A.j + (-cos(q2)) * A.k
    assert express(C.k.cross(A.i), C).trigsimp() == cos(q3) * C.j
Esempio n. 13
0
def test_coordinate_vars():
    """
    Tests the coordinate variables functionality with respect to
    reorientation of coordinate systems.
    """
    A = CoordSysCartesian('A')
    # Note that the name given on the lhs is different from A.x._name
    assert BaseScalar('A.x', 0, A, 'A_x', r'\mathbf{{x}_{A}}') == A.x
    assert BaseScalar('A.y', 1, A, 'A_y', r'\mathbf{{y}_{A}}') == A.y
    assert BaseScalar('A.z', 2, A, 'A_z', r'\mathbf{{z}_{A}}') == A.z
    assert BaseScalar('A.x', 0, A, 'A_x',
                      r'\mathbf{{x}_{A}}').__hash__() == A.x.__hash__()
    assert isinstance(A.x, BaseScalar) and \
           isinstance(A.y, BaseScalar) and \
           isinstance(A.z, BaseScalar)
    assert A.x * A.y == A.y * A.x
    assert A.scalar_map(A) == {A.x: A.x, A.y: A.y, A.z: A.z}
    assert A.x.system == A
    assert A.x.diff(A.x) == 1
    B = A.orient_new_axis('B', q, A.k)
    assert B.scalar_map(A) == {
        B.z: A.z,
        B.y: -A.x * sin(q) + A.y * cos(q),
        B.x: A.x * cos(q) + A.y * sin(q)
    }
    assert A.scalar_map(B) == {
        A.x: B.x * cos(q) - B.y * sin(q),
        A.y: B.x * sin(q) + B.y * cos(q),
        A.z: B.z
    }
    assert express(B.x, A, variables=True) == A.x * cos(q) + A.y * sin(q)
    assert express(B.y, A, variables=True) == -A.x * sin(q) + A.y * cos(q)
    assert express(B.z, A, variables=True) == A.z
    assert expand(express(B.x*B.y*B.z, A, variables=True)) == \
           expand(A.z*(-A.x*sin(q) + A.y*cos(q))*(A.x*cos(q) + A.y*sin(q)))
    assert express(B.x*B.i + B.y*B.j + B.z*B.k, A) == \
           (B.x*cos(q) - B.y*sin(q))*A.i + (B.x*sin(q) + \
           B.y*cos(q))*A.j + B.z*A.k
    assert simplify(express(B.x*B.i + B.y*B.j + B.z*B.k, A, \
                            variables=True)) == \
           A.x*A.i + A.y*A.j + A.z*A.k
    assert express(A.x*A.i + A.y*A.j + A.z*A.k, B) == \
           (A.x*cos(q) + A.y*sin(q))*B.i + \
           (-A.x*sin(q) + A.y*cos(q))*B.j + A.z*B.k
    assert simplify(express(A.x*A.i + A.y*A.j + A.z*A.k, B, \
                            variables=True)) == \
           B.x*B.i + B.y*B.j + B.z*B.k
    N = B.orient_new_axis('N', -q, B.k)
    assert N.scalar_map(A) == \
           {N.x: A.x, N.z: A.z, N.y: A.y}
    C = A.orient_new_axis('C', q, A.i + A.j + A.k)
    mapping = A.scalar_map(C)
    assert mapping[A.x].equals(C.x * (2 * cos(q) + 1) / 3 + C.y *
                               (-2 * sin(q + pi / 6) + 1) / 3 + C.z *
                               (-2 * cos(q + pi / 3) + 1) / 3)
    assert mapping[A.y].equals(C.x * (-2 * cos(q + pi / 3) + 1) / 3 + C.y *
                               (2 * cos(q) + 1) / 3 + C.z *
                               (-2 * sin(q + pi / 6) + 1) / 3)
    assert mapping[A.z].equals(C.x * (-2 * sin(q + pi / 6) + 1) / 3 + C.y *
                               (-2 * cos(q + pi / 3) + 1) / 3 + C.z *
                               (2 * cos(q) + 1) / 3)
    D = A.locate_new('D', a * A.i + b * A.j + c * A.k)
    assert D.scalar_map(A) == {D.z: A.z - c, D.x: A.x - a, D.y: A.y - b}
    E = A.orient_new_axis('E', a, A.k, a * A.i + b * A.j + c * A.k)
    assert A.scalar_map(E) == {
        A.z: E.z + c,
        A.x: E.x * cos(a) - E.y * sin(a) + a,
        A.y: E.x * sin(a) + E.y * cos(a) + b
    }
    assert E.scalar_map(A) == {
        E.x: (A.x - a) * cos(a) + (A.y - b) * sin(a),
        E.y: (-A.x + a) * sin(a) + (A.y - b) * cos(a),
        E.z: A.z - c
    }
    F = A.locate_new('F', Vector.zero)
    assert A.scalar_map(F) == {A.z: F.z, A.x: F.x, A.y: F.y}
Esempio n. 14
0
from sympy.vector.vector import Vector
from sympy.vector.coordsysrect import CoordSysCartesian
from sympy.vector.functions import express, matrix_to_vector
from sympy import symbols, S, sin, cos, ImmutableMatrix as Matrix

N = CoordSysCartesian('N')
q1, q2, q3, q4, q5 = symbols('q1 q2 q3 q4 q5')
A = N.orient_new_axis('A', q1, N.k)
B = A.orient_new_axis('B', q2, A.i)
C = B.orient_new_axis('C', q3, B.j)


def test_express():
    assert express(Vector.zero, N) == Vector.zero
    assert express(S(0), N) == S(0)
    assert express(A.i, C) == cos(q3) * C.i + sin(q3) * C.k
    assert express(A.j, C) == sin(q2)*sin(q3)*C.i + cos(q2)*C.j - \
        sin(q2)*cos(q3)*C.k
    assert express(A.k, C) == -sin(q3)*cos(q2)*C.i + sin(q2)*C.j + \
        cos(q2)*cos(q3)*C.k
    assert express(A.i, N) == cos(q1) * N.i + sin(q1) * N.j
    assert express(A.j, N) == -sin(q1) * N.i + cos(q1) * N.j
    assert express(A.k, N) == N.k
    assert express(A.i, A) == A.i
    assert express(A.j, A) == A.j
    assert express(A.k, A) == A.k
    assert express(A.i, B) == B.i
    assert express(A.j, B) == cos(q2) * B.j - sin(q2) * B.k
    assert express(A.k, B) == sin(q2) * B.j + cos(q2) * B.k
    assert express(A.i, C) == cos(q3) * C.i + sin(q3) * C.k
    assert express(A.j, C) == sin(q2)*sin(q3)*C.i + cos(q2)*C.j - \
Esempio n. 15
0
    rhs = ((v & (delop ^ u)) - (u & (delop ^ v))).doit()
    assert simplify(lhs) == simplify(rhs)

    #Fifth product rule
    lhs = (delop ^ (f * v)).doit()
    rhs = (((delop(f)) ^ v) + (f * (delop ^ v))).doit()
    assert simplify(lhs) == simplify(rhs)

    #Sixth product rule
    lhs = (delop ^ (u ^ v)).doit()
    rhs = ((u * (delop & v) - v * (delop & u) + (v & delop)(u) -
            (u & delop)(v))).doit()
    assert simplify(lhs) == simplify(rhs)


P = C.orient_new_axis('P', q, C.k)
scalar_field = 2 * x**2 * y * z
grad_field = gradient(scalar_field, C)
vector_field = y**2 * i + 3 * x * j + 5 * y * z * k
curl_field = curl(vector_field, C)


def test_conservative():
    assert is_conservative(Vector.zero) is True
    assert is_conservative(i) is True
    assert is_conservative(2 * i + 3 * j + 4 * k) is True
    assert (is_conservative(y * z * i + x * z * j + x * y * k) is True)
    assert is_conservative(x * j) is False
    assert is_conservative(grad_field) is True
    assert is_conservative(curl_field) is False
    assert (is_conservative(4 * x * y * z * i + 2 * x**2 * z * j) is False)
Esempio n. 16
0
def test_coordinate_vars():
    """
    Tests the coordinate variables functionality with respect to
    reorientation of coordinate systems.
    """
    A = CoordSysCartesian("A")
    assert BaseScalar("Ax", 0, A, " ", " ") == A.x
    assert BaseScalar("Ay", 1, A, " ", " ") == A.y
    assert BaseScalar("Az", 2, A, " ", " ") == A.z
    assert BaseScalar("Ax", 0, A, " ", " ").__hash__() == A.x.__hash__()
    assert isinstance(A.x, BaseScalar) and isinstance(A.y, BaseScalar) and isinstance(A.z, BaseScalar)
    assert A.scalar_map(A) == {A.x: A.x, A.y: A.y, A.z: A.z}
    assert A.x.system == A
    B = A.orient_new_axis("B", q, A.k)
    assert B.scalar_map(A) == {B.z: A.z, B.y: -A.x * sin(q) + A.y * cos(q), B.x: A.x * cos(q) + A.y * sin(q)}
    assert A.scalar_map(B) == {A.x: B.x * cos(q) - B.y * sin(q), A.y: B.x * sin(q) + B.y * cos(q), A.z: B.z}
    assert express(B.x, A, variables=True) == A.x * cos(q) + A.y * sin(q)
    assert express(B.y, A, variables=True) == -A.x * sin(q) + A.y * cos(q)
    assert express(B.z, A, variables=True) == A.z
    assert express(B.x * B.y * B.z, A, variables=True) == A.z * (-A.x * sin(q) + A.y * cos(q)) * (
        A.x * cos(q) + A.y * sin(q)
    )
    assert (
        express(B.x * B.i + B.y * B.j + B.z * B.k, A)
        == (B.x * cos(q) - B.y * sin(q)) * A.i + (B.x * sin(q) + B.y * cos(q)) * A.j + B.z * A.k
    )
    assert simplify(express(B.x * B.i + B.y * B.j + B.z * B.k, A, variables=True)) == A.x * A.i + A.y * A.j + A.z * A.k
    assert (
        express(A.x * A.i + A.y * A.j + A.z * A.k, B)
        == (A.x * cos(q) + A.y * sin(q)) * B.i + (-A.x * sin(q) + A.y * cos(q)) * B.j + A.z * B.k
    )
    assert simplify(express(A.x * A.i + A.y * A.j + A.z * A.k, B, variables=True)) == B.x * B.i + B.y * B.j + B.z * B.k
    N = B.orient_new_axis("N", -q, B.k)
    assert N.scalar_map(A) == {N.x: A.x, N.z: A.z, N.y: A.y}
    C = A.orient_new_axis("C", q, A.i + A.j + A.k)
    mapping = A.scalar_map(C)
    assert (
        mapping[A.x]
        == 2 * C.x * cos(q) / 3
        + C.x / 3
        - 2 * C.y * sin(q + pi / 6) / 3
        + C.y / 3
        - 2 * C.z * cos(q + pi / 3) / 3
        + C.z / 3
    )
    assert (
        mapping[A.y]
        == -2 * C.x * cos(q + pi / 3) / 3
        + C.x / 3
        + 2 * C.y * cos(q) / 3
        + C.y / 3
        - 2 * C.z * sin(q + pi / 6) / 3
        + C.z / 3
    )
    assert (
        mapping[A.z]
        == -2 * C.x * sin(q + pi / 6) / 3
        + C.x / 3
        - 2 * C.y * cos(q + pi / 3) / 3
        + C.y / 3
        + 2 * C.z * cos(q) / 3
        + C.z / 3
    )
    D = A.locate_new("D", a * A.i + b * A.j + c * A.k)
    assert D.scalar_map(A) == {D.z: A.z - c, D.x: A.x - a, D.y: A.y - b}
    E = A.orient_new_axis("E", a, A.k, a * A.i + b * A.j + c * A.k)
    assert A.scalar_map(E) == {A.z: E.z + c, A.x: E.x * cos(a) - E.y * sin(a) + a, A.y: E.x * sin(a) + E.y * cos(a) + b}
    assert E.scalar_map(A) == {
        E.x: (A.x - a) * cos(a) + (A.y - b) * sin(a),
        E.y: (-A.x + a) * sin(a) + (A.y - b) * cos(a),
        E.z: A.z - c,
    }
    F = A.locate_new("F", Vector.zero)
    assert A.scalar_map(F) == {A.z: F.z, A.x: F.x, A.y: F.y}
Esempio n. 17
0
def test_coordinate_vars():
    """
    Tests the coordinate variables functionality with respect to
    reorientation of coordinate systems.
    """
    A = CoordSysCartesian('A')
    # Note that the name given on the lhs is different from A.x._name
    assert BaseScalar('A.x', 0, A, 'A_x', r'\mathbf{{x}_{A}}') == A.x
    assert BaseScalar('A.y', 1, A, 'A_y', r'\mathbf{{y}_{A}}') == A.y
    assert BaseScalar('A.z', 2, A, 'A_z', r'\mathbf{{z}_{A}}') == A.z
    assert BaseScalar('A.x', 0, A, 'A_x', r'\mathbf{{x}_{A}}').__hash__() == A.x.__hash__()
    assert isinstance(A.x, BaseScalar) and \
           isinstance(A.y, BaseScalar) and \
           isinstance(A.z, BaseScalar)
    assert A.x*A.y == A.y*A.x
    assert A.scalar_map(A) == {A.x: A.x, A.y: A.y, A.z: A.z}
    assert A.x.system == A
    assert A.x.diff(A.x) == 1
    B = A.orient_new_axis('B', q, A.k)
    assert B.scalar_map(A) == {B.z: A.z, B.y: -A.x*sin(q) + A.y*cos(q),
                                 B.x: A.x*cos(q) + A.y*sin(q)}
    assert A.scalar_map(B) == {A.x: B.x*cos(q) - B.y*sin(q),
                                 A.y: B.x*sin(q) + B.y*cos(q), A.z: B.z}
    assert express(B.x, A, variables=True) == A.x*cos(q) + A.y*sin(q)
    assert express(B.y, A, variables=True) == -A.x*sin(q) + A.y*cos(q)
    assert express(B.z, A, variables=True) == A.z
    assert expand(express(B.x*B.y*B.z, A, variables=True)) == \
           expand(A.z*(-A.x*sin(q) + A.y*cos(q))*(A.x*cos(q) + A.y*sin(q)))
    assert express(B.x*B.i + B.y*B.j + B.z*B.k, A) == \
           (B.x*cos(q) - B.y*sin(q))*A.i + (B.x*sin(q) + \
           B.y*cos(q))*A.j + B.z*A.k
    assert simplify(express(B.x*B.i + B.y*B.j + B.z*B.k, A, \
                            variables=True)) == \
           A.x*A.i + A.y*A.j + A.z*A.k
    assert express(A.x*A.i + A.y*A.j + A.z*A.k, B) == \
           (A.x*cos(q) + A.y*sin(q))*B.i + \
           (-A.x*sin(q) + A.y*cos(q))*B.j + A.z*B.k
    assert simplify(express(A.x*A.i + A.y*A.j + A.z*A.k, B, \
                            variables=True)) == \
           B.x*B.i + B.y*B.j + B.z*B.k
    N = B.orient_new_axis('N', -q, B.k)
    assert N.scalar_map(A) == \
           {N.x: A.x, N.z: A.z, N.y: A.y}
    C = A.orient_new_axis('C', q, A.i + A.j + A.k)
    mapping = A.scalar_map(C)
    assert mapping[A.x] == (C.x*(2*cos(q) + 1)/3 +
                            C.y*(-2*sin(q + pi/6) + 1)/3 +
                            C.z*(-2*cos(q + pi/3) + 1)/3)
    assert mapping[A.y] == (C.x*(-2*cos(q + pi/3) + 1)/3 +
                            C.y*(2*cos(q) + 1)/3 +
                            C.z*(-2*sin(q + pi/6) + 1)/3)
    assert mapping[A.z] == (C.x*(-2*sin(q + pi/6) + 1)/3 +
                            C.y*(-2*cos(q + pi/3) + 1)/3 +
                            C.z*(2*cos(q) + 1)/3)
    D = A.locate_new('D', a*A.i + b*A.j + c*A.k)
    assert D.scalar_map(A) == {D.z: A.z - c, D.x: A.x - a, D.y: A.y - b}
    E = A.orient_new_axis('E', a, A.k, a*A.i + b*A.j + c*A.k)
    assert A.scalar_map(E) == {A.z: E.z + c,
                               A.x: E.x*cos(a) - E.y*sin(a) + a,
                               A.y: E.x*sin(a) + E.y*cos(a) + b}
    assert E.scalar_map(A) == {E.x: (A.x - a)*cos(a) + (A.y - b)*sin(a),
                               E.y: (-A.x + a)*sin(a) + (A.y - b)*cos(a),
                               E.z: A.z - c}
    F = A.locate_new('F', Vector.zero)
    assert A.scalar_map(F) == {A.z: F.z, A.x: F.x, A.y: F.y}
Esempio n. 18
0
def test_coordinate_vars():
    """
    Tests the coordinate variables functionality with respect to
    reorientation of coordinate systems.
    """
    A = CoordSysCartesian('A')
    assert BaseScalar('Ax', 0, A, ' ', ' ') == A.x
    assert BaseScalar('Ay', 1, A, ' ', ' ') == A.y
    assert BaseScalar('Az', 2, A, ' ', ' ') == A.z
    assert BaseScalar('Ax', 0, A, ' ', ' ').__hash__() == A.x.__hash__()
    assert isinstance(A.x, BaseScalar) and \
           isinstance(A.y, BaseScalar) and \
           isinstance(A.z, BaseScalar)
    assert A.scalar_map(A) == {A.x: A.x, A.y: A.y, A.z: A.z}
    assert A.x.system == A
    B = A.orient_new_axis('B', q, A.k)
    assert B.scalar_map(A) == {
        B.z: A.z,
        B.y: -A.x * sin(q) + A.y * cos(q),
        B.x: A.x * cos(q) + A.y * sin(q)
    }
    assert A.scalar_map(B) == {
        A.x: B.x * cos(q) - B.y * sin(q),
        A.y: B.x * sin(q) + B.y * cos(q),
        A.z: B.z
    }
    assert express(B.x, A, variables=True) == A.x * cos(q) + A.y * sin(q)
    assert express(B.y, A, variables=True) == -A.x * sin(q) + A.y * cos(q)
    assert express(B.z, A, variables=True) == A.z
    assert express(B.x*B.y*B.z, A, variables=True) == \
           A.z*(-A.x*sin(q) + A.y*cos(q))*(A.x*cos(q) + A.y*sin(q))
    assert express(B.x*B.i + B.y*B.j + B.z*B.k, A) == \
           (B.x*cos(q) - B.y*sin(q))*A.i + (B.x*sin(q) + \
           B.y*cos(q))*A.j + B.z*A.k
    assert simplify(express(B.x*B.i + B.y*B.j + B.z*B.k, A, \
                            variables=True)) == \
           A.x*A.i + A.y*A.j + A.z*A.k
    assert express(A.x*A.i + A.y*A.j + A.z*A.k, B) == \
           (A.x*cos(q) + A.y*sin(q))*B.i + \
           (-A.x*sin(q) + A.y*cos(q))*B.j + A.z*B.k
    assert simplify(express(A.x*A.i + A.y*A.j + A.z*A.k, B, \
                            variables=True)) == \
           B.x*B.i + B.y*B.j + B.z*B.k
    N = B.orient_new_axis('N', -q, B.k)
    assert N.scalar_map(A) == \
           {N.x: A.x, N.z: A.z, N.y: A.y}
    C = A.orient_new_axis('C', q, A.i + A.j + A.k)
    mapping = A.scalar_map(C)
    assert mapping[A.x] == 2*C.x*cos(q)/3 + C.x/3 - \
           2*C.y*sin(q + pi/6)/3 + C.y/3 - 2*C.z*cos(q + pi/3)/3 + C.z/3
    assert mapping[A.y] == -2*C.x*cos(q + pi/3)/3 + \
           C.x/3 + 2*C.y*cos(q)/3 + C.y/3 - 2*C.z*sin(q + pi/6)/3 + C.z/3
    assert mapping[A.z] == -2*C.x*sin(q + pi/6)/3 + C.x/3 - \
           2*C.y*cos(q + pi/3)/3 + C.y/3 + 2*C.z*cos(q)/3 + C.z/3
    D = A.locate_new('D', a * A.i + b * A.j + c * A.k)
    assert D.scalar_map(A) == {D.z: A.z - c, D.x: A.x - a, D.y: A.y - b}
    E = A.orient_new_axis('E', a, A.k, a * A.i + b * A.j + c * A.k)
    assert A.scalar_map(E) == {
        A.z: E.z + c,
        A.x: E.x * cos(a) - E.y * sin(a) + a,
        A.y: E.x * sin(a) + E.y * cos(a) + b
    }
    assert E.scalar_map(A) == {
        E.x: (A.x - a) * cos(a) + (A.y - b) * sin(a),
        E.y: (-A.x + a) * sin(a) + (A.y - b) * cos(a),
        E.z: A.z - c
    }
    F = A.locate_new('F', Vector.zero)
    assert A.scalar_map(F) == {A.z: F.z, A.x: F.x, A.y: F.y}
Esempio n. 19
0
from sympy.vector.vector import Vector
from sympy.vector.coordsysrect import CoordSysCartesian
from sympy.vector.functions import express, matrix_to_vector, orthogonalize
from sympy import symbols, S, sqrt, sin, cos, ImmutableMatrix as Matrix
from sympy.utilities.pytest import raises

N = CoordSysCartesian('N')
q1, q2, q3, q4, q5 = symbols('q1 q2 q3 q4 q5')
A = N.orient_new_axis('A', q1, N.k)
B = A.orient_new_axis('B', q2, A.i)
C = B.orient_new_axis('C', q3, B.j)


def test_express():
    assert express(Vector.zero, N) == Vector.zero
    assert express(S(0), N) == S(0)
    assert express(A.i, C) == cos(q3)*C.i + sin(q3)*C.k
    assert express(A.j, C) == sin(q2)*sin(q3)*C.i + cos(q2)*C.j - \
        sin(q2)*cos(q3)*C.k
    assert express(A.k, C) == -sin(q3)*cos(q2)*C.i + sin(q2)*C.j + \
        cos(q2)*cos(q3)*C.k
    assert express(A.i, N) == cos(q1)*N.i + sin(q1)*N.j
    assert express(A.j, N) == -sin(q1)*N.i + cos(q1)*N.j
    assert express(A.k, N) == N.k
    assert express(A.i, A) == A.i
    assert express(A.j, A) == A.j
    assert express(A.k, A) == A.k
    assert express(A.i, B) == B.i
    assert express(A.j, B) == cos(q2)*B.j - sin(q2)*B.k
    assert express(A.k, B) == sin(q2)*B.j + cos(q2)*B.k
    assert express(A.i, C) == cos(q3)*C.i + sin(q3)*C.k
Esempio n. 20
0
    rhs = ((v & (delop ^ u)) - (u & (delop ^ v))).doit()
    assert simplify(lhs) == simplify(rhs)

    #Fifth product rule
    lhs = (delop ^ (f * v)).doit()
    rhs = (((delop(f)) ^ v) + (f * (delop ^ v))).doit()
    assert simplify(lhs) == simplify(rhs)

    #Sixth product rule
    lhs = (delop ^ (u ^ v)).doit()
    rhs = ((u * (delop & v) - v * (delop & u) +
           (v & delop)(u) - (u & delop)(v))).doit()
    assert simplify(lhs) == simplify(rhs)


P = C.orient_new_axis('P', q, C.k)
scalar_field = 2*x**2*y*z
grad_field = gradient(scalar_field, C)
vector_field = y**2*i + 3*x*j + 5*y*z*k
curl_field = curl(vector_field, C)


def test_conservative():
    assert is_conservative(Vector.zero) is True
    assert is_conservative(i) is True
    assert is_conservative(2 * i + 3 * j + 4 * k) is True
    assert (is_conservative(y*z*i + x*z*j + x*y*k) is
            True)
    assert is_conservative(x * j) is False
    assert is_conservative(grad_field) is True
    assert is_conservative(curl_field) is False
Esempio n. 21
0
def test_rotation_matrix():
    N = CoordSysCartesian("N")
    A = N.orient_new_axis("A", q1, N.k)
    B = A.orient_new_axis("B", q2, A.i)
    C = B.orient_new_axis("C", q3, B.j)
    D = N.orient_new_axis("D", q4, N.j)
    E = N.orient_new_space("E", q1, q2, q3, "123")
    F = N.orient_new_quaternion("F", q1, q2, q3, q4)
    G = N.orient_new_body("G", q1, q2, q3, "123")
    assert N.rotation_matrix(C) == Matrix(
        [
            [
                -sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3),
                -sin(q1) * cos(q2),
                sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1),
            ],
            [
                sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1),
                cos(q1) * cos(q2),
                sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3),
            ],
            [-sin(q3) * cos(q2), sin(q2), cos(q2) * cos(q3)],
        ]
    )
    test_mat = D.rotation_matrix(C) - Matrix(
        [
            [
                cos(q1) * cos(q3) * cos(q4) - sin(q3) * (-sin(q4) * cos(q2) + sin(q1) * sin(q2) * cos(q4)),
                -sin(q2) * sin(q4) - sin(q1) * cos(q2) * cos(q4),
                sin(q3) * cos(q1) * cos(q4) + cos(q3) * (-sin(q4) * cos(q2) + sin(q1) * sin(q2) * cos(q4)),
            ],
            [
                sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1),
                cos(q1) * cos(q2),
                sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3),
            ],
            [
                sin(q4) * cos(q1) * cos(q3) - sin(q3) * (cos(q2) * cos(q4) + sin(q1) * sin(q2) * sin(q4)),
                sin(q2) * cos(q4) - sin(q1) * sin(q4) * cos(q2),
                sin(q3) * sin(q4) * cos(q1) + cos(q3) * (cos(q2) * cos(q4) + sin(q1) * sin(q2) * sin(q4)),
            ],
        ]
    )
    assert test_mat.expand() == zeros(3, 3)
    assert E.rotation_matrix(N) == Matrix(
        [
            [cos(q2) * cos(q3), sin(q3) * cos(q2), -sin(q2)],
            [
                sin(q1) * sin(q2) * cos(q3) - sin(q3) * cos(q1),
                sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3),
                sin(q1) * cos(q2),
            ],
            [
                sin(q1) * sin(q3) + sin(q2) * cos(q1) * cos(q3),
                -sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1),
                cos(q1) * cos(q2),
            ],
        ]
    )
    assert F.rotation_matrix(N) == Matrix(
        [
            [q1 ** 2 + q2 ** 2 - q3 ** 2 - q4 ** 2, 2 * q1 * q4 + 2 * q2 * q3, -2 * q1 * q3 + 2 * q2 * q4],
            [-2 * q1 * q4 + 2 * q2 * q3, q1 ** 2 - q2 ** 2 + q3 ** 2 - q4 ** 2, 2 * q1 * q2 + 2 * q3 * q4],
            [2 * q1 * q3 + 2 * q2 * q4, -2 * q1 * q2 + 2 * q3 * q4, q1 ** 2 - q2 ** 2 - q3 ** 2 + q4 ** 2],
        ]
    )
    assert G.rotation_matrix(N) == Matrix(
        [
            [
                cos(q2) * cos(q3),
                sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1),
                sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3),
            ],
            [
                -sin(q3) * cos(q2),
                -sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3),
                sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1),
            ],
            [sin(q2), -sin(q1) * cos(q2), cos(q1) * cos(q2)],
        ]
    )