Matrices and Vectors: Topics from Linear Algebra and Vector Calculus

Keywords

Linear algebra; Eigenvalues; Eigenvectors; Vector calculus; Engineering applications; Linear programming; Photo special effects; Applying effects to photos and figures

5.1 Nested Lists: Introduction to Matrices, Vectors, and Matrix Operations

5.1.1 Defining Nested Lists, Matrices, and Vectors

In Mathematica, a matrix is a list of lists where each list represents a row of the matrix. Therefore, the m×nImage matrix

A = ( a 11 a 12 a 13 a 1 n a 21 a 22 a 23 a 2 n a 31 a 32 a 33 a 3 n a m 1 a m 2 a m 3 a m n )

is entered with

A={{a11,a12,...,a1n},{a21,a22,...,a2n},...,{am1,am2,...amn}}.

For example, to use Mathematica to define m to be the matrix A=(a11a12a21a22)Image enter the command

m={{a11,a12},{a21,a22}}.

The command m=Array[a,{2,2}] produces a result equivalent to this. Once a matrix A has been entered, it can be viewed in the traditional row-and-column form using the command MatrixForm[A]. You can quickly construct 2×2Image matrices by clicking on the Image button from the BasicMathInput palette, which is accessed by going to Palettes followed by BasicMathInput.

As when using TableForm, the result of using MatrixForm is no longer a list that can be manipulated using Mathematica commands. Use MatrixForm to view a matrix in traditional row-and-column form. Do not attempt to perform matrix operations on a MatrixForm object.

Alternatively, you can construct matrices of any dimension by going to the Mathematica menu under Insert and selecting Create Table/Matrix/Palette...

Use Part, ([[...]]) to select elements of lists. Because of the construct of the matrix, m[[i]] returns the ith row of M. The transpose of M, MtImage, is the matrix obtained by interchanging the rows and columns of matrix M. Thus, to extract the ith column of M, use the commands mt=Transpose[m] followed by mt[[i]].

Image

The resulting pop-up window allows you to create tables, matrices, and palettes. To create a matrix, select Matrix, enter the number of rows and columns of the matrix, and select any other options. Pressing the OK button places the desired matrix at the position of the cursor in the Mathematica notebook.

Image

Example 5.1

Use Mathematica to define the matrices (a11a12a13a21a22a23a31a32a33)Image and (b11b12b13b14b21b22b23b24)Image.

More generally the commands Table[f[i,j],{i,imax},{j,jmax}] and Array[f,{imax,jmax}] yield nested lists corresponding to the imax×jmaxImage matrix

( f ( 1 , 1 ) f ( 1 , 2 ) f ( 1 , jmax ) f ( 2 , 1 ) f ( 2 , 2 ) f ( 2 , jmax ) f ( imax , 1 ) f ( imax , 2 ) f ( imax , jmax ) ) .

Table[f[i,j],{i,imin,imax,istep},{j,jmin,jmax,jstep}] returns the list of lists

{{f[imin,jmin],f[imin,jmin+jstep],...,f[imin,jmax]},
     {f[imin+istep,jmin],...,f[imin+istep,jmax]},
          ...,{f[imax,jmin],...,f[imax,jmax]}}

and the command

Table[f[i,j,k,...],{i,imin,imax,istep},{j,jmin,jmax,jstep},
     {k,kmin,kmax,kstep},...]

calculates a nested list; the list associated with i is outermost. If istep is omitted, the stepsize is one.

Example 5.2

Define C to be the 3×4Image matrix (cij)Image, where cijImage, the entry in the ith row and jth column of C, is the numerical value of cos(j2i2)sin(i2j2)Image.

Example 5.3

Define the matrix I3=(100010001)Image.

Solution

The matrix I3Image is the 3×3Image identity matrix. Generally, the n×nImage matrix with 1's on the diagonal and 0's elsewhere is the n×nImage identity matrix. The command IdentityMatrix[n] returns the n×nImage identity matrix.

IdentityMatrix [ 3 ] Image

{{1,0,0},{0,1,0},{0,0,1}}Image

The same result is obtained by going to Insert under the Mathematica menu and selecting Table/Matrix/ followed by New.... We then check Matrix, Fill with: 0 and Fill diagonal: 1.

Image

Pressing the OK button inserts the 3×3Image identity matrix at the location of the cursor.

( 1 0 0 0 1 0 0 0 1 ) Image

{{1,0,0},{0,1,0},{0,0,1}}Image □

In Mathematica, a vector is a list of numbers and, thus, is entered in the same manner as lists. For example, to use Mathematica to define the row vector vectorv to be (v1v2v3)Image enter vectorv={v1,v2,v3}. Similarly, to define the column vector vectorv to be (v1v2v3)Image enter vectorv={v1,v2,v3} or vectorv={{v1},{v2},{v3}}.

With Mathematica, you do not need to distinguish between row and column vectors. Provided that computations are well-defined, Mathematica carries them out correctly. Mathematica warns of any ambiguities when they (rarely) occur.

Generally, with Mathematica you do not need to distinguish between row and column vectors: Mathematica usually performs computations with vectors and matrices correctly as long as the computations are well-defined.

Example 5.4

Define the vector w=(452)Image, vectorv to be the vector (v1v2v3v4)Image and zerovec to be the vector (00000)Image.

Solution

To define w, we enter

w = { 4 , 5 , 2 } Image

{ 4 , 5 , 2 } Image

or

w = { { 4 } , { 5 } , { 2 } } ; MatrixForm [ w ] Image

( 4 5 2 ) Image

To define vectorv, we use Array.

vectorv = Array [ v , 4 ] Image

{ v [ 1 ] , v [ 2 ] , v [ 3 ] , v [ 4 ] } Image

Equivalent results would have been obtained by entering Table[vi,{i,1,4}]Image. To define zerovec, we use Table.

zerovec = Table [ 0 , { 5 } ] Image

{ 0 , 0 , 0 , 0 , 0 } Image

The same result is obtained by going to Insert under the Mathematica menu and selecting Table/Matrix to create the zero vector.

( 0 0 0 0 0 ) Image

{{0,0,0,0,0}}Image □

5.1.2 Extracting Elements of Matrices

For the 2×2Image matrix m={{a1,1,a1,2},{a2,1,a2,2}}Image defined earlier, m[[1]] yields the first element of matrix m which is the list {a1,1,a1,2}Image or the first row of m; m[[2,1]] yields the first element of the second element of matrix m which is a2,1Image. In general, if m is an i×jImage matrix, m[[i,j]] or Part[m,i,j] returns the unique element in the ith row and jth column of m. More specifically, m[[i,j]] yields the jth part of the ith part of m; list[[i]] or Part[list,i] yields the ith part of list; list[[i,j]] or Part[list,i,j] yields the jth part of the ith part of list, and so on.

Example 5.5

Define mb to be the matrix (106965710912)Image. (a) Extract the third row of mb. (b) Extract the element in the first row and third column of mb. (c) Display mb in traditional matrix form.

Solution

We begin by defining mb. mb[[i,j]] yields the (unique) number in the ith row and jth column of mb. Observe how various components of mb (rows and elements) can be extracted and how mb is placed in MatrixForm.

mb = { { 10 , 6 , 9 } , { 6 , 5 , 7 } , { 10 , 9 , 12 } } ; Image

MatrixForm [ mb ] Image

( 10 6 9 6 5 7 10 9 12 ) Image

mb [ [ 3 ] ] Image

{ 10 , 9 , 12 } Image

mb [ [ 1 , 3 ] ] Image

−9 □

If m is a matrix, the ith row of m is extracted with m[[i]]. The command Transpose[m] yields the transpose of the matrix m, the matrix obtained by interchanging the rows and columns of m. We extract columns of m by computing Transpose[m] and then using Part to extract rows from the transpose. Namely, if m is a matrix, Transpose[m][[i]] extracts the ith row from the transpose of m which is the same as the ith column of m.

Alternatively, if A is n×mImage (rows × columns) the ith column of A is the vector that consists of the ith part of each row of the matrix so given an i-value Table[A[[j,i]],{j,1,n}] returns the ith column of A.

Example 5.6

Extract the second and third columns from A=(022113241)Image.

Solution

We first define matrixa and then use Transpose to compute the transpose of matrixa, naming the result ta, and then displaying ta in MatrixForm.

matrixa = { { 0 , 2 , 2 } , { 1 , 1 , 3 } , { 2 , 4 , 1 } } ; Image

MatrixForm [ matrixa ] Image

( 0 2 2 1 1 3 2 4 1 ) Image

ta = Transpose [ matrixa ] Image

MatrixForm [ ta ] Image

{ { 0 , 1 , 2 } , { 2 , 1 , 4 } , { 2 , 3 , 1 } } Image

( 0 1 2 2 1 4 2 3 1 ) Image

Next, we extract the second column of matrixa using Transpose together with Part ([[...]]). Because we have already defined ta to be the transpose of matrixa, entering ta[[2]] would produce the same result.

Transpose [ matrixa ] [ [ 2 ] ] Image

{ 2 , 1 , 4 } Image

To extract the third column, we take advantage of the fact that we have already defined ta to be the transpose of matrixa. Entering Transpose[matrixa][[3]] produces the same result.

ta [ [ 3 ] ] Image

{ 2 , 3 , 1 } Image

You can also use Take to extract elements of lists and matrices. Entering

Take [ matrixa , 2 ] Image

Take [ matrixa , 2 ] // MatrixForm Image

{ { 0 , 2 , 2 } , { 1 , 1 , 3 } } Image

( 0 2 2 1 1 3 ) Image

returns the first two rows of matrixa because the first two parts of matrixa are the lists corresponding to those rows. Similarly,

Take [ matrixa , { 2 } ] Image

Take [ matrixa , { 2 } ] // MatrixForm Image

{ { 1 , 1 , 3 } } Image

( 1 1 3 ) Image

returns the second row while

Take [ matrixa , { 2 , 3 } ] Image

Take [ matrixa , { 2 , 3 } ] // MatrixForm Image

{ { 1 , 1 , 3 } , { 2 , 4 , 1 } } Image

( 1 1 3 2 4 1 ) Image

returns the second and third rows. □

The example illustrates that Take[list,n] returns the first n elements of list; Take[list,{n}] returns the nth element of list; Take[list,{n1,n2,...}] returns the n1Imagest, n2Imagend, ... elements of list, and so on.

5.1.3 Basic Computations with Matrices

Mathematica performs all of the usual operations on matrices. Matrix addition (A+BImage), scalar multiplication (kAImage), matrix multiplication (when defined) (AB), and combinations of these operations are all possible. The transpose of A, AtImage, is obtained by interchanging the rows and columns of A and is computed with the command Transpose[A]. If A is a square matrix, the determinant of A is obtained with Det[A].

If A and B are n×nImage matrices satisfying AB=BA=IImage, where I is the n×nImage matrix with 1's on the diagonal and 0's elsewhere (the n×nImage identity matrix), B is called the inverse of A and is denoted by A1Image. If the inverse of a matrix A exists, the inverse is found with Inverse[A]. Thus, assuming that (abcd)Image has an inverse (adbc0Image), the inverse is A11adbc(dbca)Image.

This easy-to-remember formula for finding the inverse of a 2×2Image matrix is sometimes called “the handy two-by-two inverse trick” by instructors and students.

Inverse [ { { a , b } , { c , d } } ] Image

{ { d b c + a d , b b c + a d } , { c b c + a d , a b c + a d } } Image

Example 5.7

Let A=(345803521)Image and B=(106965710912)Image. Compute

(a) A+BImage; (b) B4AImage; (c) the inverse of AB; (d) the transpose of (A2B)BImage; and (e) detA=|A|Image.

Solution

We enter ma (corresponding to A) and mb (corresponding to B) as nested lists where each element corresponds to a row of the matrix. We suppress the output by ending each command with a semi-colon.

ma = { { 3 , 4 , 5 } , { 8 , 0 , 3 } , { 5 , 2 , 1 } } ; Image

mb = { { 10 , 6 , 9 } , { 6 , 5 , 7 } , { 10 , 9 , 12 } } ; Image

Entering

ma + mb // MatrixForm Image

( 13 10 4 14 5 10 5 11 13 ) Image

adds matrix ma to mb and expresses the result in traditional matrix form. Entering

mb 4 ma // MatrixForm Image

( 2 10 29 26 5 5 30 1 8 ) Image

subtracts four times matrix ma from mb and expresses the result in traditional matrix form. Entering

Inverse [ ma . mb ] // MatrixForm Image

( 59 380 53 190 167 380 223 570 92 95 979 570 49 114 18 19 187 114 ) Image

computes the inverse of the matrix product AB. Similarly, entering

Matrix products, when defined, are computed by placing a period (.) between the matrices being multiplied. Note that a period is also used to compute the dot product of two vectors, when the dot product is defined.

Transpose [ ( ma 2 mb ) . mb ] // MatrixForm Image

( 352 90 384 269 73 277 373 98 389 ) Image

computes the transpose of (A2B)BImage and entering

Det [ ma ] Image

190

computes the determinant of A.  □

Example 5.8

Compute AB and BA if A=(155435324423)Image and B=(12434453)Image.

Solution

Because A is a 3×4Image matrix and B is a 4×2Image matrix, AB is defined and is a 3×2Image matrix. We define matrixa and matrixb with the following commands.

Remember that you can also define matrices by going to Insert under the Mathematica menu and selecting Table/Matrix. After entering the desired number of rows and columns and pressing the OK button, a matrix template is placed at the location of the cursor that you can fill in.

matrixa = ( 1 5 5 4 3 5 3 2 4 4 2 3 ) ; Image

matrixb = ( 1 2 4 3 4 4 5 3 ) ; Image

We then compute the product, naming the result ab, and display ab in MatrixForm.

ab = matrixa . matrixb ; Image

MatrixForm [ ab ] Image

( 19 19 1 15 3 21 ) Image

However, the matrix product BA is not defined and Mathematica produces error messages, which are not displayed here, when we attempt to compute it.

matrixb . matrixa Image

{{1,2},{4,3},{4,4},{5,3}}.{{1,5,5,4},{3,5,3,2},{4,4,2,3}}Image □

Special attention must be given to the notation that must be used in taking the product of a square matrix with itself. The following example illustrates how Mathematica interprets the expression (matrixb)^n. The command (matrixb)^n raises each element of the matrix matrixb to the nth power. The command MatrixPower is used to compute powers of matrices.

Example 5.9

Let B=(23402013146548114)Image. (a) Compute B2Image and B3Image. (b) Cube each entry of B.

Solution

After defining B, we compute B2Image. The same results would have been obtained by entering MatrixPower[matrixb,2].

matrixb = { { 2 , 3 , 4 , 0 } , { 2 , 0 , 1 , 3 } , { 1 , 4 , 6 , 5 } , Image

{ 4 , 8 , 11 , 4 } } ; Image

MatrixForm [ matrixb . matrixb ] Image

( 6 10 29 29 15 22 19 7 20 13 91 38 51 24 86 95 ) Image

Next, we use MatrixPower to compute B3Image. The same results would be obtained by entering matrixb.matrixb.matrixb.

MatrixForm [ MatrixPower [ matrixb , 3 ] ] Image

( 137 98 479 231 121 65 109 189 309 120 871 646 520 263 1381 738 ) Image

Last, we cube each entry of B with ^.

MatrixForm [ matrixb 3 ] Image

(8276408012716421612564512133164)Image □

If |A|0Image, the inverse of A can be computed using the formula

A 1 = 1 | A | A a ,

where AaImage is the transpose of the cofactor matrix.

The cofactor matrix, AcImage, of A is the matrix obtained by replacing each element of A by its cofactor.

If A has an inverse, reducing the matrix (A|I)Image to reduced row echelon form results in (I|A1)Image. This method is often easier to implement than (5.1).

Example 5.10

Calculate A1Image if A=(221022211)Image.

Solution

After defining A and I=(100010001)Image, we compute |A|=12Image, so A1Image exists.

capa = { { 2 , 2 , 1 } , { 0 , 2 , 2 } , { 2 , 1 , 1 } } Image

i3 = IdentityMatrix [ 3 ] Image

{ { 2 , 2 , 1 } , { 0 , 2 , 2 } , { 2 , 1 , 1 } } Image

{ { 1 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , 0 , 1 } } Image

Det [ capa ] Image

12

Join[a,b,n] concatenates lists a and b at level n. For matrices the level one objects (capa[[i]]) are the rows; the level two objects (capa[[i,j]]) are the entries. Thus, Join[capa,i3] returns the matrix (AI)Image while Join[capa,i3,2] forms the matrix (A|I)Image.

ai3 = Join [ capa , i3 , 2 ] Image

{ { 2 , 2 , 1 , 1 , 0 , 0 } , { 0 , 2 , 2 , 0 , 1 , 0 } , { 2 , 1 , 1 , 0 , 0 , 1 } } Image

{ { 2 , 2 , 1 , 1 , 0 , 0 } , { 0 , 2 , 2 , 0 , 1 , 0 } , Image

{ 2 , 1 , 1 , 0 , 0 , 1 } } Image

MatrixForm [ ai3 ] Image

( 2 2 1 1 0 0 0 2 2 0 1 0 2 1 1 0 0 1 ) Image

We then use RowReduce to reduce (A|I)Image to row echelon form.

RowReduce[A] reduces A to reduced row echelon form.

rrai3 = RowReduce [ ai3 ] Image

{ { 1 , 0 , 0 , 1 3 , 1 4 , 1 6 } , { 0 , 1 , 0 , 1 3 , 0 , 1 3 } , { 0 , 0 , 1 , 1 3 , 1 2 , 1 3 } } Image

{ { 1 , 0 , 0 , 1 3 , 1 4 , 1 6 } , Image

{ 0 , 1 , 0 , 1 3 , 0 , 1 3 } , { 0 , 0 , 1 , 1 3 , 1 2 , 1 3 } } Image

MatrixForm [ rrai3 ] Image

(10013141601013013001131213)Image

The result indicates that A1=(1/31/41/61/301/31/31/21/3)Image. □

5.1.4 Basic Computations with Vectors

5.1.4.1 Basic Operations on Vectors

Computations with vectors are performed in the same way as computations with matrices.

Example 5.11

Let v=(0512)Image and w=(3042)Image. (a) Calculate v2wImage and vwImage. (b) Find a unit vector with the same direction as v and a unit vector with the same direction as w.

5.1.4.2 Basic Operations on Vectors in 3-Space

We review the elementary properties of vectors in 3-space. Let

u = < u 1 , u 2 , u 3 > = u 1 i + u 2 j + u 3 k

and

v = < v 1 , v 2 , v 3 > = v 1 i + v 2 j + v 3 k

be vectors in space.

1.  u and v are equal if and only if their components are equal:

u = v u 1 = v 1 , u 2 = v 2 ,  and  u 3 = v 3 .

2.  The length (or norm) of u is

u = u 1 2 + u 2 2 + u 3 2 .

3.  If c is a scalar (number),

c u = < c u 1 , c u 2 , c u 3 > .

4.  The sum of u and v is defined to be the vector

u + v = < u 1 + v 1 , u 2 + v 2 , u 3 + v 3 > .

5.  If u0Image, a unit vector with the same direction as u is

1 u u = 1 u 1 2 + u 2 2 + u 3 2 < u 1 , u 2 , u 3 > .

6.  u and v are parallel if there is a scalar c so that u=cvImage.

7.  The dot product of u and v is

u v = u 1 v 1 + u 2 v 2 + u 3 v 3 .

If θ is the angle between u and v,

cos θ = u v u v .

Consequently, u and v are orthogonal if uv=0Image.

8.  The cross product of u and v is

u × v = | i j k u 1 u 2 u 3 v 1 v 2 v 3 | = ( u 2 v 3 u 3 v 2 ) i ( u 1 v 3 u 3 v 1 ) j + ( u 1 v 2 u 2 v 1 ) k .

You should verify that u(u×v)=0Image and v(u×v)=0Image. Hence, u×vImage is orthogonal to both u and v.

Topics from linear algebra (including determinants, which were mentioned previously) are discussed in more detail in the next sections. For now, we illustrate several of the basic operations listed above: u.v and Dot[u,v] compute uvImage; Cross[u,v] computes u×vImage.

In space, the standard unit vectors are i=<1,0,0>Image, j=<0,1,0>Image, and k=<0,0,1>Image. With the exception of the cross product, the vector operations discussed here are performed in the same way for vectors in the plane as they are in space. In the plane, the standard unit vectors are i=<1,0>Image and j=<0,1>Image.

A unit vector is a vector with length 1.

Example 5.12

Let u=<3,4,1>Image and v=<4,3,2>Image. Calculate (a) uvImage, (b) u×vImage, (c) uImage, and (d) vImage. (e) Find the angle between u and v. (f) Find unit vectors with the same direction as u, v, and u×vImage.

Solution

We begin by defining u=<3,4,1>Image and v=<4,3,2>Image. Notice that to define u=<u1,u2,u3>Image with Mathematica, we use the form

u={u1,u2,u3}.

We illustrate the use of Dot and Cross to calculate (a)–(d).

Similarly, to define u=<u1,u2>Image, we use the form u={u1,u2}.

u = { 3 , 4 , 1 } ; Image

v = { 4 , 3 , 2 } ; Image

udv = Dot [ u , v ] Image

−2

u . v Image

−2

ucv = Cross [ u , v ] Image

{ 11 , 2 , 25 } Image

nu = Norm [ u ] Image

26 Image

nv = Sqrt [ v . v ] Image

29 Image

We use the formula θ=cos1(uvuv)Image to find the angle θ between u and v.

ArcCos [ u . v / ( nu nv ) ] Image

N [ % ] Image

ArcCos [ 2 377 ] Image

1.6437

Unit vectors with the same direction as u, v, and u×vImage are found next.

normu = u / nu Image

normv = v / nv Image

{ 3 26 , 2 2 13 , 1 26 } Image

{ 4 29 , 3 29 , 2 29 } Image

nucrossv = ucv / Norm [ ucv ] Image

{ 11 5 30 , 2 15 5 , 5 6 } Image

We can graphically confirm that these three vectors are orthogonal by graphing all three vectors with the graphics primitive Arrow together with Graphics3D. We show the vectors in Fig. 5.2.

Image
Figure 5.2 Orthogonal vectors.

p1 = Graphics3D [ Arrow [ { { { 0 , 0 , 0 } , normu } , { { 0 , 0 , 0 } , normv } , { { 0 , 0 , 0 } , nucrossv } } ] , Image

BoxRatios { 1 , 1 , 1 } , AxesLabel { x , y , z } , Axes True ] Image

In the plot, the vectors may not appear to be orthogonal (perpendicular) as expected because of the aspect ratio and viewing angles of the graphic. □

With the exception of the cross product, the calculations described above can also be performed on vectors in the plane.

Example 5.13

If u and v are nonzero vectors, the projection of u onto v is

proj v u = u v v 2 v .

Find projvuImage if u=<1,4>Image and v=<2,6>Image.

Solution

First, we define u=<1,4>Image and v=<2,6>Image and then compute projvuImage.

u = { 1 , 4 } ; Image

v = { 2 , 6 } ; Image

projvu = u . v v / v . v Image

{ 11 10 , 33 10 } Image

Next, we graph u, v, and projvuImage together using Arrow, Show and GraphicsRow in Fig. 5.3.

Image
Figure 5.3 Projection of a vector.

Image

p1 = Show [ Graphics [ { Arrowheads [ Medium ] , Arrow [ { { 0 , 0 } , u } ] , Arrow [ { { 0 , 0 } , v } ] , Image

Thickness [ . 05 ] , Arrow [ { { 0 , 0 } , projvu } ] } ] , Image

Axes Automatic , AspectRatio Automatic ] ; Image

p2 = Show [ Graphics [ { Arrowheads [ Medium ] , Arrow [ { { 0 , 0 } , u } ] , Image

Arrow [ { { 0 , 0 } , v } ] , Image

Thickness [ . 03 ] , Arrow [ { { 0 , 0 } , projvu } ] , GrayLevel [ . 4 ] , Image

Arrowheads [ Large ] , Arrow [ { projvu , u } ] } ] , Image

Axes Automatic , AspectRatio Automatic ] ; Image

Show [ GraphicsRow [ { p1 , p2 } ] ] Image

In the graph, notice that u=projvu+(uprojvu)Image and the vector uprojvuImage is perpendicular to v.

With the following, we use Manipulate to generalize the example. See Fig. 5.4.

Image
Figure 5.4 Using Manipulate to visualize the projection of one vector onto another.

Clear [ u , v , projvu , p1 , p2 ] ; Image

Manipulate [ Image

projvu = u . v v / v . v ; Image

Show [ Graphics [ { Arrowheads [ Medium ] , Arrow [ { { 0 , 0 } , u } ] , Image

Arrow [ { { 0 , 0 } , v } ] , Image

Thickness [ . 005 ] , Arrow [ { { 0 , 0 } , projvu } ] , GrayLevel [ . 4 ] , Image

Arrowheads [ Large ] , Arrow [ { projvu , u } ] } ] , Image

Axes Automatic , PlotRange { { 3 , 3 } , { 0 , 6 } } , Image

AspectRatio Automatic , Ticks None ] , { { u , { 2 , 3 } } , Locator } , Image

{{v,{2,5}},Locator}]Image □

If you only need to display a two-dimensional array in row-and-column form, it is easier to use Grid rather than Table together with TableForm or MatrixForm.

Image

For a list of all the options associated with Grid, enter Options[Grid].

Image

Thus,

p0 = Grid [ { { a , b , c } , { d , e } , { f } } , Frame All ] Image

creates a basic grid. The first row consists of the entries a, b, and c; the second row d and e; and the third row f. See Fig. 5.5. Note that elements of grids can be any Mathematica object, including other grids.

Image
Figure 5.5 A basic grid.

You can create quite complex arrays with Grid. For example, elements of grids can be any Mathematica object, including grids.

In the following, we use ExampleData to generate several typical Mathematica objects.

StringTake[string,n] returns the first n characters of the string string.

p1=ExampleData[{“AerialImage”,“Earth”}];Image

p2 = StringTake [ ExampleData [ { “Text” , “GettysburgAddress” } ] , 100 ] ; Image

p3 = ExampleData [ { “Geometry3D” , “KleinBottle” } ] ; Image

p4 = ExampleData [ { “Texture” , “Bubbles3” } ] ; Image

Using our first grid, the above, and a few more strings we create a more sophisticated grid in Fig. 5.6.

Image
Figure 5.6 Very basic grids can appear to be quite complicated.

g1=Grid[{{xyx,Grid[{{p1,p2},{p3,p4}}]},{x+yz,p0}},FrameAll]Image

5.2 Linear Systems of Equations

5.2.1 Calculating Solutions of Linear Systems of Equations

To solve the system of linear equations Ax=bImage, where A is the coefficient matrix, b is the known vector and x is the unknown vector, we often proceed as follows: if A1Image exists, then AA1x=A1bImage so x=A1bImage.

Mathematica offers several commands for solving systems of linear equations, however, that do not depend on the computation of the inverse of A. The command

Solve[{eqn1,eqn2,...,eqnm},{var1,var2,...,varn}]

solves an m×nImage system of linear equations (m equations and n unknown variables). Note that both the equations as well as the variables are entered as lists. If one wishes to solve for all variables that appear in a system, the command Solve[{eqn1,eqn2,...eqnn}] attempts to solve eqn1, eqn2, ..., eqnn for all variables that appear in them. (Remember that a double equals sign (==) must be placed between the left and right-hand sides of each equation.)

Example 5.14

Solve the matrix equation (302322233)(xyz)=(314)Image.

Solution

The solution is given by (xyz)=(302322233)1(314)Image. We proceed by defining matrixa and b and then using Inverse to calculate Inverse[matrixa].b naming the resulting output {x,y,z}.

matrixa = { { 3 , 0 , 2 } , { 3 , 2 , 2 } , { 2 , 3 , 3 } } ; Image

b = { 3 , 1 , 4 } ; Image

{ x , y , z } = Inverse [ matrixa ] . b Image

{ 13 23 , 7 23 , 15 23 } Image

We verify that the result is the desired solution by calculating matrixa.{x,y,z}. Because the result of this procedure is (314)Image, we conclude that the solution to the system is (xyz)=(13/237/2315/23)Image.

matrixa . { x , y , z } Image

{ 3 , 1 , 4 } Image

We note that this matrix equation is equivalent to the system of equations

3 x + 2 z = 3 3 x + 2 y + 2 z = 1 2 x 3 y + 3 z = 4 ,

which we are able to solve with Solve. (Note that Thread[{f1,f2,...}={g1,g2,...}] returns the system of equations {f1==g1,f2==g2,...}.)

Clear [ x , y , z ] Image

sys = Thread [ matrixa . { x , y , z } == { 3 , 1 , 4 } ] Image

{ 3 x + 2 z = = 3 , 3 x + 2 y + 2 z = = 1 , 2 x 3 y + 3 z = = 4 } Image

Solve [ sys ] Image

{ { x 13 23 , y 7 23 , z 15 23 } } Image

Shortly, we will discuss using row reduction to solve systems of equations. For now, we remark that given the augmented matrix for a system, (A|b)Image, RowReduce reduces (A|b)Image to reduced row echelon form so that you can see the solution(s) to the linear system, if any.

RowReduce [ { { 3 , 0 , 2 , 3 } , { 3 , 2 , 2 , 1 } , { 2 , 3 , 3 , 4 } } ] Image

{{1,0,0,1323},{0,1,0,723},{0,0,1,1523}}Image □

In addition to using Solve to solve a system of linear equations, the command

LinearSolve[A,b]

calculates the solution vector x of the system Ax=bImage. LinearSolve generally solves a system more quickly than does Solve as we see from the comments in the Documentation Center.

Image

Example 5.15

Solve the system {x2y+z=43x+2yz=8x+3y+5z=0Image for x, y, and z.

Example 5.16

Solve the system {2x4y+z=13x+y2z=35x+y2z=4Image. Verify that the result returned satisfies the system.

Solution

To solve the system using Solve, we define eqs to be the set of three equations to be solved and vars to be the variables x, y, and z and then use Solve to solve the set of equations eqs for the variables in vars. The resulting output is named sols.

eqs = { 2 x 4 y + z == 1 , 3 x + y 2 z == 3 , 5 x + y 2 z == 4 } ; Image

vars = { x , y , z } ; Image

sols = Solve [ eqs , vars ] Image

{ { x 1 8 , y 15 56 , z 51 28 } } Image

To verify that the result given in sols is the desired solution, we replace each occurrence of x, y, and z in eqs by the values found in sols using ReplaceAll (/.). Because the result indicates each of the three equations is satisfied, we conclude that the values given in sols are the components of the desired solution.

eqs /. sols Image

{ { True , True , True } } Image

To solve the system using LinearSolve, we note that the system is equivalent to the matrix equation (241312512)(xyz)=(134)Image, define matrixa and vectorb, and use LinearSolve to solve this matrix equation.

matrixa = { { 2 , 4 , 1 } , { 3 , 1 , 2 } , { 5 , 1 , 2 } } ; Image

vectorb = { 1 , 3 , 4 } ; Image

solvector = LinearSolve [ matrixa , vectorb ] Image

{ 1 8 , 15 56 , 51 28 } Image

To verify that the results are correct, we compute matrixa.solvector. Because the result is (134)Image, we conclude that the solution to the system is (xyz)=(1/815/3651/28)Image.

matrixa . solvector Image

{ 1 , 3 , 4 } Image

The command LinearSolve[A] returns a function that when given a vector b solves the equation Ax=bImage: LinearSolve[A][b] returns x.

LinearSolve [ matrixa ] [ { 1 , 3 , 4 } ] Image

{18,1556,5128}Image □

Enter indexed variables such x1Image, x2Image, …, xnImage as x[1], x[2], …, x[n]. If you need to include the entire list, Table[x[i],{i,1,n}] usually produces the desired result(s).

Example 5.17

Solve the system of equations {4x1+5x25x38x42x5=57x1+2x210x3x46x5=46x1+2x2+10x310x4+7x5=78x1x24x3+3x5=58x17x23x3+10x4+5x5=7Image.

Solution

We solve the system in two ways. First, we use Solve to solve the system. Note that in this case, we enter the equations in the form

set of left-hand sides==set of right-hand sides.

Solve [ { 4 x [ 1 ] + 5 x [ 2 ] 5 x [ 3 ] 8 x [ 4 ] 2 x [ 5 ] , Image

7 x [ 1 ] + 2 x [ 2 ] 10 x [ 3 ] x [ 4 ] 6 x [ 5 ] , Image

6 x [ 1 ] + 2 x [ 2 ] + 10 x [ 3 ] 10 x [ 4 ] + 7 x [ 5 ] , Image

8 x [ 1 ] x [ 2 ] 4 x [ 3 ] + 3 x [ 5 ] , Image

8 x [ 1 ] 7 x [ 2 ] 3 x [ 3 ] + 10 x [ 4 ] + 5 x [ 5 ] } == { 5 , 4 , 7 , 5 , 7 } ] Image

{ { x [ 1 ] 1245 6626 , x [ 2 ] 113174 9939 , x [ 3 ] 7457 9939 , x [ 4 ] 38523 6626 , x [ 5 ] 49327 9939 } } Image

We also use LinearSolve after defining matrixa and t2. As expected, in each case, the results are the same.

Clear [ matrixa ] Image

matrixa = { { 4 , 5 , 5 , 8 , 2 } , { 7 , 2 , 10 , 1 , 6 } , Image

{ 6 , 2 , 10 , 10 , 7 } , Image

{ 8 , 1 , 4 , 0 , 3 } , { 8 , 7 , 3 , 10 , 5 } } ; Image

t2 = { 5 , 4 , 7 , 5 , 7 } ; Image

LinearSolve [ matrixa , t2 ] Image

{12456626,1131749939,74579939,385236626,493279939}Image □

5.2.2 Gauss–Jordan Elimination

Given the matrix equation Ax=bImage, where

A = ( a 11 a 12 a 1 n a 21 a 22 a 2 n a m 1 a m 2 a m n ) , x = ( x 1 x 2 x n ) , and b = ( b 1 b 2 b m ) ,

the m×nImage matrix A is called the coefficient matrix for the matrix equation Ax=bImage and the m×(n+1)Image matrix

( a 11 a 12 a 1 n b 1 a 21 a 22 a 2 n b 2 a m 1 a m 2 a m n b m )

is called the augmented (or associated) matrix for the matrix equation. We may enter the augmented matrix associated with a linear system of equations directly or we can use commands like Join to help us construct the augmented matrix. For example, if A and B are rectangular matrices that have the same number of columns, Join[A,B] returns (AB)Image. On the other hand, if A and B are rectangular matrices that have the same number of rows, Join[A,B,2] returns the concatenated matrix (AB)Image.

Example 5.18

Solve the system {2x+y2x=42x4y2z=4x4y2z=3Image using Gauss–Jordan elimination.

In the following example, we carry out the steps of the row reduction process.

Solution

The augmented matrix is A=(3221031272116)Image, defined in capa, and then displayed in traditional row-and-column form with MatrixForm. Given the matrix A, the ith part of A corresponds to the ith row of A. Therefore, A[[i]] returns the ith row of A.

Clear [ capa ] Image

capa = { { 3 , 2 , 2 , 10 } , { 3 , 1 , 2 , 7 } , { 2 , 1 , 1 , 6 } } ; Image

MatrixForm [ capa ] Image

( 3 2 2 10 3 1 2 7 2 1 1 6 ) Image

We eliminate methodically. First, we multiply row 1 by 1/3Image so that the first entry in the first column is 1.

capa={1/3capa[[1]],capa[[2]],capa[[3]]}Image

{ { 1 , 2 3 , 2 3 , 10 3 } , { 3 , 1 , 2 , 7 } , { 2 , 1 , 1 , 6 } } Image

We now eliminate below. First, we multiply row 1 by −3 and add it to row 2 and then we multiply row 1 by −2 and add it to row 3.

capa = { capa [ [ 1 ] ] , 3 capa [ [ 1 ] ] + capa [ [ 2 ] ] , Image

2 capa [ [ 1 ] ] + capa [ [ 3 ] ] } Image

{ { 1 , 2 3 , 2 3 , 10 3 } , { 0 , 1 , 0 , 3 } , { 0 , 1 3 , 1 3 , 2 3 } } Image

Observe that the first nonzero entry in the second row is 1. We eliminate below this entry by adding 1/3Image times row 2 to row 3.

capa = { capa [ [ 1 ] ] , capa [ [ 2 ] ] , 1 / 3 capa [ [ 2 ] ] + capa [ [ 3 ] ] } Image

{ { 1 , 2 3 , 2 3 , 10 3 } , { 0 , 1 , 0 , 3 } , { 0 , 0 , 1 3 , 1 3 } } Image

We multiply the third row by −3 so that the first nonzero entry is 1.

capa = { capa [ [ 1 ] ] , capa [ [ 2 ] ] , 3 capa [ [ 3 ] ] } Image

{ { 1 , 2 3 , 2 3 , 10 3 } , { 0 , 1 , 0 , 3 } , { 0 , 0 , 1 , 1 } } Image

This matrix is equivalent to the system

x 2 3 y + 2 3 z = 10 3 y = 3 z = 1 ,

which shows us that the solution is x=2Image, y=3Image, z=1Image.

Working backwards confirms this. Multiplying row 2 by 2/3 and adding to row 1 and then multiplying row 3 by 2/3Image and adding to row 1 results in

capa = { 2 / 3 capa [ [ 2 ] ] + capa [ [ 1 ] ] , capa [ [ 2 ] ] , capa [ [ 3 ] ] } Image

{ { 1 , 0 , 2 3 , 4 3 } , { 0 , 1 , 0 , 3 } , { 0 , 0 , 1 , 1 } } Image

capa = { 2 / 3 capa [ [ 3 ] ] + capa [ [ 1 ] ] , capa [ [ 2 ] ] , capa [ [ 3 ] ] } Image

{ { 1 , 0 , 0 , 2 } , { 0 , 1 , 0 , 3 } , { 0 , 0 , 1 , 1 } } Image

which is equivalent to the system x=2Image, y=3Image, z=1Image.

Equivalent results are obtained with RowReduce.

Clear [ capa ] Image

capa = { { 3 , 2 , 2 , 10 } , { 3 , 1 , 2 , 7 } , { 2 , 1 , 1 , 6 } } ; Image

capa = RowReduce [ capa ] ; Image

MatrixForm [ capa ] Image

( 1 0 0 2 0 1 0 3 0 0 1 1 ) Image

Finally, we confirm the result directly with Solve.

Solve [ { 3 x + 2 y 2 z = = 10 , Image

3 x y + 2 z = = 7 , 2 x y + z = = 6 } ] Image

{{x2,y3,z1}}Image □

It is important to remember that if you reduce the augmented matrix to reduced-row-echelon form, the results show you the solution to the problem. RowReduce[A] row reduces A to reduced-row-echelon form.

Example 5.22

The nullspace of A is the set of solutions to the system of equations Ax=0Image. Find the nullspace of A=3pt(3211233121221111101054223)Image.

5.3 Selected Topics from Linear Algebra

5.3.1 Fundamental Subspaces Associated with Matrices

Let A=(aij)Image be an n×mImage matrix with entry aijImage in the ith row and jth column. The row space of A, row(A)Image, is the spanning set of the rows of A; the column space of A, col(A)Image, is the spanning set of the columns of A. If A is any matrix, then the dimension of the column space of A is equal to the dimension of the row space of A. The dimension of the row space (column space) of a matrix A is called the rank of A. The nullspace of A is the set of solutions to the system of equations Ax=0Image. The nullspace of A is a subspace and its dimension is called the nullity of A. The rank of A is equal to the number of nonzero rows in the row echelon form of A, the nullity of A is equal to the number of zero rows in the row echelon form of A. Thus, if A is a square matrix, the sum of the rank of A and the nullity of A is equal to the number of rows (columns) of A.

1.  NullSpace[A] returns a list of vectors which form a basis for the nullspace (or kernel) of the matrix A.

2.  RowReduce[A] yields the reduced row echelon form of the matrix A.

Solution

We begin by defining the matrix matrixa. Then, RowReduce is used to place matrixa in reduced row echelon form.

capa = { { 1 , 1 , 2 , 0 , 1 } , { 2 , 2 , 0 , 0 , 2 } , Image

{ 2 , 1 , 1 , 0 , 1 } , { 1 , 1 , 1 , 2 , 2 } , Image

{ 1 , 2 , 2 , 2 , 0 } } ; Image

RowReduce [ capa ] // MatrixForm Image

( 1 0 0 2 0 0 1 0 2 0 0 0 1 2 0 0 0 0 0 1 0 0 0 0 0 ) Image

Because the row-reduced form of matrixa contains four nonzero rows, the rank of A is 4 and thus the nullity is 1. We obtain a basis for the nullspace with NullSpace.

NullSpace [ capa ] Image

{ { 2 , 2 , 2 , 1 , 0 } } Image

As expected, because the nullity is 1, a basis for the nullspace contains one vector. □

Solution

A basis for the column space of B is the same as a basis for the row space of the transpose of B. We begin by defining matrixb and then using Transpose to compute the transpose of matrixb, naming the resulting output tb.

matrixb = { { 1 , 2 , 2 , 1 , 2 } , { 1 , 1 , 2 , 2 , 2 } , Image

{ 1 , 0 , 0 , 2 , 1 } , { 0 , 0 , 0 , 2 , 0 } , Image

{ 2 , 1 , 0 , 1 , 2 } } ; Image

tb = Transpose [ matrixb ] Image

{{1,1,1,0,2},{2,1,0,0,1},{2,2,0,0,0},{1,2,2,2,1},{2,2,1,0,2}}Image

Next, we use RowReduce to row reduce tb and name the result rrtb. A basis for the column space consists of the first four elements of rrtb. We also use Transpose to show that the first four elements of rrtb are the same as the first four columns of the transpose of rrtb. Thus, the jth column of a matrix A can be extracted from A with Transpose [A][[j]].

rrtb = RowReduce [ tb ] ; Image

Transpose [ rrtb ] // MatrixForm Image

( 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 3 1 3 2 3 0 ) Image

We extract the first four elements of rrtb with Take. The results correspond to a basis for the column space of B.

Take [ rrtb , 4 ] Image

{{1,0,0,0,13},{0,1,0,0,13},{0,0,1,0,2},{0,0,0,1,3}}Image □

5.3.2 The Gram–Schmidt Process

A set of vectors {v1,v2,,vn}Image is orthonormal means that vi=1Image for all values of i and vivj=0Image for ijImage. Given a set of linearly independent vectors S={v1,v2,,vn}Image, the set of all linear combinations of the elements of S, V=spanSImage, is a vector space. Note that if S is an orthonormal set and uspanSImage, then u=(uv1)v1+(uv2)v2++(uvn)vnImage. Thus, we may easily express u as a linear combination of the vectors in S. Consequently, if we are given any vector space, V, it is frequently convenient to be able to find an orthonormal basis of V. We may use the Gram–Schmidt process to find an orthonormal basis of the vector space V=span{v1,v2,,vn}Image.

We summarize the algorithm of the Gram–Schmidt process so that given a set of n linearly independent vectors S={v1,v2,,vn}Image, where V=span{v1,v2,,vn}Image, we can construct a set of orthonormal vectors {u1,u2,,un}Image so that V=span{u1,u2,,un}Image.

1.  Let u1=1vvImage;

2.  Compute proj{u1}v2=(u1v2)u1Image, v2proj{u1}v2Image, and let

u 2 = 1 v 2 proj { u 1 } v 2 ( v 2 proj { u 1 } v 2 ) .

Then, span{u1,u2}=span{v1,v2}Image and span{u1,u2,v3,,vn}=span{v1,v1,,vn}Image;

3.  Generally, for 3inImage, compute

proj { u 1 , u 2 , , u n } v i = ( u 1 v i ) u 1 + ( u 2 v i ) u 2 + + ( u i 1 v i ) u i 1 ,

viproj{u1,u2,,un}viImage, and let

u 1 = 1 proj { u 1 , u 2 , , u n } v i | ( proj { u 1 , u 2 , , u n } v i ) .

Then, span{u1,u2,,ui}=span{v1,v2,,vi}Image and

span { u 1 , u 2 , , u i , v i + 1 , , v n } = span { v 1 , v 2 , v 3 , , v n } ;

and

4.  Because span{u1,u2,,un}=span{v1,v2,,vn}Image and {u1,u2,,un}Image is an orthonormal set, {u1,u2,,un}Image is an orthonormal basis of V.

The Gram–Schmidt procedure is well-suited to computer arithmetic. The following code performs each step of the Gram–Schmidt process on a set of n linearly independent vectors {v1,v1,,vn}Image. At the completion of each step of the procedure, gramschmidt[vecs] prints the list of vectors corresponding to {u1,u2,,ui,vi+1,,vn}Image and returns the list of vectors {u1,u2,,un}Image. Note how comments are inserted into the code using (*...*).

gramschmidt [ vecs _ ] := Module [ { n , proj , u , capw } , Image

(*n represents the number of vectors in the list vecs*) Image

n = Length [ vecs ] ; Image

(* proj [ v , capw ] computes the projection of v onto capw *) Image

proj [ v_ , capw_ ] := Image

i = 1 Length [ capw ] capw [ [ i ] ] . v capw [ [ i ] ] ; Image

u [ 1 ] = vecs [ [ 1 ] ] vecs [ [ 1 ] ] . vecs [ [ 1 ] ] ; Image

capw = { } ; Image

u [ i_ ] := u [ i ] = Module [ { stepone } , Image

stepone = vecs [ [ i ] ] proj [ vecs [ [ i ] ] , capw ] ; Image

Together [ stepone stepone . stepone ] ] ; Image

Do [ Image

u [ i ] ; Image

AppendTo [ capw , u [ i ] ] ; Image

Print [ Join [ capw , Drop [ vecs , i ] ] ] , { i , 1 , n 1 } ] ; Image

u [ n ] ; Image

AppendTo [ capw , u [ n ] ] ] Image

Example 5.25

Use the Gram–Schmidt process to transform the basis S={(212),(012),(132)}Image of R3Image into an orthonormal basis.

Solution

We proceed by defining v1, v2, and v3 to be the vectors in the basis S and using gramschmidt[{v1,v2,v3}] to find an orthonormal basis.

v1 = { 2 , 1 , 2 } ; Image

v2 = { 0 , 1 , 2 } ; Image

v3 = { 1 , 3 , 2 } ; Image

gramschmidt [ { v1 , v2 , v3 } ] Image

{ { 2 3 , 1 3 , 2 3 } , { 0 , 1 , 2 } , { 1 , 3 , 2 } } Image

{ { 2 3 , 1 3 , 2 3 } , { 1 3 , 2 3 , 2 3 } , { 1 , 3 , 2 } } Image

{ { 2 3 , 1 3 , 2 3 } , { 1 3 , 2 3 , 2 3 } , { 2 3 , 2 3 , 1 3 } } Image

On the first line of output, the result {u1,v2,v3}Image is given; {u1,u2,v3}Image appears on the second line; {u1,u2,u3}Image follows on the third. □

Example 5.26

Compute an orthonormal basis for the subspace of R4Image spanned by the vectors (2441)Image, (4132)Image, and (1441)Image. Also, verify that the basis vectors are orthogonal and have norm 1.

Solution

With gramschmidt, we compute the orthonormal basis vectors. Note that Mathematica names oset the last result returned by gramschmidt. The orthogonality of these vectors is then verified. Notice that Together is used to simplify the result in the case of oset[[2]].oset[[3]]. The norm of each vector is then found to be 1.

oset = gramschmidt [ { { 2 , 4 , 4 , 1 } , { 4 , 1 , 3 , 2 } , { 1 , 4 , 4 , 1 } } ] Image

{ { 2 37 , 4 37 , 4 37 , 1 37 } , { 4 , 1 , 3 , 2 } , { 1 , 4 , 4 , 1 } } Image

{ { 2 37 , 4 37 , 4 37 , 1 37 } , { 60 2 16909 , 93 33818 , 55 33818 , 44 2 16909 } , { 1 , 4 , 4 , 1 } } Image

{ { 2 37 , 4 37 , 4 37 , 1 37 } , { 60 2 16909 , 93 33818 , 55 33818 , 44 2 16909 } , { 449 934565 , 268 934565 , 156 934565 , 798 934565 } } Image

The three vectors are extracted with oset using oset[[1]], oset[[2]], and oset[[3]].

oset [ [ 1 ] ] . oset [ [ 2 ] ] Image

oset [ [ 1 ] ] . oset [ [ 3 ] ] Image

oset [ [ 2 ] ] . oset [ [ 3 ] ] Image

0

0

0

Sqrt [ oset [ [ 1 ] ] . oset [ [ 1 ] ] ] Image

Sqrt [ oset [ [ 2 ] ] . oset [ [ 2 ] ] ] Image

Sqrt [ oset [ [ 3 ] ] . oset [ [ 3 ] ] ] Image

1

1

1 □

Mathematica contains functions that perform most of the operations discussed here.

1.  Orthogonalize[{v1,v2,...},Method->GramSchmidt] returns an orthonormal set of vectors given the set of vectors {v1,v2,,vn}Image. Note that this command does not illustrate each step of the Gram–Schmidt procedure as the gramschmidt function defined above.

2.  Normalize[v] returns 1vvImage given the nonzero vector v.

3.  Projection[v1,v2] returns the projection of v1Image onto v2Image: projv2v1=v1v2v22v2Image.

Thus,

Orthogonalize [ { { 2 , 4 , 4 , 1 } , { 4 , 1 , 3 , 2 } , { 1 , 4 , 4 , 1 } } , Method “GramSchmidt” ] Image

{ { 2 37 , 4 37 , 4 37 , 1 37 } , { 60 2 16909 , 93 33818 , 55 33818 , 44 2 16909 } , { 449 934565 , 268 934565 , 156 934565 , 798 934565 } } Image

returns an orthonormal basis for the subspace of R4Image spanned by the vectors (2441)Image, (4132)Image, and (1441)Image. The command

Normalize [ { 2 , 4 , 4 , 1 } ] Image

{ 2 37 , 4 37 , 4 37 , 1 37 } Image

finds a unit vector with the same direction as the vector v=(2441)Image. Entering

Projection [ { 2 , 4 , 4 , 1 } , { 4 , 1 , 3 , 2 } ] Image

{2815,715,75,1415}Image

finds the projection of v=(2441)Image onto w=(4132)Image.

5.3.3 Linear Transformations

A function T:RnRmImage is a linear transformation means that T satisfies the properties T(u+v)=T(u)+T(v)Image and T(cu)=cT(u)Image for all vectors u and v in RnImage and all real numbers c. Let T:RnRmImage be a linear transformation and suppose T(e1)=v1Image, T(e2)=v2Image, …, T(en)=vnImage where {e1,e2,,en}Image represents the standard basis of RnImage and v1Image, v2Image, …, vnImage are (column) vectors in RmImage. The associated matrix of T is the m×nImage matrix A=(v1v2vn)Image:

if  x = ( x 1 x 2 x n ) , T ( x ) = T ( ( x 1 x 2 x n ) ) = Ax = ( v 1 v 2 v n ) ( x 1 x 2 x n )

Moreover, if A is any m×nImage matrix, then A is the associated matrix of the linear transformation defined by T(x)=AxImage. In fact, a linear transformation T is completely determined by its action on any basis.

The kernel of the linear transformation T, ker(T)Image, is the set of all vectors x in RnImage such that T(x)=0Image: ker(T)={xRn|T(x)=0}Image. The kernel of T is a subspace of RnImage. Because T(x)=AxImage for all x in RnImage, ker(T)={xRn|T(x)=0}={xRn|Ax=0}Image so the kernel of T is the same as the nullspace of A.

Example 5.27

Let T:R5R3Image be the linear transformation defined by T(x)=(031313333122112)xImage. (a) Calculate a basis for the kernel of the linear transformation. (b) Determine which of the vectors (42006)Image and (12123)Image is in the kernel of T.

Solution

We begin by defining matrixa to be the matrix A=(031313333122112)Image and then defining t. A basis for the kernel of T is the same as a basis for the nullspace of A found with NullSpace.

Clear [ t , x , matrixa ] Image

matrixa = { { 0 , 3 , 1 , 3 , 1 } , { 3 , 3 , 3 , 3 , 1 } , Image

{ 2 , 2 , 1 , 1 , 2 } } ; Image

t [ x_ ] = matrixa . x ; Image

NullSpace [ matrixa ] Image

{{2,1,0,0,3},{6,8,15,13,0}}Image

Because (42006)Image is a linear combination of the vectors that form a basis for the kernel, (42006)Image is in the kernel while (12123)Image is not. These results are verified by evaluating t for each vector.

t [ { 4 , 2 , 0 , 0 , 6 } ] Image

{ 0 , 0 , 0 } Image

t [ { 1 , 2 , 1 , 2 , 3 } ] Image

{2,9,11}Image □

Application: Rotations

Let x=(x1x2)Image be a vector in R2Image and θ an angle. Then, there are numbers r and ϕ given by r=x12+x22Image and ϕ=tan1(x2/x1)Image so that x1=rcosϕImage and x2=rsinϕImage. When we rotate x=(x1x2)=(rcosϕrsinϕ)Image through the angle θ, we obtain the vector x=(rcos(θ+ϕ)rsin(θ+ϕ))Image. Using the trigonometric identities sin(θ±ϕ)=sinθcosϕ±sinϕcosθImage and cos(θ±ϕ)=cosθcosϕsinθsinϕImage we rewrite

x = ( r cos ( θ + ϕ ) r sin ( θ + ϕ ) ) = ( r cos θ cos ϕ r sin θ sin ϕ r sin θ cos ϕ + r sin ϕ cos θ ) = ( cos θ sin θ sin θ cos θ ) ( r cos ϕ r sin ϕ ) = ( cos θ sin θ sin θ cos θ ) ( x 1 x 2 ) .

Thus, the vector xImage is obtained from x by computing (cosθsinθsinθcosθ)xImage. Generally, if θ represents an angle, the linear transformation T:R2R2Image defined by T(x)=(cosθsinθsinθcosθ)xImage is called the rotation of R2Image through the angle θ. We write code to rotate a polygon through an angle θ. The procedure rotate uses a list of n points and the rotation matrix defined in r to produce a new list of points that are joined using the Line graphics directive. Entering

Line[{{x1,y1},{x2,y2},...,{xn,yn}}]

represents the graphics primitive for a line in two dimensions that connects the points listed in {{x1,y1},{x2,y2},...,{xn,yn}}. Entering

Show[Graphics[Line[{{x1,y1},{x2,y2},...,{xn,yn}}]]]

displays the line. This rotation can be determined for one value of θ. However, a more interesting result is obtained by creating a list of rotations for a sequence of angles and then displaying the graphics objects. This is done for θ=0Image to θ=π/2Image using increments of π/16Image. Hence, a list of nine graphs is given for the square with vertices (1,1)Image, (1,1)Image, (1,1)Image, and (1,1)Image and displayed in Fig. 5.7.

Image
Figure 5.7 A rotated square.

r [ θ _ ] = ( Cos [ θ ] Sin [ θ ] Sin [ θ ] Cos [ θ ] ) ; Image

r [ θ _ ] = ( Cos [ θ ] Sin [ θ ] Sin [ θ ] Cos [ θ ] ) ; Image

rotate [ pts _ , angle _ ] := Module [ { newpts } , Image

newpts = Table [ r [ angle ] . pts [ [ i ] ] , { i , 1 , Length [ pts ] } ] ; Image

newpts = AppendTo [ newpts , newpts [ [ 1 ] ] ] ; Image

figure = Line [ newpts ] ; Image

Show [ Graphics [ figure ] , AspectRatio 1 , Image

PlotRange { { 1.5 , 1.5 } , { 1.5 , 1.5 } } , Image

] ] Image

graphs = Table [ rotate [ { { 1 , 1 } , { 1 , 1 } , { 1 , 1 } , { 1 , 1 } } , t ] , { t , 0 , π 2 , π 16 } ] ; Image

array = Partition [ graphs , 3 ] ; Image

Show [ GraphicsGrid [ array ] ] Image

5.3.4 Eigenvalues and Eigenvectors

Let A be an n×nImage matrix. λ is an eigenvalue of A if there is a nonzero vector, v, called an eigenvector, satisfying Av=λvImage. Because (AλI)v=0Image has a unique solution of v=0Image if |AλI|0Image, to find non-zero solutions, v, of (AλI)v=0Image, we begin by solving |AλI|=0Image. That is, we find the eigenvalues of A by solving the characteristic polynomial |AλI|=0Image for λ. Once we find the eigenvalues, the corresponding eigenvectors are found by solving (AλI)v=0Image for v.

If A is n×nImage, Eigenvalues[A] finds the eigenvalues of A, Eigenvectors[A] finds the eigenvectors, and Eigensystem[A] finds the eigenvalues and corresponding eigenvectors. CharacteristicPolynomial[A,lambda] finds the characteristic polynomial of A as a function of λ.

Example 5.28

Find the eigenvalues and corresponding eigenvectors for each of the following matrices. (a) A=(3223)Image, (b) A=(1113)Image, (c) A=(011101110)Image, and (d) A=(1/4281/4)Image.

Solution

(a) We begin by finding the eigenvalues. Solving

| A λ I | = | 3 λ 2 2 3 λ | = λ 2 + 6 λ + 5 = 0

gives us λ1=5Image and λ2=1Image.

Observe that the same results are obtained using CharacteristicPolynomial and Eigenvalues.

capa = { { 3 , 2 } , { 2 , 3 } } ; Image

cp1 = CharacteristicPolynomial [ capa , λ ] Image

5 + 6 λ + λ 2 Image

Solve [ cp1 = = 0 ] Image

{ { λ 5 } , { λ 1 } } Image

e1 = Eigenvalues [ capa ] Image

{ 5 , 1 } Image

We now find the corresponding eigenvectors. Let v1=(x1y1)Image be an eigenvector corresponding to λ1Image, then

( A λ 1 I ) v 1 = 0 [ ( 3 2 2 3 ) ( 5 ) ( 1 0 0 1 ) ] ( x 1 y 1 ) = ( 0 0 ) ( 2 2 2 2 ) ( x 1 y 1 ) = ( 0 0 ) ,

which row reduces to

( 1 1 0 0 ) ( x 1 y 1 ) = ( 0 0 ) .

That is, x1+y1=0Image or x1=y1Image. Hence, for any value of y10Image,

v 1 = ( x 1 y 1 ) = ( y 1 y 1 ) = y 1 ( 1 1 )

is an eigenvector corresponding to λ1Image. Of course, this represents infinitely many vectors. But, they are all linearly dependent. Choosing y1=1Image yields v1=(11)Image. Note that you might have chosen y1=1Image and obtained v1=(11)Image. However, both of our results are “correct” because these vectors are linearly dependent.

Similarly, letting v2=(x2y2)Image be an eigenvector corresponding to λ2Image we solve (Aλ2I)v1=0Image:

( 2 2 2 2 ) ( x 2 y 2 ) = ( 0 0 ) or ( 1 1 0 0 ) ( x 2 y 2 ) = ( 0 0 ) .

Thus, x2y2=0Image or x2=y2Image. Hence, for any value of y20Image,

v 2 = ( x 2 y 2 ) = ( y 2 y 2 ) = y 2 ( 1 1 )

is an eigenvector corresponding to λ2Image. Choosing y2=1Image yields v2=(11)Image. We confirm these results using RowReduce.

i2 = IdentityMatrix [ 2 ] ; Image

ev1 = capa e1 [ [ 1 ] ] i2 Image

{ { 2 , 2 } , { 2 , 2 } } Image

RowReduce [ ev1 ] Image

{ { 1 , 1 } , { 0 , 0 } } Image

We obtain the same results using Eigenvectors and Eigensystem.

Eigenvectors [ capa ] Image

Eigensystem [ capa ] Image

{ { 1 , 1 } , { 1 , 1 } } Image

{ { 5 , 1 } , { { 1 , 1 } , { 1 , 1 } } } Image

(b) In this case, we see that λ=2Image has multiplicity 2. There is only one linearly independent eigenvector, v=(11)Image, corresponding to λ.

capa = { { 1 , 1 } , { 1 , 3 } } ; Image

Factor [ CharacteristicPolynomial [ capa , λ ] ] Image

( 2 + λ ) 2 Image

Eigenvectors [ capa ] Image

{{1,1},{0,0}}Image

Eigensystem [ capa ] Image

{ { 2 , 2 } , { { 1 , 1 } , { 0 , 0 } } } Image

(c) The eigenvalue λ1=2Image has corresponding eigenvector v1=(111)Image. The eigenvalue λ2,3=1Image has multiplicity 2. In this case, there are two linearly independent eigenvectors corresponding to this eigenvalue: v2=(101)Image and v3=(110)Image.

capa = { { 0 , 1 , 1 } , { 1 , 0 , 1 } , { 1 , 1 , 0 } } ; Image

Factor [ CharacteristicPolynomial [ capa , λ ] ] Image

( 2 + λ ) ( 1 + λ ) 2 Image

Eigenvectors [ capa ] Image

{ { 1 , 1 , 1 } , { 1 , 0 , 1 } , { 1 , 1 , 0 } } Image

Eigensystem [ capa ] Image

{ { 2 , 1 , 1 } , { { 1 , 1 , 1 } , { 1 , 0 , 1 } , { 1 , 1 , 0 } } } Image

(d) In this case, the eigenvalues λ1,2=14±4iImage are complex conjugates. We see that the eigenvectors v1,2=(02)±(10)iImage are complex conjugates as well.

capa = { { 1 / 4 , 2 } , { 8 , 1 / 4 } } ; Image

Factor [ CharacteristicPolynomial [ capa , λ ] , Image

GaussianIntegers True ] Image

1 16 ( ( 1 16 i ) + 4 λ ) ( ( 1 + 16 i ) + 4 λ ) Image

Eigenvalues [ capa ] Image

{ 1 4 + 4 i , 1 4 4 i } Image

Eigenvectors [ capa ] Image

{ { i , 2 } , { i , 2 } } Image

Eigensystem [ capa ] Image

{{14+4i,144i},{{i,2},{i,2}}}Image □

5.3.5 Jordan Canonical Form

Let Nk=(nij)={1,j=i+10,otherwiseImage represent a k×kImage matrix with the indicated elements. The k×kImage Jordan block matrix is given by B(λ)=λI+NkImage where λ is a constant:

N k = ( 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) and B ( λ ) = λ I + N k = ( λ 1 0 0 0 λ 1 0 0 0 0 1 0 0 0 λ ) .

Hence, B(λ)Image can be defined as B(λ)=(bij)={λ,i=j1,j=i+10,otherwiseImage. A Jordan matrix has the form

J = ( B 1 ( λ ) 0 0 0 B 2 ( λ ) 0 0 0 B n ( λ ) )

where the entries Bj(λ)Image, j=1Image, 2, …, n represent Jordan block matrices.

Suppose that A is an n×nImage matrix. Then there is an invertible n×nImage matrix C such that C1AC=JImage where J is a Jordan matrix with the eigenvalues of A as diagonal elements. The matrix J is called the Jordan canonical form of A. The command

JordanDecomposition[m]

yields a list of matrices {s,j} such that m=s.j.Inverse[s] and j is the Jordan canonical form of the matrix m.

For a given matrix A, the unique monic polynomial q of least degree satisfying q(A)=0Image is called the minimal polynomial of A. Let p denote the characteristic polynomial of A. Because p(A)=0Image, it follows that q divides p. We can use the Jordan canonical form of a matrix to determine its minimal polynomial.

Example 5.29

Find the Jordan canonical form, JAImage, of A=(299086097)Image.

Solution

After defining matrixa, we use JordanDecomposition to find the Jordan canonical form of a and name the resulting output ja.

matrixa = { { 2 , 9 , 9 } , { 0 , 8 , 6 } , { 0 , 9 , 7 } } ; Image

ja = JordanDecomposition [ matrixa ] Image

{ { { 3 , 0 , 1 } , { 2 , 1 , 0 } , { 3 , 1 , 0 } } , { { 1 , 0 , 0 } , { 0 , 2 , 0 } , { 0 , 0 , 2 } } } Image

The Jordan matrix corresponds to the second element of ja extracted with ja[[2]] and displayed in MatrixForm.

ja [ [ 2 ] ] // MatrixForm Image

( 1 0 0 0 2 0 0 0 2 ) Image

We also verify that the matrices ja[[1]] and ja[[2]] satisfy

matrixa=ja[[1]].ja[[2]].Inverse[ja[[1]]].

ja [ [ 1 ] ] . ja [ [ 2 ] ] . Inverse [ ja [ [ 1 ] ] ] Image

{ { 2 , 9 , 9 } , { 0 , 8 , 6 } , { 0 , 9 , 7 } } Image

Next, we use CharacteristicPolynomial to find the characteristic polynomial of matrixa and then verify that matrixa satisfies its characteristic polynomial.

p = CharacteristicPolynomial [ matrixa , x ] Image

4 + 3 x 2 x 3 Image

4 IdentityMatrix [ 3 ] + 3 MatrixPower [ matrixa , 2 ] MatrixPower [ matrixa , 3 ] Image

{ { 0 , 0 , 0 } , { 0 , 0 , 0 } , { 0 , 0 , 0 } } Image

From the Jordan form, we see that the minimal polynomial of A is (x+1)(x2)Image. We define the minimal polynomial to be q and then verify that matrixa satisfies its minimal polynomial.

q = Expand [ ( x + 1 ) ( x 2 ) ] Image

2 x + x 2 Image

2 IdentityMatrix [ 3 ] matrixa + MatrixPower [ matrixa , 2 ] Image

{ { 0 , 0 , 0 } , { 0 , 0 , 0 } , { 0 , 0 , 0 } } Image

As expected, q divides p.

Cancel [ p / q ] Image

2xImage □

Example 5.30

If A=(3861320333134862)Image, find the characteristic and minimal polynomials of A.

Solution

As in the previous example, we first define matrixa and then use JordanDecomposition to find the Jordan canonical form of A.

matrixa = { { 3 , 8 , 6 , 1 } , { 3 , 2 , 0 , 3 } , { 3 , 3 , 1 , 3 } , Image

{ 4 , 8 , 6 , 2 } } ; Image

ja = JordanDecomposition [ matrixa ] Image

{ { { 3 , 1 , 1 , 0 } , { 1 , 1 , 0 , 1 2 } , { 0 , 2 , 0 , 1 2 } , { 4 , 0 , 1 , 0 } } , { { 1 , 0 , 0 , 0 } , { 0 , 1 , 0 , 0 } , { 0 , 0 , 2 , 1 } , { 0 , 0 , 0 , 2 } } } Image

The Jordan canonical form of A is the second element of ja, extracted with ja[[2]] and displayed in MatrixForm.

ja [ [ 2 ] ] // MatrixForm Image

( 1 0 0 0 0 1 0 0 0 0 2 1 0 0 0 2 ) Image

From this result, we see that the minimal polynomial of A is (x+1)(x2)2Image. We define q to be the minimal polynomial of A and then verify that matrixa satisfies q.

q = Expand [ ( x 2 ) 2 ( x + 1 ) ] Image

4 3 x 2 + x 3 Image

4 IdentityMatrix [ 4 ] 3 MatrixPower [ matrixa , 2 ] + MatrixPower [ matrixa , 3 ] Image

{ { 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 } } Image

The characteristic polynomial is obtained next and named p. As expected, q divides p, verified with Cancel.

p = CharacteristicPolynomial [ matrixa , x ] Image

4 + 4 x 3 x 2 2 x 3 + x 4 Image

Cancel [ p / q ] Image

1+xImage □

5.3.6 The QR Method

The conjugate transpose (or Hermitian adjoint matrix) of the m×nImage complex matrix A which is denoted by AImage is the transpose of the complex conjugate of A. Symbolically, we have A=(A¯)tImage. A complex matrix A is unitary if A=A1Image. Given a matrix A, there is a unitary matrix Q and an upper triangular matrix R such that A=QRImage. The product matrix QR is called the QR factorization of A. The command

QRDecomposition[N[m]]

determines the QR decomposition of the matrix m by returning the list {q,r}, where q is an orthogonal matrix, r is an upper triangular matrix and m=Transpose[q].r.

Example 5.31

Find the QR factorization of the matrix A=3pt(411141114)Image.

Solution

We define matrixa and then use QRDecomposition to find the QR decomposition of matrixa, naming the resulting output qrm.

matrixa = { { 4 , 1 , 1 } , { 1 , 4 , 1 } , { 1 , 1 , 4 } } ; Image

qrm = QRDecomposition [ N [ matrixa ] ] Image

{ { { 0.942809 , 0.235702 , 0.235702 } , { 0.142134 , 0.92387 , 0.355335 } , { 0.301511 , 0.301511 , 0.904534 } } , { { 4.24264 , 1.64992 , 1.64992 } , { 0 . , 3.90868 , 2.48734 } , { 0 . , 0 . , 3.01511 } } } Image

The first matrix in qrm is extracted with qrm[[1]] and the second with qrm[[2]].

qrm [ [ 1 ] ] // MatrixForm Image

( 0.942809 0.235702 0.235702 0.142134 0.92387 0.355335 0.301511 0.301511 0.904534 ) Image

qrm [ [ 2 ] ] // MatrixForm Image

(4.242641.649921.649920.3.908682.487340.0.3.01511)Image

We verify that the results returned are the QR decomposition of A.

Transpose [ qrm [ [ 1 ] ] ] . qrm [ [ 2 ] ] // MatrixForm Image

(4.1.1.1.4.1.1.1.4.)Image □

One of the most efficient and most widely used methods for numerically calculating the eigenvalues of a matrix is the QR Method. Given a matrix A, then there is a Hermitian matrix Q and an upper triangular matrix R such that A=QRImage. If we define a sequence of matrices A1=AImage, factored as A1=Q1R1Image; A2=R1Q1Image, factored as A2=R2Q2Image; A3=R2Q2Image, factored as A2=R3Q3Image; and in general, Ak=Rk+1Qk+1Image, k=1Image, 2, … then the sequence {An}Image converges to a triangular matrix with the eigenvalues of A along the diagonal or to a nearly triangular matrix from which the eigenvalues of A can be calculated rather easily.

Example 5.32

Consider the 3×3Image matrix A=(411141114)Image. Approximate the eigenvalues of A with the QR Method.

Solution

We define the sequence a and qr recursively. We define a using the form a[n_]:=a[n]=... and qr using the form qr[n_]:=qr[n]=... so that Mathematica “remembers” the values of a and qr computed, and thus Mathematica avoids recomputing values previously computed. This is of particular advantage when computing a[n] and qr[n] for large values of n.

matrixa = { { 4 , 1 , 1 } , { 1 , 4 , 1 } , { 1 , 1 , 4 } } ; Image

a [ 1 ] = N [ matrixa ] ; Image

qr [ 1 ] = QRDecomposition [ a [ 1 ] ] ; Image

a [ n _ ] := a [ n ] = qr [ n 1 ] [ [ 2 ] ] . Transpose [ qr [ n 1 ] [ [ 1 ] ] ] ; Image

qr [ n _ ] := qr [ n ] = QRDecomposition [ a [ n ] ] ; Image

We illustrate a[n] and qr[n] by computing qr[9] and a[10]. Note that computing a[10] requires the computation of qr[9]. From the results, we suspect that the eigenvalues of A are 5 and 2.

qr [ 9 ] Image

{{{1.,2.2317292355411738`*7,0.000278046},{8.926920162652915`*8,1.,0.000481589},{0.000278046,0.000481589,1.}},{{5.,1.5622104650343012`*6,0.00194632},{0.,5.,0.00337112},{0.,0.,2.}}}Image

a [ 10 ] // MatrixForm Image

( 5 . 1.7853841951182494 ` * 7 0.000556091 1.7853841934911076 ` * 7 5 . 0.000963178 0.000556091 0.000963178 2 . ) Image

Next, we compute a[n] for n=5Image, 10, and 15, displaying the result in TableForm. We obtain further evidence that the eigenvalues of A are 5 and 2.

Table [ a [ n ] // MatrixForm , { n , 5 , 15 , 5 } ] // TableForm Image

( 4.99902 0.001701 0.0542614 0.001701 4.99706 0.0939219 0.0542614 0.0939219 2.00393 ) ( 5 . 1.7853841951182494 ` * 7 0.000556091 1.7853841934911076 ` * 7 5 . 0.000963178 0.000556091 0.000963178 2 . ) ( 5 . 1.872126315868421 ` * 11 5.694375937113059 ` * 6 1.872110026712737 ` * 11 5 . 9.862948441373512 ` * 6 5.694375937403863 ` * 6 9.862948440910027 ` * 6 2 . ) Image

We verify that the eigenvalues of A are indeed 5 and 2 with Eigenvalues.

Eigenvalues [ matrixa ] Image

{5,5,2}Image □

5.4 Maxima and Minima Using Linear Programming

5.4.1 The Standard Form of a Linear Programming Problem

We call the linear programming problem of the following form the standard form of the linear programming problem:

Minimize  Z = c 1 x 1 + c 2 x 2 + + c n x n function ,  subject to the restrictions { a 11 x 1 + a 12 x 2 + + a 1 n x n b 1 a 21 x 1 + a 22 x 2 + + a 2 n x n b 2 a m 1 x 1 + a m 2 x 2 + + a m n x n b m and  x 1 0 , x 2 0 , , x n 0 .

The command

Minimize[{function,inequalities},{variables}]

solves the standard form of the linear programming problem. Similarly, the command

Maximize[{function,inequalities},{variables}]

solves the linear programming problem: Maximize Z=c1x1+c2x2++cnxnfunctionImage, subject to the restrictions

{ a 11 x 1 + a 12 x 2 + + a 1 n x n b 1 a 21 x 1 + a 22 x 2 + + a 2 n x n b 2 a m 1 x 1 + a m 2 x 2 + + a m n x n b m

and x10Image, x20Image, …, xn0Image.

Example 5.33

Maximize Z(x1,x2,x3)=4x13x2+2x3Image subject to the constraints 3x15x2+2x360Image, x1x2+2x310Image, x1+x2x320Image, and x1Image, x2Image, x3Image all nonnegative.

Solution

In order to solve a linear programming problem with Mathematica, the variables {x1,x2,x3} and objective function z[x1,x2,x3] are first defined. In an effort to limit the amount of typing required to complete the problem, the set of inequalities is assigned the name ineqs while the set of variables is called vars. The symbol “<=”, obtained by typing the “<” key and then the “=” key, represents “less than or equal to” and is used in ineqs. Hence, the maximization problem is solved with the command

Maximize[{z[x1,x2,x3],ineqs},vars].

Clear [ x1 , x2 , x3 , z , ineqs , vars ] Image

vars = { x1 , x2 , x3 } ; Image

z [ x1 _ , x2 _ , x3 _ ] = 4 x1 3 x2 + 2 x3 ; Image

ineqs = { 3 x1 5 x2 + x3 60 , x1 x2 + 2 x3 10 , x1 + x2 x3 20 , Image

x1 0 , x2 0 , x3 0 } ; Image

Maximize [ { z [ x1 , x2 , x3 ] , ineqs } , vars ] Image

{ 45 , { x1 15 , x2 5 , x3 0 } } Image

The solution gives the maximum value of z subject to the given constraints as well as the values of x1, x2, and x3 that maximize z. Thus, we see that the maximum value of Z is 45 if x1=15Image, x2=5Image, and x3=0Image. □

We demonstrate the use of Minimize in the following example.

Example 5.34

Minimize Z(x,y,z)=4x3y+2zImage subject to the constraints 3x5y+z60Image, xy+2z10Image, x+yz20Image, and x, y, z all nonnegative.

Solution

After clearing all previously used names of functions and variable values, the variables, objective function, and set of constraints for this problem are defined and entered as they were in the first example. By using Minimize, the minimum value of the objective function is obtained as well as the variable values that give this minimum.

Clear [ x1 , x2 , x3 , z , ineqs , vars ] Image

vars = { x1 , x2 , x3 } ; Image

z [ x1 _ , x2 _ , x3 _ ] = 4 x1 3 x2 + 2 x3 ; Image

ineqs = { 3 x1 5 x2 + x3 60 , x1 x2 + 2 x3 10 , x1 + x2 x3 20 , Image

x1 0 , x2 0 , x3 0 } ; Image

Minimize [ { z [ x1 , x2 , x3 ] , ineqs } , vars ] Image

{ 90 , { x1 0 , x2 50 , x3 30 } } Image

We conclude that the minimum value is −90 and occurs if x1=0Image, x2=50Image, and x3=30Image. □

5.4.2 The Dual Problem

Given the standard form of the linear programming problem in equations (5.2), the dual problem is as follows: “Maximize Y=i=1mbiyyImage subject to the constraints i=1maijyicijImage for j=1Image, 2, …, n and yi0Image for i=1Image, 2, …, m.” Similarly, for the problem: “Maximize Z=j=1ncjxjImage subject to the constraints j=1naijxjbjImage for i=1Image, 2, …, m and xj0Image for j=1Image, 2, …, n,” the dual problem is as follows: “Minimize Y=i=1mbiyiImage subject to the constraints i=1maijyicjImage for j=1Image, 2, …, n and yi0Image for i=1Image, 2, …, m.”

Example 5.35

Maximize Z=6x+8yImage subject to the constraints 5x+2y20Image, x+2y10Image, x0Image, and y0Image. State the dual problem and find its solution.

Solution

First, the original (or primal) problem is solved. The objective function for this problem is represented by zx. Finally, the set of inequalities for the primal is defined to be ineqsx. Using the command

Maximize[{zx,ineqsx},{x[1],x[2]}],

the maximum value of zx is found to be 45.

Clear [ zx , zy , x , y , valsx , valsy , ineqsx , ineqsy ] Image

zx = 6 x [ 1 ] + 8 x [ 2 ] ; ineqsx = { 5 x [ 1 ] + 2 x [ 2 ] 20 , x [ 1 ] + 2 x [ 2 ] 10 , x [ 1 ] 0 , Image

x [ 2 ] 0 } ; Image

Maximize [ { zx , ineqsx } , { x [ 1 ] , x [ 2 ] } ] Image

{45,{x[1]52,x[2]154}}Image

Because in this problem we have c1=6Image, c2=8Image, b1=20Image, and b2=10Image, the dual problem is as follows: Minimize Z=20y1+10y2Image subject to the constraints 5y1+y26Image, 2y1+2y28Image, y10Image, and y20Image. The dual is solved in a similar fashion by defining the objective function zy and the collection of inequalities ineqsy. The minimum value obtained by zy subject to the constraints ineqsy is 45, which agrees with the result of the primal and is found with

Minimize[{zy,ineqsy},{y[1],y[2]}].

zy = 20 y [ 1 ] + 10 y [ 2 ] ; ineqsy = { 5 y [ 1 ] + y [ 2 ] 6 , 2 y [ 1 ] + 2 y [ 2 ] 8 , Image

y [ 1 ] 0 , y [ 2 ] 0 } ; Image

Minimize [ { zy , ineqsy } , { y [ 1 ] , y [ 2 ] } ] Image

{45,{y[1]12,y[2]72}}Image □

Of course, linear programming models can involve numerous variables. Consider the following: given the standard form linear programming problem in equations (5.2), let x=(x1x2xn)Image, b=(b1b2bm)Image, c=(c1c2cn)Image, and A denote the m×nImage matrix A=(a11a12a1na21a22a2nam1am2amn)Image. Then the standard form of the linear programming problem is equivalent to finding the vector x that maximizes Z=cxImage subject to the restrictions AxbImage and x10Image, x20Image, …, xn0Image. The dual problem is: “Minimize Y=ybImage where y=(y1y2ym)Image subject to the restrictions yAcImage (componentwise) and y10Image, y20Image, …, ym0Image.”

The command

LinearProgramming[c,A,b]

finds the vector x that minimizes the quantity Z=c.x subject to the restrictions A.x>=b and x>=0. LinearProgramming does not yield the minimum value of Z as did Minimize and Maximize and the value must be determined from the resulting vector.

Example 5.36

Maximize Z=5x17x2+7x3+5x4+6x5Image subject to the constraints 2x1+3x2+3x3+2x4+2x510Image, 6x1+5x2+4x3+x4+4x530Image, 3x12x23x34x45Image, x1x2x410Image, and x10Image for i=1Image, 2, 3, 4, and 5. State the dual problem. What is its solution?

Solution

For this problem, x=(x1x2x3x4x5)Image, b=(1030510)Image, c=(57756)Image, and A=(23322654143234011010)Image. First, the vectors c and b are entered and then matrix A is entered and named matrixa.

Clear [ matrixa , x , y , c , b ] Image

c = { 5 , 7 , 7 , 5 , 6 } ; b = { 10 , 30 , 5 , 10 } ; Image

matrixa = { { 2 , 3 , 3 , 2 , 2 } , { 6 , 5 , 4 , 1 , 4 } , Image

{ 3 , 2 , 3 , 4 , 0 } , { 1 , 1 , 0 , 1 , 0 } } ; Image

Next, we use Array[x,5] to create the list of five elements {x[1],x[2],...,x[5]} named xvec. The command Table[x[i], {i,1,5}] returns the same list. These variables must be defined before attempting to solve this linear programming problem.

xvec = Array [ x , 5 ] Image

{ x [ 1 ] , x [ 2 ] , x [ 3 ] , x [ 4 ] , x [ 5 ] } Image

After entering the objective function coefficients with the vector c, the matrix of coefficients from the inequalities with matrixa, and the right-hand side values found in b; the problem is solved with

LinearProgramming[c,matrixa,b].

The solution is called xvec. Hence, the maximum value of the objective function is obtained by evaluating the objective function at the variable values that yield a maximum. Because these values are found in xvec, the maximum is determined with the dot product of the vector c and the vector xvec. (Recall that this product is entered as c.xvec.) This value is found to be 35/4.

xvec = LinearProgramming [ c , matrixa , b ] Image

{ 0 , 5 2 , 0 , 0 , 35 8 } Image

c . xvec Image

35 4 Image

Because the dual of the problem is “Minimize the number Y=y.b subject to the restrictions y.A<c and y>0,” we use Mathematica to calculate y.b and y.A. A list of the dual variables {y[1],y[2],y[3],y[4]} is created with Array[y,4]. This list includes four elements because there are four constraints in the original problem. The objective function of the dual problem is, therefore, found with yvec.b, and the left-hand sides of the set of inequalities are given with yvec.matrixa.

yvec = Array [ y , 4 ] Image

{ y [ 1 ] , y [ 2 ] , y [ 3 ] , y [ 4 ] } Image

yvec . b Image

10y[1]+30y[2]5y[3]10y[4]Image

yvec . matrixa Image

{ 2 y [ 1 ] + 6 y [ 2 ] 3 y [ 3 ] y [ 4 ] , 3 y [ 1 ] + 5 y [ 2 ] 2 y [ 3 ] y [ 4 ] , 3 y [ 1 ] + 4 y [ 2 ] 3 y [ 3 ] , 2 y [ 1 ] + y [ 2 ] 4 y [ 3 ] y [ 4 ] , 2 y [ 1 ] + 4 y [ 2 ] } Image

Hence, we may state the dual problem as:

Minimize  Y = 10 y 1 + 30 y 2 5 y 3 10 y 4  subject to the constraints  { 2 y 1 + 6 y 2 3 y 3 y 4 5 3 y 1 + 5 y 2 2 y 3 y 4 7 3 y 1 + 4 y 2 3 y 3 7 2 y 1 + y 2 4 y 3 y 4 5 2 y 1 + 4 y 2 6

and yi0Image for i=1Image, 2, 3, and 4. □

Application: A Transportation Problem

A certain company has two factories, F1 and F2, each producing two products, P1 and P2, that are to be shipped to three distribution centers, D1, D2, and D3. The following table illustrates the cost associated with shipping each product from the factory to the distribution center, the minimum number of each product each distribution center needs, and the maximum output of each factory. How much of each product should be shipped from each plant to each distribution center to minimize the total shipping costs?

F1/P1 F1/P2 F2/P1 F2/P2 Minimum
D1/P1 $0.75 $0.80 500
D1/P2 $0.50 $0.40 400
D2/P1 $1.00 $0.90 300
D2/P2 $0.75 $1.20 500
D3/P1 $0.90 $0.85 700
D3/P2 $0.80 $0.95 300
Maximum Output 1000 400 800 900

Image

Solution

Let x1Image denote the number of units of P1 shipped from F1 to D1; x2Image the number of units of P2 shipped from F1 to D1; x3Image the number of units of P1 shipped from F1 to D2; x4Image the number of units of P2 shipped from F1 to D2; x5Image the number of units of P1 shipped from F1 to D3; x6Image the number of units of P2 shipped from F1 to D3; x7Image the number of units of P1 shipped from F2 to D1; x8Image the number of units of P2 shipped from F2 to D1; x9Image the number of units of P1 shipped from F2 to D2; x10Image the number of units of P2 shipped from F2 to D2; x11Image the number of units of P1 shipped from F2 to D3; and x12Image the number of units of P2 shipped from F2 to D3.

Then, it is necessary to minimize the number

Z = . 75 x 1 + . 5 x 2 + x 3 + . 75 x 4 + . 9 x 5 + . 8 x 6 + . 8 x 7 + . 4 x 8 + . 9 x 9 + 1.2 x 10 + . 85 x 11 + . 95 x 12

subject to the constraints x1+x3+x51000Image, x2+x4+x6400Image, x7+x9+x11800Image, x8+x10+x12900Image, x1+x7500Image, x3+x9500Image, x5+x11700Image, x2+x8400Image, x4+x10500Image, x6+x12300Image, and xiImage nonnegative for i=1Image, 2, …, 12. In order to solve this linear programming problem, the objective function which computes the total cost, the 12 variables, and the set of inequalities must be entered. The coefficients of the objective function are given in the vector c. Using the command Array[x,12] illustrated in the previous example to define the list of 12 variables {x[1],x[2],...,x[12]}, the objective function is given by the product z=xvec.c, where xvec is the name assigned to the list of variables.

Clear [ xvec , z , constraints , vars , c ] Image

c = { 0.75 , 0.5 , 1 , 0.75 , 0.9 , 0.8 , 0.8 , 0.4 , 0.9 , 1.2 , 0.85 , 0.95 } ; Image

xvec = Array [ x , 12 ] Image

{ x [ 1 ] , x [ 2 ] , x [ 3 ] , x [ 4 ] , x [ 5 ] , x [ 6 ] , x [ 7 ] , x [ 8 ] , x [ 9 ] , x [ 10 ] , x [ 11 ] , x [ 12 ] } Image

{ x [ 1 ] , x [ 2 ] , x [ 3 ] , x [ 4 ] , x [ 5 ] , x [ 6 ] , Image

x [ 7 ] , x [ 8 ] , x [ 9 ] , x [ 10 ] , x [ 11 ] , x [ 12 ] } Image

z = xvec . c Image

0.75 x [ 1 ] + 0.5 x [ 2 ] + x [ 3 ] + 0.75 x [ 4 ] + 0.9 x [ 5 ] + 0.8 x [ 6 ] + 0.8 x [ 7 ] + 0.4 x [ 8 ] + 0.9 x [ 9 ] + 1.2 x [ 10 ] + 0.85 x [ 11 ] + 0.95 x [ 12 ] Image

0.75 x [ 1 ] + 0.5 x [ 2 ] + x [ 3 ] + 0.75 x [ 4 ] + Image

0.9 x [ 5 ] + 0.8 x [ 6 ] + 0.8 x [ 7 ] + 0.4 x [ 8 ] + Image

0.9 x [ 9 ] + 1.2 x [ 10 ] + 0.85 x [ 11 ] + 0.95 x [ 12 ] Image

The set of constraints are then entered and named constraints for easier use. Therefore, the minimum cost and the value of each variable which yields this minimum cost are found with the command

Minimize[{z,constraints},xvec].

constraints = { x [ 1 ] + x [ 3 ] + x [ 5 ] 1000 , x [ 2 ] + x [ 4 ] + x [ 6 ] 400 , Image

x [ 7 ] + x [ 9 ] + x [ 11 ] 800 , x [ 8 ] + x [ 10 ] + x [ 12 ] 900 , Image

x [ 1 ] + x [ 7 ] 500 , x [ 3 ] + x [ 9 ] 300 , x [ 5 ] + x [ 11 ] 700 , Image

x [ 2 ] + x [ 8 ] 400 , x [ 4 ] + x [ 10 ] > 500 , x [ 6 ] + x [ 12 ] > 300 , Image

x [ 1 ] 0 , x [ 2 ] 0 , x [ 3 ] 0 , x [ 4 ] 0 , Image

x [ 5 ] 0 , x [ 6 ] 0 , x [ 7 ] 0 , x [ 8 ] 0 , Image

x [ 9 ] 0 , x [ 10 ] 0 , x [ 11 ] 0 , x [ 12 ] 0 } ; Image

values = Minimize [ { z , constraints } , xvec ] Image

{ 2115 . , { x [ 1 ] 500 . , x [ 2 ] 0 . , x [ 3 ] 0 . , x [ 4 ] 400 . , x [ 5 ] 200 . , x [ 6 ] 0 . , x [ 7 ] 0 . , x [ 8 ] 400 . , x [ 9 ] 300 . , x [ 10 ] 100 . , x [ 11 ] 500 . , x [ 12 ] 300 . } } Image

{2115.,{x[1]500.,x[2]0.,x[3]0.,x[4]400.,Image

x [ 5 ] 200 . , x [ 6 ] 0 . , x [ 7 ] 0 . , x [ 8 ] 400 . , Image

x [ 9 ] 300 . , x [ 10 ] 100 . , x [ 11 ] 500 . , x [ 12 ] 300 . } } Image

Notice that values is a list consisting of two elements: the minimum value of the cost function, 2115, and the list of the variable values {x[1]->500,x[2]->0, ...}. Hence, the minimum cost is obtained with the command values[[1]] and the list of variable values that yield the minimum cost is extracted with values[[2]].

values [ [ 1 ] ] Image

2115.

values [ [ 2 ] ] Image

{ x [ 1 ] 500 . , x [ 2 ] 0 . , x [ 3 ] 0 . , x [ 4 ] 400 . , x [ 5 ] 200 . , x [ 6 ] 0 . , x [ 7 ] 0 . , x [ 8 ] 400 . , x [ 9 ] 300 . , x [ 10 ] 100 . , x [ 11 ] 500 . , x [ 12 ] 300 . } Image

Using these extraction techniques, the number of units produced by each factory can be computed. Because x1Image denotes the number of units of P1 shipped from F1 to D1, x3Image the number of units of P1 shipped from F1 to D2, and x5Image the number of units of P1 shipped from F1 to D3, the total number of units of Product 1 produced by Factory 1 is given by the command x[1]+x[3]+x[5] /. values[[2]] which evaluates this sum at the values of x[1], x[3], and x[5] given in the list values[[2]].

x [ 1 ] + x [ 3 ] + x [ 5 ] /. values [ [ 2 ] ] Image

700.

Also, the number of units of Products 1 and 2 received by each distribution center can be computed. The command x[3]+x[9] //values[[2]] gives the total amount of P1 received at D2 because x[3]=amount of P1 received by D2 from F1 and x[9]= amount of P1 received by D2 from F2. Notice that this amount is the minimum number of units (300) of P1 requested by D2.

x [ 3 ] + x [ 9 ] /. values [ [ 2 ] ] Image

300.

The number of units of each product that each factory produces can be calculated and the amount of P1 and P2 received at each distribution center is calculated in a similar manner.

{ x [ 1 ] + x [ 3 ] + x [ 5 ] , x [ 2 ] + x [ 4 ] + x [ 6 ] , x [ 7 ] + x [ 9 ] + x [ 11 ] , Image

x [ 8 ] + x [ 10 ] + x [ 12 ] , x [ 1 ] + x [ 7 ] , x [ 3 ] + x [ 9 ] , Image

x [ 5 ] + x [ 11 ] , x [ 2 ] + x [ 8 ] , Image

x [ 4 ] + x [ 10 ] , x [ 6 ] + x [ 12 ] } /. values [ [ 2 ] ] // Image

TableForm

700 . 400 . 800 . 800 . 500 . 300 . 700 . 400 . 500 . 300 . Image

From these results, we see that F1 produces 700 units of P1, F1 produces 400 units of P2, F2 produces 800 units of P1, F2 produces 800 units of P2, and each distribution center receives exactly the minimum number of each product it requests. □

5.5 Selected Topics from Vector Calculus

5.5.1 Vector-Valued Functions

We now turn our attention to vector-valued functions. In particular, we consider vector-valued functions of the following forms.

Plane curves: r ( t ) = x ( t ) i + y ( t ) j

Space curves: r ( t ) = x ( t ) i + y ( t ) j + z ( t ) k

Parametric surfaces: r ( s , t ) = x ( s , t ) i + y ( s , t ) j + z ( s , t ) k

Vector fields in the plane: F ( x , y ) = P ( x , y ) i + Q ( x , y ) j

Vector fields in space: F ( x , y , z ) = P ( x , y , z ) i + Q ( x , y , z ) j + R ( x , y , z ) k

For the vector-valued functions (5.3) and (5.4), differentiation and integration are carried out term-by-term, provided that all the terms are differentiable and integrable. Suppose that C is a smooth curve defined by r(t)Image, atbImage.

1.  If r(t)0Image, the unit tangent vector, T(t)Image, is T(t)=r(t)r(t)Image.

2.  If T(t)0Image, the principal unit normal vector, N(t)Image, is N(t)=T(t)T(t)Image.

3.  The arc length function, s(t)Image, is s(t)=atr(u)duImage. In particular, the length of C on the interval [a,b]Image is abr(t)dtImage.

4.  The curvature, κ, of C is

κ = T ( t ) r ( t ) = a ( t ) N ( t ) v ( t ) 2 = r ( t ) × r ( t ) r ( t ) 3 ,

where v(t)=r(t)Image and a(t)=r(t)Image.

It is a good exercise to show that the curvature of a circle of radius r is 1/rImage.

In 2-space, i=<1,0>Image and j=<0,1>Image. In 3-space i=<1,0,0>Image, j=<0,1,0>Image, and k=<0,0,1>Image.

Example 5.37

Folium of Descartes

The Folium of Descartes is defined by

r ( t ) = 3 a t 1 + t 3 i + 3 a t 2 1 + t 3 j

for t1Image, if a=1Image. (a) Find r(t)Image, r(t)Image and r(t)dtImage. (b) Find T(t)Image and N(t)Image. (c) Find the curvature, κ. (d) Find the length of the loop of the folium.

Solution

(a) After defining r(t)Image,

r [ t _ ] = { 3 a t / ( 1 + t 3 ) , 3 a t 2 / ( 1 + t 3 ) } ; Image

a = 1 ; Image

we compute r(t)Image and r(t)dtImage with ′, ″ and Integrate, respectively. We name r(t)Image dr, r(t)Image dr2, and r(t)dtImage ir.

dr = Simplify [ r [ t ] ] Image

dr2 = Simplify [ r [ t ] ] Image

ir = Integrate [ r [ t ] , t ] Image

{ 3 6 t 3 ( 1 + t 3 ) 2 , 3 t ( 2 + t 3 ) ( 1 + t 3 ) 2 } Image

{ 18 t 2 ( 2 + t 3 ) ( 1 + t 3 ) 3 , 6 ( 1 7 t 3 + t 6 ) ( 1 + t 3 ) 3 } Image

{ 3 ( ArcTan [ 1 + 2 t 3 ] 3 1 3 Log [ 1 + t ] + 1 6 Log [ 1 t + t 2 ] ) , Log [ 1 + t 3 ] } Image

(b) Mathematica does not automatically make assumptions regarding the value of t, so it does not algebraically simplify r(t)Image as we might typically do unless we use PowerExpand

PowerExpand[Sqrt[x̂2]] returns x rather than |x|Image.

nr = PowerExpand [ Sqrt [ dr . dr ] // Simplify ] Image

3 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 ( 1 + t 3 ) 2 Image

The unit tangent vector, T(t)Image is formed in ut.

ut = dr / nr // Simplify Image

{ 1 2 t 3 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 , t ( 2 + t 3 ) 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 } Image

We perform the same steps to compute the unit normal vector, N(t)Image. In particular, note that dutb=T(t)Image.

dut = D [ ut , t ] // Simplify Image

{2t(23t3+t9)(1+4t24t34t5+4t6+t8)3/2,26t64t9(1+4t24t34t5+4t6+t8)3/2}Image

duta = dut . dut // Simplify Image

4 ( 1 + t 3 ) 4 ( 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 ) 2 Image

dutb = PowerExpand [ Sqrt [ duta ] ] Image

2 ( 1 + t 3 ) 2 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 Image

nt = dut / dutb // Simplify Image

{ t ( 2 + t 3 ) 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 , 1 2 t 3 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 } Image

(c) We use the formula κ=T(t)r(t)Image to determine the curvature in curvature.

curvature = Simplify [ dutb / nr ] Image

2 ( 1 + t 3 ) 4 3 ( 1 + 4 t 2 4 t 3 4 t 5 + 4 t 6 + t 8 ) 3 / 2 Image

We graphically illustrate the unit tangent and normal vectors at r(1)=<3/2,3/2>Image. First, we compute the unit tangent and normal vectors if t=1Image using /. (ReplaceAll).

ut1 = ut /. t 1 Image

nt1 = nt /. t 1 Image

{ 1 2 , 1 2 } Image

{ 1 2 , 1 2 } Image

We then compute the curvature if t=1Image in smallk. The center of the osculating circle at r(1)Image is found in x0 and y0.

The radius of the osculating circle is 1/κImage; the position vector of the center is r+1κNImage.

smallk = curvature /. t 1 Image

N [ smallk ] Image

x0 = ( r [ t ] + 1 / curvature nt /. t 1 ) [ [ 1 ] ] Image

y0 = ( r [ t ] + 1 / curvature nt /. t 1 ) [ [ 2 ] ] Image

8 2 3 Image

3.77124

21 16 Image

2116Image

We now graph r(t)Image with ParametricPlot. The unit tangent and normal vectors at r(1)Image are graphed with Arrow in a1 and a2. The osculating circle at r(1)Image is graphed with Circle in c1. All four graphs are displayed together with Show in Fig. 5.8.

Graphics[Circle[{x0, y0}, r]] is a two-dimensional graphics object that represents a circle of radius r centered at the point (x0,y0)Image. Use Show to display the graph.

Image
Figure 5.8 The folium with an osculating circle (Brigham Young University colors).

p1 = ParametricPlot [ r [ t ] , { t , 100 , 100 } , Image

PlotRange { { 2 , 3 } , { 2 , 3 } } , AspectRatio 1 , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ 1 , . 62 , 0 , . 52 ] } } ] ; Image

p2 = Graphics [ { Thickness [ . 0075 ] , CMYKColor [ . 18 , . 31 , . 56 , 0 ] , Image

Circle [ { x0 , y0 } , 1 / smallk ] , Image

Arrow [ { r [ 1 ] , r [ 1 ] + ut1 } ] , Arrow [ { r [ 1 ] , r [ 1 ] + nt1 } ] } ] ; Image

Show [ p1 , p2 , AspectRatio Automatic ] Image

(d) The loop is formed by graphing r(t)Image for t0Image. Hence, the length of the loop is given by the improper integral 0r(t)dtImage, which we compute with NIntegrate.

NIntegrate [ nr , { t , 0 , Infinity } ] Image

4.91749 □

In the example, we computed the curvature at t=1Image. Of course, we could choose other t values. With Manipulate,

Manipulate [ Image

r [ t _ ] = { 3 t / ( 1 + t 3 ) , 3 t 2 / ( 1 + t 3 ) } ; Image

dr = Simplify [ r [ t ] ] ; Image

dr2 = Simplify [ r [ t ] ] ; Image

ir = Integrate [ r [ t ] , t ] ; Image

nr = PowerExpand [ Sqrt [ dr . dr ] // Simplify ] ; Image

ut = dr / nr // Simplify ; Image

dut = D [ ut , t ] // Simplify ; Image

duta = dut . dut // Simplify ; Image

dutb = PowerExpand [ Sqrt [ duta ] ] ; Image

nt = dut / dutb // Simplify ; Image

curvature = Simplify [ dutb / nr ] ; Image

ut1 = ut /. t t 0 ; Image

nt1 = nt /. t t 0 ; Image

smallk = curvature /. t t 0 ; Image

x0 = ( r [ t ] + 1 / curvature nt /. t t 0 ) [ [ 1 ] ] ; Image

y0 = ( r [ t ] + 1 / curvature nt /. t t 0 ) [ [ 2 ] ] ; Image

p1 = ParametricPlot [ r [ t ] , { t , 10 , 10 } , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ 1 , . 62 , 0 , . 52 ] } } , Image

PlotRange { { 2 , 3 } , { 2 , 3 } } , AspectRatio 1 , PlotPoints 200 ] ; Image

p2 = Graphics [ { Circle [ { x0 , y0 } , 1 / smallk ] , Image

Arrow [ { r [ t 0 ] , r [ t 0 ] + ut1 } ] , Arrow [ { r [ t 0 ] , r [ t 0 ] + nt1 } ] } ] ; Image

. Show [ p1 , p2 ] , { { t 0 , 1 } , 5 , 10 } ] Image

we can see the osculating circle at various values of y01Image. See Fig. 5.9.

Image
Figure 5.9 Using Manipulate to see the osculating circle at various values of t0.

Of course, this particular choice of using the folium to illustrate the procedure could be modified as well. With

Manipulate [ Image

folium [ t _ ] = { 3 t / ( 1 + t 3 ) , 3 t 2 / ( 1 + t 3 ) } ; Image

cycloid [ t _ ] = { 1 / ( 2 Pi ) ( t Sin [ t ] ) , ( 1 Cos [ t ] ) / ( 2 Pi ) } ; Image

rose [ t _ ] = { 3 / 2 Cos [ 2 t ] Cos [ t ] , 3 / 2 Cos [ 2 t ] Sin [ t ] } ; Image

squiggle [ t _ ] = { Cos [ t ] Sin [ 2 t ] , Sin [ 2 t ] + Cos [ 5 t ] } ; Image

cornu [ t _ ] = { 2.5 FresnelC [ t ] , 2.5 FresnelS [ t ] } ; Image

lissajous [ t _ ] = { 2 Cos [ t ] , Sin [ 2 t ] } ; Image

evolute [ t _ ] = { Cos [ t ] 3 , 2 Sin [ t ] 3 } ; Image

dr = Simplify [ r [ t ] ] ; Image

dr2 = Simplify [ r [ t ] ] ; Image

ir = Integrate [ r [ t ] , t ] ; Image

nr = PowerExpand [ Sqrt [ dr . dr ] // Simplify ] ; Image

ut = dr / nr // Simplify ; Image

dut = D [ ut , t ] // Simplify ; Image

duta = dut . dut // Simplify ; Image

dutb = PowerExpand [ Sqrt [ duta ] ] ; Image

nt = dut / dutb // Simplify ; Image

curvature = Simplify [ dutb / nr ] ; Image

ut1 = ut /. t t 0 ; Image

nt1 = nt /. t t 0 ; Image

smallk = curvature /. t t 0 ; Image

x0 = ( r [ t ] + 1 / curvature nt /. t t 0 ) [ [ 1 ] ] ; Image

y0 = ( r [ t ] + 1 / curvature nt /. t t 0 ) [ [ 2 ] ] ; Image

p1 = ParametricPlot [ r [ t ] , { t , 10 , 10 } , Image

PlotRange { { 3 , 3 } , { 3 , 3 } } , AspectRatio 1 , PlotPoints 200 ] ; Image

p2 = Graphics [ { Thickness [ . 0075 ] , CMYKColor [ . 18 , . 31 , . 56 , 0 ] , Image

Circle [ { x0 , y0 } , 1 / smallk ] , Image

Arrow [ { r [ t 0 ] , r [ t 0 ] + ut1 } ] , Arrow [ { r [ t 0 ] , r [ t 0 ] + nt1 } ] } ] ; Image

Show [ p1 , p2 ] , { { r , folium } , Image

{ folium , cycloid , rose , squiggle , cornu , lissajous , evolute } } , { { t 0 , 3 / 2 } , 5 , 10 } ] Image

we not only allow t0Image to vary but also r(t)Image. Note that the resulting Manipulate object is quite slow on all except the fastest computers. See Fig. 5.10 (b).

Image
Figure 5.10 The osculating circle for various r(t) and t0.

Recall that the gradient of z=f(x,y)Image is the vector-valued function f(x,y)=<fx(x,y),fy(x,y)>Image. Similarly, we define the gradient of w=f(x,y,z)Image to be

f ( x , y , z ) = < f x ( x , y , z ) , f y ( x , y , z ) , f z ( x , y , z ) > = f x i + f y j + f z k .

A vector field F is conservative if there is a function f, called a potential function, satisfying f=FImage. In the special case that F(x,y)=P(x,y)i+Q(x,y)jImage, F is conservative if and only if

P y = Q x .

The divergence of the vector field F(x,y,z)=P(x,y,z)i+Q(x,y,z)j+R(x,y,z)kImage is the scalar field

div F = F = P x + Q y + R z .

The Div command can be used to find the divergence of a vector field:

Div[{P(x,y,z),Q(x,y,z),R(x,y,z)},"Cartesian"]

computes the divergence of F(x,y,z)=P(x,y,z)i+Q(x,y,z)j+R(x,y,z)kImage in the Cartesian coordinate system. If you omit “Cartesian,” the default coordinates are the Cartesian coordinate system. However, if you are using a non-Cartesian coordinates system such as cylindrical or spherical coordinates, be sure to replace “Cartesian” with “Cylindrical,” “Spherical” or the name of the coordinate system you are using. Note that Mathematica supports nearly all coordinate systems used by scientists.

The Laplacian of the scalar field w=f(x,y,z)Image is defined to be

div ( f ) = ( f ) = 2 f = 2 f x 2 + 2 f y 2 + 2 f z 2 = f .

In the same way that Div computes the divergence of a vector field Laplacian computes the Laplacian of a scalar field.

The curl of the vector field F(x,y,z)=P(x,y,z)i+Q(x,y,z)j+R(x,y,z)kImage is

curl F ( x , y , z ) = × F ( x , y , z ) = | i j k x y z P ( x , y , z ) Q ( x , y , z ) R ( x , y , z ) | = ( R y Q z ) i ( R x P z ) j + ( Q x P y ) k .

If F(x,y,z)=P(x,y,z)i+Q(x,y,z)j+R(x,y,z)kImage, F is conservative if and only if curlF(x,y,z)=0Image, in which case F is said to be irrotational.

Solution

We define P(x,y)=(12x2)yex2y2Image and Q(x,y)=Image (12y2)xex2y2Image. Then we use D and Simplify to see that Py(x,y)=Qx(x,y)Image. Hence, F is conservative.

p [ x _ , y _ ] = ( 1 2 x 2 ) y Exp [ x 2 y 2 ] ; Image

q [ x _ , y _ ] = ( 1 2 y 2 ) x Exp [ x 2 y 2 ] ; Image

Simplify [ D [ p [ x , y ] , y ] ] Image

Simplify [ D [ q [ x , y ] , x ] ] Image

e x 2 y 2 ( 1 + 2 x 2 ) ( 1 + 2 y 2 ) Image

e x 2 y 2 ( 1 + 2 x 2 ) ( 1 + 2 y 2 ) Image

We use Integrate to find f satisfying f=FImage.

i1 = Integrate [ p [ x , y ] , x ] + g [ y ] Image

e x 2 y 2 x y + g [ y ] Image

Solve [ D [ i1 , y ] = = q [ x , y ] , g [ y ] ] Image

{ { g [ y ] 0 } } Image

Therefore, g(y)=CImage, where C is an arbitrary constant. Letting C=0Image gives us the following potential function.

f = i1 /. g [ y ] - > 0 Image

e x 2 y 2 x y Image

Remember that the vectors F are perpendicular to the level curves of f. To see this, we normalize F in uv.

uv = { p [ x , y ] , q [ x , y ] } / Image

Sqrt [ { p [ x , y ] , q [ x , y ] } . { p [ x , y ] , q [ x , y ] } ] // Simplify Image

{ e x 2 y 2 ( y 2 x 2 y ) e 2 ( x 2 + y 2 ) ( y 2 + 4 x 4 y 2 + x 2 ( 1 8 y 2 + 4 y 4 ) ) , e x 2 y 2 ( x 2 x y 2 ) e 2 ( x 2 + y 2 ) ( y 2 + 4 x 4 y 2 + x 2 ( 1 8 y 2 + 4 y 4 ) ) } Image

We then graph several level curves of f in cp1 and cp2 with ContourPlot and several vectors of uv with VectorPlot. We show the graphs together with Show in Fig. 5.11.

Image
Figure 5.11 Two different views illustrating that the vectors F are perpendicular to the level curves of f (University of Vermont colors).

cp1 = ContourPlot [ f , { x , 3 2 , 3 2 } , { y , 3 2 , 3 2 } , Contours 15 , . Image

ContourShading False , PlotPoints 60 , Frame False , Image

Axes Automatic , AxesOrigin { 0 , 0 } , AxesLabel { x , y } , Image

ContourStyle { { Thickness [ . 0075 ] , CMYKColor [ . 85 , 0 , . 64 , . 45 ] } } ] ; Image

cp2 = ContourPlot [ f , { x , 3 2 , 3 2 } , { y , 3 2 , 3 2 } , Contours 20 , Frame False , . Image

Axes Automatic , AxesOrigin { 0 , 0 } , AxesLabel { x , y } , Image

PlotPoints 60 , ContourStyle CMYKColor [ . 6 , . 01 , . 93 , . 1 ] ] ; Image

fp = VectorPlot [ uv , { x , 3 / 2 , 3 / 2 } , { y , 3 / 2 , 3 / 2 } , Image

VectorStyle - > CMYKColor [ . 35 , 0 , . 95 , 0 ] ] ; Image

Show [ GraphicsRow [ { Show [ cp1 , fp , PlotLabel “(a)” ] , Image

Show[cp2,fp,PlotLabel“(b)”]}]]Image □

Example 5.39

(a) Show that

F ( x , y , z ) = 10 x y 2 i + ( 3 z 3 10 x 2 y ) j + 9 y z 2 k

is irrotational. (b) Find a function y=f(x,y)Image satisfying f=FImage. (c) Compute div FImage and 2fImage.

Solution

(a) After defining F(x,y,z)Image, we use Curl, to see that curl F(x,y,z)=0Image.

Clear [ f , x , y , z ] Image

f [ x _ , y _ , z _ ] = { 10 x y 2 , 3 z 3 10 x 2 y , 9 y z 2 } Image

{ 10 x y 2 , 10 x 2 y + 3 z 3 , 9 y z 2 } Image

Curl [ f [ x , y , z ] , { x , y , z } ] Image

{ 0 , 0 , 0 } Image

(b) We then use Integrate to find w=f(x,y,z)Image satisfying f=FImage.

i1 = Integrate [ f [ x , y , z ] [ [ 1 ] ] , x ] + g [ y , z ] Image

5 x 2 y 2 + g [ y , z ] Image

i2 = D [ i1 , y ] Image

10 x 2 y + g ( 1 , 0 ) [ y , z ] Image

Solve [ i2 = = f [ x , y , z ] [ [ 2 ] ] , g ( 1 , 0 ) [ y , z ] ] Image

{ { g ( 1 , 0 ) [ y , z ] 3 z 3 } } Image

i3 = Integrate [ 3 z 3 , y ] + h [ z ] Image

3 y z 3 + h [ z ] Image

i4 = i1 /. g [ y , z ] - > i3 Image

5 x 2 y 2 + 3 y z 3 + h [ z ] Image

Solve [ D [ i4 , z ] = = f [ x , y , z ] [ [ 3 ] ] ] Image

{ { z InverseFunction [ h , 1 , 1 ] [ 0 ] } } Image

With h(z)=CImage and C=0Image we have f(x,y,z)=5x2y2+3yz3Image.

lf = 5 x 2 y 2 + 3 y z 3 ; Image

f is orthogonal to the level surfaces of f. To illustrate this, we use ContourPlot3D to graph several level surfaces of w=f(x,y,z)Image for 10x10Image, 10y10Image, and 10z10Image in pf. We then use GradientFieldPlot3D, which is contained in the VectorFieldPlots package, to graph several vectors in the gradient field of f over the same domain in gradf. The two plots are shown together with Show in Fig. 5.12. In the plot, notice that the vectors appear to be perpendicular to the surface.

Image
Figure 5.12f is orthogonal to the level surfaces of f (University of Oregon colors).

pf1 = ContourPlot3D [ lf = = 5 , { x , 10 , 10 } , { y , 10 , 10 } , Image

{ z , 10 , 10 } , PlotPoints 40 , Image

ContourStyle { { Thickness [ . 01 ] , CMYKColor [ . 02 , . 02 , . 95 , 0 ] } } ] ; Image

pf2 = ContourPlot3D [ lf = = 10 , { x , 10 , 10 } , { y , 10 , 10 } , Image

{ z , 10 , 10 } , PlotPoints 40 , Mesh None , Image

ContourStyle Directive [ CMYKColor [ . 02 , . 02 , . 95 , 0 ] , Opacity [ 0.8 ] , Image

Specularity [ White , 10 ] ] ] ; Image

pf3 = ContourPlot3D [ lf = = 100 , { x , 10 , 10 } , { y , 10 , 10 } , Image

{ z , 10 , 10 } , Mesh None , Image

ContourStyle Directive [ CMYKColor [ . 02 , . 02 , . 95 , 0 ] , Opacity [ 0.5 ] ] , Image

PlotPoints 40 ] ; Image

pf4 = ContourPlot3D [ lf , { x , 10 , 10 } , { y , 10 , 10 } , { z , 10 , 10 } , Image

PlotPoints 50 , Mesh None , Image

ContourStyle Directive [ CMYKColor [ . 02 , . 02 , . 95 , 0 ] , Opacity [ 0.3 ] , Image

Specularity [ White , 30 ] ] ] ; Image

gf = VectorPlot3D [ Evaluate [ { D [ lf , x ] , D [ lf , y ] , D [ lf , z ] } ] , { x , 10 , 10 } , Image

{ y , 10 , 10 } , { z , 10 , 10 } , VectorPoints 15 , Image

VectorStyle CMYKColor [ . 87 , . 45 , . 78 , . 49 ] ] Image

Show [ GraphicsGrid [ { { Show [ pf1 , gf , PlotLabel “(a)” ] , Image

Show [ pf2 , gf , PlotLabel “(b)” ] } , Image

{ Show [ pf3 , gf , PlotLabel “(c)” ] , Show [ pf4 , gf , Image

PlotLabel “(d)” ] } } ] ] Image

For (c), we take advantage of Div and Laplacian. As expected, the results are the same. □

5.5.2 Line Integrals

If F is continuous on the smooth curve C with parametrization r(t)Image, atbImage, the line integral of F on C is

C F d r = a b F r ( t ) d t

If F is conservative and C is piecewise smooth, line integrals can be evaluated using the Fundamental Theorem of Line Integrals.

Example 5.40

Find CFdrImage where F(x,y)=(eyyex)i+(exxey)jImage and C is defined by r(t)=costi+ln(2t/π)jImage, π/2t4πImage.

If C is a piecewise smooth simple closed curve and P(x,y)Image and Q(x,y)Image have continuous partial derivatives, Green's Theorem relates the line integral C(P(x,y)dx+Q(x,y)dy)Image to a double integral.

Solution

After defining P(x,y)=exsinyImage and Q(x,y)=cosxeyImage, we use Plot to determine the region R bounded by C in Fig. 5.13.

Image
Figure 5.13 y = x2 and y=xImage, 0 ⩽ x ⩽ 1 (University of Arizona colors).

p [ x _ , y _ ] = Exp [ x ] Sin [ y ] ; Image

q [ x _ , y _ ] = Cos [ x ] Exp [ y ] ; Image

Plot [ { x 2 , Sqrt [ x ] } , { x , 0 , 1.1 } , Image

PlotStyle - > { { Thickness [ . 01 ] , CMYKColor [ 0 , 1 , . 65 , . 15 ] } , Image

{ Thickness [ . 01 ] , CMYKColor [ 1 , . 72 , 0 , . 38 ] } } , Image

AspectRatio - > Automatic , AxesLabel { x , y } ] Image

Using equation (5.14),

C ( e x sin y ) d x + ( cos x e y ) d y = R ( Q x P y ) d A = R ( cos y sin x ) d A = 0 1 x 2 x ( cos y sin x ) d y d x ,

dqdp=Simplify[D[q[x,y],x]D[p[x,y],y]]Image

Cos [ y ] Sin [ x ] Image

which we evaluate with Integrate.

Integrate [ dqdp , { x , 0 , 1 } , { y , x 2 , Sqrt [ x ] } ] Image

N [ % ] Image

1 2 ( 4 2 π ( FresnelC [ 2 π ] + FresnelS [ 2 π ] ) + 8 Sin [ 1 ] ) Image

0.151091

Notice that the result is given in terms of the FresnelS and FresnelC functions, which are defined by

F r e s n e l S [ x ] = 0 x sin ( π 2 t 2 ) d t and F r e s n e l C [ x ] = 0 x cos ( π 2 t 2 ) d t .

A more meaningful approximation is obtained with N. We conclude that

0 1 x 2 x ( cos y sin x ) d y d x 0.151 .

 □

5.5.3 Surface Integrals

Let S be the graph of z=f(x,y)Image (y=h(x,z)Image, x=k(y,z)Image) and let RxyImage (RxzImage, RyzImage) be the projection of S onto the xy (xz, yz) plane. Then,

S g ( x , y , z ) d S = R x y g ( x , y , f ( x , y ) ) [ f x ( x , y ) ] 2 + [ f y ( x , y ) ] 2 + 1 d A

= R x z g ( x , h ( x , z ) , z ) [ h x ( x , z ) ] 2 + [ h z ( x , z ) ] 2 + 1 d A

= R y z g ( k ( y , z ) , y , z ) [ k y ( y , z ) ] 2 + [ k z ( y , z ) ] 2 + 1 d A .

If S is defined parametrically by

r ( s , t ) = x ( s , t ) i + y ( s , t ) j + z ( s , t ) k , ( s , t ) R

the formula

S g ( x , y , z ) d S = R g ( r ( s , t ) ) r s × r t d A ,

where

r s = x s i + y s j + z s k and r t = x t i + y t j + z t k ,

is also useful.

In (5.19), SFndSImage is called the outward flux of the vector field F across the surface S. If S is a portion of the level curve g(x,y)=CImage for some g, then a unit normal vector n may be taken to be either

n = g g or n = g g .

If S is defined parametrically by

r ( s , t ) = x ( s , t ) i + y ( s , t ) j + z ( s , t ) k , ( s , t ) R ,

a unit normal vector to the surface is n=rs×rtrs×rtImage and (5.19) becomes SFndS=RF(rs×rt)dAImage.

Example 5.42

Find the outward flux of the vector field

F ( x , y , z ) = ( x z + x y z 2 ) i + ( x y + x 2 y z ) j + ( y z + x y 2 z ) k

through the surface of the cube cut from the first octant by the planes x=1Image, y=1Image, and z=1Image.

In other words, the surface integral of the normal component of the curl of F taken over S equals the line integral of the tangential component of the field taken over C. In particular, if F=P(x,y,z)i+Q(x,y,z)j+R(x,y,z)kImage, then

C ( P ( x , y , z ) d x + Q ( x , y , z ) d y + R ( x , y , z ) d z ) = S curl  F n d S .

Solution

The curl of F is computed with Curl in curlcapf.

capf [ x _ , y _ , z _ ] = { x 2 y , y 2 z , x + z 2 } ; Image

f [ x _ , y _ ] = 9 ( x 2 + y 2 ) ; Image

curlcapf = Curl [ capf [ x , y , z ] , { x , y , z } ] Image

{ 1 , 1 , 1 } Image

Next, we define the function h(x,y,z)=zf(x,y)Image. A normal vector to the surface is given by ▽h. A unit normal vector, n, is then given by n=hhImage, which is computed in un.

h [ x _ , y _ , z _ ] = z f [ x , y ] Image

normtosurf = Grad [ h [ x , y , z ] , { x , y , z } ] Image

9 + x 2 + y 2 + z Image

{ 2 x , 2 y , 1 } Image

un = Simplify [ normtosurf / Sqrt [ normtosurf . normtosurf ] ] Image

{ 2 x 1 + 4 x 2 + 4 y 2 , 2 y 1 + 4 x 2 + 4 y 2 , 1 1 + 4 x 2 + 4 y 2 } Image

The dot product curl FnImage is computed in g.

g = Simplify [ curlcapf . un ] Image

1+2x2y1+4x2+4y2Image

Using the surface integral evaluation formula (5.15),

S curl  F n d S = R g ( x , y , f ( x , y ) ) [ f x ( x , y ) ] 2 + [ f y ( x , y ) ] 2 + 1 d A = 3 3 9 x 2 9 x 2 g ( x , y , f ( x , y ) ) [ f x ( x , y ) ] 2 + [ f y ( x , y ) ] 2 + 1 d y d x = 9 π ,

In this example, R, the projection of f(x,y)Image onto the xy-plane, is the region bounded by the graph of the circle x2+y2=9Image.

which we compute with Integrate.

tointegrate = Simplify [ ( g /. z f [ x , y ] ) ] Image

Sqrt [ D [ f [ x , y ] , x ] 2 + D [ f [ x , y ] , y ] 2 + 1 ] Image

1 + 2 x 2 y Image

i1 = Integrate [ tointegrate , { x , 3 , 3 } , Image

{ y , Sqrt [ 9 x 2 ] , Sqrt [ 9 x 2 ] } ] Image

9π

To verify Stokes' theorem, we must compute the associated line integral. Notice that the boundary of z=f(x,y)=9(x2+y2)Image, z=0Image, is the circle x2+y2=9Image with parametrization x=3costImage, y=3sintImage, z=0Image, 0t2πImage. This parametrization is substituted into F(x,y,z)Image and named pvf.

pvf = capf [ 3 Cos [ t ] , 3 Sin [ t ] , 0 ] Image

{ 9 Cos [ t ] 2 3 Sin [ t ] , 9 Sin [ t ] 2 , 3 Cos [ t ] } Image

To evaluate the line integral along the circle, we next define the parametrization of the circle and calculate drImage. The dot product of pvf and dr represents the integrand of the line integral.

r [ t _ ] = { 3 Cos [ t ] , 3 Sin [ t ] , 0 } ; Image

dr = r [ t ] Image

tointegrate = pvf . dr ; Image

{ 3 Sin [ t ] , 3 Cos [ t ] , 0 } Image

As before with x and y, we instruct Mathematica to assume that t is real, compute the dot product of pvf and dr, and evaluate the line integral with Integrate.

Integrate [ tointegrate , { t , 0 , 2 Pi } ] Image

9π

As expected, the result is 9π.  □

5.5.4 A Note on Nonorientability

See “When is a surface not orientable?” by Braselton, Abell, and Braselton [4] for a detailed discussion regarding the examples in this section.

Suppose that S is the surface determined by

r ( s , t ) = x ( s , t ) i + y ( s , t ) j + z ( s , t ) k , ( s , t ) R

and let

n = r s × r t r s × r t or n = r s × r t r s × r t ,

where

r s = x s i + y s j + z s k and r t = x t i + y t j + z t k ,

if rs×rt0Image. If n is defined, n is orthogonal (or perpendicular) to S. We state three familiar definitions of orientable.

•  S is orientable if S has a unit normal vector field, n, that varies continuously between any two points (x0,y0,z0)Image and (x1,y1,z1)Image on S. (See [5].)

•  S is orientable if S has a continuous unit normal vector field, n. (See [5] and [16].)

•  S is orientable if a unit vector n can be defined at every nonboundary point of S in such a way that the normal vectors vary continuously over the surface S. (See [11].)

A path is order preserving if our chosen orientation is preserved as we move along the path.

Thus, a surface like a torus is orientable.

Example 5.44

The Torus

Using the standard parametrization of the torus, we use ParametricPlot3D to plot the torus if c=3Image and a=1Image in Fig. 5.14.

Also see Example 2.33.

Image
Figure 5.14 A torus (University of Alabama colors).

Clear [ r ] Image

c = 3 ; Image

a = 1 ; Image

x [ s _ , t _ ] = ( c + a Cos [ s ] ) Cos [ t ] ; Image

y [ s _ , t _ ] = ( c + a Cos [ s ] ) Sin [ t ] ; Image

z [ s _ , t _ ] = a Sin [ s ] ; Image

r [ s _ , t _ ] = { x [ s , t ] , y [ s , t ] , z [ s , t ] } ; Image

threedp1t = ParametricPlot3D [ r [ s , t ] , { s , Pi , Pi } , Image

{ t , Pi , Pi } , PlotPoints - > { 30 , 30 } , AspectRatio - > 1 , Image

PlotRange - > { { 4 , 4 } , { 4 , 4 } , { 1 , 1 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

PlotStyle { { CMYKColor [ . 25 , 1 , . 79 , . 2 ] , Opacity [ . 3 ] } } ] Image

To plot a normal vector field on the torus, we compute sr(s,t)Image,

rs = D [ r [ s , t ] , s ] Image

{ Cos [ t ] Sin [ s ] , Sin [ s ] Sin [ t ] , Cos [ s ] } Image

rt = D [ r [ s , t ] , t ] Image

{ ( 3 + Cos [ s ] ) Sin [ t ] , ( 3 + Cos [ s ] ) Cos [ t ] , 0 } Image

The cross product sr(s,t)×tImage is formed in rscrossrt.

rscrossrt = Cross [ rs , rt ] // Simplify Image

{ Cos [ s ] ( 3 + Cos [ s ] ) Cos [ t ] , Cos [ s ] ( 3 + Cos [ s ] ) Sin [ t ] , ( 3 + Cos [ s ] ) Sin [ s ] } Image

Sqrt [ rscrossrt . rscrossrt ] // FullSimplify Image

( 3 + Cos [ s ] ) 2 Image

Using equation (5.24), we define un: given s and t, un[s,t] returns a unit normal to the torus.

Clear [ un ] Image

un [ s _ , t _ ] = Image

rscrossrt / Sqrt [ rscrossrt . Image

rscrossrt ] // PowerExpand // FullSimplify Image

{Cos[s](3+Cos[s])Cos[t](3+Cos[s])2,Cos[s](3+Cos[s])Sin[t](3+Cos[s])2,(3+Cos[s])Sin[s](3+Cos[s])2}Image

Map [ PowerExpand , un [ s , t ] ] Image

{ Cos [ s ] Cos [ t ] , Cos [ s ] Sin [ t ] , Sin [ s ] } Image

r [ s , t ] Image

{ ( 3 + Cos [ s ] ) Cos [ t ] , ( 3 + Cos [ s ] ) Sin [ t ] , Sin [ s ] } Image

un [ s , t ] Image

{ Cos [ s ] ( 3 + Cos [ s ] ) Cos [ t ] ( 3 + Cos [ s ] ) 2 , Cos [ s ] ( 3 + Cos [ s ] ) Sin [ t ] ( 3 + Cos [ s ] ) 2 , ( 3 + Cos [ s ] ) Sin [ s ] ( 3 + Cos [ s ] ) 2 } Image

To plot the normal vector field on the torus, we take advantage of the command Arrow. The command

Arrow[{{u1,u2,u3},{v1,v2,v3}}]

generates an arrow from (u1,u2,u3)Image to (v1,v2,v3)Image, which we interpret to be the vector going from (u1,u2,u3)Image to (v1,v2,v3)Image. To display the Arrow object, use Show together with Graphics (for two-dimensional arrows) or Graphics3D (for three dimensional arrows). See Fig. 5.15.

Image
Figure 5.15 Unit normal vector field on a torus.

Clear [ vecs ] Image

vecs = Flatten [ Table [ { r [ s , t ] , r [ s , t ] + un [ s , t ] } , Image

{ s , Pi , Pi , 2 Pi / 14 } , { t , Pi , Pi , 2 Pi / 29 } ] , 1 ] ; Image

pp2 = Show [ Graphics3D [ Arrow [ vecs ] ] ] Image

We use Show (illustrating the use of the ViewPoint option) together with GraphicsGrid to see the vector field on the torus together from various angles in Fig. 5.16. Regardless of the viewing angle, the figure looks the same; the torus is orientable.

Image
Figure 5.16 The torus is orientable.

Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } ] Image

g1 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 2.729 , 0.000 , 2.000 } ] ; Image

g2 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint->{1.365,2.364,2.000}];Image

g3 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] ; Image

g4 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 2.729 , 0.000 , 2.000 } ] ; Image

g5 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] ; Image

g6 = Show [ threedp1t , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 5 , 5 } , { 5 , 5 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] ; Image

Show [ GraphicsGrid [ { { g1 , g2 } , { g3 , g4 } , { g5 , g6 } } ] ] Image

If a 2-manifold, S, has an order reversing path (or not order preserving path), S is nonorientable (or not orientable).

Determining whether a given surface S is orientable or not may be a difficult problem.

Example 5.45

The Möbius Strip

The Möbius strip is frequently cited as an example of a nonorientable surface with boundary: it has one side and is physically easy to construct by hand by half twisting and taping (or pasting) together the ends of a piece of paper (for example, see [5], [11], and [16]). A parametrization of the Möbius strip is r(s,t)=x(s,t)i+y(s,t)j+z(s,t)kImage, 1s1Image, πtπImage, where

x = [ c + s cos ( 1 2 t ) ] cos t , y = [ c + s cos ( 1 2 t ) ] sin t ,  and z = s sin ( 1 2 t ) ,

and we assume that c>1Image. In Fig. 5.17, we graph the Möbius strip using c=3Image.

Image
Figure 5.17 Parametric plot of equations (5.22) if c = 3 (Mississippi State University colors).

c = 3 ; Image

x [ s _ , t _ ] = ( c + s Cos [ t / 2 ] ) Cos [ t ] ; Image

y [ s _ , t _ ] = ( c + s Cos [ t / 2 ] ) Sin [ t ] ; Image

z [ s _ , t _ ] = s Sin [ t / 2 ] ; Image

r [ s _ , t _ ] = { x [ s , t ] , y [ s , t ] , z [ s , t ] } ; Image

threedp1 = ParametricPlot3D [ r [ s , t ] , { s , 1 , 1 } , Image

{ t , Pi , Pi } , PlotPoints - > { 30 , 30 } , Image

AspectRatio - > 1 , PlotRange Image

{ { 4 , 4 } , { 4 , 4 } , { 1 , 1 } } , BoxRatios - > { 4 , 4 , 1 } , Image

AxesLabel - > { x , y , z } , Image

Mesh False , PlotStyle { { CMYKColor [ . 5 , 1 , 1.25 ] , Opacity [ . 8 ] } } ] Image

Although it is relatively easy to see in the plot that the Möbius strip has only one side, the fact that a unit vector, n, normal to the Möbius strip at a point P reverses its direction as n moves around the strip to P is not obvious to the novice.

With Mathematica, we compute rs×rtImage and n=rs×rtrs×rtImage.

rs = D [ r [ s , t ] , s ] Image

{ Cos [ t 2 ] Cos [ t ] , Cos [ t 2 ] Sin [ t ] , Sin [ t 2 ] } Image

rt = D [ r [ s , t ] , t ] Image

{12sCos[t]Sin[t2](3+sCos[t2])Sin[t],(3+sCos[t2])Cos[t]12sSin[t2]Sin[t],12sCos[t2]}Image

rscrossrt = Cross [ rs , rt ] // Simplify Image

{ 1 2 ( s Cos [ t 2 ] + 6 Cos [ t ] + s Cos [ 3 t 2 ] ) Sin [ t 2 ] , 1 4 ( s 6 Cos [ t 2 ] 2 s Cos [ t ] + 6 Cos [ 3 t 2 ] + s Cos [ 2 t ] ) , Cos [ t 2 ] ( 3 + s Cos [ t 2 ] ) } Image

Sqrt [ rscrossrt . rscrossrt ] // FullSimplify Image

9 + 3 s 2 4 + 6 s Cos [ t 2 ] + 1 2 s 2 Cos [ t ] Image

Clear [ un ] Image

un [ s _ , t _ ] = Image

rscrossrt / Sqrt [ rscrossrt . rscrossrt ] // FullSimplify Image

{ 2 Sin [ t 2 ] ( 3 Cos [ t ] + s Sin [ t 2 ] Sin [ t ] ) 36 + 3 s 2 + 24 s Cos [ t 2 ] + 2 s 2 Cos [ t ] , 3 Cos [ t 2 ] 3 Cos [ 3 t 2 ] + s ( Cos [ t ] + Sin [ t ] 2 ) 36 + 3 s 2 + 24 s Cos [ t 2 ] + 2 s 2 Cos [ t ] , s + 6 Cos [ t 2 ] + s Cos [ t ] 36 + 3 s 2 + 24 s Cos [ t 2 ] + 2 s 2 Cos [ t ] } Image

Consider the path C given by r(0,t)Image, πtπImage that begins and ends at <3,0,0>Image. On C, n(0,t)Image is given by

un [ 0 , t ] Image

{ Cos [ t ] Sin [ t 2 ] , 1 6 ( 3 Cos [ t 2 ] + 3 Cos [ 3 t 2 ] ) , Cos [ t 2 ] } Image

At t=πImage, n(0,π)=<1,0,0>Image, while at t=πImage, n(0,π)=<1,0,0>Image.

r [ 0 , Pi ] Image

r [ 0 , Pi ] Image

{ 3 , 0 , 0 } Image

{ 3 , 0 , 0 } Image

As n moves along C from r(0,π)Image to r(0,π)Image, the orientation of n reverses, as shown in Fig. 5.18.

Image
Figure 5.18 Parametric plot of equations (5.22) if c = 3.

l1 = Table [ r [ 0 , t ] , { t , Pi , Pi , 2 Pi / 179 } ] ; Image

threedp2 = Show [ Graphics3D [ { Thickness [ . 02 ] , Image

CMYKColor [ . 3 , . 2 , . 17 , . 57 ] , Line [ l1 ] } ] , Axes - > Automatic , Image

PlotRange - > { { 4 , 4 } , { 4 , 4 } , { 1 , 1 } } , Image

BoxRatios->{4,4,1},AspectRatio->1];Image

vecs = Table [ Arrow [ { r [ 0 , t ] , r [ 0 , t ] + un [ 0 , t ] } ] , { t , π , π , 2 π 59 } ] ; Image

pp2 = Show [ Graphics3D [ vecs ] ] ; Image

Show [ threedp2 , pp2 , ViewPoint Image

{ 2.093 , 2.124 , 1.600 } , AxesLabel - > { x , y , z } , Image

Boxed - > False ] Image

Several different views of Fig. 5.18 on the Möbius strip shown in Fig. 5.17 are shown in Fig. 5.19. C is an orientation reversing path and we can conclude that the Möbius strip is not orientable.

Image
Figure 5.19 Different views of a Möbius strip with an orientation reversing path.

An animation is particularly striking.

g1 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 2.729 , 0.000 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

g2 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

g3 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

g4 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 2.729 , 0.000 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

g5 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

g6 = Show [ threedp1 , threedp2 , pp2 , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } , Image

AxesLabel - > { x , y , z } , Boxed - > False ] ; Image

Show [ GraphicsGrid [ { { g1 , g2 } , { g3 , g4 } , { g5 , g6 } } ] ] Image

Example 5.46

The Klein bottle is an interesting surface with neither an inside nor an outside, which indicates to us that it is not orientable. In Fig. 5.20 (a) we show the “usual” immersion of the Klein bottle. Although the Klein bottle does not intersect itself, it is not possible to visualize it in Euclidean 3-space without it doing so. Visualizations of 2-manifolds like the Klein bottle's “usual” rendering in Euclidean 3-space are called immersions. (See [14] for a nontechnical discussion of immersions.)

Image
Figure 5.20 Two different immersions of the Klein bottle: (a) the “usual” immersion; (b) the Figure-8 immersion (Louisiana State University colors).

r = 4 ( 1 1 / 2 Cos [ u ] ) ; Image

x1 [ u _ , v _ ] = 6 ( 1 + Sin [ u ] ) Cos [ u ] + r Cos [ u ] Cos [ v ] ; Image

x2 [ u _ , v _ ] = 6 ( 1 + Sin [ u ] ) Cos [ u ] + r Cos [ v + Pi ] ; Image

y1 [ u _ , v _ ] = 16 Sin [ u ] + r Sin [ u ] Cos [ v ] ; Image

y2 [ u _ , v _ ] = 16 Sin [ u ] ; Image

z [ u _ , v _ ] = r Sin [ v ] ; Image

kb1a = ParametricPlot3D [ { x1 [ s , t ] , y1 [ s , t ] , z [ s , t ] } , Image

{ s , 0 , Pi } , { t , 0 , 2 Pi } , PlotPoints - > { 30 , 30 } , Image

AspectRatio - > 1 , AxesLabel - > { x , y , z } , Image

Mesh False , PlotStyle { { CMYKColor [ 0 , . 19 , . 89 , 0 ] , Opacity [ . 8 ] } } ] ; Image

kb1b = ParametricPlot3D [ { x1 [ s , t ] , y1 [ s , t ] , z [ s , t ] } , Image

{ s , Pi , 2 Pi } , { t , 0 , 2 Pi } , PlotPoints - > { 30 , 30 } , Image

AspectRatio - > 1 , AxesLabel - > { x , y , z } , Image

Mesh False , PlotStyle { { CMYKColor [ 0 , . 19 , . 89 , 0 ] , Opacity [ . 8 ] } } ] Image

kb1 = Show [ kb1a , kb1b , PlotRange { { 20 , 20 } , { 20 , 20 } , { 20 , 20 } } ] Image

Fig. 5.20 (b) shows the Figure-8 immersion of the Klein bottle. Notice that it is not easy to see that the Klein bottle has neither an inside nor an outside in Fig. 5.14.

a = 3 ; Image

x [ u _ , v _ ] = ( a + Cos [ u / 2 ] Sin [ v ] Sin [ u / 2 ] Sin [ 2 v ] ) Cos [ u ] ; Image

y [ u _ , v _ ] = ( a + Cos [ u / 2 ] Sin [ v ] Sin [ u / 2 ] Sin [ 2 v ] ) Sin [ u ] ; Image

z [ u _ , v _ ] = Sin [ u / 2 ] Sin [ v ] + Cos [ u / 2 ] Sin [ 2 v ] ; Image

r [ u _ , v _ ] = { x [ u , v ] , y [ u , v ] , z [ u , v ] } ; Image

ParametricPlot3D [ r [ t , t ] , { t , 0 , 2 Pi } ] Image

kb2 = ParametricPlot3D [ r [ s , t ] , { s , Pi , Pi } , { t , Pi , Pi } , Image

PlotPoints - > { 30 , 30 } , AspectRatio - > 1 , Image

AxesLabel - > { x , y , z } , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 2 , 2 } } , BoxRatios - > { 4 , 4 , 1 } , Mesh False , Image

PlotStyle { { CMYKColor [ . 82 , . 98 , 0 , . 12 ] , Opacity [ . 4 ] } } ] Image

Show [ GraphicsRow [ { kb1 , kb2 } ] ] Image

In fact, to many readers it may not be clear whether the Klein bottle is orientable or nonorientable, especially when we compare the graph to the graphs of the Möbius strip and torus in the previous examples.

A parametrization of the Figure-8 immersion of the Klein bottle (see [17]) is r(s,t)=x(s,t)i+y(s,t)j+z(s,t)kImage, πsπImage, πtπImage, where

x = [ c + cos ( 1 2 s ) sin t sin ( 1 2 s ) sin 2 t ] cos s , y = [ c + cos ( 1 2 s ) sin t sin ( 1 2 s ) sin 2 t ] sin s , and z = sin ( 1 2 s ) sin t + cos ( 1 2 s ) sin 2 t .

The plot in Fig. 5.20 (b) uses equation (5.23) if c=3Image.

Using (5.21), let

n = r s × r t r s × r t .

Let C be the path given by

r ( t , t ) = x ( t , t ) i + y ( t , t ) j + z ( t , t ) k , π t π

that begins and ends at r(π,π)=r(π,π)=<3,0,0>Image and where the components are given by (5.23). The components of r and n are computed with Mathematica. The final calculations are quite lengthy so we suppress the output of the last few by placing a semicolon (;) at the end of those commands.

rs=D[r[s,t],s]//SimplifyImage

{ 1 2 Cos [ s ] ( Sin [ s 2 ] Sin [ t ] + Cos [ s 2 ] Sin [ 2 t ] ) + Sin [ s ] ( 3 Cos [ s 2 ] Sin [ t ] + Sin [ s 2 ] Sin [ 2 t ] ) , 1 2 Sin [ s ] ( Sin [ s 2 ] Sin [ t ] + Cos [ s 2 ] Sin [ 2 t ] ) + Cos [ s ] ( 3 + Cos [ s 2 ] Sin [ t ] Sin [ s 2 ] Sin [ 2 t ] ) , 1 2 ( Cos [ s 2 ] 2 Cos [ t ] Sin [ s 2 ] ) Sin [ t ] } Image

rt = D [ r [ s , t ] , t ] // Simplify Image

{ Cos [ s ] ( Cos [ s 2 ] Cos [ t ] 2 Cos [ 2 t ] Sin [ s 2 ] ) , ( Cos [ s 2 ] Cos [ t ] 2 Cos [ 2 t ] Sin [ s 2 ] ) Sin [ s ] , 2 Cos [ s 2 ] Cos [ 2 t ] + Cos [ t ] Sin [ s 2 ] } Image

rscrossrt = Cross [ rs , rt ] ; Image

normcross = Sqrt [ rscrossrt . rscrossrt ] ; Image

Clear [ un ] Image

un [ s _ , t _ ] = rscrossrt / Sqrt [ rscrossrt . rscrossrt ] ; Image

At t=πImage, n(π,π)=<15,0,25>Image, while at t=πImage, n(π,π)=<15,0,25>Image so as n moves along C from r(π,π)Image to r(π,π)Image, the orientation of n reverses. Several different views of the orientation reversing path on the Klein bottle shown in Fig. 5.20 (b) are shown in Fig. 5.21.

Image
Figure 5.21 Different views of the Figure-8 immersion of the Klein bottle with an orientation reversing path.

l1 = Table [ r [ s , s ] , { s , Pi , Pi , 2 Pi / 179 } ] ; Image

threedp2 = Show [ Graphics3D [ { Thickness [ . 02 ] , Image

GrayLevel [ . 6 ] , Line [ l1 ] } ] , Axes - > Automatic , Image

PlotRange - > { { 4 , 4 } , { 4 , 4 } , { 4 , 4 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AspectRatio - > 1 ] ; Image

vecs = Table [ Arrow [ { { r [ s , s ] , r [ s , s ] + un [ s , s ] } } ] , { s , π , π , 2 π 59 } ] ; Image

pp2 = Show [ Graphics3D [ vecs ] ] ; Image

pp3 = Show [ threedp2 , pp2 , Image

AxesLabel - > { x , y , z } , Image

Boxed - > False , PlotRange { { 5 , 5 } , Image

{ 5 , 5 } , { 5 , 5 } } ] Image

g1 = Show [ kb2 , threedp2 , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint->{2.729,0.000,2.000}]Image

g2 = Show [ kb2 , threedp2 , pp2 , Image

AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , Image

AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] Image

g3 = Show [ kb2 , threedp2 , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 6 , 6 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] Image

g4 = Show [ kb2 , threedp2 , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 6 , 6 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 2.729 , 0.000 , 2.000 } ] Image

g5 = Show [ kb2 , pp2 , AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 6 , 6 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] Image

g6 = Show [ kb2 , pp3 , AspectRatio - > 1 , Image

PlotRange - > { { 6 , 6 } , { 6 , 6 } , { 2 , 2 } } , Image

BoxRatios - > { 4 , 4 , 1 } , AxesLabel - > { x , y , z } , Image

ViewPoint - > { 1.365 , 2.364 , 2.000 } ] Image

Show [ GraphicsGrid [ { { g1 , g2 } , { g3 , g4 } , { g5 , g6 } } ] ] Image

C is an orientation reversing path and we can conclude that the Klein bottle is not orientable.

5.5.5 More on Tangents, Normals, and Curvature in R3Image

Earlier, we discussed the unit tangent and normal vectors and curvature for a vector-valued function γ:(a,b)R2Image. These concepts can be extended to curves and surfaces in space.

These concepts are presented beautifully and extensively for the Mathematica user in Modern Differential Geometry of Curves and Surfaces with Mathematica, Third Edition, CRC Press, 2006, by Alfred Gray, Simon Salamon, and Elsa Abbena. Our treatment just touches on a few of the topics discussed by Gray et al. and updates some of their wonderful and elegant work to Mathematica 11.

For γ:(a,b)R3Image, the Frenet frame field is the ordered triple {T,N,B}Image, where T is the unit tangent vector field, N is the unit normal vector field, and B is the unit binormal vector field. Each of these vectors has norm 1 and each is orthogonal to the other (the dot product of one with another is 0) and the Frenet formulas are satisfied: T=κNImage, N=κT+τBImage, B=τNImage. τ is the torsion of the curve γ; κ is the curvature. For the curve γ:(a,b)R3Image, formulas for these quantities are given by:

T = γ γ , N = B × T , B = γ × γ γ × γ , κ = γ × γ γ 3 , τ = γ × γ γ γ × γ 2 .

For many good reasons, sometimes the “Frenet formulas” are also called the “Frenet-Serret formulas.”

We adjust Gray's routines slightly for Mathematica 11. Here is the unit tangent vector,

tangent [ α _ ] [ t _ ] := D [ α [ tt ] , tt ] / FullSimplify [ Norm [ D [ α [ tt ] , tt ] ] , Image

AssumptionsttReals]/.tttImage

Similarly, the binormal is defined with

binormal [ α _ ] [ t _ ] := FullSimplify [ Image

Cross [ D [ α [ tt ] , tt ] , D [ α [ tt ] , { tt , 2 } ] ] ] / Image

FullSimplify [ Norm [ Cross [ D [ α [ tt ] , tt ] , D [ α [ tt ] , { tt , 2 } ] ] ] , Image

Assumptions tt Reals ] /. tt t Image

so the unit normal is defined with

normal [ α _ ] [ t _ ] := Cross [ binormal [ α ] [ t ] , tangent [ α ] [ t ] ] ; Image

Notice how we use Assumptions to instruct Mathematica to assume that the domain of γ consists of real numbers. In the same manner, we define the curvature and torsion.

curve2 [ α _ ] [ t _ ] := Simplify [ Norm [ Cross [ D [ α [ tt ] , tt ] , Image

D [ α [ tt ] , { tt , 2 } ] ] ] / Image

Norm [ D [ α [ tt ] , tt ] ] 3 , Image

Assumptions tt Reals ] /. tt t ; Image

torsion2 [ α _ ] [ t _ ] := Simplify [ Cross [ D [ α [ tt ] , tt ] , Image

D [ α [ tt ] , { tt , 2 } ] ] . D [ α [ tt ] , { tt , 3 } ] / Image

Norm [ Cross [ D [ α [ tt ] , tt ] , D [ α [ tt ] , { tt , 2 } ] ] ] 2 , Image

Assumptions tt Reals ] /. tt t ; Image

In even the simplest situations, these calculations are quite complicated. Graphically seeing the results may be more meaningful that the explicit formulas.

Example 5.47

Consider the spherical spiral given by γ(t)=<8cos3tcos2t,8sin3tcos2t,8sin2t>Image. The curvature and torsion for the curve are graphed with Plot and shown in Fig. 5.22.

Image
Figure 5.22 The curvature and torsion for a spherical spiral (University of Tennessee colors).

γ [ t _ ] = { 8 Cos [ 3 t ] Cos [ 2 t ] , 8 Sin [ 3 t ] Cos [ 2 t ] , 8 Sin [ 2 t ] } Image

{ 8 Cos [ 2 t ] Cos [ 3 t ] , 8 Cos [ 2 t ] Sin [ 3 t ] , 8 Sin [ 2 t ] } Image

Plot [ Tooltip [ { curve2 [ γ ] [ t ] , torsion2 [ γ ] [ t ] } ] , { t , 0 , 2 Pi } , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ 0 , . 5 , 1 , 0 ] } , Image

{ Thickness [ . 01 ] , CMYKColor [ 0 , 0 , 0 , . 6 ] } } ] Image

We now compute T, B, and N. For length considerations, we display an abbreviated portion of B with Short.

tangent [ γ ] [ t ] Image

binormal [ γ ] [ t ] Image

normal [ γ ] [ t ] // Short Image

{ 16 Cos [ 3 t ] Sin [ 2 t ] 24 Cos [ 2 t ] Sin [ 3 t ] 4 34 + 18 Cos [ 4 t ] , 24 Cos [ 2 t ] Cos [ 3 t ] 16 Sin [ 2 t ] Sin [ 3 t ] 4 34 + 18 Cos [ 4 t ] , 4 Cos [ 2 t ] 34 + 18 Cos [ 4 t ] } Image

{ 2 ( 3 Sin [ t ] + 34 Sin [ 3 t ] + 15 Sin [ 7 t ] ) 21886 + 12456 Cos [ 4 t ] + 810 Cos [ 8 t ] , 2 ( 3 Cos [ t ] + 34 Cos [ 3 t ] + 15 Cos [ 7 t ] ) 21886 + 12456 Cos [ 4 t ] + 810 Cos [ 8 t ] , 6 ( 21 + 5 Cos [ 4 t ] ) 21886 + 12456 Cos [ 4 t ] + 810 Cos [ 8 t ] } Image

{ 8 + 60 2 Sin [ 3 t ] 17 + 9 1 1 , 1 , 1 } Image

It is difficult to see how these complicated formulas relate to this spherical spiral. To help us understand what they mean, we first plot the spiral with ParametricPlot3D. See Fig. 5.23 (a).

Image
Figure 5.23 (a) The spherical spiral. (b) Various T, N, and B for the spherical spiral. (c) The spherical spiral with various T, N, and B shown together.

p1 = ParametricPlot3D [ γ [ t ] , { t , 0 , 2 Pi } , Image

PlotRange { { 8.5 , 8.5 } , { 8.5 , 8.5 } , { 8.5 , 8.5 } } , Image

PlotStyle { { CMYKColor [ 0 , . 5 , 1 , 0 ] , Thick } } ] Image

Next, we use Table to compute lists of two ordered triples. For each list, the first ordered triple consists of γ(t)Image and the second the value of the sum of γ(t)Image and T(γ(t))Image (B(γ(t))Image, N(γ(t))Image). These ordered triples that correspond to vectors are plotted with Arrow together with Show and Graphics3D.

ts = Table [ Arrow [ { { γ [ t ] , γ [ t ] + tangent [ γ ] [ t ] } } // N ] , { t , 0 , 2 Pi , 2 Pi / 99 } ] ; Image

bs = Table [ Arrow [ { { γ [ t ] , γ [ t ] + binormal [ γ ] [ t ] } } // N ] , { t , 0 , 2 Pi , 2 Pi / 99 } ] ; Image

ns = Table [ Arrow [ { { γ [ t ] , γ [ t ] + normal [ γ ] [ t ] } } // N ] , { t , 0 , 2 Pi , 2 Pi / 99 } ] ; Image

ysplot = Show [ Graphics3D [ ts ] ] ; Image

bsplot = Show [ Graphics3D [ bs ] ] ; Image

nsplot = Show [ Graphics3D [ ns ] ] ; Image

p2=Show[ysplot,bsplot,nsplot]Image

For a nice view of p1 and p2, display them together with Show. See Fig. 5.23 (c).

Show [ p1 , p2 ] Image

Show [ GraphicsRow [ { p1 , p2 , Show [ p1 , p2 ] } ] ] Image

The previous example illustrates that capturing the depth of three-dimensional curves by projections into two dimensions can be difficult. Sometimes taking advantage of three-dimensional surface plots can help. For a basic space curve, tubecurve places a “tube” of radius r around the space curve.

Clear [ tubecurve , γ , r ] Image

tubecurve [ γ _ ] [ r _ ] [ t _ , θ _ ] = γ [ t ] + Image

r ( Cos [ θ ] normal [ γ ] [ t ] + Sin [ θ ] binormal [ γ ] [ t ] ) ; Image

To illustrate the utility, we redefine torusknot that was presented in Chapter 2.

The results displayed in the text are in black-and-white and do not reflect the stunning color images generated by these commands.

torusknot [ a _ , b _ , c _ ] [ p _ , q _ ] [ t _ ] := Image

{ ( a + b Cos [ q t ] ) Cos [ p t ] , ( a + b Cos [ q t ] ) Sin [ p t ] , Image

c Sin [ q t ] } Image

Example 5.48

For the knot torusknot}[8,3,5][2,5] we plot the curvature and torsion with Plot in Fig. 5.24.

Image
Figure 5.24 The curvature and torsion for the torus knot, torusknot[8,3,5][2,5].

Plot [ Tooltip [ { curve2 [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ t ] , Image

torsion2 [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ t ] } ] , { t , 0 , 3 Pi } , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ 0 , . 5 , 1 , 0 ] } , Image

{ Thickness [ . 01 ] , CMYKColor [ 0 , 0 , 0 , . 6 ] } } ] Image

We generate a basic plot of this torus knot in 3-space with ParametricPlot3D. See Fig. 5.25 (a).

Image
Figure 5.25 (a) A basic plot of a curve in 3-space. (b) Placing a “tube” around the curve.

ParametricPlot3D [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] , { t , 0 , 3 Pi } , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ 0 , . 5 , 1 , 0 ] } } ] Image

Using tubecurve, we place a “tube” around the knot. See Fig. 5.25 (b).

p1 = ParametricPlot3D [ tubecurve [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ 1.3 ] [ t , θ ] , Image

{ t , 0 , 2 Pi } , { θ , 0 , 2 Pi } , Mesh False , Image

PlotStyle { { CMYKColor [ 0 , . 5 , 1 , 0 ] , Opacity [ . 5 ] } } , Image

PlotPoints { 40 , 40 } ] Image

A more interesting graphic is obtained by placing a transparent tube around the curve

p1b = ParametricPlot3D [ tubecurve [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ 1 ] [ t , θ ] , Image

{ t , 0 , 2 Pi } , { θ , 0 , 2 Pi } , Mesh False , Image

PlotStyle { { CMYKColor [ 0 , . 5 , 1 , 0 ] , Opacity [ . 3 ] } } , Image

PlotPoints { 40 , 40 } ] Image

and then creating a thicker version of the curve.

p2 = ParametricPlot3D [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] , { t , 0 , 3 Pi } , Image

PlotStyle{{Thickness[.01],CMYKColor[0,.5,1,0]}}]Image

As before, we use tangent, normal, and binormal to create a vector field on the curve.

ts = Table [ Arrow [ { { torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] , Image

torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] + tangent [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ t ] } } // N ] , Image

{ t , 0 , 3 Pi , 3 Pi / 99 } ] ; Image

bs = Table [ Arrow [ { { torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] , Image

torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] + binormal [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ t ] } } // N ] , Image

{ t , 0 , 3 Pi , 3 Pi / 99 } ] ; Image

ns = Table [ Arrow [ { { torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] , Image

torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] [ t ] + normal [ torusknot [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ t ] } } // N ] , Image

{ t , 0 , 3 Pi , 3 Pi / 99 } ] ; Image

A striking graph is generated by showing the three graphs together. See Fig. 5.26

Image
Figure 5.26 The torus knot, torusknot[8,3,5][2,5], with its Frenet field.

ysplot = Show [ Graphics3D [ { Arrowheads [ . 025 ] , ts } ] ] ; Image

bsplot = Show [ Graphics3D [ { Arrowheads [ . 025 ] , bs } ] ] ; Image

nsplot = Show [ Graphics3D [ { Arrowheads [ . 025 ] , ns } ] ] ; Image

p3 = Show [ ysplot , bsplot , nsplot ] Image

Show [ p2 , p1b , p3 ] Image

Alternatively, display the results as an array with GraphicsGrid. See Fig. 5.27.

Image
Figure 5.27 (a) A “tubed” knot. (b) A thick knot. (c) A knot within a tube around it. (d) A knot within a tube illustrating the Frenet field.

Show [ GraphicsGrid [ { { p1 , p2 } , { Show [ p2 , p1b ] , Show [ p2 , p1b , p3 ] } } ] ] Image

Example 5.49

The Trefoil knot is the special case of torusknot[8,3,5][2,3]][t]. We use Plot to graph its curvature and torsion in Fig. 5.28. Because we have used Tooltip, you can identify each plot by moving the cursor over the curve in Fig. 5.28.

Image
Figure 5.28 The curvature and torsion for the Trefoil knot (University of Alaska colors).

Plot [ Tooltip [ { curve2 [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] ] [ t ] , Image

torsion2 [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] ] [ t ] } ] , { t , 0 , 2 Pi } , PlotRange All , Image

PlotStyle { { Thickness [ . 01 ] , CMYKColor [ . 98 , 0 , . 72 , . 61 ] } , Image

{ Thickness [ . 01 ] , CMYKColor [ 0 , . 24 , . 94 , 0 ] } } ] Image

Next, we generate a thickened version of the Trefoil knot.

p1 = ParametricPlot3D [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] [ t ] , { t , 0 , 2 Pi } , Image

PlotStyle{Thickness[.01],CMYKColor[.98,0,.72,.61]}]Image

Three different tube plots of the Trefoil knot are generated. In p2, the result is a basic plot. In p2b, The plot is shaded according to the Rainbow color gradient. In p2c, the plot is shaded according to the knots curvature. The knot together with the three surfaces are shown together in Fig. 5.29.

Image
Figure 5.29 (a) The Trefoil knot with a tube around it; (b) and (c) Changing the color of the tube.

p2 = ParametricPlot3D [ tubecurve [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] ] [ 1.3 ] [ t , θ ] , Image

{ t , 0 , 2 Pi } , { θ , 0 , 2 Pi } , Mesh False , Image

PlotStyle { { CMYKColor [ . 98 , 0 , . 72 , . 61 ] , Opacity [ . 5 ] } } , Image

PlotPoints { 40 , 40 } ] Image

p2b = ParametricPlot3D [ tubecurve [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] ] [ 1.3 ] [ t , θ ] , { t , 0 , 2 Pi } , { θ , 0 , 2 Pi } , Mesh False , PlotPoints { 40 , 40 } , PlotStyle - > { { CMYKColor [ . 70 , . 14 , . 59 , . 01 ] , Opacity [ . 5 ] } } ] Image

p2c = ParametricPlot3D [ tubecurve [ torusknot [ 8 , 3 , 5 ] [ 2 , 3 ] ] [ 1.3 ] [ t , θ ] , Image

{ t , 0 , 2 Pi } , { θ , 0 , 2 Pi } , Mesh False , Image

PlotStyle - > { { CMYKColor [ 0 , . 6 , 1 , 0 ] , Opacity [ . 5 ] } } , Image

PlotPoints { 40 , 40 } ] Image

ba1 = Show [ p2 , p1 , Boxed False , Axes None ] Image

ba2 = Show [ p2b , p1 , Boxed False , Axes None ] Image

ba3 = Show [ p2c , p1 , Boxed False , Axes None ] Image

Show [ GraphicsRow [ { ba1 , ba2 , ba3 } ] ] Image

For surfaces in R3Image, extending and stating these definitions precisely becomes even more complicated. First, define the vector triple product (xyz), where x=(x1x2x3)Image, y=(y1y2y3)Image, and z=(z1z2z3)Image, by (xyz)=|x1x2x3y1y2y3z1z2z3|Image. We assume that γ=γ(u,v)Image is a vector-valued function with domain contained in a “nice” region UR2Image and range in R3Image. The Gaussian curvature, KImage, and the mean curvature, HImage, under reasonable conditions, are given by the formulas

K = ( γ u u γ u γ v ) ( γ v v γ u γ v ) ( γ u v γ u γ v ) 2 ( γ u 2 γ v 2 ( γ u γ v ) 2 ) 2 and H = ( γ u u γ u γ v ) γ v 2 2 ( γ u v γ u γ v ) ( γ u γ v ) + ( γ v v γ u γ v ) γ u 2 2 ( γ u 2 γ v 2 ( γ u γ v ) 2 ) 3 / 2 .

For the parametrically defined surface γ=γ(u,v)Image, the unit normal field, U, is U=γu×γvγu×γvImage. Observe that the expressions that result from explicitly computing U, KImage, and HImage are almost always so complicated that they are impossible to understand.

After defining vtp to return the vector triple product of three vectors, we define gaussianc and meanc to compute KImage and HImage for a parametrically defined surface γ(u,v)=<x(u,v),y(u,v),z(u,v)>Image.

vtp [ x _ , y _ , z _ ] := Det [ { { x [ [ 1 ] ] , x [ [ 2 ] ] , x [ [ 3 ] ] } , Image

{ y [ [ 1 ] ] , y [ [ 2 ] ] , y [ [ 3 ] ] } , { z [ [ 1 ] ] , z [ [ 2 ] ] , z [ [ 3 ] ] } } ] Image

gaussianc [ γ _ ] [ u _ , v _ ] := Image

Module [ { lu , lv , vtp } , Image

vtp [ x _ , y _ , z _ ] := Det [ { { x [ [ 1 ] ] , x [ [ 2 ] ] , x [ [ 3 ] ] } , Image

{ y [ [ 1 ] ] , y [ [ 2 ] ] , y [ [ 3 ] ] } , { z [ [ 1 ] ] , z [ [ 2 ] ] , z [ [ 3 ] ] } } ] ; Image

( vtp [ D [ γ [ lu , lv ] , { lu , 2 } ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] Image

vtp [ D [ γ [ lu , lv ] , { lv , 2 } ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] Image

vtp [ D [ γ [ lu , lv ] , lu , lv ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] 2 ) / Image

( Norm [ D [ γ [ lu , lv ] , lu ] ] 2 Norm [ D [ γ [ lu , lv ] , lv ] ] 2 Image

( D [ γ [ lu , lv ] , lu ] . D [ γ [ lu , lv ] , lv ] ) 2 ) 2 /. Image

{ lu u , lv v } // PowerExpand // Simplify Image

]

meanc [ γ _ ] [ u _ , v _ ] := Image

Module [ { lu , lv , vtp } , Image

vtp [ x _ , y _ , z _ ] := Det [ { { x [ [ 1 ] ] , x [ [ 2 ] ] , x [ [ 3 ] ] } , Image

{ y [ [ 1 ] ] , y [ [ 2 ] ] , y [ [ 3 ] ] } , { z [ [ 1 ] ] , z [ [ 2 ] ] , z [ [ 3 ] ] } } ] ; Image

( vtp [ D [ γ [ lu , lv ] , { lu , 2 } ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] Image

Norm [ D [ γ [ lu , lv ] , lv ] ] 2 Image

2 vtp [ D [ γ [ lu , lv ] , lu , lv ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] Image

( D [ γ [ lu , lv ] , lu ] . D [ γ [ lu , lv ] , lv ] ) + Image

vtp [ D [ γ [ lu , lv ] , { lv , 2 } ] , D [ γ [ lu , lv ] , lu ] , D [ γ [ lu , lv ] , lv ] ] Image

Norm [ D [ γ [ lu , lv ] , lu ] ] 2 ) / Image

( 2 ( Norm [ D [ γ [ lu , lv ] , lu ] ] 2 Norm [ D [ γ [ lu , lv ] , lv ] ] 2 Image

( D [ γ [ lu , lv ] , lu ] . D [ γ [ lu , lv ] , lv ] ) 2 ) ( 3 / 2 ) ) /. Image

{ lu u , lv v } // PowerExpand // Simplify Image

]

Example 5.50

We illustrate the commands with the torus, first discussed in Chapter 2, and ParametricPlot3D. For convenience, we redefine torus.

torus [ a _ , b _ , c _ ] [ p _ , q _ ] [ u _ , v _ ] := { ( a + b Cos [ u ] ) Image

Cos [ v ] , ( a + b Cos [ u ] ) Sin [ v ] , c Sin [ u ] } Image

In pp1, we generate a basic plot of the torus. The shading is changed in pp2. In pp3 the surface is shaded according to its Gaussian curvature while in pp4 the surface is shaded according to its mean curvature. All four plots are shown together in Fig. 5.30.

Image
Figure 5.30 (a) A basic torus. (b) Changing the coloring of the torus. (c) Shading according to Gaussian curvature. (d) Shading according to mean curvature.

pp1 = ParametricPlot3D [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] [ u , v ] , { u , 0 , 2 Pi } , Image

{ v , 0 , 2 Pi } ] Image

pp1 = ParametricPlot3D [ Evaluate [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] [ u , v ] ] , { u , 0 , 2 Pi } , Image

{v,0,2Pi},PlotPoints60]Image

pp2 = ParametricPlot3D [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] [ u , v ] , Image

{ u , 0 , 2 Pi } , { v , 0 , 2 Pi } , Mesh False , PlotStyle Opacity [ . 75 ] , Image

PlotPoints { 25 , 25 } , ColorFunction Image

ColorData [ “MintColors” ] ] Image

pp3 = ParametricPlot3D [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] [ u , v ] , Image

{ u , 0 , 2 Pi } , { v , 0 , 2 Pi } , Mesh False , PlotStyle Opacity [ . 5 ] , Image

PlotPoints { 25 , 25 } , ColorFunction Image

( ColorData [ “MintColors” ] [ gaussianc [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ # 1 , # 2 ] // N // Image

Chop ] & ) ] Image

pp4 = ParametricPlot3D [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] [ u , v ] , Image

{ u , 0 , 2 Pi } , { v , 0 , 2 Pi } , Mesh False , PlotStyle Opacity [ . 5 ] , Image

PlotPoints { 25 , 25 } , ColorFunction Image

( ColorData [ “MintColors” ] [ meanc [ torus [ 8 , 3 , 5 ] [ 2 , 5 ] ] [ # 1 , # 2 ] // N // Chop ] & ) ] Image

Show [ GraphicsGrid [ { { pp1 , pp2 } , { pp3 , pp4 } } ] ] Image

5.6 Matrices and Graphics

5.6.1 Manipulating Photographs with Built-In Functions

As introduced in Chapter 2, Mathematica contains a wide range of functions that allow you to manipulate images such as photographs quickly to achieve a variety of photographic effects.

To import a photograph or other image into Mathematica, use Import. Generally, the object that is to be imported should be in your root directory. However, Mathematica supports clicking and dragging: you can simply click on the file and drag it to the desired location in your Mathematica notebook.

For “standard” effects and manipulation of photographs, try using ImageEffect first. ImageEffect is fast and has a wide range of options. We illustrate just a few here. First, we import a graphic,

p1 = Import [ “1000182.jpg” ] ; Image

Show [ p1 , ImageSize Small ] Image

Image

Next, we use ImageEffect to apply a variety of commonly used enhancements to the image, p1. The results are shown in Fig. 5.31.

Image
Figure 5.31 Using ImageEffect with the Charcoal, Comics, SaltPepperNoise, and Embossing options.

p1a = ImageEffect [ p1 , { “Charcoal” , 2 } ] ; Image

p1b = ImageEffect [ p1 , { “Comics” , { . 25 , . 5 } } ] ; Image

p1c = ImageEffect [ p1 , { “SaltPepperNoise” , . 2 } ] ; Image

p1d = ImageEffect [ p1 , { “Embossing” , 4 , 0 } ] ; Image

Show [ GraphicsGrid [ { { p1a , p1b } , { p1c , p1d } } ] ] Image

Once you have imported an image either using Import or by selecting and dragging the image into the desired location in your Mathematica notebook, Mathematica gives you a wide range of functions to obtain information about the image.

p1 = Import [ “IMG5209.jpg” ] ; Image

Show [ p1 , ImageSize Small ] Image

Image

To determine the size of your image, number of pixel columns by number of pixel rows, use ImageDimensions.

ImageDimensions [ p1 ] Image

{640,640}Image

Here, we illustrate ImageAdjust with a few of its options (see Fig. 5.32).

Image
Figure 5.32 Using ImageAdjust with the LaplacianGaussianFilter and ColorQuantize options.

p2a = ImageAdjust [ p1 , { 1 , 1 } ] ; p2b = ImageAdjust [ LaplacianGaussianFilter [ p1 , 5 ] ] ; Image

p2c = ImageAdjust [ p1 , { 0 . , 3.7 , 2.7 } ] ; Image

p2d = ImageAdjust [ ColorQuantize [ p1 , 5 ] , { . 15 , . 75 } ] ; Image

Show [ GraphicsGrid [ { { p2a , p2b } , { p2c , p2d } } ] ] Image

ColorQuantize[image,n] approximates image with n colors. To see the resulting colors, use DominantColors. Observe that the colors are displayed in small squares.

dcp2a = DominantColors [ p2a ] Image

Image

To see the RGB code, click on the color or use InputForm to see the actual color codes displayed as a list.

InputForm [ dcp2a ] Image

{ RGBColor [ 0.9993332719608886 , 0.9983786009836767 , 0.9976452825923762 ] , RGBColor [ 0.010466076648957105 , 0.004068849634045346 , 0.004172871274537774 ] , RGBColor [ 0.4284221221669545 , 0.531302194561179 , 0.06417935218806642 ] , RGBColor [ 0.9885278855002001 , 0.9959965192142667 , 0.13330881577073309 ] , RGBColor [ 0.6554690223969046 , 0.47494092958610595 , 0.34335869307359934 ] , RGBColor [ 1 . , 0.4073167704732596 , 0.8661078573314603 ] , RGBColor [ 0.9994877730131592 , 0.17160548964165695 , 0.4709315807968833 ] } Image

ImageApply may give the most flexibility for dealing with a graphic as it allows you to manipulate the graphic pixel-by-pixel. Closely related commands to those discussed include ImageFilter, ImageConvolve, and ImageCorrelate. Use ?<command> to obtain detailed help regarding the capabilities of each (see Fig. 5.33).

Image
Figure 5.33 Illustrating elementary uses of ImageApply.

p1 = Import [ “IMG3065.jpg” ] ; Image

Show [ p1 , ImageSize Small ] Image

p2a = ImageApply [ ( # [ [ 1 ] ] + # [ [ 2 ] ] + # [ [ 3 ] ] ) / 3 & , p1 ] ; Image

p2b = ImageApply [ ( # [ [ 2 ] ] 2 + # [ [ 3 ] ] ) / 2 & , p1 ] ; Image

p2c = ImageApply [ # ( 1 / 3 ) & , p1 ] ; Image

Show [ GraphicsRow [ { p2a , p2b , p2c } ] ] Image

5.6.2 Manipulating Photographs by Viewing Them as a Matrix or Array

With Mathematica, virtually every object is a list or list of lists, including images. In situations where you want to manipulate your image or photograph with more detail than that provided by the built-in Mathematica functions for manipulating Image objects, you may want to manipulate the data that determines the image directly. To do so, it is important to understand that the underlying data of an Image object is generally a matrix. Typically, the entries of the matrix for the image are single digits for black-and-white images or ordered triples of the form {r,g,b} for color jpegs. The easiest way to determine the size of the image is to use ImageDimensions[image]. The resulting list {n,m} indicates that the dimensions of image are n pixels of rows by m pixels of columns.

Mathematica contains several functions that allow you to represent matrices graphically. These commands are analogous to the corresponding ones for dealing with lists (like ListPlot) or functions (such as Plot, Plot3D, and ContourPlot).

1.  MatrixPlot[A] generates a grid with the same dimensions as A. The cells are shaded according to the entries of A. The default is in color.

2.  ArrayPlot[A] generates a grid with the same dimensions as A. The cells are shaded according to the entries of A. The default is in black and white.

3.  ListContourPlot[A] generates a contour plot using the entries of A as the height values.

4.  ReliefPlot[A] generates a relief plot using the entries of A as the height values.

Observe that ArrayPlot and MatrixPlot are virtually interchangeable. However, the entries of ArrayPlot need not be numbers. If Mathematica cannot determine how to shade a cell, the default is to shade it in a dark maroon color. Although these functions generate graphics that depend on the entries of the matrix, loosely speaking we will use phrases like “we use MatrixPlot to plot A” and “we use ArrayPlot to graph A” to describe the graphic that results from applying one of these functions to an array.

As the figures in the text are in black and white, refer to the on-line version of the text to see the images in color.

For example, consider the arrays A=(10.3.4.5.1.2.30)Image, B=(10010.1.2.3)Image, and C=((100)(010)(.3.4.5)(.1.2.3))Image.

In the first command, Mathematica shades all the cells according to its GrayLevel value. However, in the second and third commands, Mathematica cannot shade the cells in the second row and all the cells, respectively, because ordered triples cannot be evaluated by GrayLevel. However, RGBColor evaluates ordered triples so Mathematica shades the cells in Fig. 5.34 (c) according to their RGBColor value. See Fig. 5.34.

Image
Figure 5.34 (a) Mathematica shades all cells according to their heights. (b) Mathematica does not know how to shade the cells in the second row. (c) Mathematica cannot shade any of the cells. (d) Mathematica shades all four cells using RGBColor.

ap1 = ArrayPlot [ { { 1 , 0 , . 3 } , { . 4 , . 5 , . 1 } , { . 2 , . 3 , 0 } } ] ; Image

ap2 = ArrayPlot [ { { 1 , 0 } , { { . 3 , . 4 , . 5 } , { . 1 , . 2 , . 3 } } } ] ; Image

ap3 = ArrayPlot [ { { { 1 , 0 , 0 } , { 0 , 1 , 0 } } , { { . 3 , . 4 , . 5 } , Image

{ . 1 , . 2 , . 3 } } } ] ; Image

ap4 = ArrayPlot [ { { { 1 , 0 , 0 } , { 0 , 1 , 0 } } , { { . 3 , . 4 , . 5 } , Image

{ . 1 , . 2 , . 3 } } } , Image

ColorFunction RGBColor ] ; Image

Show [ GraphicsRow [ { ap1 , ap2 , ap3 , ap4 } ] ] Image

MatrixPlot is unable to graphically represent B or C. However, coloring is automatic with MatrixPlot. See Fig. 5.35.

Image
Figure 5.35 By default, MatrixPlot uses a color scheme. Use ColorFunction to change the colors.

mp1 = MatrixPlot [ { { 1 , 0 , . 3 } , { . 4 , . 5 , . 1 } , { . 2 , . 3 , 0 } } ] ; Image

mp2 = MatrixPlot [ { { 1 , 0 , . 3 } , { . 4 , . 5 , . 1 } , { . 2 , . 3 , 0 } } , Image

ColorFunction “PlumColors” ] ; Image

Show [ GraphicsRow [ { mp1 , mp2 } ] ] Image

If you need to adjust the color of a graphic, usually you can use the ColorSchemes palette to select an appropriate gradient or color function. In other situations, you might wish to create your own using Blend. To use Blend, you might need to know how various RGBColors or CMYKColors vary as the variables affecting the color change.

ArrayPlot can help us see the variability in the colors. With the following, we see how RGBColor[r,g,b] affects color for b=0Image, g=0Image, and then r=0Image. The results are shown together in Fig. 5.36. The figure can help us select appropriate values to generate our own color blending function using Blend rather than relying on Mathematica's built-in color schemes and gradients.

Image
Figure 5.36 A comparison of how red, green, and blue affect RGBColor[r,g,b].

In these calculations, t1 is a 256×256Image array for which each entry is an ordered triple. In the first t1, the ordered triple has the form (r,g,0)Image, in the second the form (r,0,b)Image, and so on.

t1 = Table [ { r , g , 0 } // N , { r , 0 , 255 } , { g , 0 , 255 } ] ; Image

redgreen = ArrayPlot [ t1 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { red , green } , Image

LabelStyleMedium,ColorFunctionRGBColor];Image

t2 = Table [ { r , 0 , b } // N , { r , 0 , 255 } , { b , 0 , 255 } ] ; Image

redblue = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { red , blue } , Image

LabelStyle Medium , ColorFunction RGBColor ] ; Image

t2 = Table [ { 0 , g , b } // N , { g , 0 , 255 } , { b , 0 , 255 } ] ; Image

greenblue = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { green , blue } , Image

LabelStyle Medium , ColorFunction RGBColor ] ; Image

s1 = Show [ GraphicsRow [ { redgreen , redblue , greenblue } ] ] Image

We modify the calculation slightly to see how CMYKColor varies as we adjust two parameters. Keep in mind that each t2 is a 256×256Image array. Each entry of t2 is an ordered quadruple, which is illustrated in the first calculation where we use Part to take the 5th element of the 8th part of t2 (see Fig. 5.37).

Image
Figure 5.37 A comparison of how c, m, y, and k affect CMYKColor[c,m,y,k].

t2 = Table [ { c , m , 0 , 0 } // N , { c , 0 , 255 } , { m , 0 , 255 } ] ; Image

t2 [ [ 8 , 5 ] ] Image

{ 7 . , 4 . , 0 . , 0 . } Image

cmplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { c , m } , ColorFunction CMYKColor ] ; Image

t2 = Table [ { c , 0 , y , 0 } // N , { c , 0 , 255 } , { y , 0 , 255 } ] ; Image

cyplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicksAutomatic,FrameLabel{c,y},ColorFunctionCMYKColor];Image

t2 = Table [ { c , 0 , 0 , k } // N , { c , 0 , 255 } , { k , 0 , 255 } ] ; Image

ckplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { c , k } , ColorFunction CMYKColor ] ; Image

t2 = Table [ { 0 , m , y , 0 } // N , { m , 0 , 255 } , { y , 0 , 255 } ] ; Image

myplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { m , y } , ColorFunction CMYKColor ] ; Image

t2 = Table [ { 0 , m , 0 , k } // N , { m , 0 , 255 } , { k , 0 , 255 } ] ; Image

mkplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { m , k } , ColorFunction CMYKColor ] ; Image

t2 = Table [ { 0 , 0 , y , k } // N , { y , 0 , 255 } , { k , 0 , 255 } ] ; Image

ykplot = ArrayPlot [ t2 , Axes Automatic , AxesOrigin { 0 , 0 } , Image

FrameTicks Automatic , FrameLabel { y , k } , ColorFunction CMYKColor ] ; Image

Show [ GraphicsGrid [ { { cmplot , cyplot , ckplot } , { myplot , mkplot , ykplot } } ] ] Image

Keep in mind that you can load files into Mathematica with Import or by clicking and dragging the image to the desired location in your Mathematica notebook. Generally, the underlying structure of the loaded file is relatively easy to understand. Be careful when you import data into Mathematica. We recommend that you use ExampleData to investigate your routines before finalizing them. Although importing external files into Mathematica is easy, understanding the underlying structure of the imported data may take some time but be necessary to produce the results you desire.

We illustrate a few of the subtle differences that can be encountered with several images.

Using Import, we import a graphic into Mathematica. The result is shown in Fig. 5.38 (a).

Image
Figure 5.38 (a) The original. (b) Applying ArrayPlot to the original data points. (c) Reorienting the image. (d) Applying a color function to the data points.

p1 = Import [ “9306COL.jpg” ] ; Image

Show [ p1 , ImageSize Small ] Image

Image

We use ImageDimensions to determine the size of the image.

ImageDimensions [ p1 ] Image

{ 640 , 439 } Image

Alternatively, using Length we see that p2 has 439 rows (pixels)

Length [ p2 ] Image

439

and then counting the number of entries in the first row of p2, we see that p2 has 640 columns (pixels).

Length [ p2 [ [ 1 ] ] ] Image

640

To convert the image to an array (matrix) that we can manipulate, we use ImageData.

p2 = ImageData [ p1 ] ; Image

After we have obtained the image data from p1 in p2, we see that it is a matrix where each entry is a list of the form (r,g,b)Image, corresponding to the RGB color code for that pixel.

Short [ p2 ] Image

{ { { 0.137255 , 20 , 0.160784 } , 638 , 1 } , 437 , { 1 } } Image

ArrayPlot produces the negative of an image. See Fig. 5.38 (a).

g1a = ArrayPlot [ p2 ] Image

To manipulate p2, it is important to understand that p2 is a 2×2Image array where each entry is a 3×1Image list, corresponding to the RGB color codes for that particular pixel.

p2 [ [ 1 ] ] [ [ 2 ] ] Image

{ 0.133333 , 0.0901961 , 0.156863 } Image

Length [ p2 [ [ 1 ] ] ] Image

640

To convert the image to a different color, we first convert the matrix to a list of ordered triples, p3, define f({x,y,z})=(x+y+z)/3Image, apply f to p3, and then apply a color function to the result. In this example, we chose to use the Rainbow color function.

f [ { x _ , y _ , z _ } ] := ( x + y + z ) / 3 ; Image

p3 = Flatten [ p2 , 1 ] ; Image

Take [ p3 , { 1 , 5 } ] Image

p4 = Flatten [ Map [ f , p3 ] ] ; Image

p5 = Partition [ p4 , 640 ] ; Image

{ { 0.137255 , 0.0941176 , 0.160784 } , { 0.133333 , 0.0901961 , 0.156863 } , { 0.121569 , 0.0784314 , 0.145098 } , { 0.113725 , 0.0705882 , 0.137255 } , { 0.113725 , 0.0705882 , 0.137255 } } Image

g2a = ArrayPlot [ p5 , ColorFunction “Rainbow” ] Image

We show the results in Fig. 5.38. On a color printer, the results are amazing.

Show [ GraphicsGrid [ { { p1 , g1a } , { g1b , g2a } } ] ] Image

g2a = ArrayPlot [ Reverse [ p1 [ [ 1 , 1 ] ] ] , ColorFunction "Pastel" ] Image

The results are shown side-by-side in Fig. 5.38. Printed on a color printer, the results are amazing.

Show [ GraphicsRow [ { p1 , g1a , g1b , g2a } ] ] Image

Now that we understand how to manipulate an image, we can be creative. In the following, the image is scaled so that the width of the image is 70 pixels (because of ImageSize->70). We then display the small image with another graphic. Using Inset, we put the Colliseum next to a sine graph that is plotted using the same coloring gradient. See Fig. 5.39.

Image
Figure 5.39 Use Inset to place one graphic within another.

g1 = ArrayPlot [ p5 , ColorFunction “BrightBands” , ImageSize 70 ] ; Image

p2 = Plot [ Sin [ x ] , { x , 0 , 2 Pi } , Epilog - > Inset [ g1 , { 3 Pi / 2 , 1 / 2 } ] , Image

ColorFunction “BrightBands” , PlotStyle Thickness [ . 05 ] ] Image

An alternative way to visualize the data is to use ListContourPlot. To assure that the aspect ratio of the original image is preserved, include the AspectRatio->Automatic option in the ListContourPlot command (see Fig. 5.40).

Image
Figure 5.40 Using ListContourPlot rather than ArrayPlot.

glp1 = ListContourPlot [ p5 // Reverse , AspectRatio Automatic ] ; Image

g1p2 = ListContourPlot [ p5 // Reverse , ColorFunction “Pastel” , Image

AspectRatio Automatic ] Image

g1p3 = ListContourPlot [ p5 // Reverse , ColorFunction “GrayTones” , Image

AspectRatio Automatic ] Image

Show [ GraphicsGrid [ { { p1 , glp1 } , { g1p2 , g1p3 } } ] ] Image

The structure of a black and white jpeg differs from that of a color one. To see so, we import a very old picture of the second author of this text,

p1 = Import [ “littlejim.jpg” ] ; Image

Show[p1,ImageSizeSmall]Image

Image

and name the result p1. With ImageDimensions, we see that p1 is 428 pixels wide by 600 pixels tall.

ImageDimensions [ p1 ] Image

{ 428 , 600 } Image

We obtain the data for the image with ImageData. With Length, we see that the resulting array has 600 rows and 428 columns, confirming the result obtained with ImageDimensions. Using Short, we see the form of each entry. For the black-and-white image, each entry is a number that corresponds to a GrayLevel.

p2 = ImageData [ p1 ] ; Image

Length [ p2 ] Image

600

Length [ p2 [ [ 1 ] ] ] Image

428

Short [ p2 ] Image

{ { 0.529412 , 426 , 0.419608 } , 598 , { 1 } } Image

In Fig. 5.41, we illustrate the use of ListContourPlot and ReliefPlot along with various options.

Image
Figure 5.41 Using ListContourPlot and ReliefPlot along with various options to graphically represent a matrix.

g2 = ReliefPlot [ p2 , AspectRatio Automatic , Image

ColorFunction “GrayTones” , FrameTicks None ] ; Image

g3 = ListContourPlot [ p2 // Reverse , AspectRatio Automatic , Image

ColorFunction “GrayTones” , FrameTicks None ] ; Image

g4 = ListContourPlot [ p2 // Reverse , AspectRatio Automatic , Image

ContourStyle Black , ContourShading False , Image

FrameTicks None ] ; Image

Show[GraphicsRow[{g2,g3,g4}]]Image

ReliefPlot can help add insight to images, especially when they have geographical or biological meaning. For example, this jpeg

p1 = Import [ “071105fertx2c.jpg” ] ; Image

Show [ p1 , ImageSize Small ] Image

Image

shows the beginning of a biological process of a cell.

With ImageDimensions, we see that p1 is a 400 pixels wide by 500 pixels tall. After obtaining the image data with ImageData, these calculations are confirmed with length.

ImageDimensions [ p1 ] Image

{ 400 , 500 } Image

p2 = ImageData [ p1 ] ; Image

Length [ p2 ] Image

500

Length [ p1 [ [ 1 , 1 ] ] ] Image

500

Length [ p1 [ [ 1 , 1 , 1 ] ] ] Image

400

Viewing p2 as a 500×400Image array, each entry is 1×3Image array/vector. To easily apply a function, f, that assigns a number to each ordered triple, we use Flatten to convert the nested list/array p2 to a list of ordered triples in p3.

p3 = Flatten [ p2 , 1 ] ; Image

Short [ p3 ] Image

Length [ p3 ] Image

200000

{ { 0.384314 , 20 , 0.12549 } , 199998 , { 1 } } Image

To apply our own color function to this data set, we convert the ordered triples to some other form. For illustrative purposes, we convert each ordered triple (x,y,z)Image in p3 to the number x+y2Image. The result is converted back to a 500×400Image array, with Partition in p4.

f [ y _ ] := y [ [ 1 ] ] + y [ [ 2 ] ] 2 Image

p4 = Partition [ Map [ f , p3 ] , 400 ] ; Image

Length [ p4 ] Image

500

We then use ReliefPlot, ListContourPlot, and ListDensityPlot along with various options to graph the result in Fig. 5.42.

Image
Figure 5.42 Using ReliefPlot, ListContourPlot, and ListDensityPlot along with various options to graphically represent a matrix.

g1 = ReliefPlot [ p4 , AspectRatio Automatic , Image

ColorFunction“DarkRainbow”]Image

g2 = ReliefPlot [ p4 , AspectRatio Automatic , Image

ColorFunction “NeonColors” , Ticks None , Image

Axes None , FrameTicks None ] Image

g3 = ListContourPlot [ p4 , AspectRatio Automatic , Image

ColorFunction “NeonColors” , Ticks None , Image

Axes None , FrameTicks None ] Image

g4 = ListDensityPlot [ p4 , AspectRatio Automatic , Image

ColorFunction “NeonColors” , Ticks None , Image

Axes None , FrameTicks None ] Image