Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

All published worksheets from http://sagenb.org

Views: 168754
Image: ubuntu2004

A Smattering of Multivariate Calculus Commands

Tim McLarnan, Earlham College

Multivariate calculus is actually one of Sage's weaker areas.  Sage's 3D graphics capability is somewhat awkward.  Sage lacks a vector field class.  The authors of Sage are clearly more interested in algebra and in number theory than in analysis.  That said, Sage can still be used for the basic tools we need in Multivariate Calculus.

3D Plots

var('x y') plot3d(x^2-y^4, [x,-1.5,1.5], [y,-1.2,1.2])
show(contour_plot(x^2-y^4, [x,-1.5,1.5], [y,-1.2,1.2]), aspect_ratio=1)
show(plot_vector_field([x^2, y^2], [x,-1,1], [y,-1,1]), aspect_ratio=1)
var('t') parametric_plot3d([cos(t), sin(t), t], [t, 0, 4*pi])
var('theta phi') parametric_plot3d([2*cos(theta)*sin(phi), 4*sin(theta)*sin(phi), cos(phi)], [theta, 0, 2*pi], [phi, 0, pi])
show(_, aspect_ratio=1)
plot3d(y^2/x^4, [x,-1,1], [y,-1,1])
contour_plot(y^2/x^4, [x,-0.1,0.1], [y,-0.1,0.1])
p1 = implicit_plot(y^2/x^4==1, (x,-1,1), (y,-1,1), plot_points=1000) p2 = implicit_plot(y^2/x^4==2, (x,-1,1), (y,-1,1), plot_points=1000) phalf = implicit_plot(y^2/x^4==1/2, (x,-1,1), (y,-1,1), plot_points=1000) show(p1+p2+phalf, aspect_ratio=1)

Vectors and Matrices

Matrices and vectors work pretty much the way you would expect, except that in keeping with a number of programming languages, entries and rows and columns are numbered starting at 0, not 1.

v = vector([3,1,4]) v
\newcommand{\Bold}[1]{\mathbf{#1}}\left(3,1,4\right)
v[0]
\newcommand{\Bold}[1]{\mathbf{#1}}3
v[1]
\newcommand{\Bold}[1]{\mathbf{#1}}1
v[2]
\newcommand{\Bold}[1]{\mathbf{#1}}4
u = vector([1,-3,2])
v.dot_product(u)
\newcommand{\Bold}[1]{\mathbf{#1}}8
v*u
\newcommand{\Bold}[1]{\mathbf{#1}}8

Notice that in this last product, v was treated as a row vector, and u as a column vector.

v.cross_product(u)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(14,-2,-10\right)
M = matrix([[1,2,3],[3,1,4],[-1,1,1]]) M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(123314111\begin{array}{rrr} 1 & 2 & 3 \\ 3 & 1 & 4 \\ -1 & 1 & 1 \end{array}\right)
M[1,2]
\newcommand{\Bold}[1]{\mathbf{#1}}4
M.determinant()
\newcommand{\Bold}[1]{\mathbf{#1}}-5
M.inverse()
\newcommand{\Bold}[1]{\mathbf{#1}}\left(351517545145351\begin{array}{rrr} \frac{3}{5} & -\frac{1}{5} & -1 \\ \frac{7}{5} & -\frac{4}{5} & -1 \\ -\frac{4}{5} & \frac{3}{5} & 1 \end{array}\right)
M^2
\newcommand{\Bold}[1]{\mathbf{#1}}\left(471421117102\begin{array}{rrr} 4 & 7 & 14 \\ 2 & 11 & 17 \\ 1 & 0 & 2 \end{array}\right)
M.charpoly()
\newcommand{\Bold}[1]{\mathbf{#1}}x^{3} - 3x^{2} - 4x + 5
print(M.eigenvalues())
[-1.571201422548122?, 0.8567226781603571?, 3.714478744387765?]
print(M.eigenvectors_left())
[(-1.571201422548122?, [(1, -0.8205055024661761?, 0.10968491514959334?)], 1), (0.8567226781603571?, [(1, -0.6818607149130776?, -1.902304822899590?)], 1), (3.714478744387765?, [(1, 2.502366217379254?, 4.792619907749997?)], 1)]
M*v
\newcommand{\Bold}[1]{\mathbf{#1}}\left(17,26,2\right)

Here v was viewed as a column vector.

v*M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(2,11,17\right)

And here v was a row vector.

Although matrices can be written as simply as we did above, Sage would really rather we specified what ring the entries of any matrix lie in: the integers Z\mathbb Z, which Sage writes as ZZ, the rationals Q\mathbb Q, which Sage calls QQ, the reals R\mathbb R, which is roughly Sage's RR, the integers mod 7, Z7\mathbb Z_7, which is Sage's Zmod(7), etc.  Depending on what ring the entries lie in, some matrix operations will behave differently.

M = matrix(QQ, [[1,2],[3,4]]) M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1234\begin{array}{rr} 1 & 2 \\ 3 & 4 \end{array}\right)
M^2
\newcommand{\Bold}[1]{\mathbf{#1}}\left(7101522\begin{array}{rr} 7 & 10 \\ 15 & 22 \end{array}\right)
M^(-1)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(213212\begin{array}{rr} -2 & 1 \\ \frac{3}{2} & -\frac{1}{2} \end{array}\right)
M7 = matrix(Zmod(7), [[1,2],[3,4]]) M7
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1234\begin{array}{rr} 1 & 2 \\ 3 & 4 \end{array}\right)
M7^2
\newcommand{\Bold}[1]{\mathbf{#1}}\left(0311\begin{array}{rr} 0 & 3 \\ 1 & 1 \end{array}\right)
M7^(-1)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(5153\begin{array}{rr} 5 & 1 \\ 5 & 3 \end{array}\right)
MQ = matrix(QQ, [[6,2,1],[10,3,6],[4,1,5]]) MQ
\newcommand{\Bold}[1]{\mathbf{#1}}\left(6211036415\begin{array}{rrr} 6 & 2 & 1 \\ 10 & 3 & 6 \\ 4 & 1 & 5 \end{array}\right)
MQ.echelon_form()
\newcommand{\Bold}[1]{\mathbf{#1}}\left(10920113000\begin{array}{rrr} 1 & 0 & \frac{9}{2} \\ 0 & 1 & -13 \\ 0 & 0 & 0 \end{array}\right)
MZ = matrix(ZZ, [[6,2,1],[10,3,6],[4,1,5]]) MZ
\newcommand{\Bold}[1]{\mathbf{#1}}\left(6211036415\begin{array}{rrr} 6 & 2 & 1 \\ 10 & 3 & 6 \\ 4 & 1 & 5 \end{array}\right)
MZ.echelon_form()
\newcommand{\Bold}[1]{\mathbf{#1}}\left(2090113000\begin{array}{rrr} 2 & 0 & 9 \\ 0 & 1 & -13 \\ 0 & 0 & 0 \end{array}\right)
MZ.pivots()
\newcommand{\Bold}[1]{\mathbf{#1}}\left[0, 1\right]

As a tool in teaching and learning, it's cute that Sage lets one do Gaussian elimination a step at a time, like this:

(Notice that the row operations don't return a new matrix, but that they modify the original matrix in place.)

M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1234\begin{array}{rr} 1 & 2 \\ 3 & 4 \end{array}\right)
M.add_multiple_of_row(1,0,-3) M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1202\begin{array}{rr} 1 & 2 \\ 0 & -2 \end{array}\right)
M.rescale_row(1, -1/2) M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1201\begin{array}{rr} 1 & 2 \\ 0 & 1 \end{array}\right)
M.add_multiple_of_row(0,1,-2) M
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1001\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)
var('x y z w') vandermonde = matrix(list(list(k^n for n in range(4)) for k in [x,y,z,w])) vandermonde
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1xx2x31yy2y31zz2z31ww2w3\begin{array}{rrrr} 1 & x & x^{2} & x^{3} \\ 1 & y & y^{2} & y^{3} \\ 1 & z & z^{2} & z^{3} \\ 1 & w & w^{2} & w^{3} \end{array}\right)
vdet = vandermonde.det() print(vdet)
-w^3*x^2*y + w^3*x^2*z + w^3*x*y^2 - w^3*x*z^2 - w^3*y^2*z + w^3*y*z^2 + w^2*x^3*y - w^2*x^3*z - w^2*x*y^3 + w^2*x*z^3 + w^2*y^3*z - w^2*y*z^3 - w*x^3*y^2 + w*x^3*z^2 + w*x^2*y^3 - w*x^2*z^3 - w*y^3*z^2 + w*y^2*z^3 + x^3*y^2*z - x^3*y*z^2 - x^2*y^3*z + x^2*y*z^3 + x*y^3*z^2 - x*y^2*z^3
factor(vdet)
\newcommand{\Bold}[1]{\mathbf{#1}}-{\left(y - z\right)} {\left(x - z\right)} {\left(x - y\right)} {\left(w - z\right)} {\left(w - y\right)} {\left(w - x\right)}

Div, Grad, Curl, and All That

Weirdly, Sage has gradients built in, but not divergence or curl or even the vector fields for which these operators would make sense.  Of course, we can implement these things ourselves, but it's somewhat shocking that we need to.  Here are some very quick and dirty definitions of these functions assuming that the variables involved are xx, yy, and zz.  The Sage wiki has a somewhat more professional version, but obviously Sage needs someone to build a proper vector field class.

var('t x y z') f(x,y,z) = sin(x) - cos(y) + z f(x,y,z)
\newcommand{\Bold}[1]{\mathbf{#1}}z + \sin\left(x\right) - \cos\left(y\right)
gr = f(x,y,z).gradient() gr
\newcommand{\Bold}[1]{\mathbf{#1}}\left(\cos\left(x\right),\sin\left(y\right),1\right)
gr.derivative(x)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(-\sin\left(x\right),0,0\right)
def divergence(F): assert(len(F) == 3) return diff(F[0],x) + diff(F[1],y) + diff(F[2],z)
gr
\newcommand{\Bold}[1]{\mathbf{#1}}\left(\cos\left(x\right),\sin\left(y\right),1\right)
divergence(gr)
\newcommand{\Bold}[1]{\mathbf{#1}}-\sin\left(x\right) + \cos\left(y\right)
divergence([x,y,z])
\newcommand{\Bold}[1]{\mathbf{#1}}3
def curl(F): assert(len(F) == 3) return vector([diff(F[2],y)-diff(F[1],z), diff(F[0],z)-diff(F[2],x), diff(F[1],x)-diff(F[0],y)])
curl(gr)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(0,0,0\right)
curl([-y, x, 0])
\newcommand{\Bold}[1]{\mathbf{#1}}\left(0,0,2\right)
gr[1]
\newcommand{\Bold}[1]{\mathbf{#1}}\sin\left(y\right)