Tutorial 3
Click the badges above to run this tutorial interactively in your browser without installing anything!
- Binder: Free cloud-based Jupyter environment
- Colab: Google's free Jupyter notebook environment
Topics Covered
This tutorial covers the following topics using Python and SymPy:
- Vectors: position vectors, magnitude, scalar multiplication
- Unit vectors and direction cosines
- Vector, parametric and Cartesian equations of lines
- Dot product and cross product
- Gradient, divergence and curl
Introduction
A vector is just a Matrix with one column. Matrix([2, 4]) is the position vector
and Matrix([1, 3, -7]) is .
import sympy as sy
from sympy.abc import x, y, z, t
from sympy.solvers import solve
from sympy import sqrt, tan, sin, cos, sec, pi, ln, exp
from sympy import atan, acos, asin, diff, Matrix, simplify, nsimplify
sy.init_printing(use_latex=True)
# --- handy helpers used in Q7, Q8 and Q9 ---
def gradient(f, vars=(x, y, z)):
"""Gradient of a scalar field, returned as a column vector."""
return Matrix([diff(f, v) for v in vars])
def divergence(F, vars=(x, y, z)):
"""Divergence of a vector field given as a list/Matrix of components."""
return sum(diff(F[i], vars[i]) for i in range(len(vars)))
def curl(F):
"""Curl of a 3D vector field given as a list/Matrix of components."""
return Matrix([diff(F[2], y) - diff(F[1], z),
diff(F[0], z) - diff(F[2], x),
diff(F[1], x) - diff(F[0], y)])
Question 1
Sketch and and find the distance between them.
P = Matrix([3, -1, 5])
Q = Matrix([2, 1, -1])
PQ = Q - P
display(PQ, sqrt(PQ.dot(PQ))) # <-1,2,-6>, sqrt(41)
The distance is .
Question 2
For , compute , and .
a = Matrix([2, 4])
display(3*a) # <6, 12>
display(a/2) # <1, 2>
display(-2*a) # <-4, -8>
Scalar multiplication never changes the direction of a vector, only its length — except for a negative scalar, which reverses the direction. A scalar larger than stretches the vector, a scalar between and shrinks it, and doubles the length while flipping it through .
Question 3
Given and .
i. Find the unit vector in the direction of .
OP = Matrix([1, 3, -7])
OQ = Matrix([5, -2, 4])
PQ = OQ - OP
display(PQ) # <4, -5, 11>
display(sqrt(PQ.dot(PQ))) # 9*sqrt(2)
display(PQ / sqrt(PQ.dot(PQ))) # (1/(9*sqrt(2)))<4,-5,11>
ii. Find the direction cosines of .
unit_PQ = PQ / sqrt(PQ.dot(PQ))
display(list(unit_PQ)) # [cos(alpha), cos(beta), cos(gamma)]
So , and .
iii. Find the vector of magnitude in the direction of , in polar form.
display(5 * (-unit_PQ)) # the vector itself
angles = [acos(e) * 180/pi for e in (-unit_PQ)] # polar angles of QP
display([sy.N(a, 6) for a in angles]) # 108.32, 66.87, 149.80 degrees
The vector of magnitude in the direction of is .
Question 4
and .
i. Vector equation of the line through and .
A = Matrix([1, 2])
B = Matrix([3, 4])
AB = B - A
display(AB) # <2, 2>
So .
ii. Points on the line for .
display([(ti, A + ti*AB) for ti in range(6)])
| 0 | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 |
Question 5
A unit vector makes an angle of with , with and an acute angle with . Find and the components of .
The components of a unit vector are exactly its direction cosines, and .
cos_a = cos(pi/3)
cos_b = cos(pi/4)
cos2_g = 1 - cos_a**2 - cos_b**2
display(simplify(cos2_g)) # 1/4
theta = acos(sqrt(cos2_g)) # acute angle only
display(theta, sy.N(theta*180/pi, 6)) # pi/3, 60 degrees
a = Matrix([cos_a, cos_b, cos(theta)])
display(simplify(a), sqrt(a.dot(a))) # <1/2, 1/sqrt(2), 1/2>, |a| = 1
Hence and .
The printed solution also lists the case
. Because the question
specifies an acute angle, that case must be discarded — taking acos of the
positive root gives the acute angle directly.
Question 6
If is a unit vector and , find .
Expanding the dot product gives , and .
X = sy.Symbol('X', nonnegative=True) # X = |x|
display(solve(sy.Eq(X**2 - 1, 8), X)) # [3]
So (the negative root is rejected because a magnitude cannot be negative).
Question 7
Find the gradient of .
f = (2*x**2 + y)/(x**2 - y**2)
grad_f = gradient(f, (x, y))
display(simplify(grad_f[0])) # -2*x*y*(2*y + 1)/(x**2 - y**2)**2
display(simplify(grad_f[1])) # (x**2 + 4*x**2*y + y**2)/(x**2 - y**2)**2
Question 8
Calculate the divergence of the vector fields.
a.
display(divergence(Matrix([y**3, x*y]), (x, y))) # x
b.
display(simplify(divergence(Matrix([4*y/x**2, sin(y), 3])))) # cos(y) - 8*y/x**3
c.
display(simplify(divergence(Matrix([exp(x), ln(x*y), exp(x*y*z)])))) # e**x + 1/y + x*y*e**(x*y*z)
Question 9
Calculate the curl of the vector fields.
a.
display(curl(Matrix([3*x**2, 2*z, -x]))) # <-2, 1, 0>
b.
display(curl(Matrix([y**3, x*y, -z]))) # <0, 0, y - 3*y**2>
The curl points along only.
c.
display(simplify(curl(Matrix([1 + y + z**2, exp(x*y*z), -x*y*z]))))
The printed solution drops the minus sign on in the and components and mislabels the term as . SymPy differentiates each component literally, so the signs come out right.
Extra Learning Resources
Key Concepts to Master
- Magnitude:
- Unit vector:
- Direction cosines: the components of a unit vector, with
- Cross product: is perpendicular to both, with
- Del operator: (gradient, a vector), (divergence, a scalar), (curl, a vector)
SymPy Resources
- SymPy Matrices —
dot,cross,norm,jacobian - SymPy Calculus — the
diffused by the helpers above - SymPy Vector module —
CoordSys3D,gradient,divergence,curlas ready-made functions
Common Pitfalls
Matrix([1,2,3])is a column vector;dotandcrossonly work onMatrixobjects, not plain lists- Use
**for powers, and remembersec(x) = 1/cos(x) solvereturns a list — index it ([0]) or filter it before using a root- Always declare an applied variable as positive (
sy.Symbol('r', positive=True)) to discard non-physical roots