.. -*- coding: utf-8 -*-

.. linkall

.. _prep-quickstart-multivariate-calculus:

Sage Quickstart for Multivariable Calculus
==========================================

This `Sage <http://www.sagemath.org>`_ quickstart tutorial was developed
for the MAA PREP Workshop "Sage: Using Open\-Source Mathematics Software
with Undergraduates" (funding provided by NSF DUE 0817071).  It is
licensed under the Creative Commons Attribution\-ShareAlike 3.0 license
(`CC BY\-SA <http://creativecommons.org/licenses/by-sa/3.0/>`_).

Because much related material was covered in the calculus tutorial, this
quickstart is designed to:

- Give concrete examples of some things not covered there, without huge
  amounts of commentary, and

- Remind the reader of a few of the things in that tutorial.

Vector Calculus
----------------

In Sage, vectors are primarily linear algebra objects, but they are
slowly becoming simultaneously analytic continuous functions.

Dot Product, Cross Product
~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    sage: v = vector(RR, [1.2, 3.5, 4.6])
    sage: w = vector(RR, [1.7,-2.3,5.2])
    sage: v*w
    17.9100000000000

::

    sage: v.cross_product(w)
    (28.7800000000000, 1.58000000000000, -8.71000000000000)

Lines and Planes
~~~~~~~~~~~~~~~~

Intersect :math:`x-2y-7z=6` with
:math:`\frac{x-3}{2}=\frac{y+4}{-3}=\frac{z-1}{1}`.  One way to plot the
equation of a line in three dimensions is with ``parametric_plot3d``.

::

    sage: # designed with intersection at t = 2, i.e. (7, -10, 3)
    sage: var('t, x, y')
    (t, x, y)
    sage: line = parametric_plot3d([2*t+3, -3*t-4, t+1], (t, 0, 4),color='red')
    sage: plane = plot3d((1/5)*(-12+x-2*y), (x, 4, 10), (y, -13,-7), opacity=0.5)
    sage: intersect=point3d([7,-10,3],color='black',size=30)
    sage: line+plane+intersect
    Graphics3d Object

Vector\-Valued Functions
~~~~~~~~~~~~~~~~~~~~~~~~

We can make vector-valued functions and do the usual analysis with them.

::

    sage: var('t')
    t
    sage: r=vector((2*t-4, t^2, (1/4)*t^3))
    sage: r
    (2*t - 4, t^2, 1/4*t^3)

::

    sage: r(t=5)
    (6, 25, 125/4)

The following makes the derivative also a vector\-valued expression.

::

    sage: velocity = r.diff(t) # velocity(t) = list(r.diff(t)) also would work
    sage: velocity
    (2, 2*t, 3/4*t^2)

Currently, this expression does *not* function as a function, so we need to
substitute explicitly.

::

    sage: velocity(t=1)
    (2, 2, 3/4)

::

    sage: T=velocity/velocity.norm()

::

    sage: T(t=1).n()
    (0.683486126173409, 0.683486126173409, 0.256307297315028)

Here we compute the arclength between :math:`t=0` and :math:`t=1` by
integrating the normalized derivative. As pointed out in the
:doc:`calculus tutorial <../Calculus>`, the syntax for
``numerical_integral`` is slightly nonstandard -- we just put in the
endpoints, not the variable.

::

    sage: arc_length = numerical_integral(velocity.norm(), 0,1)
    sage: arc_length
    (2.3169847271197814, 2.572369791753217e-14)

We can also plot vector fields, even in three dimensions.

::

    sage: x,y,z=var('x y z')
    sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),colors=['red','green','blue'])
    Graphics3d Object

If we know a little vector calculus, we can also do line integrals.
Here, based on an example by Ben Woodruff of BYU-Idaho, we
compute a number of quantities in a physical three-dimensional setting.

Try to read through the entire code.  We make an auxiliary function that
will calculate :math:`\int (\text{integrand})\, dt`. We'll use our
formulas relating various differentials to :math:`dt` to easily specify
the integrands.

::

    sage: density(x,y,z)=x^2+z
    sage: r=vector([3*cos(t), 3*sin(t),4*t])
    sage: tstart=0
    sage: tend=2*pi
    sage: t = var('t')
    sage: t_range=(t,tstart,tend)
    sage: def line_integral(integrand):
    ....:     return RR(numerical_integral((integrand).subs(x=r[0], y=r[1],z=r[2]), tstart, tend)[0])
    sage: _ = var('x,y,z,t')
    sage: r_prime = diff(r,t)
    sage: ds=diff(r,t).norm()
    sage: s=line_integral(ds)
    sage: centroid_x=line_integral(x*ds)/s
    sage: centroid_y=line_integral(y*ds)/s
    sage: centroid_z=line_integral(z*ds)/s
    sage: dm=density(x,y,z)*ds
    sage: m=line_integral(dm)
    sage: avg_density = m/s
    sage: moment_about_yz_plane=line_integral(x*dm)
    sage: moment_about_xz_plane=line_integral(y*dm)
    sage: moment_about_xy_plane=line_integral(z*dm)
    sage: center_mass_x = moment_about_yz_plane/m
    sage: center_mass_y = moment_about_xz_plane/m
    sage: center_mass_z = moment_about_xy_plane/m
    sage: Ix=line_integral((y^2+z^2)*dm)
    sage: Iy=line_integral((x^2+z^2)*dm)
    sage: Iz=line_integral((x^2+y^2)*dm)
    sage: Rx = sqrt(Ix/m)
    sage: Ry = sqrt(Iy/m)
    sage: Rz = sqrt(Iz/m)

Finally, we can display everything in a nice :ref:`table <Tables>`.
Recall that we use the ``r"stuff"`` syntax to indicate "raw" strings
so that backslashes from LaTeX won't cause trouble.

.. skip

::

    sage: html.table([
    ....:     [r"Density $\delta(x,y)$", density],
    ....:     [r"Curve $\vec r(t)$",r],
    ....:     [r"$t$ range", t_range],
    ....:     [r"$\vec r'(t)$", r_prime],
    ....:     [r"$ds$, a little bit of arclength", ds],
    ....:     [r"$s$ - arclength", s],
    ....:     [r"Centroid (constant density) $\left(\frac{1}{m}\int x\,ds,\frac{1}{m}\int y\,ds, \frac{1}{m}\int z\,ds\right)$", (centroid_x,centroid_y,centroid_z)],
    ....:     [r"$dm=\delta ds$ - a little bit of mass", dm],
    ....:     [r"$m=\int \delta ds$ - mass", m],
    ....:     [r"average density $\frac{1}{m}\int ds$" , avg_density.n()],
    ....:     [r"$M_{yz}=\int x dm$ - moment about $yz$ plane", moment_about_yz_plane],
    ....:     [r"$M_{xz}=\int y dm$ - moment about $xz$ plane", moment_about_xz_plane],
    ....:     [r"$M_{xy}=\int z dm$ - moment about $xy$ plane", moment_about_xy_plane],
    ....:     [r"Center of mass $\left(\frac1m \int xdm, \frac1m \int ydm, \frac1m \int z dm\right)$", (center_mass_x, center_mass_y, center_mass_z)],
    ....:     [r"$I_x = \int (y^2+z^2) dm$", Ix],[r"$I_y=\int (x^2+z^2) dm$", Iy],[mp(r"$I_z=\int (x^2+y^2)dm$"), Iz],
    ....:     [r"$R_x=\sqrt{I_x/m}$", Rx],[mp(r"$R_y=\sqrt{I_y/m}"), Ry],[mp(r"$R_z=\sqrt{I_z/m}"),Rz]
    ....:     ])

Functions of Several Variables
-------------------------------

This connects directly to other issues of multivariable functions.

How to view these was mostly addressed in the various plotting
tutorials.  Here is a reminder of what can be done.

::

    sage: # import matplotlib.cm; matplotlib.cm.datad.keys()
    sage: # 'Spectral', 'summer', 'blues'
    sage: g(x,y)=e^-x*sin(y)
    sage: contour_plot(g, (x, -2, 2), (y, -4*pi, 4*pi), cmap = 'Blues', contours=10, colorbar=True)
    Graphics object consisting of 1 graphics primitive

Partial Differentiation
~~~~~~~~~~~~~~~~~~~~~~~

The following exercise is from Hass, Weir, and Thomas, University
Calculus, Exercise 12.7.35.  This function has a local minimum at :math:`(4,-2)`.

::

    sage: f(x, y) = x^2 + x*y + y^2 - 6*x + 2

Quiz: Why did we  *not*  need to declare the variables in this case?

::

    sage: fx(x,y)= f.diff(x)
    sage: fy(x,y) = f.diff(y)
    sage: fx; fy
    (x, y) |--> 2*x + y - 6
    (x, y) |--> x + 2*y

::

    sage: f.gradient()
    (x, y) |--> (2*x + y - 6, x + 2*y)

::

    sage: solve([fx==0, fy==0], (x, y))
    [[x == 4, y == -2]]

::

    sage: H = f.hessian()
    sage: H(x,y)
    [2 1]
    [1 2]

And of course if the Hessian has positive determinant and :math:`f_{xx}`
is positive, we have a local minimum.

.. skip

::

    sage: html("$f_{xx}=%s$"%H(4,-2)[0,0])
    sage: html("$D=%s$"%H(4,-2).det())

Notice how we were able to use many things we've done up to now to solve
this.

- Matrices

- Symbolic functions

- Solving

- Differential calculus

- Special formatting commands

- And, below, plotting!

::

    sage: plot3d(f,(x,-5,5),(y,-5,5))+point((4,-2,f(4,-2)),color='red',size=20)
    Graphics3d Object

Multiple Integrals and More
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Naturally, there is lots more that one can do.

::

    sage: f(x,y)=x^2*y
    sage: # integrate in the order dy dx
    sage: f(x,y).integrate(y,0,4*x).integrate(x,0,3)
    1944/5
    sage: # another way to integrate, and in the opposite order too
    sage: integrate( integrate(f(x,y), (x, y/4, 3)), (y, 0, 12) )
    1944/5

::

    sage: var('u v')
    (u, v)
    sage: surface = plot3d(f(x,y), (x, 0, 3.2), (y, 0, 12.3), color = 'blue', opacity=0.3)
    sage: domain = parametric_plot3d([3*u, 4*(3*u)*v,0], (u, 0, 1), (v, 0,1), color = 'green', opacity = 0.75)
    sage: image = parametric_plot3d([3*u, 4*(3*u)*v, f(3*u, 12*u*v)], (u, 0, 1), (v, 0,1), color = 'green', opacity = 1.00)
    sage: surface+domain+image
    Graphics3d Object

Quiz: why did we need to declare variables this time?