I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,464 @@
from sympy.testing.pytest import raises
from sympy.vector.coordsysrect import CoordSys3D
from sympy.vector.scalar import BaseScalar
from sympy.core.function import expand
from sympy.core.numbers import pi
from sympy.core.symbol import symbols
from sympy.functions.elementary.hyperbolic import (cosh, sinh)
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import (acos, atan2, cos, sin)
from sympy.matrices.dense import zeros
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
from sympy.simplify.simplify import simplify
from sympy.vector.functions import express
from sympy.vector.point import Point
from sympy.vector.vector import Vector
from sympy.vector.orienters import (AxisOrienter, BodyOrienter,
SpaceOrienter, QuaternionOrienter)
x, y, z = symbols('x y z')
a, b, c, q = symbols('a b c q')
q1, q2, q3, q4 = symbols('q1 q2 q3 q4')
def test_func_args():
A = CoordSys3D('A')
assert A.x.func(*A.x.args) == A.x
expr = 3*A.x + 4*A.y
assert expr.func(*expr.args) == expr
assert A.i.func(*A.i.args) == A.i
v = A.x*A.i + A.y*A.j + A.z*A.k
assert v.func(*v.args) == v
assert A.origin.func(*A.origin.args) == A.origin
def test_coordsys3d_equivalence():
A = CoordSys3D('A')
A1 = CoordSys3D('A')
assert A1 == A
B = CoordSys3D('B')
assert A != B
def test_orienters():
A = CoordSys3D('A')
axis_orienter = AxisOrienter(a, A.k)
body_orienter = BodyOrienter(a, b, c, '123')
space_orienter = SpaceOrienter(a, b, c, '123')
q_orienter = QuaternionOrienter(q1, q2, q3, q4)
assert axis_orienter.rotation_matrix(A) == Matrix([
[ cos(a), sin(a), 0],
[-sin(a), cos(a), 0],
[ 0, 0, 1]])
assert body_orienter.rotation_matrix() == Matrix([
[ cos(b)*cos(c), sin(a)*sin(b)*cos(c) + sin(c)*cos(a),
sin(a)*sin(c) - sin(b)*cos(a)*cos(c)],
[-sin(c)*cos(b), -sin(a)*sin(b)*sin(c) + cos(a)*cos(c),
sin(a)*cos(c) + sin(b)*sin(c)*cos(a)],
[ sin(b), -sin(a)*cos(b),
cos(a)*cos(b)]])
assert space_orienter.rotation_matrix() == Matrix([
[cos(b)*cos(c), sin(c)*cos(b), -sin(b)],
[sin(a)*sin(b)*cos(c) - sin(c)*cos(a),
sin(a)*sin(b)*sin(c) + cos(a)*cos(c), sin(a)*cos(b)],
[sin(a)*sin(c) + sin(b)*cos(a)*cos(c), -sin(a)*cos(c) +
sin(b)*sin(c)*cos(a), cos(a)*cos(b)]])
assert q_orienter.rotation_matrix() == 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]])
def test_coordinate_vars():
"""
Tests the coordinate variables functionality with respect to
reorientation of coordinate systems.
"""
A = CoordSys3D('A')
# Note that the name given on the lhs is different from A.x._name
assert BaseScalar(0, A, 'A_x', r'\mathbf{{x}_{A}}') == A.x
assert BaseScalar(1, A, 'A_y', r'\mathbf{{y}_{A}}') == A.y
assert BaseScalar(2, A, 'A_z', r'\mathbf{{z}_{A}}') == A.z
assert BaseScalar(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}
def test_rotation_matrix():
N = CoordSys3D('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_with_orientation():
"""
Tests the effects of orientation of coordinate systems on
basic vector operations.
"""
N = CoordSys3D('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
def test_orient_new_methods():
N = CoordSys3D('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')
def test_locatenew_point():
"""
Tests Point class, and locate_new method in CoordSys3D.
"""
A = CoordSys3D('A')
assert isinstance(A.origin, Point)
v = a*A.i + b*A.j + c*A.k
C = A.locate_new('C', v)
assert C.origin.position_wrt(A) == \
C.position_wrt(A) == \
C.origin.position_wrt(A.origin) == v
assert A.origin.position_wrt(C) == \
A.position_wrt(C) == \
A.origin.position_wrt(C.origin) == -v
assert A.origin.express_coordinates(C) == (-a, -b, -c)
p = A.origin.locate_new('p', -v)
assert p.express_coordinates(A) == (-a, -b, -c)
assert p.position_wrt(C.origin) == p.position_wrt(C) == \
-2 * v
p1 = p.locate_new('p1', 2*v)
assert p1.position_wrt(C.origin) == Vector.zero
assert p1.express_coordinates(C) == (0, 0, 0)
p2 = p.locate_new('p2', A.i)
assert p1.position_wrt(p2) == 2*v - A.i
assert p2.express_coordinates(C) == (-2*a + 1, -2*b, -2*c)
def test_create_new():
a = CoordSys3D('a')
c = a.create_new('c', transformation='spherical')
assert c._parent == a
assert c.transformation_to_parent() == \
(c.r*sin(c.theta)*cos(c.phi), c.r*sin(c.theta)*sin(c.phi), c.r*cos(c.theta))
assert c.transformation_from_parent() == \
(sqrt(a.x**2 + a.y**2 + a.z**2), acos(a.z/sqrt(a.x**2 + a.y**2 + a.z**2)), atan2(a.y, a.x))
def test_evalf():
A = CoordSys3D('A')
v = 3*A.i + 4*A.j + a*A.k
assert v.n() == v.evalf()
assert v.evalf(subs={a:1}) == v.subs(a, 1).evalf()
def test_lame_coefficients():
a = CoordSys3D('a', 'spherical')
assert a.lame_coefficients() == (1, a.r, sin(a.theta)*a.r)
a = CoordSys3D('a')
assert a.lame_coefficients() == (1, 1, 1)
a = CoordSys3D('a', 'cartesian')
assert a.lame_coefficients() == (1, 1, 1)
a = CoordSys3D('a', 'cylindrical')
assert a.lame_coefficients() == (1, a.r, 1)
def test_transformation_equations():
x, y, z = symbols('x y z')
# Str
a = CoordSys3D('a', transformation='spherical',
variable_names=["r", "theta", "phi"])
r, theta, phi = a.base_scalars()
assert r == a.r
assert theta == a.theta
assert phi == a.phi
raises(AttributeError, lambda: a.x)
raises(AttributeError, lambda: a.y)
raises(AttributeError, lambda: a.z)
assert a.transformation_to_parent() == (
r*sin(theta)*cos(phi),
r*sin(theta)*sin(phi),
r*cos(theta)
)
assert a.lame_coefficients() == (1, r, r*sin(theta))
assert a.transformation_from_parent_function()(x, y, z) == (
sqrt(x ** 2 + y ** 2 + z ** 2),
acos((z) / sqrt(x**2 + y**2 + z**2)),
atan2(y, x)
)
a = CoordSys3D('a', transformation='cylindrical',
variable_names=["r", "theta", "z"])
r, theta, z = a.base_scalars()
assert a.transformation_to_parent() == (
r*cos(theta),
r*sin(theta),
z
)
assert a.lame_coefficients() == (1, a.r, 1)
assert a.transformation_from_parent_function()(x, y, z) == (sqrt(x**2 + y**2),
atan2(y, x), z)
a = CoordSys3D('a', 'cartesian')
assert a.transformation_to_parent() == (a.x, a.y, a.z)
assert a.lame_coefficients() == (1, 1, 1)
assert a.transformation_from_parent_function()(x, y, z) == (x, y, z)
# Variables and expressions
# Cartesian with equation tuple:
x, y, z = symbols('x y z')
a = CoordSys3D('a', ((x, y, z), (x, y, z)))
a._calculate_inv_trans_equations()
assert a.transformation_to_parent() == (a.x1, a.x2, a.x3)
assert a.lame_coefficients() == (1, 1, 1)
assert a.transformation_from_parent_function()(x, y, z) == (x, y, z)
r, theta, z = symbols("r theta z")
# Cylindrical with equation tuple:
a = CoordSys3D('a', [(r, theta, z), (r*cos(theta), r*sin(theta), z)],
variable_names=["r", "theta", "z"])
r, theta, z = a.base_scalars()
assert a.transformation_to_parent() == (
r*cos(theta), r*sin(theta), z
)
assert a.lame_coefficients() == (
sqrt(sin(theta)**2 + cos(theta)**2),
sqrt(r**2*sin(theta)**2 + r**2*cos(theta)**2),
1
) # ==> this should simplify to (1, r, 1), tests are too slow with `simplify`.
# Definitions with `lambda`:
# Cartesian with `lambda`
a = CoordSys3D('a', lambda x, y, z: (x, y, z))
assert a.transformation_to_parent() == (a.x1, a.x2, a.x3)
assert a.lame_coefficients() == (1, 1, 1)
a._calculate_inv_trans_equations()
assert a.transformation_from_parent_function()(x, y, z) == (x, y, z)
# Spherical with `lambda`
a = CoordSys3D('a', lambda r, theta, phi: (r*sin(theta)*cos(phi), r*sin(theta)*sin(phi), r*cos(theta)),
variable_names=["r", "theta", "phi"])
r, theta, phi = a.base_scalars()
assert a.transformation_to_parent() == (
r*sin(theta)*cos(phi), r*sin(phi)*sin(theta), r*cos(theta)
)
assert a.lame_coefficients() == (
sqrt(sin(phi)**2*sin(theta)**2 + sin(theta)**2*cos(phi)**2 + cos(theta)**2),
sqrt(r**2*sin(phi)**2*cos(theta)**2 + r**2*sin(theta)**2 + r**2*cos(phi)**2*cos(theta)**2),
sqrt(r**2*sin(phi)**2*sin(theta)**2 + r**2*sin(theta)**2*cos(phi)**2)
) # ==> this should simplify to (1, r, sin(theta)*r), `simplify` is too slow.
# Cylindrical with `lambda`
a = CoordSys3D('a', lambda r, theta, z:
(r*cos(theta), r*sin(theta), z),
variable_names=["r", "theta", "z"]
)
r, theta, z = a.base_scalars()
assert a.transformation_to_parent() == (r*cos(theta), r*sin(theta), z)
assert a.lame_coefficients() == (
sqrt(sin(theta)**2 + cos(theta)**2),
sqrt(r**2*sin(theta)**2 + r**2*cos(theta)**2),
1
) # ==> this should simplify to (1, a.x, 1)
raises(TypeError, lambda: CoordSys3D('a', transformation={
x: x*sin(y)*cos(z), y:x*sin(y)*sin(z), z: x*cos(y)}))
def test_check_orthogonality():
x, y, z = symbols('x y z')
u,v = symbols('u, v')
a = CoordSys3D('a', transformation=((x, y, z), (x*sin(y)*cos(z), x*sin(y)*sin(z), x*cos(y))))
assert a._check_orthogonality(a._transformation) is True
a = CoordSys3D('a', transformation=((x, y, z), (x * cos(y), x * sin(y), z)))
assert a._check_orthogonality(a._transformation) is True
a = CoordSys3D('a', transformation=((u, v, z), (cosh(u) * cos(v), sinh(u) * sin(v), z)))
assert a._check_orthogonality(a._transformation) is True
raises(ValueError, lambda: CoordSys3D('a', transformation=((x, y, z), (x, x, z))))
raises(ValueError, lambda: CoordSys3D('a', transformation=(
(x, y, z), (x*sin(y/2)*cos(z), x*sin(y)*sin(z), x*cos(y)))))
def test_rotation_trans_equations():
a = CoordSys3D('a')
from sympy.core.symbol import symbols
q0 = symbols('q0')
assert a._rotation_trans_equations(a._parent_rotation_matrix, a.base_scalars()) == (a.x, a.y, a.z)
assert a._rotation_trans_equations(a._inverse_rotation_matrix(), a.base_scalars()) == (a.x, a.y, a.z)
b = a.orient_new_axis('b', 0, -a.k)
assert b._rotation_trans_equations(b._parent_rotation_matrix, b.base_scalars()) == (b.x, b.y, b.z)
assert b._rotation_trans_equations(b._inverse_rotation_matrix(), b.base_scalars()) == (b.x, b.y, b.z)
c = a.orient_new_axis('c', q0, -a.k)
assert c._rotation_trans_equations(c._parent_rotation_matrix, c.base_scalars()) == \
(-sin(q0) * c.y + cos(q0) * c.x, sin(q0) * c.x + cos(q0) * c.y, c.z)
assert c._rotation_trans_equations(c._inverse_rotation_matrix(), c.base_scalars()) == \
(sin(q0) * c.y + cos(q0) * c.x, -sin(q0) * c.x + cos(q0) * c.y, c.z)

View File

@ -0,0 +1,134 @@
from sympy.core.numbers import pi
from sympy.core.symbol import symbols
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
from sympy.simplify.simplify import simplify
from sympy.vector import (CoordSys3D, Vector, Dyadic,
DyadicAdd, DyadicMul, DyadicZero,
BaseDyadic, express)
A = CoordSys3D('A')
def test_dyadic():
a, b = symbols('a, b')
assert Dyadic.zero != 0
assert isinstance(Dyadic.zero, DyadicZero)
assert BaseDyadic(A.i, A.j) != BaseDyadic(A.j, A.i)
assert (BaseDyadic(Vector.zero, A.i) ==
BaseDyadic(A.i, Vector.zero) == Dyadic.zero)
d1 = A.i | A.i
d2 = A.j | A.j
d3 = A.i | A.j
assert isinstance(d1, BaseDyadic)
d_mul = a*d1
assert isinstance(d_mul, DyadicMul)
assert d_mul.base_dyadic == d1
assert d_mul.measure_number == a
assert isinstance(a*d1 + b*d3, DyadicAdd)
assert d1 == A.i.outer(A.i)
assert d3 == A.i.outer(A.j)
v1 = a*A.i - A.k
v2 = A.i + b*A.j
assert v1 | v2 == v1.outer(v2) == a * (A.i|A.i) + (a*b) * (A.i|A.j) +\
- (A.k|A.i) - b * (A.k|A.j)
assert d1 * 0 == Dyadic.zero
assert d1 != Dyadic.zero
assert d1 * 2 == 2 * (A.i | A.i)
assert d1 / 2. == 0.5 * d1
assert d1.dot(0 * d1) == Vector.zero
assert d1 & d2 == Dyadic.zero
assert d1.dot(A.i) == A.i == d1 & A.i
assert d1.cross(Vector.zero) == Dyadic.zero
assert d1.cross(A.i) == Dyadic.zero
assert d1 ^ A.j == d1.cross(A.j)
assert d1.cross(A.k) == - A.i | A.j
assert d2.cross(A.i) == - A.j | A.k == d2 ^ A.i
assert A.i ^ d1 == Dyadic.zero
assert A.j.cross(d1) == - A.k | A.i == A.j ^ d1
assert Vector.zero.cross(d1) == Dyadic.zero
assert A.k ^ d1 == A.j | A.i
assert A.i.dot(d1) == A.i & d1 == A.i
assert A.j.dot(d1) == Vector.zero
assert Vector.zero.dot(d1) == Vector.zero
assert A.j & d2 == A.j
assert d1.dot(d3) == d1 & d3 == A.i | A.j == d3
assert d3 & d1 == Dyadic.zero
q = symbols('q')
B = A.orient_new_axis('B', q, A.k)
assert express(d1, B) == express(d1, B, B)
expr1 = ((cos(q)**2) * (B.i | B.i) + (-sin(q) * cos(q)) *
(B.i | B.j) + (-sin(q) * cos(q)) * (B.j | B.i) + (sin(q)**2) *
(B.j | B.j))
assert (express(d1, B) - expr1).simplify() == Dyadic.zero
expr2 = (cos(q)) * (B.i | A.i) + (-sin(q)) * (B.j | A.i)
assert (express(d1, B, A) - expr2).simplify() == Dyadic.zero
expr3 = (cos(q)) * (A.i | B.i) + (-sin(q)) * (A.i | B.j)
assert (express(d1, A, B) - expr3).simplify() == Dyadic.zero
assert d1.to_matrix(A) == Matrix([[1, 0, 0], [0, 0, 0], [0, 0, 0]])
assert d1.to_matrix(A, B) == Matrix([[cos(q), -sin(q), 0],
[0, 0, 0],
[0, 0, 0]])
assert d3.to_matrix(A) == Matrix([[0, 1, 0], [0, 0, 0], [0, 0, 0]])
a, b, c, d, e, f = symbols('a, b, c, d, e, f')
v1 = a * A.i + b * A.j + c * A.k
v2 = d * A.i + e * A.j + f * A.k
d4 = v1.outer(v2)
assert d4.to_matrix(A) == Matrix([[a * d, a * e, a * f],
[b * d, b * e, b * f],
[c * d, c * e, c * f]])
d5 = v1.outer(v1)
C = A.orient_new_axis('C', q, A.i)
for expected, actual in zip(C.rotation_matrix(A) * d5.to_matrix(A) * \
C.rotation_matrix(A).T, d5.to_matrix(C)):
assert (expected - actual).simplify() == 0
def test_dyadic_simplify():
x, y, z, k, n, m, w, f, s, A = symbols('x, y, z, k, n, m, w, f, s, A')
N = CoordSys3D('N')
dy = N.i | N.i
test1 = (1 / x + 1 / y) * dy
assert (N.i & test1 & N.i) != (x + y) / (x * y)
test1 = test1.simplify()
assert test1.simplify() == simplify(test1)
assert (N.i & test1 & N.i) == (x + y) / (x * y)
test2 = (A**2 * s**4 / (4 * pi * k * m**3)) * dy
test2 = test2.simplify()
assert (N.i & test2 & N.i) == (A**2 * s**4 / (4 * pi * k * m**3))
test3 = ((4 + 4 * x - 2 * (2 + 2 * x)) / (2 + 2 * x)) * dy
test3 = test3.simplify()
assert (N.i & test3 & N.i) == 0
test4 = ((-4 * x * y**2 - 2 * y**3 - 2 * x**2 * y) / (x + y)**2) * dy
test4 = test4.simplify()
assert (N.i & test4 & N.i) == -2 * y
def test_dyadic_srepr():
from sympy.printing.repr import srepr
N = CoordSys3D('N')
dy = N.i | N.j
res = "BaseDyadic(CoordSys3D(Str('N'), Tuple(ImmutableDenseMatrix([["\
"Integer(1), Integer(0), Integer(0)], [Integer(0), Integer(1), "\
"Integer(0)], [Integer(0), Integer(0), Integer(1)]]), "\
"VectorZero())).i, CoordSys3D(Str('N'), Tuple(ImmutableDenseMatrix("\
"[[Integer(1), Integer(0), Integer(0)], [Integer(0), Integer(1), "\
"Integer(0)], [Integer(0), Integer(0), Integer(1)]]), VectorZero())).j)"
assert srepr(dy) == res

View File

@ -0,0 +1,321 @@
from sympy.core.function import Derivative
from sympy.vector.vector import Vector
from sympy.vector.coordsysrect import CoordSys3D
from sympy.simplify import simplify
from sympy.core.symbol import symbols
from sympy.core import S
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.vector.vector import Dot
from sympy.vector.operators import curl, divergence, gradient, Gradient, Divergence, Cross
from sympy.vector.deloperator import Del
from sympy.vector.functions import (is_conservative, is_solenoidal,
scalar_potential, directional_derivative,
laplacian, scalar_potential_difference)
from sympy.testing.pytest import raises
C = CoordSys3D('C')
i, j, k = C.base_vectors()
x, y, z = C.base_scalars()
delop = Del()
a, b, c, q = symbols('a b c q')
def test_del_operator():
# Tests for curl
assert delop ^ Vector.zero == Vector.zero
assert ((delop ^ Vector.zero).doit() == Vector.zero ==
curl(Vector.zero))
assert delop.cross(Vector.zero) == delop ^ Vector.zero
assert (delop ^ i).doit() == Vector.zero
assert delop.cross(2*y**2*j, doit=True) == Vector.zero
assert delop.cross(2*y**2*j) == delop ^ 2*y**2*j
v = x*y*z * (i + j + k)
assert ((delop ^ v).doit() ==
(-x*y + x*z)*i + (x*y - y*z)*j + (-x*z + y*z)*k ==
curl(v))
assert delop ^ v == delop.cross(v)
assert (delop.cross(2*x**2*j) ==
(Derivative(0, C.y) - Derivative(2*C.x**2, C.z))*C.i +
(-Derivative(0, C.x) + Derivative(0, C.z))*C.j +
(-Derivative(0, C.y) + Derivative(2*C.x**2, C.x))*C.k)
assert (delop.cross(2*x**2*j, doit=True) == 4*x*k ==
curl(2*x**2*j))
#Tests for divergence
assert delop & Vector.zero is S.Zero == divergence(Vector.zero)
assert (delop & Vector.zero).doit() is S.Zero
assert delop.dot(Vector.zero) == delop & Vector.zero
assert (delop & i).doit() is S.Zero
assert (delop & x**2*i).doit() == 2*x == divergence(x**2*i)
assert (delop.dot(v, doit=True) == x*y + y*z + z*x ==
divergence(v))
assert delop & v == delop.dot(v)
assert delop.dot(1/(x*y*z) * (i + j + k), doit=True) == \
- 1 / (x*y*z**2) - 1 / (x*y**2*z) - 1 / (x**2*y*z)
v = x*i + y*j + z*k
assert (delop & v == Derivative(C.x, C.x) +
Derivative(C.y, C.y) + Derivative(C.z, C.z))
assert delop.dot(v, doit=True) == 3 == divergence(v)
assert delop & v == delop.dot(v)
assert simplify((delop & v).doit()) == 3
#Tests for gradient
assert (delop.gradient(0, doit=True) == Vector.zero ==
gradient(0))
assert delop.gradient(0) == delop(0)
assert (delop(S.Zero)).doit() == Vector.zero
assert (delop(x) == (Derivative(C.x, C.x))*C.i +
(Derivative(C.x, C.y))*C.j + (Derivative(C.x, C.z))*C.k)
assert (delop(x)).doit() == i == gradient(x)
assert (delop(x*y*z) ==
(Derivative(C.x*C.y*C.z, C.x))*C.i +
(Derivative(C.x*C.y*C.z, C.y))*C.j +
(Derivative(C.x*C.y*C.z, C.z))*C.k)
assert (delop.gradient(x*y*z, doit=True) ==
y*z*i + z*x*j + x*y*k ==
gradient(x*y*z))
assert delop(x*y*z) == delop.gradient(x*y*z)
assert (delop(2*x**2)).doit() == 4*x*i
assert ((delop(a*sin(y) / x)).doit() ==
-a*sin(y)/x**2 * i + a*cos(y)/x * j)
#Tests for directional derivative
assert (Vector.zero & delop)(a) is S.Zero
assert ((Vector.zero & delop)(a)).doit() is S.Zero
assert ((v & delop)(Vector.zero)).doit() == Vector.zero
assert ((v & delop)(S.Zero)).doit() is S.Zero
assert ((i & delop)(x)).doit() == 1
assert ((j & delop)(y)).doit() == 1
assert ((k & delop)(z)).doit() == 1
assert ((i & delop)(x*y*z)).doit() == y*z
assert ((v & delop)(x)).doit() == x
assert ((v & delop)(x*y*z)).doit() == 3*x*y*z
assert (v & delop)(x + y + z) == C.x + C.y + C.z
assert ((v & delop)(x + y + z)).doit() == x + y + z
assert ((v & delop)(v)).doit() == v
assert ((i & delop)(v)).doit() == i
assert ((j & delop)(v)).doit() == j
assert ((k & delop)(v)).doit() == k
assert ((v & delop)(Vector.zero)).doit() == Vector.zero
# Tests for laplacian on scalar fields
assert laplacian(x*y*z) is S.Zero
assert laplacian(x**2) == S(2)
assert laplacian(x**2*y**2*z**2) == \
2*y**2*z**2 + 2*x**2*z**2 + 2*x**2*y**2
A = CoordSys3D('A', transformation="spherical", variable_names=["r", "theta", "phi"])
B = CoordSys3D('B', transformation='cylindrical', variable_names=["r", "theta", "z"])
assert laplacian(A.r + A.theta + A.phi) == 2/A.r + cos(A.theta)/(A.r**2*sin(A.theta))
assert laplacian(B.r + B.theta + B.z) == 1/B.r
# Tests for laplacian on vector fields
assert laplacian(x*y*z*(i + j + k)) == Vector.zero
assert laplacian(x*y**2*z*(i + j + k)) == \
2*x*z*i + 2*x*z*j + 2*x*z*k
def test_product_rules():
"""
Tests the six product rules defined with respect to the Del
operator
References
==========
.. [1] https://en.wikipedia.org/wiki/Del
"""
#Define the scalar and vector functions
f = 2*x*y*z
g = x*y + y*z + z*x
u = x**2*i + 4*j - y**2*z*k
v = 4*i + x*y*z*k
# First product rule
lhs = delop(f * g, doit=True)
rhs = (f * delop(g) + g * delop(f)).doit()
assert simplify(lhs) == simplify(rhs)
# Second product rule
lhs = delop(u & v).doit()
rhs = ((u ^ (delop ^ v)) + (v ^ (delop ^ u)) + \
((u & delop)(v)) + ((v & delop)(u))).doit()
assert simplify(lhs) == simplify(rhs)
# Third product rule
lhs = (delop & (f*v)).doit()
rhs = ((f * (delop & v)) + (v & (delop(f)))).doit()
assert simplify(lhs) == simplify(rhs)
# Fourth product rule
lhs = (delop & (u ^ v)).doit()
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) # type: ignore
scalar_field = 2*x**2*y*z
grad_field = gradient(scalar_field)
vector_field = y**2*i + 3*x*j + 5*y*z*k
curl_field = curl(vector_field)
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)
assert is_conservative(z*P.i + P.x*k) is True
def test_solenoidal():
assert is_solenoidal(Vector.zero) is True
assert is_solenoidal(i) is True
assert is_solenoidal(2 * i + 3 * j + 4 * k) is True
assert (is_solenoidal(y*z*i + x*z*j + x*y*k) is
True)
assert is_solenoidal(y * j) is False
assert is_solenoidal(grad_field) is False
assert is_solenoidal(curl_field) is True
assert is_solenoidal((-2*y + 3)*k) is True
assert is_solenoidal(cos(q)*i + sin(q)*j + cos(q)*P.k) is True
assert is_solenoidal(z*P.i + P.x*k) is True
def test_directional_derivative():
assert directional_derivative(C.x*C.y*C.z, 3*C.i + 4*C.j + C.k) == C.x*C.y + 4*C.x*C.z + 3*C.y*C.z
assert directional_derivative(5*C.x**2*C.z, 3*C.i + 4*C.j + C.k) == 5*C.x**2 + 30*C.x*C.z
assert directional_derivative(5*C.x**2*C.z, 4*C.j) is S.Zero
D = CoordSys3D("D", "spherical", variable_names=["r", "theta", "phi"],
vector_names=["e_r", "e_theta", "e_phi"])
r, theta, phi = D.base_scalars()
e_r, e_theta, e_phi = D.base_vectors()
assert directional_derivative(r**2*e_r, e_r) == 2*r*e_r
assert directional_derivative(5*r**2*phi, 3*e_r + 4*e_theta + e_phi) == 5*r**2 + 30*r*phi
def test_scalar_potential():
assert scalar_potential(Vector.zero, C) == 0
assert scalar_potential(i, C) == x
assert scalar_potential(j, C) == y
assert scalar_potential(k, C) == z
assert scalar_potential(y*z*i + x*z*j + x*y*k, C) == x*y*z
assert scalar_potential(grad_field, C) == scalar_field
assert scalar_potential(z*P.i + P.x*k, C) == x*z*cos(q) + y*z*sin(q)
assert scalar_potential(z*P.i + P.x*k, P) == P.x*P.z
raises(ValueError, lambda: scalar_potential(x*j, C))
def test_scalar_potential_difference():
point1 = C.origin.locate_new('P1', 1*i + 2*j + 3*k)
point2 = C.origin.locate_new('P2', 4*i + 5*j + 6*k)
genericpointC = C.origin.locate_new('RP', x*i + y*j + z*k)
genericpointP = P.origin.locate_new('PP', P.x*P.i + P.y*P.j + P.z*P.k)
assert scalar_potential_difference(S.Zero, C, point1, point2) == 0
assert (scalar_potential_difference(scalar_field, C, C.origin,
genericpointC) ==
scalar_field)
assert (scalar_potential_difference(grad_field, C, C.origin,
genericpointC) ==
scalar_field)
assert scalar_potential_difference(grad_field, C, point1, point2) == 948
assert (scalar_potential_difference(y*z*i + x*z*j +
x*y*k, C, point1,
genericpointC) ==
x*y*z - 6)
potential_diff_P = (2*P.z*(P.x*sin(q) + P.y*cos(q))*
(P.x*cos(q) - P.y*sin(q))**2)
assert (scalar_potential_difference(grad_field, P, P.origin,
genericpointP).simplify() ==
potential_diff_P.simplify())
def test_differential_operators_curvilinear_system():
A = CoordSys3D('A', transformation="spherical", variable_names=["r", "theta", "phi"])
B = CoordSys3D('B', transformation='cylindrical', variable_names=["r", "theta", "z"])
# Test for spherical coordinate system and gradient
assert gradient(3*A.r + 4*A.theta) == 3*A.i + 4/A.r*A.j
assert gradient(3*A.r*A.phi + 4*A.theta) == 3*A.phi*A.i + 4/A.r*A.j + (3/sin(A.theta))*A.k
assert gradient(0*A.r + 0*A.theta+0*A.phi) == Vector.zero
assert gradient(A.r*A.theta*A.phi) == A.theta*A.phi*A.i + A.phi*A.j + (A.theta/sin(A.theta))*A.k
# Test for spherical coordinate system and divergence
assert divergence(A.r * A.i + A.theta * A.j + A.phi * A.k) == \
(sin(A.theta)*A.r + cos(A.theta)*A.r*A.theta)/(sin(A.theta)*A.r**2) + 3 + 1/(sin(A.theta)*A.r)
assert divergence(3*A.r*A.phi*A.i + A.theta*A.j + A.r*A.theta*A.phi*A.k) == \
(sin(A.theta)*A.r + cos(A.theta)*A.r*A.theta)/(sin(A.theta)*A.r**2) + 9*A.phi + A.theta/sin(A.theta)
assert divergence(Vector.zero) == 0
assert divergence(0*A.i + 0*A.j + 0*A.k) == 0
# Test for spherical coordinate system and curl
assert curl(A.r*A.i + A.theta*A.j + A.phi*A.k) == \
(cos(A.theta)*A.phi/(sin(A.theta)*A.r))*A.i + (-A.phi/A.r)*A.j + A.theta/A.r*A.k
assert curl(A.r*A.j + A.phi*A.k) == (cos(A.theta)*A.phi/(sin(A.theta)*A.r))*A.i + (-A.phi/A.r)*A.j + 2*A.k
# Test for cylindrical coordinate system and gradient
assert gradient(0*B.r + 0*B.theta+0*B.z) == Vector.zero
assert gradient(B.r*B.theta*B.z) == B.theta*B.z*B.i + B.z*B.j + B.r*B.theta*B.k
assert gradient(3*B.r) == 3*B.i
assert gradient(2*B.theta) == 2/B.r * B.j
assert gradient(4*B.z) == 4*B.k
# Test for cylindrical coordinate system and divergence
assert divergence(B.r*B.i + B.theta*B.j + B.z*B.k) == 3 + 1/B.r
assert divergence(B.r*B.j + B.z*B.k) == 1
# Test for cylindrical coordinate system and curl
assert curl(B.r*B.j + B.z*B.k) == 2*B.k
assert curl(3*B.i + 2/B.r*B.j + 4*B.k) == Vector.zero
def test_mixed_coordinates():
# gradient
a = CoordSys3D('a')
b = CoordSys3D('b')
c = CoordSys3D('c')
assert gradient(a.x*b.y) == b.y*a.i + a.x*b.j
assert gradient(3*cos(q)*a.x*b.x+a.y*(a.x+(cos(q)+b.x))) ==\
(a.y + 3*b.x*cos(q))*a.i + (a.x + b.x + cos(q))*a.j + (3*a.x*cos(q) + a.y)*b.i
# Some tests need further work:
# assert gradient(a.x*(cos(a.x+b.x))) == (cos(a.x + b.x))*a.i + a.x*Gradient(cos(a.x + b.x))
# assert gradient(cos(a.x + b.x)*cos(a.x + b.z)) == Gradient(cos(a.x + b.x)*cos(a.x + b.z))
assert gradient(a.x**b.y) == Gradient(a.x**b.y)
# assert gradient(cos(a.x+b.y)*a.z) == None
assert gradient(cos(a.x*b.y)) == Gradient(cos(a.x*b.y))
assert gradient(3*cos(q)*a.x*b.x*a.z*a.y+ b.y*b.z + cos(a.x+a.y)*b.z) == \
(3*a.y*a.z*b.x*cos(q) - b.z*sin(a.x + a.y))*a.i + \
(3*a.x*a.z*b.x*cos(q) - b.z*sin(a.x + a.y))*a.j + (3*a.x*a.y*b.x*cos(q))*a.k + \
(3*a.x*a.y*a.z*cos(q))*b.i + b.z*b.j + (b.y + cos(a.x + a.y))*b.k
# divergence
assert divergence(a.i*a.x+a.j*a.y+a.z*a.k + b.i*b.x+b.j*b.y+b.z*b.k + c.i*c.x+c.j*c.y+c.z*c.k) == S(9)
# assert divergence(3*a.i*a.x*cos(a.x+b.z) + a.j*b.x*c.z) == None
assert divergence(3*a.i*a.x*a.z + b.j*b.x*c.z + 3*a.j*a.z*a.y) == \
6*a.z + b.x*Dot(b.j, c.k)
assert divergence(3*cos(q)*a.x*b.x*b.i*c.x) == \
3*a.x*b.x*cos(q)*Dot(b.i, c.i) + 3*a.x*c.x*cos(q) + 3*b.x*c.x*cos(q)*Dot(b.i, a.i)
assert divergence(a.x*b.x*c.x*Cross(a.x*a.i, a.y*b.j)) ==\
a.x*b.x*c.x*Divergence(Cross(a.x*a.i, a.y*b.j)) + \
b.x*c.x*Dot(Cross(a.x*a.i, a.y*b.j), a.i) + \
a.x*c.x*Dot(Cross(a.x*a.i, a.y*b.j), b.i) + \
a.x*b.x*Dot(Cross(a.x*a.i, a.y*b.j), c.i)
assert divergence(a.x*b.x*c.x*(a.x*a.i + b.x*b.i)) == \
4*a.x*b.x*c.x +\
a.x**2*c.x*Dot(a.i, b.i) +\
a.x**2*b.x*Dot(a.i, c.i) +\
b.x**2*c.x*Dot(b.i, a.i) +\
a.x*b.x**2*Dot(b.i, c.i)

View File

@ -0,0 +1,184 @@
from sympy.vector.vector import Vector
from sympy.vector.coordsysrect import CoordSys3D
from sympy.vector.functions import express, matrix_to_vector, orthogonalize
from sympy.core.numbers import Rational
from sympy.core.singleton import S
from sympy.core.symbol import symbols
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
from sympy.testing.pytest import raises
N = CoordSys3D('N')
q1, q2, q3, q4, q5 = symbols('q1 q2 q3 q4 q5')
A = N.orient_new_axis('A', q1, N.k) # type: ignore
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.Zero, N) is S.Zero
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 - \
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
# Check to make sure UnitVectors get converted properly
assert express(N.i, N) == N.i
assert express(N.j, N) == N.j
assert express(N.k, N) == N.k
assert express(N.i, A) == (cos(q1)*A.i - sin(q1)*A.j)
assert express(N.j, A) == (sin(q1)*A.i + cos(q1)*A.j)
assert express(N.k, A) == A.k
assert express(N.i, B) == (cos(q1)*B.i - sin(q1)*cos(q2)*B.j +
sin(q1)*sin(q2)*B.k)
assert express(N.j, B) == (sin(q1)*B.i + cos(q1)*cos(q2)*B.j -
sin(q2)*cos(q1)*B.k)
assert express(N.k, B) == (sin(q2)*B.j + cos(q2)*B.k)
assert express(N.i, C) == (
(cos(q1)*cos(q3) - sin(q1)*sin(q2)*sin(q3))*C.i -
sin(q1)*cos(q2)*C.j +
(sin(q3)*cos(q1) + sin(q1)*sin(q2)*cos(q3))*C.k)
assert express(N.j, C) == (
(sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*C.i +
cos(q1)*cos(q2)*C.j +
(sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*C.k)
assert express(N.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 -
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(B.i, N) == (cos(q1)*N.i + sin(q1)*N.j)
assert express(B.j, N) == (-sin(q1)*cos(q2)*N.i +
cos(q1)*cos(q2)*N.j + sin(q2)*N.k)
assert express(B.k, N) == (sin(q1)*sin(q2)*N.i -
sin(q2)*cos(q1)*N.j + cos(q2)*N.k)
assert express(B.i, A) == A.i
assert express(B.j, A) == (cos(q2)*A.j + sin(q2)*A.k)
assert express(B.k, A) == (-sin(q2)*A.j + cos(q2)*A.k)
assert express(B.i, B) == B.i
assert express(B.j, B) == B.j
assert express(B.k, B) == B.k
assert express(B.i, C) == (cos(q3)*C.i + sin(q3)*C.k)
assert express(B.j, C) == C.j
assert express(B.k, C) == (-sin(q3)*C.i + cos(q3)*C.k)
assert express(C.i, N) == (
(cos(q1)*cos(q3) - sin(q1)*sin(q2)*sin(q3))*N.i +
(sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*N.j -
sin(q3)*cos(q2)*N.k)
assert express(C.j, N) == (
-sin(q1)*cos(q2)*N.i + cos(q1)*cos(q2)*N.j + sin(q2)*N.k)
assert express(C.k, N) == (
(sin(q3)*cos(q1) + sin(q1)*sin(q2)*cos(q3))*N.i +
(sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*N.j +
cos(q2)*cos(q3)*N.k)
assert express(C.i, A) == (cos(q3)*A.i + sin(q2)*sin(q3)*A.j -
sin(q3)*cos(q2)*A.k)
assert express(C.j, A) == (cos(q2)*A.j + sin(q2)*A.k)
assert express(C.k, A) == (sin(q3)*A.i - sin(q2)*cos(q3)*A.j +
cos(q2)*cos(q3)*A.k)
assert express(C.i, B) == (cos(q3)*B.i - sin(q3)*B.k)
assert express(C.j, B) == B.j
assert express(C.k, B) == (sin(q3)*B.i + cos(q3)*B.k)
assert express(C.i, C) == C.i
assert express(C.j, C) == C.j
assert express(C.k, C) == C.k == (C.k)
# Check to make sure Vectors get converted back to UnitVectors
assert N.i == express((cos(q1)*A.i - sin(q1)*A.j), N).simplify()
assert N.j == express((sin(q1)*A.i + cos(q1)*A.j), N).simplify()
assert N.i == express((cos(q1)*B.i - sin(q1)*cos(q2)*B.j +
sin(q1)*sin(q2)*B.k), N).simplify()
assert N.j == express((sin(q1)*B.i + cos(q1)*cos(q2)*B.j -
sin(q2)*cos(q1)*B.k), N).simplify()
assert N.k == express((sin(q2)*B.j + cos(q2)*B.k), N).simplify()
assert A.i == express((cos(q1)*N.i + sin(q1)*N.j), A).simplify()
assert A.j == express((-sin(q1)*N.i + cos(q1)*N.j), A).simplify()
assert A.j == express((cos(q2)*B.j - sin(q2)*B.k), A).simplify()
assert A.k == express((sin(q2)*B.j + cos(q2)*B.k), A).simplify()
assert A.i == express((cos(q3)*C.i + sin(q3)*C.k), A).simplify()
assert A.j == express((sin(q2)*sin(q3)*C.i + cos(q2)*C.j -
sin(q2)*cos(q3)*C.k), A).simplify()
assert A.k == express((-sin(q3)*cos(q2)*C.i + sin(q2)*C.j +
cos(q2)*cos(q3)*C.k), A).simplify()
assert B.i == express((cos(q1)*N.i + sin(q1)*N.j), B).simplify()
assert B.j == express((-sin(q1)*cos(q2)*N.i +
cos(q1)*cos(q2)*N.j + sin(q2)*N.k), B).simplify()
assert B.k == express((sin(q1)*sin(q2)*N.i -
sin(q2)*cos(q1)*N.j + cos(q2)*N.k), B).simplify()
assert B.j == express((cos(q2)*A.j + sin(q2)*A.k), B).simplify()
assert B.k == express((-sin(q2)*A.j + cos(q2)*A.k), B).simplify()
assert B.i == express((cos(q3)*C.i + sin(q3)*C.k), B).simplify()
assert B.k == express((-sin(q3)*C.i + cos(q3)*C.k), B).simplify()
assert C.i == express((cos(q3)*A.i + sin(q2)*sin(q3)*A.j -
sin(q3)*cos(q2)*A.k), C).simplify()
assert C.j == express((cos(q2)*A.j + sin(q2)*A.k), C).simplify()
assert C.k == express((sin(q3)*A.i - sin(q2)*cos(q3)*A.j +
cos(q2)*cos(q3)*A.k), C).simplify()
assert C.i == express((cos(q3)*B.i - sin(q3)*B.k), C).simplify()
assert C.k == express((sin(q3)*B.i + cos(q3)*B.k), C).simplify()
def test_matrix_to_vector():
m = Matrix([[1], [2], [3]])
assert matrix_to_vector(m, C) == C.i + 2*C.j + 3*C.k
m = Matrix([[0], [0], [0]])
assert matrix_to_vector(m, N) == matrix_to_vector(m, C) == \
Vector.zero
m = Matrix([[q1], [q2], [q3]])
assert matrix_to_vector(m, N) == q1*N.i + q2*N.j + q3*N.k
def test_orthogonalize():
C = CoordSys3D('C')
a, b = symbols('a b', integer=True)
i, j, k = C.base_vectors()
v1 = i + 2*j
v2 = 2*i + 3*j
v3 = 3*i + 5*j
v4 = 3*i + j
v5 = 2*i + 2*j
v6 = a*i + b*j
v7 = 4*a*i + 4*b*j
assert orthogonalize(v1, v2) == [C.i + 2*C.j, C.i*Rational(2, 5) + -C.j/5]
# from wikipedia
assert orthogonalize(v4, v5, orthonormal=True) == \
[(3*sqrt(10))*C.i/10 + (sqrt(10))*C.j/10, (-sqrt(10))*C.i/10 + (3*sqrt(10))*C.j/10]
raises(ValueError, lambda: orthogonalize(v1, v2, v3))
raises(ValueError, lambda: orthogonalize(v6, v7))

View File

@ -0,0 +1,90 @@
from sympy.core.relational import Eq
from sympy.core.singleton import S
from sympy.abc import x, y, z, s, t
from sympy.sets import FiniteSet, EmptySet
from sympy.geometry import Point
from sympy.vector import ImplicitRegion
from sympy.testing.pytest import raises
def test_ImplicitRegion():
ellipse = ImplicitRegion((x, y), (x**2/4 + y**2/16 - 1))
assert ellipse.equation == x**2/4 + y**2/16 - 1
assert ellipse.variables == (x, y)
assert ellipse.degree == 2
r = ImplicitRegion((x, y, z), Eq(x**4 + y**2 - x*y, 6))
assert r.equation == x**4 + y**2 - x*y - 6
assert r.variables == (x, y, z)
assert r.degree == 4
def test_regular_point():
r1 = ImplicitRegion((x,), x**2 - 16)
assert r1.regular_point() == (-4,)
c1 = ImplicitRegion((x, y), x**2 + y**2 - 4)
assert c1.regular_point() == (0, -2)
c2 = ImplicitRegion((x, y), (x - S(5)/2)**2 + y**2 - (S(1)/4)**2)
assert c2.regular_point() == (S(5)/2, -S(1)/4)
c3 = ImplicitRegion((x, y), (y - 5)**2 - 16*(x - 5))
assert c3.regular_point() == (5, 5)
r2 = ImplicitRegion((x, y), x**2 - 4*x*y - 3*y**2 + 4*x + 8*y - 5)
assert r2.regular_point() == (S(4)/7, S(9)/7)
r3 = ImplicitRegion((x, y), x**2 - 2*x*y + 3*y**2 - 2*x - 5*y + 3/2)
raises(ValueError, lambda: r3.regular_point())
def test_singular_points_and_multiplicty():
r1 = ImplicitRegion((x, y, z), Eq(x + y + z, 0))
assert r1.singular_points() == EmptySet
r2 = ImplicitRegion((x, y, z), x*y*z + y**4 -x**2*z**2)
assert r2.singular_points() == FiniteSet((0, 0, z), (x, 0, 0))
assert r2.multiplicity((0, 0, 0)) == 3
assert r2.multiplicity((0, 0, 6)) == 2
r3 = ImplicitRegion((x, y, z), z**2 - x**2 - y**2)
assert r3.singular_points() == FiniteSet((0, 0, 0))
assert r3.multiplicity((0, 0, 0)) == 2
r4 = ImplicitRegion((x, y), x**2 + y**2 - 2*x)
assert r4.singular_points() == EmptySet
assert r4.multiplicity(Point(1, 3)) == 0
def test_rational_parametrization():
p = ImplicitRegion((x,), x - 2)
assert p.rational_parametrization() == (x - 2,)
line = ImplicitRegion((x, y), Eq(y, 3*x + 2))
assert line.rational_parametrization() == (x, 3*x + 2)
circle1 = ImplicitRegion((x, y), (x-2)**2 + (y+3)**2 - 4)
assert circle1.rational_parametrization(parameters=t) == (4*t/(t**2 + 1) + 2, 4*t**2/(t**2 + 1) - 5)
circle2 = ImplicitRegion((x, y), (x - S.Half)**2 + y**2 - (S(1)/2)**2)
assert circle2.rational_parametrization(parameters=t) == (t/(t**2 + 1) + S(1)/2, t**2/(t**2 + 1) - S(1)/2)
circle3 = ImplicitRegion((x, y), Eq(x**2 + y**2, 2*x))
assert circle3.rational_parametrization(parameters=(t,)) == (2*t/(t**2 + 1) + 1, 2*t**2/(t**2 + 1) - 1)
parabola = ImplicitRegion((x, y), (y - 3)**2 - 4*(x + 6))
assert parabola.rational_parametrization(t) == (-6 + 4/t**2, 3 + 4/t)
rect_hyperbola = ImplicitRegion((x, y), x*y - 1)
assert rect_hyperbola.rational_parametrization(t) == (-1 + (t + 1)/t, t)
cubic_curve = ImplicitRegion((x, y), x**3 + x**2 - y**2)
assert cubic_curve.rational_parametrization(parameters=(t)) == (t**2 - 1, t*(t**2 - 1))
cuspidal = ImplicitRegion((x, y), (x**3 - y**2))
assert cuspidal.rational_parametrization(t) == (t**2, t**3)
I = ImplicitRegion((x, y), x**3 + x**2 - y**2)
assert I.rational_parametrization(t) == (t**2 - 1, t*(t**2 - 1))
sphere = ImplicitRegion((x, y, z), Eq(x**2 + y**2 + z**2, 2*x))
assert sphere.rational_parametrization(parameters=(s, t)) == (2/(s**2 + t**2 + 1), 2*t/(s**2 + t**2 + 1), 2*s/(s**2 + t**2 + 1))
conic = ImplicitRegion((x, y), Eq(x**2 + 4*x*y + 3*y**2 + x - y + 10, 0))
assert conic.rational_parametrization(t) == (
S(17)/2 + 4/(3*t**2 + 4*t + 1), 4*t/(3*t**2 + 4*t + 1) - S(11)/2)
r1 = ImplicitRegion((x, y), y**2 - x**3 + x)
raises(NotImplementedError, lambda: r1.rational_parametrization())
r2 = ImplicitRegion((x, y), y**2 - x**3 - x**2 + 1)
raises(NotImplementedError, lambda: r2.rational_parametrization())

View File

@ -0,0 +1,106 @@
from sympy.core.numbers import pi
from sympy.core.singleton import S
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.testing.pytest import raises
from sympy.vector.coordsysrect import CoordSys3D
from sympy.vector.integrals import ParametricIntegral, vector_integrate
from sympy.vector.parametricregion import ParametricRegion
from sympy.vector.implicitregion import ImplicitRegion
from sympy.abc import x, y, z, u, v, r, t, theta, phi
from sympy.geometry import Point, Segment, Curve, Circle, Polygon, Plane
C = CoordSys3D('C')
def test_parametric_lineintegrals():
halfcircle = ParametricRegion((4*cos(theta), 4*sin(theta)), (theta, -pi/2, pi/2))
assert ParametricIntegral(C.x*C.y**4, halfcircle) == S(8192)/5
curve = ParametricRegion((t, t**2, t**3), (t, 0, 1))
field1 = 8*C.x**2*C.y*C.z*C.i + 5*C.z*C.j - 4*C.x*C.y*C.k
assert ParametricIntegral(field1, curve) == 1
line = ParametricRegion((4*t - 1, 2 - 2*t, t), (t, 0, 1))
assert ParametricIntegral(C.x*C.z*C.i - C.y*C.z*C.k, line) == 3
assert ParametricIntegral(4*C.x**3, ParametricRegion((1, t), (t, 0, 2))) == 8
helix = ParametricRegion((cos(t), sin(t), 3*t), (t, 0, 4*pi))
assert ParametricIntegral(C.x*C.y*C.z, helix) == -3*sqrt(10)*pi
field2 = C.y*C.i + C.z*C.j + C.z*C.k
assert ParametricIntegral(field2, ParametricRegion((cos(t), sin(t), t**2), (t, 0, pi))) == -5*pi/2 + pi**4/2
def test_parametric_surfaceintegrals():
semisphere = ParametricRegion((2*sin(phi)*cos(theta), 2*sin(phi)*sin(theta), 2*cos(phi)),\
(theta, 0, 2*pi), (phi, 0, pi/2))
assert ParametricIntegral(C.z, semisphere) == 8*pi
cylinder = ParametricRegion((sqrt(3)*cos(theta), sqrt(3)*sin(theta), z), (z, 0, 6), (theta, 0, 2*pi))
assert ParametricIntegral(C.y, cylinder) == 0
cone = ParametricRegion((v*cos(u), v*sin(u), v), (u, 0, 2*pi), (v, 0, 1))
assert ParametricIntegral(C.x*C.i + C.y*C.j + C.z**4*C.k, cone) == pi/3
triangle1 = ParametricRegion((x, y), (x, 0, 2), (y, 0, 10 - 5*x))
triangle2 = ParametricRegion((x, y), (y, 0, 10 - 5*x), (x, 0, 2))
assert ParametricIntegral(-15.6*C.y*C.k, triangle1) == ParametricIntegral(-15.6*C.y*C.k, triangle2)
assert ParametricIntegral(C.z, triangle1) == 10*C.z
def test_parametric_volumeintegrals():
cube = ParametricRegion((x, y, z), (x, 0, 1), (y, 0, 1), (z, 0, 1))
assert ParametricIntegral(1, cube) == 1
solidsphere1 = ParametricRegion((r*sin(phi)*cos(theta), r*sin(phi)*sin(theta), r*cos(phi)),\
(r, 0, 2), (theta, 0, 2*pi), (phi, 0, pi))
solidsphere2 = ParametricRegion((r*sin(phi)*cos(theta), r*sin(phi)*sin(theta), r*cos(phi)),\
(r, 0, 2), (phi, 0, pi), (theta, 0, 2*pi))
assert ParametricIntegral(C.x**2 + C.y**2, solidsphere1) == -256*pi/15
assert ParametricIntegral(C.x**2 + C.y**2, solidsphere2) == 256*pi/15
region_under_plane1 = ParametricRegion((x, y, z), (x, 0, 3), (y, 0, -2*x/3 + 2),\
(z, 0, 6 - 2*x - 3*y))
region_under_plane2 = ParametricRegion((x, y, z), (x, 0, 3), (z, 0, 6 - 2*x - 3*y),\
(y, 0, -2*x/3 + 2))
assert ParametricIntegral(C.x*C.i + C.j - 100*C.k, region_under_plane1) == \
ParametricIntegral(C.x*C.i + C.j - 100*C.k, region_under_plane2)
assert ParametricIntegral(2*C.x, region_under_plane2) == -9
def test_vector_integrate():
halfdisc = ParametricRegion((r*cos(theta), r* sin(theta)), (r, -2, 2), (theta, 0, pi))
assert vector_integrate(C.x**2, halfdisc) == 4*pi
assert vector_integrate(C.x, ParametricRegion((t, t**2), (t, 2, 3))) == -17*sqrt(17)/12 + 37*sqrt(37)/12
assert vector_integrate(C.y**3*C.z, (C.x, 0, 3), (C.y, -1, 4)) == 765*C.z/4
s1 = Segment(Point(0, 0), Point(0, 1))
assert vector_integrate(-15*C.y, s1) == S(-15)/2
s2 = Segment(Point(4, 3, 9), Point(1, 1, 7))
assert vector_integrate(C.y*C.i, s2) == -6
curve = Curve((sin(t), cos(t)), (t, 0, 2))
assert vector_integrate(5*C.z, curve) == 10*C.z
c1 = Circle(Point(2, 3), 6)
assert vector_integrate(C.x*C.y, c1) == 72*pi
c2 = Circle(Point(0, 0), Point(1, 1), Point(1, 0))
assert vector_integrate(1, c2) == c2.circumference
triangle = Polygon((0, 0), (1, 0), (1, 1))
assert vector_integrate(C.x*C.i - 14*C.y*C.j, triangle) == 0
p1, p2, p3, p4 = [(0, 0), (1, 0), (5, 1), (0, 1)]
poly = Polygon(p1, p2, p3, p4)
assert vector_integrate(-23*C.z, poly) == -161*C.z - 23*sqrt(17)*C.z
point = Point(2, 3)
assert vector_integrate(C.i*C.y - C.z, point) == ParametricIntegral(C.y*C.i, ParametricRegion((2, 3)))
c3 = ImplicitRegion((x, y), x**2 + y**2 - 4)
assert vector_integrate(45, c3) == 180*pi
c4 = ImplicitRegion((x, y), (x - 3)**2 + (y - 4)**2 - 9)
assert vector_integrate(1, c4) == 6*pi
pl = Plane(Point(1, 1, 1), Point(2, 3, 4), Point(2, 2, 2))
raises(ValueError, lambda: vector_integrate(C.x*C.z*C.i + C.k, pl))

View File

@ -0,0 +1,43 @@
from sympy.vector import CoordSys3D, Gradient, Divergence, Curl, VectorZero, Laplacian
from sympy.printing.repr import srepr
R = CoordSys3D('R')
s1 = R.x*R.y*R.z # type: ignore
s2 = R.x + 3*R.y**2 # type: ignore
s3 = R.x**2 + R.y**2 + R.z**2 # type: ignore
v1 = R.x*R.i + R.z*R.z*R.j # type: ignore
v2 = R.x*R.i + R.y*R.j + R.z*R.k # type: ignore
v3 = R.x**2*R.i + R.y**2*R.j + R.z**2*R.k # type: ignore
def test_Gradient():
assert Gradient(s1) == Gradient(R.x*R.y*R.z)
assert Gradient(s2) == Gradient(R.x + 3*R.y**2)
assert Gradient(s1).doit() == R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
assert Gradient(s2).doit() == R.i + 6*R.y*R.j
def test_Divergence():
assert Divergence(v1) == Divergence(R.x*R.i + R.z*R.z*R.j)
assert Divergence(v2) == Divergence(R.x*R.i + R.y*R.j + R.z*R.k)
assert Divergence(v1).doit() == 1
assert Divergence(v2).doit() == 3
# issue 22384
Rc = CoordSys3D('R', transformation='cylindrical')
assert Divergence(Rc.i).doit() == 1/Rc.r
def test_Curl():
assert Curl(v1) == Curl(R.x*R.i + R.z*R.z*R.j)
assert Curl(v2) == Curl(R.x*R.i + R.y*R.j + R.z*R.k)
assert Curl(v1).doit() == (-2*R.z)*R.i
assert Curl(v2).doit() == VectorZero()
def test_Laplacian():
assert Laplacian(s3) == Laplacian(R.x**2 + R.y**2 + R.z**2)
assert Laplacian(v3) == Laplacian(R.x**2*R.i + R.y**2*R.j + R.z**2*R.k)
assert Laplacian(s3).doit() == 6
assert Laplacian(v3).doit() == 2*R.i + 2*R.j + 2*R.k
assert srepr(Laplacian(s3)) == \
'Laplacian(Add(Pow(R.x, Integer(2)), Pow(R.y, Integer(2)), Pow(R.z, Integer(2))))'

View File

@ -0,0 +1,97 @@
from sympy.core.numbers import pi
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.vector.coordsysrect import CoordSys3D
from sympy.vector.parametricregion import ParametricRegion, parametric_region_list
from sympy.geometry import Point, Segment, Curve, Ellipse, Line, Parabola, Polygon
from sympy.testing.pytest import raises
from sympy.abc import a, b, r, t, x, y, z, theta, phi
C = CoordSys3D('C')
def test_ParametricRegion():
point = ParametricRegion((3, 4))
assert point.definition == (3, 4)
assert point.parameters == ()
assert point.limits == {}
assert point.dimensions == 0
# line x = y
line_xy = ParametricRegion((y, y), (y, 1, 5))
assert line_xy .definition == (y, y)
assert line_xy.parameters == (y,)
assert line_xy.dimensions == 1
# line y = z
line_yz = ParametricRegion((x,t,t), x, (t, 1, 2))
assert line_yz.definition == (x,t,t)
assert line_yz.parameters == (x, t)
assert line_yz.limits == {t: (1, 2)}
assert line_yz.dimensions == 1
p1 = ParametricRegion((9*a, -16*b), (a, 0, 2), (b, -1, 5))
assert p1.definition == (9*a, -16*b)
assert p1.parameters == (a, b)
assert p1.limits == {a: (0, 2), b: (-1, 5)}
assert p1.dimensions == 2
p2 = ParametricRegion((t, t**3), t)
assert p2.parameters == (t,)
assert p2.limits == {}
assert p2.dimensions == 0
circle = ParametricRegion((r*cos(theta), r*sin(theta)), r, (theta, 0, 2*pi))
assert circle.definition == (r*cos(theta), r*sin(theta))
assert circle.dimensions == 1
halfdisc = ParametricRegion((r*cos(theta), r*sin(theta)), (r, -2, 2), (theta, 0, pi))
assert halfdisc.definition == (r*cos(theta), r*sin(theta))
assert halfdisc.parameters == (r, theta)
assert halfdisc.limits == {r: (-2, 2), theta: (0, pi)}
assert halfdisc.dimensions == 2
ellipse = ParametricRegion((a*cos(t), b*sin(t)), (t, 0, 8))
assert ellipse.parameters == (t,)
assert ellipse.limits == {t: (0, 8)}
assert ellipse.dimensions == 1
cylinder = ParametricRegion((r*cos(theta), r*sin(theta), z), (r, 0, 1), (theta, 0, 2*pi), (z, 0, 4))
assert cylinder.parameters == (r, theta, z)
assert cylinder.dimensions == 3
sphere = ParametricRegion((r*sin(phi)*cos(theta),r*sin(phi)*sin(theta), r*cos(phi)),
r, (theta, 0, 2*pi), (phi, 0, pi))
assert sphere.definition == (r*sin(phi)*cos(theta),r*sin(phi)*sin(theta), r*cos(phi))
assert sphere.parameters == (r, theta, phi)
assert sphere.dimensions == 2
raises(ValueError, lambda: ParametricRegion((a*t**2, 2*a*t), (a, -2)))
raises(ValueError, lambda: ParametricRegion((a, b), (a**2, sin(b)), (a, 2, 4, 6)))
def test_parametric_region_list():
point = Point(-5, 12)
assert parametric_region_list(point) == [ParametricRegion((-5, 12))]
e = Ellipse(Point(2, 8), 2, 6)
assert parametric_region_list(e, t) == [ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi))]
c = Curve((t, t**3), (t, 5, 3))
assert parametric_region_list(c) == [ParametricRegion((t, t**3), (t, 5, 3))]
s = Segment(Point(2, 11, -6), Point(0, 2, 5))
assert parametric_region_list(s, t) == [ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1))]
s1 = Segment(Point(0, 0), (1, 0))
assert parametric_region_list(s1, t) == [ParametricRegion((t, 0), (t, 0, 1))]
s2 = Segment(Point(1, 2, 3), Point(1, 2, 5))
assert parametric_region_list(s2, t) == [ParametricRegion((1, 2, 2*t + 3), (t, 0, 1))]
s3 = Segment(Point(12, 56), Point(12, 56))
assert parametric_region_list(s3) == [ParametricRegion((12, 56))]
poly = Polygon((1,3), (-3, 8), (2, 4))
assert parametric_region_list(poly, t) == [ParametricRegion((1 - 4*t, 5*t + 3), (t, 0, 1)), ParametricRegion((5*t - 3, 8 - 4*t), (t, 0, 1)), ParametricRegion((2 - t, 4 - t), (t, 0, 1))]
p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7,8)))
raises(ValueError, lambda: parametric_region_list(p1))

View File

@ -0,0 +1,221 @@
# -*- coding: utf-8 -*-
from sympy.core.function import Function
from sympy.integrals.integrals import Integral
from sympy.printing.latex import latex
from sympy.printing.pretty import pretty as xpretty
from sympy.vector import CoordSys3D, Del, Vector, express
from sympy.abc import a, b, c
from sympy.testing.pytest import XFAIL
def pretty(expr):
"""ASCII pretty-printing"""
return xpretty(expr, use_unicode=False, wrap_line=False)
def upretty(expr):
"""Unicode pretty-printing"""
return xpretty(expr, use_unicode=True, wrap_line=False)
# Initialize the basic and tedious vector/dyadic expressions
# needed for testing.
# Some of the pretty forms shown denote how the expressions just
# above them should look with pretty printing.
N = CoordSys3D('N')
C = N.orient_new_axis('C', a, N.k) # type: ignore
v = []
d = []
v.append(Vector.zero)
v.append(N.i) # type: ignore
v.append(-N.i) # type: ignore
v.append(N.i + N.j) # type: ignore
v.append(a*N.i) # type: ignore
v.append(a*N.i - b*N.j) # type: ignore
v.append((a**2 + N.x)*N.i + N.k) # type: ignore
v.append((a**2 + b)*N.i + 3*(C.y - c)*N.k) # type: ignore
f = Function('f')
v.append(N.j - (Integral(f(b)) - C.x**2)*N.k) # type: ignore
upretty_v_8 = """\
⎛ 2 ⌠ ⎞ \n\
j_N + ⎜x_C - ⎮ f(b) db⎟ k_N\n\
⎝ ⌡ ⎠ \
"""
pretty_v_8 = """\
j_N + / / \\\n\
| 2 | |\n\
|x_C - | f(b) db|\n\
| | |\n\
\\ / / \
"""
v.append(N.i + C.k) # type: ignore
v.append(express(N.i, C)) # type: ignore
v.append((a**2 + b)*N.i + (Integral(f(b)))*N.k) # type: ignore
upretty_v_11 = """\
⎛ 2 ⎞ ⎛⌠ ⎞ \n\
⎝a + b⎠ i_N + ⎜⎮ f(b) db⎟ k_N\n\
⎝⌡ ⎠ \
"""
pretty_v_11 = """\
/ 2 \\ + / / \\\n\
\\a + b/ i_N| | |\n\
| | f(b) db|\n\
| | |\n\
\\/ / \
"""
for x in v:
d.append(x | N.k) # type: ignore
s = 3*N.x**2*C.y # type: ignore
upretty_s = """\
2\n\
3⋅y_C⋅x_N \
"""
pretty_s = """\
2\n\
3*y_C*x_N \
"""
# This is the pretty form for ((a**2 + b)*N.i + 3*(C.y - c)*N.k) | N.k
upretty_d_7 = """\
⎛ 2 ⎞ \n\
⎝a + b⎠ (i_N|k_N) + (3⋅y_C - 3⋅c) (k_N|k_N)\
"""
pretty_d_7 = """\
/ 2 \\ (i_N|k_N) + (3*y_C - 3*c) (k_N|k_N)\n\
\\a + b/ \
"""
def test_str_printing():
assert str(v[0]) == '0'
assert str(v[1]) == 'N.i'
assert str(v[2]) == '(-1)*N.i'
assert str(v[3]) == 'N.i + N.j'
assert str(v[8]) == 'N.j + (C.x**2 - Integral(f(b), b))*N.k'
assert str(v[9]) == 'C.k + N.i'
assert str(s) == '3*C.y*N.x**2'
assert str(d[0]) == '0'
assert str(d[1]) == '(N.i|N.k)'
assert str(d[4]) == 'a*(N.i|N.k)'
assert str(d[5]) == 'a*(N.i|N.k) + (-b)*(N.j|N.k)'
assert str(d[8]) == ('(N.j|N.k) + (C.x**2 - ' +
'Integral(f(b), b))*(N.k|N.k)')
@XFAIL
def test_pretty_printing_ascii():
assert pretty(v[0]) == '0'
assert pretty(v[1]) == 'i_N'
assert pretty(v[5]) == '(a) i_N + (-b) j_N'
assert pretty(v[8]) == pretty_v_8
assert pretty(v[2]) == '(-1) i_N'
assert pretty(v[11]) == pretty_v_11
assert pretty(s) == pretty_s
assert pretty(d[0]) == '(0|0)'
assert pretty(d[5]) == '(a) (i_N|k_N) + (-b) (j_N|k_N)'
assert pretty(d[7]) == pretty_d_7
assert pretty(d[10]) == '(cos(a)) (i_C|k_N) + (-sin(a)) (j_C|k_N)'
def test_pretty_print_unicode_v():
assert upretty(v[0]) == '0'
assert upretty(v[1]) == 'i_N'
assert upretty(v[5]) == '(a) i_N + (-b) j_N'
# Make sure the printing works in other objects
assert upretty(v[5].args) == '((a) i_N, (-b) j_N)'
assert upretty(v[8]) == upretty_v_8
assert upretty(v[2]) == '(-1) i_N'
assert upretty(v[11]) == upretty_v_11
assert upretty(s) == upretty_s
assert upretty(d[0]) == '(0|0)'
assert upretty(d[5]) == '(a) (i_N|k_N) + (-b) (j_N|k_N)'
assert upretty(d[7]) == upretty_d_7
assert upretty(d[10]) == '(cos(a)) (i_C|k_N) + (-sin(a)) (j_C|k_N)'
def test_latex_printing():
assert latex(v[0]) == '\\mathbf{\\hat{0}}'
assert latex(v[1]) == '\\mathbf{\\hat{i}_{N}}'
assert latex(v[2]) == '- \\mathbf{\\hat{i}_{N}}'
assert latex(v[5]) == ('\\left(a\\right)\\mathbf{\\hat{i}_{N}} + ' +
'\\left(- b\\right)\\mathbf{\\hat{j}_{N}}')
assert latex(v[6]) == ('\\left(\\mathbf{{x}_{N}} + a^{2}\\right)\\mathbf{\\hat{i}_' +
'{N}} + \\mathbf{\\hat{k}_{N}}')
assert latex(v[8]) == ('\\mathbf{\\hat{j}_{N}} + \\left(\\mathbf{{x}_' +
'{C}}^{2} - \\int f{\\left(b \\right)}\\,' +
' db\\right)\\mathbf{\\hat{k}_{N}}')
assert latex(s) == '3 \\mathbf{{y}_{C}} \\mathbf{{x}_{N}}^{2}'
assert latex(d[0]) == '(\\mathbf{\\hat{0}}|\\mathbf{\\hat{0}})'
assert latex(d[4]) == ('\\left(a\\right)\\left(\\mathbf{\\hat{i}_{N}}{\\middle|}' +
'\\mathbf{\\hat{k}_{N}}\\right)')
assert latex(d[9]) == ('\\left(\\mathbf{\\hat{k}_{C}}{\\middle|}' +
'\\mathbf{\\hat{k}_{N}}\\right) + \\left(' +
'\\mathbf{\\hat{i}_{N}}{\\middle|}\\mathbf{' +
'\\hat{k}_{N}}\\right)')
assert latex(d[11]) == ('\\left(a^{2} + b\\right)\\left(\\mathbf{\\hat{i}_{N}}' +
'{\\middle|}\\mathbf{\\hat{k}_{N}}\\right) + ' +
'\\left(\\int f{\\left(b \\right)}\\, db\\right)\\left(' +
'\\mathbf{\\hat{k}_{N}}{\\middle|}\\mathbf{' +
'\\hat{k}_{N}}\\right)')
def test_issue_23058():
from sympy import symbols, sin, cos, pi, UnevaluatedExpr
delop = Del()
CC_ = CoordSys3D("C")
y = CC_.y
xhat = CC_.i
t = symbols("t")
ten = symbols("10", positive=True)
eps, mu = 4*pi*ten**(-11), ten**(-5)
Bx = 2 * ten**(-4) * cos(ten**5 * t) * sin(ten**(-3) * y)
vecB = Bx * xhat
vecE = (1/eps) * Integral(delop.cross(vecB/mu).doit(), t)
vecE = vecE.doit()
vecB_str = """\
⎛ ⎛y_C⎞ ⎛ 5 ⎞⎞ \n\
⎜2⋅sin⎜───⎟⋅cos⎝10 ⋅t⎠⎟ i_C\n\
⎜ ⎜ 3⎟ ⎟ \n\
⎜ ⎝10 ⎠ ⎟ \n\
⎜─────────────────────⎟ \n\
⎜ 4 ⎟ \n\
⎝ 10 ⎠ \
"""
vecE_str = """\
⎛ 4 ⎛ 5 ⎞ ⎛y_C⎞ ⎞ \n\
⎜-10 ⋅sin⎝10 ⋅t⎠⋅cos⎜───⎟ ⎟ k_C\n\
⎜ ⎜ 3⎟ ⎟ \n\
⎜ ⎝10 ⎠ ⎟ \n\
⎜─────────────────────────⎟ \n\
⎝ 2⋅π ⎠ \
"""
assert upretty(vecB) == vecB_str
assert upretty(vecE) == vecE_str
ten = UnevaluatedExpr(10)
eps, mu = 4*pi*ten**(-11), ten**(-5)
Bx = 2 * ten**(-4) * cos(ten**5 * t) * sin(ten**(-3) * y)
vecB = Bx * xhat
vecB_str = """\
⎛ -4 ⎛ 5⎞ ⎛ -3⎞⎞ \n\
⎝2⋅10 ⋅cos⎝t⋅10 ⎠⋅sin⎝y_C⋅10 ⎠⎠ i_C \
"""
assert upretty(vecB) == vecB_str
def test_custom_names():
A = CoordSys3D('A', vector_names=['x', 'y', 'z'],
variable_names=['i', 'j', 'k'])
assert A.i.__str__() == 'A.i'
assert A.x.__str__() == 'A.x'
assert A.i._pretty_form == 'i_A'
assert A.x._pretty_form == 'x_A'
assert A.i._latex_form == r'\mathbf{{i}_{A}}'
assert A.x._latex_form == r"\mathbf{\hat{x}_{A}}"

View File

@ -0,0 +1,266 @@
from sympy.core import Rational, S
from sympy.simplify import simplify, trigsimp
from sympy.core.function import (Derivative, Function, diff)
from sympy.core.numbers import pi
from sympy.core.symbol import symbols
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.integrals.integrals import Integral
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
from sympy.vector.vector import Vector, BaseVector, VectorAdd, \
VectorMul, VectorZero
from sympy.vector.coordsysrect import CoordSys3D
from sympy.vector.vector import Cross, Dot, cross
from sympy.testing.pytest import raises
C = CoordSys3D('C')
i, j, k = C.base_vectors()
a, b, c = symbols('a b c')
def test_cross():
v1 = C.x * i + C.z * C.z * j
v2 = C.x * i + C.y * j + C.z * k
assert Cross(v1, v2) == Cross(C.x*C.i + C.z**2*C.j, C.x*C.i + C.y*C.j + C.z*C.k)
assert Cross(v1, v2).doit() == C.z**3*C.i + (-C.x*C.z)*C.j + (C.x*C.y - C.x*C.z**2)*C.k
assert cross(v1, v2) == C.z**3*C.i + (-C.x*C.z)*C.j + (C.x*C.y - C.x*C.z**2)*C.k
assert Cross(v1, v2) == -Cross(v2, v1)
assert Cross(v1, v2) + Cross(v2, v1) == Vector.zero
def test_dot():
v1 = C.x * i + C.z * C.z * j
v2 = C.x * i + C.y * j + C.z * k
assert Dot(v1, v2) == Dot(C.x*C.i + C.z**2*C.j, C.x*C.i + C.y*C.j + C.z*C.k)
assert Dot(v1, v2).doit() == C.x**2 + C.y*C.z**2
assert Dot(v1, v2).doit() == C.x**2 + C.y*C.z**2
assert Dot(v1, v2) == Dot(v2, v1)
def test_vector_sympy():
"""
Test whether the Vector framework confirms to the hashing
and equality testing properties of SymPy.
"""
v1 = 3*j
assert v1 == j*3
assert v1.components == {j: 3}
v2 = 3*i + 4*j + 5*k
v3 = 2*i + 4*j + i + 4*k + k
assert v3 == v2
assert v3.__hash__() == v2.__hash__()
def test_vector():
assert isinstance(i, BaseVector)
assert i != j
assert j != k
assert k != i
assert i - i == Vector.zero
assert i + Vector.zero == i
assert i - Vector.zero == i
assert Vector.zero != 0
assert -Vector.zero == Vector.zero
v1 = a*i + b*j + c*k
v2 = a**2*i + b**2*j + c**2*k
v3 = v1 + v2
v4 = 2 * v1
v5 = a * i
assert isinstance(v1, VectorAdd)
assert v1 - v1 == Vector.zero
assert v1 + Vector.zero == v1
assert v1.dot(i) == a
assert v1.dot(j) == b
assert v1.dot(k) == c
assert i.dot(v2) == a**2
assert j.dot(v2) == b**2
assert k.dot(v2) == c**2
assert v3.dot(i) == a**2 + a
assert v3.dot(j) == b**2 + b
assert v3.dot(k) == c**2 + c
assert v1 + v2 == v2 + v1
assert v1 - v2 == -1 * (v2 - v1)
assert a * v1 == v1 * a
assert isinstance(v5, VectorMul)
assert v5.base_vector == i
assert v5.measure_number == a
assert isinstance(v4, Vector)
assert isinstance(v4, VectorAdd)
assert isinstance(v4, Vector)
assert isinstance(Vector.zero, VectorZero)
assert isinstance(Vector.zero, Vector)
assert isinstance(v1 * 0, VectorZero)
assert v1.to_matrix(C) == Matrix([[a], [b], [c]])
assert i.components == {i: 1}
assert v5.components == {i: a}
assert v1.components == {i: a, j: b, k: c}
assert VectorAdd(v1, Vector.zero) == v1
assert VectorMul(a, v1) == v1*a
assert VectorMul(1, i) == i
assert VectorAdd(v1, Vector.zero) == v1
assert VectorMul(0, Vector.zero) == Vector.zero
raises(TypeError, lambda: v1.outer(1))
raises(TypeError, lambda: v1.dot(1))
def test_vector_magnitude_normalize():
assert Vector.zero.magnitude() == 0
assert Vector.zero.normalize() == Vector.zero
assert i.magnitude() == 1
assert j.magnitude() == 1
assert k.magnitude() == 1
assert i.normalize() == i
assert j.normalize() == j
assert k.normalize() == k
v1 = a * i
assert v1.normalize() == (a/sqrt(a**2))*i
assert v1.magnitude() == sqrt(a**2)
v2 = a*i + b*j + c*k
assert v2.magnitude() == sqrt(a**2 + b**2 + c**2)
assert v2.normalize() == v2 / v2.magnitude()
v3 = i + j
assert v3.normalize() == (sqrt(2)/2)*C.i + (sqrt(2)/2)*C.j
def test_vector_simplify():
A, s, k, m = symbols('A, s, k, m')
test1 = (1 / a + 1 / b) * i
assert (test1 & i) != (a + b) / (a * b)
test1 = simplify(test1)
assert (test1 & i) == (a + b) / (a * b)
assert test1.simplify() == simplify(test1)
test2 = (A**2 * s**4 / (4 * pi * k * m**3)) * i
test2 = simplify(test2)
assert (test2 & i) == (A**2 * s**4 / (4 * pi * k * m**3))
test3 = ((4 + 4 * a - 2 * (2 + 2 * a)) / (2 + 2 * a)) * i
test3 = simplify(test3)
assert (test3 & i) == 0
test4 = ((-4 * a * b**2 - 2 * b**3 - 2 * a**2 * b) / (a + b)**2) * i
test4 = simplify(test4)
assert (test4 & i) == -2 * b
v = (sin(a)+cos(a))**2*i - j
assert trigsimp(v) == (2*sin(a + pi/4)**2)*i + (-1)*j
assert trigsimp(v) == v.trigsimp()
assert simplify(Vector.zero) == Vector.zero
def test_vector_dot():
assert i.dot(Vector.zero) == 0
assert Vector.zero.dot(i) == 0
assert i & Vector.zero == 0
assert i.dot(i) == 1
assert i.dot(j) == 0
assert i.dot(k) == 0
assert i & i == 1
assert i & j == 0
assert i & k == 0
assert j.dot(i) == 0
assert j.dot(j) == 1
assert j.dot(k) == 0
assert j & i == 0
assert j & j == 1
assert j & k == 0
assert k.dot(i) == 0
assert k.dot(j) == 0
assert k.dot(k) == 1
assert k & i == 0
assert k & j == 0
assert k & k == 1
raises(TypeError, lambda: k.dot(1))
def test_vector_cross():
assert i.cross(Vector.zero) == Vector.zero
assert Vector.zero.cross(i) == Vector.zero
assert i.cross(i) == Vector.zero
assert i.cross(j) == k
assert i.cross(k) == -j
assert i ^ i == Vector.zero
assert i ^ j == k
assert i ^ k == -j
assert j.cross(i) == -k
assert j.cross(j) == Vector.zero
assert j.cross(k) == i
assert j ^ i == -k
assert j ^ j == Vector.zero
assert j ^ k == i
assert k.cross(i) == j
assert k.cross(j) == -i
assert k.cross(k) == Vector.zero
assert k ^ i == j
assert k ^ j == -i
assert k ^ k == Vector.zero
assert k.cross(1) == Cross(k, 1)
def test_projection():
v1 = i + j + k
v2 = 3*i + 4*j
v3 = 0*i + 0*j
assert v1.projection(v1) == i + j + k
assert v1.projection(v2) == Rational(7, 3)*C.i + Rational(7, 3)*C.j + Rational(7, 3)*C.k
assert v1.projection(v1, scalar=True) == S.One
assert v1.projection(v2, scalar=True) == Rational(7, 3)
assert v3.projection(v1) == Vector.zero
assert v3.projection(v1, scalar=True) == S.Zero
def test_vector_diff_integrate():
f = Function('f')
v = f(a)*C.i + a**2*C.j - C.k
assert Derivative(v, a) == Derivative((f(a))*C.i +
a**2*C.j + (-1)*C.k, a)
assert (diff(v, a) == v.diff(a) == Derivative(v, a).doit() ==
(Derivative(f(a), a))*C.i + 2*a*C.j)
assert (Integral(v, a) == (Integral(f(a), a))*C.i +
(Integral(a**2, a))*C.j + (Integral(-1, a))*C.k)
def test_vector_args():
raises(ValueError, lambda: BaseVector(3, C))
raises(TypeError, lambda: BaseVector(0, Vector.zero))
def test_srepr():
from sympy.printing.repr import srepr
res = "CoordSys3D(Str('C'), Tuple(ImmutableDenseMatrix([[Integer(1), "\
"Integer(0), Integer(0)], [Integer(0), Integer(1), Integer(0)], "\
"[Integer(0), Integer(0), Integer(1)]]), VectorZero())).i"
assert srepr(C.i) == res
def test_scalar():
from sympy.vector import CoordSys3D
C = CoordSys3D('C')
v1 = 3*C.i + 4*C.j + 5*C.k
v2 = 3*C.i - 4*C.j + 5*C.k
assert v1.is_Vector is True
assert v1.is_scalar is False
assert (v1.dot(v2)).is_scalar is True
assert (v1.cross(v2)).is_scalar is False