From 50cb6454527e6c071ef1636c476d8ff9350d1b57 Mon Sep 17 00:00:00 2001 From: jverzani Date: Tue, 29 Jul 2025 17:05:59 -0400 Subject: [PATCH] add some examples, figures --- .../vectors.qmd | 1744 +++++++++++------ 1 file changed, 1141 insertions(+), 603 deletions(-) diff --git a/quarto/differentiable_vector_calculus/vectors.qmd b/quarto/differentiable_vector_calculus/vectors.qmd index 2dad038..cf16f5c 100644 --- a/quarto/differentiable_vector_calculus/vectors.qmd +++ b/quarto/differentiable_vector_calculus/vectors.qmd @@ -13,38 +13,179 @@ using LinearAlgebra using SymPy ``` +```{julia} +#| echo: false +## Some plotting functions +begin + function projection_plane(v) + vx, vy, vz = v + a = [-vy, vx, 0] # v ⋅ a = 0 + b = v × a # so v ⋅ b = 0 + return (a/norm(a), b/norm(b)) +end + +function project(x, v) + â, b̂ = projection_plane(v) + (x ⋅ â, x ⋅ b̂) # (x ⋅ â) â + (x ⋅ b̂) b̂ +end + + empty_style = (xaxis = ([], false), + yaxis = ([], false), + legend=false) + axis_style = (arrow=true, side=:head, line=(:gray, 1)) + + project(x) = project(x, [2, -2, 1]) +end +nothing +``` --- -In [vectors](../precalc/vectors.html) we introduced the concept of a vector. For `Julia`, vectors are a useful storage container and are used to hold, for example, zeros of functions or the coefficients of a polynomial. This section is about their mathematical properties. A [vector](https://en.wikipedia.org/wiki/Euclidean_vector) mathematically is a geometric object with two attributes a magnitude and a direction. (The direction is undefined in the case the magnitude is $0$.) Vectors are typically visualized with an arrow, where the anchoring of the arrow is context dependent and is not particular to a given vector. +In [vectors](../precalc/vectors.html) we introduced the concept of a +vector. For `Julia`, vectors are a useful storage container and are +used to hold, for example, zeros of functions or the coefficients of a +polynomial. Matrices are a two-dimensional version of vector. This +section is about the mathematical properties or vectors and matrices. -Vectors and points are related, but distinct. They are identified when the tail of the vector is taken to be the origin. Let's focus on $3$ dimensions. Mathematically, the notation for a point is $p=(x,y,z)$ while the notation for a vector is $\vec{v} = \langle x, y, z \rangle$. The $i$th component in a vector is referenced by a subscript: $v_i$. With this, we may write a typical vector as $\vec{v} = \langle v_1, v_2, \dots, v_n \rangle$ and a vector in $n=3$ as $\vec{v} =\langle v_1, v_2, v_3 \rangle$. The different grouping notation distinguishes the two objects. As another example, the notation $\{x, y, z\}$ indicates a set. Vectors and points may be *identified* by anchoring the vector at the origin. Sets are quite different from both, as the order of their entries is not unique. +## Vectors + + A [vector](https://en.wikipedia.org/wiki/Euclidean_vector) mathematically is a geometric object with two attributes a magnitude and a direction. (The direction is undefined in the case the magnitude is $0$.) Vectors are typically visualized with an arrow, where the anchoring of the arrow is context dependent and is not particular to a given vector. -In `Julia`, the notation to define a point and a vector would be identical, using square brackets to group like-type values: `[x, y, z]`. The notation `(x,y,z)` would form a [tuple](https://en.wikipedia.org/wiki/Euclidean_vector) which though similar in many respects, are different, as tuples do not have the operations associated with a point or a vector defined for them. +A point is a position in $R^n$, denoted by $n$ components. Vectors and points are related, but distinct concepts. The two are identified when the tail of the vector is taken to be the origin. Let's focus on $3$ dimensions. Mathematically, the notation for a point is $p=(x,y,z)$ while the notation for a vector is $\vec{v} = \langle x, y, z \rangle$. The $i$th component in a vector is referenced by a subscript: $v_i$. With this, we may write a typical vector as $\vec{v} = \langle v_1, v_2, \dots, v_n \rangle$ and a vector in $n=3$ as $\vec{v} =\langle v_1, v_2, v_3 \rangle$. The different grouping notation distinguishes the two objects. As another example, the notation $\{x, y, z\}$ indicates a set. While vectors and points may be *identified* by anchoring the vector at the origin. Sets are quite different from both, as the order of their entries is not unique. +`Julia` uses square brackets to group together the components of a vector. The construction `[v1, v2, ..., vn]` creates a `Vector` object: + +```{julia} +[1, 2, 3] +``` + +(The type of the elements is also indicated.) + +We have seen that `Plots` interprets tuples as points. We can use tuples as points, though it can be a bit cumbersome as certain arithmetic operations aren't defined for tuples. As such, we often use a vector to indicate a point or a vector, leaving the interpretation to the reader. + The square bracket constructor has some subtleties: - * `[x,y,z]` calls `vect` and creates a 1-dimensional array - * `[x; y; z]` calls `vcat` to **v**ertically con**cat**enate values together. With simple (scalar) values `[x,y,z]` and `[x; y; z]` are identical, but not in other cases. (For example, if `A` is a matrix then `[A, A]` is a vector of matrices, `[A; A]` is a matrix combined from the two pieces. - * `[x y z]` calls `hcat` to **h**orizontally con**cat**enate values together. If `x`, `y` are numbers then `[x y]` is *not* a vector, but rather a $2$D array with a single row and two columns. - * finally `[w x; y z]` calls `hvcat` to horizontally and vertically concatenate values together to create a container in two dimensions, like a matrix. +* `[x, y, z]` calls `Base.vect` and creates a 1-dimensional array or vector. + +* `[x; y; z]` calls `vcat` to **v**ertically con**cat**enate values together. With simple (scalar) values `[x, y, z]` and `[x; y; z]` are identical, but not in other cases. (For example, if `A` is a matrix then `[A, A]` is a vector of matrices, `[A; A]` is a matrix combined from the two pieces. + +* `[x y z]` calls `hcat` to **h**orizontally con**cat**enate values together. If `x`, `y` are numbers then `[x y]` is *not* a vector, but rather a $2$D array with a single row and two columns. + +* finally `[w x; y z]` calls `hvcat` to horizontally and vertically concatenate values together to create a container in two dimensions, like a matrix. -(A vector, mathematically, is a one-dimensional collection of numbers, a matrix a two-dimensional *rectangular* collection of numbers, and an array an $n$-dimensional rectangular-like collection of numbers. In `Julia`, a vector can hold a collection of objects of arbitrary type, though each will be promoted to a common type.) +(A vector, mathematically, is a one-dimensional collection of numbers, a matrix a two-dimensional *rectangular* collection of numbers, and an array an $n$-dimensional rectangular-like collection of numbers. In `Julia` the `Array` type is a general type to hold *homogeneous* data along different dimensions. The `Vector` type is an array specialized to one dimension; the `Matrix` type is a specialization to two dimensions.) + +### Vector addition -## Vector addition, scalar multiplication +As seen earlier, vectors have some arithmetic operations defined for them. As a typical use of vectors, mathematically, is to collect the $x$, $y$, and $z$ (in $3$D) components together, operations like addition and subtraction operate component wise. -As seen earlier, vectors have some arithmetic operations defined for them. As a typical use of vectors, mathematically, is to collect the $x$, $y$, and $z$ (in $3$D) components together, operations like addition and subtraction operate component wise. With this, addition can be visualized geometrically: put the tail of $\vec{v}$ at the tip of $\vec{u}$ and draw a vector from the tail of $\vec{u}$ to the tip of $\vec{v}$ and you have $\vec{u}+\vec{v}$. This is identical by $\vec{v} + \vec{u}$ as vector addition is commutative. Unless $\vec{u}$ and $\vec{v}$ are parallel or one has $0$ length, the addition will create a vector with a different direction from the two. +:::{.callout-note appearance="minimal"} +# Vector addition +$$ +\langle a_1, a_2, \dots, a_n \rangle + +\langle b_1, b_2, \dots, b_n \rangle = +\langle (a_1 + b_1), (a_2 + b_2), \dots, (a_n + b_n) \rangle +$$ +::: + +With this, addition can be visualized geometrically: put the tail of $\vec{v}$ at the tip of $\vec{u}$ and draw a vector from the tail of $\vec{u}$ to the tip of $\vec{v}$ and you have $\vec{u}+\vec{v}$. This is identical by $\vec{v} + \vec{u}$ as vector addition is commutative. Unless $\vec{u}$ and $\vec{v}$ are parallel or one has $0$ length, the addition will create a vector with a different direction from the two. + +:::{#fig-vector-addition-2-3d} + +```{julia} +#| echo: false +gr() +p1 = let + # plot two vectors + P,Q = (1,2), (2, 1) + O = (0,0) + plot(; empty_style..., xlim=(0, 3.5)) + plot!([O, (3, 0)]; axis_style...) + plot!([O, (0,3)]; axis_style...) + + plot!([O, O .+ P]; arrow=true, line=(:black, 2)) + plot!([O, O .+ Q]; arrow=true, line=(:black, 2)) + plot!([Q, Q .+ P]; arrow=true, line=(:black, 1, :dash)) + plot!([O, Q .+ P]; arrow=true, line=(:black, 1, :dash)) + + annotate!([ + (3, 0, text(L"x", :top)), + (0, 3, text(L"y", :right)), + (P..., text(L"\vec{v}", :top, :left)), + (Q..., text(L"\vec{u}", :top, :left)), + ((P .+Q)..., text(L"\vec{u}+\vec{v}", :top, :left)) + + ]) +end + +p2 = let + # plot two vectors + P,Q = (1,1,3), (2, 1/3,7/4) + O = (0,0,0) + plot(; empty_style..., xlim=(0, 4)) + plot!(project.([O, (4, 0, 0)]); axis_style..., linealpha=0.5) + plot!(project.([O, (0, 4, 0)]); axis_style..., linealpha=0.5) + plot!(project.([O, (0, 0, 4)]); axis_style..., linealpha=0.5) + annotate!([ + (project((4, 0, 0))..., text(L"x",:top)), + (project((0, 4, 0))..., text(L"y",:top)), + (project((0, 0, 4))..., text(L"z",:left)), + ]) + + plot!(project.([O, P]); arrow=true, line=(:black, 2)) + plot!(project.([O, Q]); arrow=true, line=(:black, 2)) + plot!(project.([Q, P .+ Q]); arrow=true, line=(:black, 1, :dash)) + plot!(project.([O, P .+ Q]); arrow=true, line=(:black, 1, :dash)) -Another operation for vectors is *scalar* multiplication. Geometrically this changes the magnitude, but not the direction of a vector, when the *scalar* is positive. Scalar multiplication is defined component wise, like addition so the $i$th component of $c \vec{v}$ is $c$ times the $i$th component of $\vec{v}$. When the scalar is negative, the direction is "reversed." + for pt in (P, Q, P .+ Q) + plot!(project.([(pt[1],0,0), (pt[1], pt[2],0), pt]); line=(:black, 1, 0.25, :dot)) + end + + + annotate!([ + (project(P)..., text(L"\vec{v}", :top, :left)), + (project(Q)..., text(L"\vec{u}", :top, :left)), + (project(P .+ Q)..., text(L"\vec{u}+\vec{v}", :top, :left)) + + ]) +end + +plot(p1, p2; layout=[2, 1]) +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +Illustration of vector addition in $2$ and $3$ dimensions +::: + +### Scalar multiplication + +Another operation for vectors is *scalar* multiplication. Geometrically this changes the magnitude, but not the direction of a vector, when the *scalar* is positive. Scalar multiplication is defined component wise, like addition so the $i$th component of $c \vec{v}$ is $c$ times the $i$th component of $\vec{v}$. + + +:::{.callout-note appearance="minimal"} +# Scalar multiplication +$$ +c \cdot \langle a_1, a_2, \dots, a_n \rangle = +\langle c\cdot a_1, c \cdot a_2 , \dots, c \cdot a_n \rangle +$$ +::: + + +When the scalar is negative, the direction is "reversed." To illustrate we define two $3$-dimensional vectors: @@ -71,7 +212,7 @@ Scalar multiplication by `2`, say, multiplies each entry by `2`: 2 * u ``` -## The length and direction of a vector +### The length and direction of a vector If a vector $\vec{v} = \langle v_1, v_2, \dots, v_n\rangle$ then the *norm* (also Euclidean norm or length) of $\vec{v}$ is defined by: @@ -90,7 +231,7 @@ A vector with length $1$ is called a *unit* vector. Dividing a non-zero vector b The direction indicated by $\vec{v}$ can be visualized as an angle in $2$- or $3$-dimensions, but in higher dimensions, visualization is harder. For $2$-dimensions, we might associate with a vector, it's unit vector. This in turn may be identified with a point on the unit circle, which from basic trigonometry can be associated with an angle. Something similar, can be done in $3$ dimensions, using two angles. However, the "direction" of a vector is best thought of in terms of its associated unit vector. With this, we have a decomposition of a non-zero vector $\vec{v}$ into a magnitude and a direction when we write $\vec{v} = \|\vec{v}\| \cdot (\vec{v} / \|\vec{v}\|)=\|\vec{v}\| \hat{v}$. -## Visualization of vectors +### Visualization of vectors Vectors may be visualized in $2$ or $3$ dimensions using `Plots`. In $2$ dimensions, the `quiver` function may be used. To graph a vector, it must have its tail placed at a point, so two values are needed. @@ -103,7 +244,10 @@ To plot `u=[1,2]` from `p=[0,0]` we have the following usage: quiver([0],[0], quiver=([1],[2])) ``` -The cumbersome syntax is typical here. We naturally describe vectors and points using `[a,b,c]` to combine them, but the plotting functions want to plot many such at a time and expect vectors containing just the `x` values, just the `y` values, etc. The above usage looks a bit odd, as these vectors of `x` and `y` values have only one entry. Converting from the one representation to the other requires reshaping the data. We will use the `unzip` function from `CalculusWithJulia` which in turn just uses the the `invert` function of the `SplitApplyCombine` package ("return a new nested container by reversing the order of the nested container") for the bulk of its work. +The cumbersome syntax, `quiver(x, y, quiver=(u, v))`, is typical here. We naturally describe vectors and points using `[a,b,c]` to combine them, but the plotting functions want to plot many such at a time and expect vectors containing just the `x` values, just the `y` values, etc. The above usage looks a bit odd, as these vectors of `x` and `y` values have only one entry. + + +Converting from the one representation to the other requires reshaping the data. We will use the `unzip` function from `CalculusWithJulia` which in turn just uses the the `invert` function of the `SplitApplyCombine` package ("return a new nested container by reversing the order of the nested container") for the bulk of its work. This function takes a vector of vectors, and returns a tuple containing the `x` values, the `y` values, etc. So if `u=[1,2,3]` and `v=[4,5,6]`, then `unzip([u,v])` becomes `([1,4],[2,5],[3,6])`, etc. (The `zip` function in base does essentially the reverse operation, hence the name.) Notationally, `A = [u,v]` can have the third element of the first vector (`u`) accessed by `A[1][3]`, where as `unzip(A)[3][1]` will do the same. We use `unzip([u])` in the following, which for this `u` returns `([1],[2],[3])`. (Note the `[u]` to make a vector of a vector.) @@ -126,6 +270,10 @@ quiver!(unzip([u])..., quiver=unzip([v])) quiver!(unzip([p])..., quiver=unzip([w])) ``` +For some plotting backends---though not `plotly`--- there is an `arrow` argument that can be passed to the line-plotting command. If `p` and `u` are *tuples*, then the command `plot([p, p .+ u]; arrow=true, side=:head)` will draw the vector `u` anchored at `p`. (There can be many more points in the curve used to create curved arrows.) + + + Plotting a $3$-d vector is not supported in all toolkits with `quiver`. A line segment may be substituted and can be produced with `plot(unzip([p,p+v])...)`. To avoid all these details, the `CalculusWithJulia` provides the `arrow!` function to *add* a vector to an existing plot. The function requires a point, `p`, and the vector, `v`: @@ -144,7 +292,7 @@ arrow!(u, v) arrow!(p, w) ``` -The distinction between a point and a vector within `Julia` is only mental. We use the same storage type. Mathematically, we can **identify** a point and a vector, by considering the vector with its tail placed at the origin. In this case, the tip of the arrow is located at the point. But this is only an identification, though a useful one. It allows us to "add" a point and a vector (e.g., writing $P + \vec{v}$) by imagining the point as a vector anchored at the origin. +The distinction between a point and a vector within `Julia` is only mental. We often use the same storage type (`Vector`). Mathematically, we can **identify** a point and a vector, by considering the vector with its tail placed at the origin. In this case, the tip of the arrow is located at the point. But this is only an identification, though a useful one. It allows us to "add" a point and a vector (e.g., writing $P + \vec{v}$) by imagining the point as a vector anchored at the origin. (If `P` is represented with a tuple, we can still add to a vector through broadcasting: `P .+ v`.) To see that a unit vector has the same "direction" as the vector, we might draw them with different widths: @@ -163,13 +311,14 @@ arrow!(p, u, linewidth=5) The `norm` function is in the standard library, `LinearAlgebra`, which must be loaded first through the command `using LinearAlgebra`. (Though here it is redundant, as that package is loaded and reexported when the `CalculusWithJulia` package is loaded.) -## Aside: review of `Julia`'s use of dots to work with containers +#### Aside: review of `Julia`'s use of dots to work with containers `Julia` makes use of the dot, "`.`", in a few ways to simplify usage when containers, such as vectors, are involved: +##### Splatting - * **Splatting**. The use of three dots, "`...`", to "splat" the values from a container like a vector (or tuple) into *arguments* of a function can be very convenient. It was used above in the definition for the `arrow!` function: essentially `quiver!(unzip([p])..., quiver=unzip([v]))`. The `quiver` function expects $2$ (or $3$) arguments describing the `xs` and `ys` (and sometimes `zs`). The `unzip` function returns these in a container, so splatting is used to turn the values in the container into distinct arguments of the function. Whereas the `quiver` argument expects a tuple of vectors, so no splatting is used for that part of the definition. Another use of splatting we will see is with functions of vectors. These can be defined in terms of the vector's components or the vector as a whole, as below: +The use of three dots, "`...`", to "splat" the values from a container like a vector (or tuple) into *arguments* of a function can be very convenient. It was used above in the definition for the `arrow!` function: essentially `quiver!(unzip([p])..., quiver=unzip([v]))`. The `quiver` function expects $2$ (or $3$) arguments describing the `xs` and `ys` (and sometimes `zs`). The `unzip` function returns these in a container, so splatting is used to turn the values in the container into distinct arguments of the function. Whereas the `quiver` argument expects a tuple of vectors, so no splatting is used for that part of the definition. Another use of splatting we will see is with functions of vectors. These can be defined in terms of the vector's components or the vector as a whole, as below: ```{julia} @@ -194,7 +343,9 @@ The splatting will mean `g(v)` eventually calls `g(x, y, z)` through `Julia`'s m (The three dots can also appear in the definition of the arguments to a function, but there the usage is not splatting but rather a specification of a variable number of arguments.) - * **Broadcasting**. For a univariate function, `f`, and vector, `xs`, the call `f.(xs)` *broadcasts* `f` over each value of `xs` and returns a container holding all the values. This is a compact alternative to a comprehension when a function is defined. When `f` depends on more than one value, broadcasting can still be used: `f.(xs, ys)` will broadcast `f` over values formed from *both* `xs` and `ys`. Broadcasting has the extra feature (over `map`) of attempting to match up the shapes of `xs` and `ys` when they are not identical. (See the help page for `broadcast` for more details.) +##### Broadcasting + +For a univariate function, `f`, and vector, `xs`, the call `f.(xs)` *broadcasts* `f` over each value of `xs` and returns a container holding all the values. This is a compact alternative to a comprehension when a function is defined. When `f` depends on more than one value, broadcasting can still be used: `f.(xs, ys)` will broadcast `f` over values formed from *both* `xs` and `ys`. Broadcasting has the extra feature (over `map`) of attempting to match up the shapes of `xs` and `ys` when they are not identical. (See the help page for `broadcast` for more details.) For example, if `xs` is a vector and `ys` a scalar, then the value in `ys` is repeated many times to match up with the values of `xs`. Or if `xs` and `ys` have different dimensions, the values of one will be repeated. Consider this: @@ -224,210 +375,8 @@ The two dimensions are different so for each value of `xs` the vector of `ys` is At times using the "apply" notation: `x |> f`, in place of using `f(x)` is useful, as it can move the wrapping function to the right of the expression. To broadcast, `.|>` is available. -## Aside: simplifying calculations using containers and higher-order functions -Storing data in a container, be it a vector or a tuple, can seem at first more complicated, but in fact can lead to much simpler computations. - -A simple example might be to add up a sequence of numbers. A direct way might be: - -```{julia} -x1, x2, x3, x4, x5, x6 = 1, 2, 3, 4, 5, 6 -x1 + x2 + x3 + x4 + x5 + x6 -``` - -Someone doesn't need to know `Julia`'s syntax to guess what this computes, save for the idiosyncratic tuple assignment used, which could have been bypassed at the cost of even more typing. - -A more efficient means to do, as each component isn't named, this would be to store the data in a container: - -```{julia} -xs = [1, 2, 3, 4, 5, 6] # as a vector -sum(xs) -``` - -Sometimes tuples are used for containers. The difference to `sum` is not noticeable (though a different code path for the computation is taken behind the scenes): - -```{julia} -xs = (1, 2, 3, 4, 5, 6) -sum(xs) -``` - -(Tuples and vectors are related, but tuples don't have built-in arithmetic defined. Several popular packages, such as `Plots`, draw a distinction between the two basic containers, but most generic functions just need to be able to iterate over the values.) - -The `sum` function has a parallel `prod` function for finding the product of the entries: - -```{julia} -prod(xs) -``` - -Both `sum` and `prod` will error if the container is empty. - -These two functions are *reductions*. There are others, such as `maximum` and `minimum`. They reduce the dimensionality of the container, in this case from a vector to a scalar. When applied to higher-dimensional containers, dimenensions to reduce over are specified. The higher-order `reduce` function can be used as a near alternate to `sum`: - -```{julia} -reduce(+, xs; init=0) # sum(xs) -``` - -or - -```{julia} -reduce(*, xs; init=1) # prod(xs) -``` - -The functions (`+` and `*`) are binary operators and are serially passed the running value (or `init`) and the new term from the iterator. - -The initial value above is the unit for the operation (which could be found programmatically by `zero(eltype(xs))` or `one(eltype(xs))` where the type is useful for better performance). - -The `foldl` and `foldr` functions are similar to `reduce` only left (and right) associativity is guaranteed. This example uses the binary, infix `Pair` operator, `=>`, to illustrate the difference: - -```{julia} -foldl(=>, xs) -``` - -and - -```{julia} -foldr(=>, xs) -``` - -Next, we do a slightly more complicated problem. - -Recall the distance formula between two points, also called the *norm*. It is written here with the square root on the other side: $d^2 = (x_1-y_1)^2 + (x_0 - y_0)^2$. This computation can be usefully generalized to higher dimensional points (with $n$ components each). - -This first example shows how the value for $d^2$ can be found using broadcasting and `sum`: - -```{julia} -xs = [1, 2, 3, 4, 5] -ys = [1, 3, 5, 7, 3] - -sum((xs - ys).^2) -``` - - -This formula is a sum after applying an operation to the paired off values. Using a generator that sum would look like: - -```{julia} -sum((xi - yi)^2 for (xi, yi) in zip(xs, ys)) -``` - -The `zip` function, used above, produces an iterator over tuples of the paired off values in the two (or more) containers passed to it. - - -This pattern---where a reduction follows a function's application to the components---is implemented in `mapreduce`. - - -```{julia} -f(xy) = (xy[1] - xy[2])^2 -mapreduce(f, +, zip(xs, ys)) -``` - -In the generator example above, the components of the tuple are destructured into `(xi, yi)`; in the function `f` above $1$-based indexing is used to access the first and second components. - -The `mapreduce` function can take more than one iterator to reduce over, When used this way, the function takes multiple arguments. Unlike the above example, where `f` was first defined and then used, we use an anonymous function below, to make the example a one-liner: - -```{julia} -mapreduce((xi,yi) -> (xi-yi)^2, +, xs, ys) -``` - - -(The `mapreduce` form is more performant than broadcasting where the vectors are traversed more times.) - - -### Extracting pieces of a container - -At times, extracting all but the first or last value can be of interest. For example, a polygon comprised of $n$ points (the vertices), might be stored using a vector for the $x$ and $y$ values with an additional point that mirrors the first. Here are the points: - -```{julia} -xs = [1, 3, 4, 2] -ys = [1, 1, 2, 3] -pts = zip(xs, ys) # recipe for [(x1,y1), (x2,y2), (x3,y3), (x4,y4)] -``` - -To *add* the additional point we might just use `push!`: - -```{julia} -push!(xs, first(xs)) -push!(ys, first(ys)) -``` - -(Though this approach won't work with `pts`, only with mutable containers.) - -The `first` and `last` methods refer to the specific elements in the indexed collection. To get the rest of the values can be done a few ways. For example, this pattern peels off the first and leaves a new container to hold the rest: - -```{julia} -a, bs... = xs -a, bs -``` - -The splatting operation for `bs....` is usually seen inside a function, so this is a bit unusual. The `Iterators.peel` method also can also do this task (the `Iterators` module and its methods are not exported, so `peel` is necessarily qualified if not imported): - -```{julia} -a, bs = Iterators.peel(xs) -bs -``` - - -The `bs` are represented with an iterator and can be collected to yield the values, though often this is unnecessary and possibly a costly step: - -```{julia} -collect(bs), sum(bs) -``` - -The iterators shown here are *lazy* and only construct a recipe to produce the points one after another. Reductions like `sum` and `prod` can use this recipe to produce an answer without needing to realize in memory at one time the entire collection of values being represented. - -The `Iterators.rest` method can be used to take the rest of the container starting a given index. This command also finds the `bs` above: - -```{julia} -bs = Iterators.rest(xs, 2) -collect(bs) -``` - -The `Iterators.take` method can be used to take values at the beginning of a container. This command takes all but the last value of `xs`: - -```{julia} -as = Iterators.take(xs, length(xs) - 1) -collect(as) -``` - -The `take` method could be used to remove the padded value from the `xs` and `ys`. Between `Iterators.take` and `Iterators.rest` the iterable object can be split into a head and tail. - -##### Example: Riemann sums - -In the computation of a Riemann sum, the interval $[a,b]$ is partitioned using $n+1$ points $a=x_0 < x_1 < \cdots < x_{n-1} < x_n = b$. - -```{julia} -a, b, n = 0, 1, 4 -xs = range(a, b, n+1) # n + 1 points gives n subintervals [xᵢ, xᵢ₊₁] -``` - -To grab these points as adjacent pairs can be done by combining the first $n$ points and the last $n$ points, as follows: - -```{julia} -partitions = zip(Iterators.take(xs, n), Iterators.rest(xs, 1)) -collect(partitions) -``` - -A left-hand Riemann sum for `f` could then be done with: - -```{julia} -f(x) = x^2 -sum(f ∘ first, partitions) -``` - -This uses a few things: like `mapreduce`, `sum` allows a function to -be applied to each element in the `partitions` collection. (Indeed, the default method to compute `sum(xs)` for an arbitrary container resolves to `mapreduce(identity, add_sum, xs)` where `add_sum` is basically `+`.) - -In this case, the -values come as tuples to the function to apply to each component. -The function above uses `first` to find the left-endpoint value and then calls `f`. The composition (through `∘`) implements this. - -Alternatively, `zip` can be avoided with: - -```{julia} -mapreduce((l, r) -> l^2, +, Iterators.take(xs, n), Iterators.rest(xs, 1)) -``` - - -## The dot product +### The dot product There is no concept of multiplying two vectors, or for that matter dividing two vectors. However, there are two operations between vectors that are somewhat similar to multiplication, these being the dot product and the cross product. Each has an algebraic definition, but their geometric properties are what motivate their usage. We begin by discussing the dot product. @@ -450,7 +399,59 @@ $$ \vec{v} \cdot \vec{w} = \|\vec{v}\| \|\vec{w}\| \cos(\theta). $$ -If we denoted $\hat{v} = \vec{v} / \| \vec{v} \|$, the unit vector in the direction of $\vec{v}$, then by dividing, we see that $\cos(\theta) = \hat{v} \cdot \hat{w}$. That is the angle does not depend on the magnitude of the vectors involved. +If we denoted $\hat{v} = \vec{v} / \| \vec{v} \|$, the unit vector in the direction of $\vec{v}$, then by dividing, we see that + +$$ +\cos(\theta) = \hat{v} \cdot \hat{w}. +$$ + +That is, the angle does not depend on the magnitude of the vectors involved. + +:::{#fig-angle-between-vectors} +```{julia} +#| echo: false +gr() +let + # dot product + θ₀, θ₁ = pi/8, 7pi/16 + r₀, r₁ = 3/2, 2 + O = (0,0) + x′, y′ = (2,2) + plot(; empty_style..., aspect_ratio=:equal, xlim=(0, x′ + 0.25)) + plot!([O, (x′, 0)]; axis_style...) + plot!([O, (0,y′)]; axis_style...) + annotate!([ + (x′, 0, text(L"x", :top, :left)), + (0, y′, text(L"y", :left)) + ]) + + for (r, θ, l, l̂) ∈ ((r₀,θ₀, L"\vec{u}", L"\hat{u}"), (r₁, θ₁,L"\vec{v}", L"\hat{v}")) + P = (r*cos(θ), r * sin(θ)) + plot!([O, P]; arrow=true, line=(:black, 2)) + plot!([O, (cos(θ), sin(θ))]; arrow=true, line=(:red, 5, 0.5)) + annotate!([(P..., text(l, :top, :left)), + (1/2*cos(θ), 1/2*sin(θ), text(l̂, :top, :left)) + ]) + + end + + rᵢ = 1/5 + pts = [(rᵢ*cos(t), rᵢ*sin(t)) for t in range(θ₀, θ₁, 100)] + plot!(pts; arrow=true, line=(:black, 1) ) + tᵢ = (θ₀ + θ₁)/2 + annotate!([(2rᵢ*cos(tᵢ), 2rᵢ*sin(tᵢ), text(L"\theta"))]) + current() +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +The angle between two vectors is the same as that between their unit vectors. It can be defined to be between $0$ and $\pi$. Its cosine is realized by the dot product of the unit vectors, $\hat{u} \cdot \hat{v}$. +::: The dot product is computed in `Julia` by the `dot` function, which is in the `LinearAlgebra` package of the standard library. This must be loaded (as above) before its use either directly or through the `CalculusWithJulia` package: @@ -505,41 +506,82 @@ u ⋅ v #### Projection - -From right triangle trigonometry, we learn that $\cos(\theta) = \text{adjacent}/\text{hypotenuse}$. If we use a vector, $\vec{h}$ for the hypotenuse, and $\vec{a} = \langle 1, 0 \rangle$, we have this picture: +A key fact about *non* parallel vectors, $\vec{u}$ and $\vec{v}$, is that $\vec{v}$ can be expressed as a scalar multiple of $\vec{u}$ plus a second vector which is orthogonal to $\vec{u}$. +::: {#fig-projection-v-on-u} ```{julia} -#| hold: true -h = [2, 3] -a = [1, 0] # unit vector -h_hat = h / norm(h) -theta = acos(h_hat ⋅ a) +#| echo: false +gr() +let + ## projection + O = (0,0) + A = (2,1) + Â = A ./ norm(A) + B = (1, 2) -plot(legend=false) -arrow!([0,0], h) -arrow!([0,0], norm(h) * cos(theta) * a) -arrow!([0,0], a, linewidth=3) + plot(; empty_style..., aspect_ratio=:equal) + plot!([O,A]; arrow=true, line=(:black, 1)) + plot!([O, B]; arrow=true, line=(:black, 1)) + + p_ab = (B ⋅ Â) .* Â + plot!([O, p_ab]; arrow=true, line=(:red, 3)) + + n = B .- p_ab + plot!([p_ab, B]; arrow=true, line=(:red, 3)) + + λ = 1/8 + plot!([p_ab .- λ .* Â, + p_ab .- λ .* Â .+ λ .* n./norm(n), + p_ab .+ λ .* n./norm(n), + ]; line=(:black, 1)) + + θ₀, θ₁ = atan(A[2],A[1]), atan(B[2],B[1]) + θ₂ = (θ₀ + θ₁)/2 + pts = [(λ*cos(t), λ*sin(t)) for t in range(θ₀, θ₁, 25)] + plot!(pts, line=(:black, 1) ) + + annotate!([ + (2λ*cos(θ₂), 2λ*sin(θ₂), text(L"\theta")), + ((A./1.1)..., text(L"\vec{u}", :top)), + ((B./2)..., text(L"\vec{v}", :bottom,:right)), + ((p_ab./2)..., text(L"proj_{\vec{u}}(\vec{v})", :bottom; + rotation=atand(A[2],A[1]), color=:red)), + ((p_ab .+ n ./ 2)..., text(L"\vec{n}=\vec{v} - proj_{\vec{u}}(\vec{v})", :bottom, + color=:red, rotation=atand(-n[2],-n[1]))) + + ]) +end ``` -We used vectors to find the angle made by `h`, and from there, using the length of the hypotenuse is `norm(h)`, we can identify the length of the adjacent side, it being the length of the hypotenuse times the cosine of $\theta$. Geometrically, we call the vector `norm(h) * cos(theta) * a` the *projection* of $\vec{h}$ onto $\vec{a}$, the word coming from the shadow $\vec{h}$ would cast on the direction of $\vec{a}$ were there light coming perpendicular to $\vec{a}$. +```{julia} +#| echo: false +plotly() +nothing +``` +The vector $\vec{v}$ *projected* onto $\vec{u}$ decomposes $\vec{v}$ into a sum of vectors---one is parallel to $\vec{u}$ the other orthogonal. +::: -The projection can be made for any pair of vectors, and in any dimension $n > 1$. The projection of $\vec{u}$ on $\vec{v}$ would be a vector of length $\vec{u}$ (the hypotenuse) times the cosine of the angle in the direction of $\vec{v}$. In dot-product notation: - +In @fig-projection-v-on-u we see graphically the decomposition. The length of the vector parallel to $\vec{u}$ can be seen from right-triangle geometry to be +$\lVert \vec{v} \rVert \cos(\theta)$, so the vector parallel to $\vec{u}$ would be this length times the unit vector in the direction of $\vec{u}$. +:::{.callout-note appearance="minimal"} +## Projection of one vector onto another $$ -proj_{\vec{v}}(\vec{u}) = \| \vec{u} \| \frac{\vec{u}\cdot\vec{v}}{\|\vec{u}\|\|\vec{v}\|} \frac{\vec{v}}{\|\vec{v}\|}. +\begin{align*} +\text{proj}_{\vec{u}}(\vec{v}) +&= \lVert \vec{v} \rVert \cos(\theta) \hat{u} \\ +&= \frac{\vec{v} \cdot \vec{u}}{\lVert\vec{u}\rVert} \frac{\vec{u}}{\lVert\vec{u}\rVert} \\ +&= (\vec{v} \cdot \hat{u}) \hat{u}. +\end{align*} $$ -This can simplify. After cancelling, and expressing norms in terms of dot products, we have: +::: +With this projection function, the orthogonal piece can be recovered by subtraction: $\vec{v} - (\vec{v} \cdot \hat{u}) \hat{u}$. -$$ -proj_{\vec{v}}(\vec{u}) = \frac{\vec{u} \cdot \vec{v}}{\vec{v} \cdot \vec{v}} \vec{v} = (\vec{u} \cdot \hat{v}) \hat{v}, -$$ - -where $\hat{v}$ is the unit vector in the direction of $\vec{v}$. +This is readily seen to be orthogonal to $\vec{u}$ just by taking the dot product. ##### Example @@ -630,9 +672,678 @@ The dot product is similar to multiplication, but different, as it is an operati The last two can be combined: $\vec{u}\cdot(s \vec{v} + t \vec{w}) = s(\vec{u}\cdot\vec{v}) + t (\vec{u}\cdot\vec{w})$. -But the associative property does not make sense, as $(\vec{u} \cdot \vec{v}) \cdot \vec{w}$ does not make sense as two dot products: the result of the first is not a vector, but a scalar. +But the associative property does not, as $(\vec{u} \cdot \vec{v}) \cdot \vec{w}$ does not make sense as two dot products: the result of the first is not a vector, but a scalar. + +### Cross product + + +In three dimensions, there is a another operation between vectors that is similar to multiplication, though we will see with many differences. + +Let $\vec{u}$ and $\vec{v}$ be two $3$-dimensional vectors, then the *cross* product, $\vec{u} \times \vec{v}$, is defined as a vector with length: + + +$$ +\| \vec{u} \times \vec{v} \| = \| \vec{u} \| \| \vec{v} \| \sin(\theta), +$$ + +with $\theta$ being the angle in $[0, \pi]$ between $\vec{u}$ and $\vec{v}$. Consequently, $\sin(\theta) \geq 0$. + +::: {#fig-cross-product} +```{julia} +#| echo: false +gr() +let + O = (0,0,0) + u = (5/2, 1, 1/8) + v = (2, 1, 1/2) + kross(u,v)= tuple(cross(collect(u), collect(v))...) + w = kross(u,v) + û, v̂, ŵ = u ./ norm(u), v ./ norm(v), w ./ norm(w) + + plot(; empty_style..., aspect_ratio=:equal) + plot!([O,u]; arrow=true, line=(:black, 1)) + plot!([O,v]; arrow=true, line=(:black, 1)) + plot!([O,w]; arrow=true, line=(:black, 1)) + r = 1/8 + plot!([r.*û, r.*û .+ r.*ŵ, r.*ŵ], line=(:black, 1)) + plot!([r.*v̂, r.*v̂ .+ r.*ŵ, r.*ŵ], line=(:black, 1)) + + θ = asin(û⋅v̂) + pts = [((cos(t) .* û) .+ (sin(t) .* v̂)) ./ 4 for t in range(0, θ, 20)] + plot!(pts) + + annotate!([ + (u..., text(L"\vec{u}", :top)), + (v..., text(L"\vec{v}", :top)), + (w..., text(L"\vec{w}", :bottom, :left)), + (((û .+ v̂)./4)..., text(L"\theta")) + + + + ]) + +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +Cross product of $\vec{u}$ and $\vec{v}$ will be orthogonal to both with length given by the lengths of both vectors and the sine of the angle between them. +::: + + +The direction of the cross product is such that it is *orthogonal* to *both* $\vec{u}$ and $\vec{v}$. There are two such directions, to identify which is correct, the [right-hand rule](https://en.wikipedia.org/wiki/Cross_product#Definition) is used. This rule points the right hand fingers in the direction of $\vec{u}$ and curls them towards $\vec{v}$ (so that the angle between the two vectors is in $[0, \pi]$). The thumb will point in the direction. Call this direction $\hat{n}$, a normal unit vector. Then the cross product can be defined by: + + +$$ +\vec{u} \times \vec{v} = \| \vec{u} \| \| \vec{v} \| \sin(\theta) \hat{n}. +$$ + +:::{.callout-note} +## The right-hand rule +The right-hand rule is also useful to understand how standard household screws will behave when twisted with a screwdriver. If the right hand fingers curl in the direction of the twisting screwdriver, then the screw will go in or out following the direction pointed to by the thumb. + +::: + +The right-hand rule depends on the order of consideration of the vectors. If they are reversed, the opposite direction is determined. A consequence is that the cross product is **anti**-commutative, unlike multiplication: + + +$$ +\vec{u} \times \vec{v} = - \vec{v} \times \vec{u}. +$$ + +Mathematically, the definition in terms of its components is a bit involved. + + +$$ +\vec{u} \times \vec{v} = \langle u_2 v_3 - u_3 v_2, u_3 v_1 - u_1 v_3, u_1 v_2 - u_2 v_1 \rangle. +$$ + + +From the $\sin(\theta)$ term in the definition, we see that $\vec{u}\times\vec{u}=0$. In fact, the cross product is $0$ only if the two vectors involved are parallel or there is a zero vector. + + +In `Julia`, the `cross` function from the `LinearAlgebra` package implements the cross product. For example: + + +```{julia} +a = [1, 2, 3] +b = [4, 2, 1] +cross(a, b) +``` + +There is also the *infix* unicode operator `\times[tab]` that can be used for similarity to traditional mathematical syntax. + + +```{julia} +a × b +``` + +We can see the cross product is anti-commutative by comparing the last answer with: + + +```{julia} +b × a +``` + +Using vectors of size different than $n=3$ produces a dimension mismatch error: + + +```{julia} +#| error: true +[1, 2] × [3, 4] +``` + +(It can prove useful to pad $2$-dimensional vectors into $3$-dimensional vectors by adding a $0$ third component. We will see this in the discussion on curvature in the plane.) + + +Consider this extended picture involving two vectors $\vec{u}$ and $\vec{v}$ drawn in two dimensions: + + +```{julia} +u₁ = [1, 2] +v₁ = [2, 1] +p₁ = [0,0] + +plot(aspect_ratio=:equal) +arrow!(p₁, u₁) +arrow!(p₁, v₁) +arrow!(u₁, v₁) +arrow!(v₁, u₁) + +puv₁ = (u₁ ⋅ v₁) / (v₁ ⋅ v₁) * v₁ +porth₁ = u₁ - puv₁ +arrow!(puv₁, porth₁) +``` + +The enclosed shape is a parallelogram. To this we added the projection of $\vec{u}$ onto $\vec{v}$ (`puv`) and then the *orthogonal* part (`porth`). + + +The *area* of a parallelogram is the length of one side times the perpendicular height. The perpendicular height could be found from `norm(porth)`, so the area is: + + +```{julia} +norm(v₁) * norm(porth₁) +``` + +However, from trigonometry we have the height would also be the norm of $\vec{u}$ times $\sin(\theta)$, a value that is given through the length of the cross product of $\vec{u}$ and $\hat{v}$, the unit vector, were these vectors viewed as $3$ dimensional by adding a $0$ third component. In formulas, this is also the case: + + +$$ +\text{area of the parallelogram} = \| \vec{u} \times \hat{v} \| \| \vec{v} \| = \| \vec{u} \times \vec{v} \|. +$$ + +We have, for our figure, after extending `u` and `v` to be three dimensional the area of the parallelogram: + + +```{julia} +u₂ = [1, 2, 0] +v₂ = [2, 1, 0] +norm(u₂ × v₂) +``` + +--- + + +This analysis can be extended to the case of 3 vectors, which---when not co-planar---will form a *parallelepiped*. + + +```{julia} +u₃, v₃, w₃ = [1,2,3], [2,1,0], [1,1,2] +plot() +p₃ = [0,0,0] + +plot(legend=false) +arrow!(p₃, u₃); arrow!(p₃, v₃); arrow!(p₃, w₃) +arrow!(u₃, v₃); arrow!(u₃, w₃) +arrow!(v₃, u₃); arrow!(v₃, w₃) +arrow!(w₃, u₃); arrow!(w₃, v₃) +arrow!(u₃ + v₃, w₃); arrow!(u₃ + w₃, v₃); arrow!(v₃ + w₃, u₃) +``` + +The volume of a parallelepiped is the area of a base parallelogram times the height of a perpendicular. If $\vec{u}$ and $\vec{v}$ form the base parallelogram, then the perpendicular will have height $\|\vec{w}\| \cos(\theta)$ where the angle is the one made by $\vec{w}$ with the normal, $\vec{n}$. Since $\vec{u} \times \vec{v} = \| \vec{u} \times \vec{v}\| \hat{n} = \hat{n}$ times the area of the base parallelogram, we have if we dot this answer with $\vec{w}$: + + +$$ +(\vec{u} \times \vec{v}) \cdot \vec{w} = +\|\vec{u} \times \vec{v}\| (\vec{n} \cdot \vec{w}) = +\|\vec{u} \times \vec{v}\| \| \vec{w}\| \cos(\theta), +$$ + +that is, the area of the parallelepiped. Wait, what about $(\vec{v}\times\vec{u})\cdot\vec{w}$? That will have an opposite sign. Yes, in the above, there is an assumption that $\vec{n}$ and $\vec{w}$ have a an angle between them within $[0, \pi/2]$, otherwise an absolute value must be used, as volume is non-negative. + + +:::{.callout-note} +## Orientation +The triple-scalar product, $\vec{u}\cdot(\vec{v}\times\vec{w})$, gives the volume of the parallelepiped up to sign. If the sign of this is positive, the $3$ vectors are said to have a *positive* orientation, if the triple-scalar product is negative, the vectors have a *negative* orientation. + +::: + +#### Algebraic properties + + +The cross product has many properties, some different from regular multiplication: + + + * scalar multiplication: $(c\vec{u})\times\vec{v} = c(\vec{u}\times\vec{v})$ + * distributive over addition: $\vec{u} \times (\vec{v} + \vec{w}) = \vec{u}\times\vec{v} + \vec{u}\times\vec{w}$. + * *anti*-commutative: $\vec{u} \times \vec{v} = - \vec{v} \times \vec{u}$ + * *not* associative: that is there is no guarantee that $(\vec{u}\times\vec{v})\times\vec{w}$ will be equivalent to $\vec{u}\times(\vec{v}\times\vec{w})$. + * The triple cross product $(\vec{u}\times\vec{v}) \times \vec{w}$ must be orthogonal to $\vec{u}\times\vec{v}$ so lies in a plane with this as a normal vector. But, $\vec{u}$ and $\vec{v}$ will generate this plane, so it should be possible to express this triple product in terms of a sum involving $\vec{u}$ and $\vec{v}$ and indeed: + + +$$ +(\vec{u}\times\vec{v})\times\vec{w} = (\vec{u}\cdot\vec{w})\vec{v} - (\vec{v}\cdot\vec{w})\vec{u}. +$$ + +--- + + +The following shows the algebraic properties stated above hold for symbolic vectors. First the linearity of the dot product: + + +```{julia} +@syms s₄ t₄ u₄[1:3]::real v₄[1:3]::real w₄[1:3]::real + +u₄ ⋅ (s₄ * v₄ + t₄ * w₄) - (s₄ * (u₄ ⋅ v₄) + t₄ * (u₄ ⋅ w₄)) |> simplify +``` + +This shows the dot product is commutative: + + +```{julia} +(u₄ ⋅ v₄) - (v₄ ⋅ u₄) |> simplify +``` + +This shows the linearity of the cross product over scalar multiplication and vector addition: + + +```{julia} +u₄ × (s₄* v₄ + t₄ * w₄) - (s₄ * (u₄ × v₄) + t₄ * (u₄ × w₄)) .|> simplify +``` + +(We use `.|>` to broadcast `simplify` over each component.) + + +The cross product is anti-commutative: + + +```{julia} +u₄ × v₄ + v₄ × u₄ .|> simplify +``` + +but not associative: + + +```{julia} +u₄ × (v₄ × w₄) - (u₄ × v₄) × w₄ .|> simplify +``` + +Finally we verify the decomposition of the triple cross product: + + +```{julia} +(u₄ × v₄) × w₄ - ( (u₄ ⋅ w₄) * v₄ - (v₄ ⋅ w₄) * u₄) .|> simplify +``` + +--- + + +This table shows common usages of the symbols for various multiplication types: `*`, $\cdot$, and $\times$: + + +| Symbol | inputs | output | type | +|:--------:|:-------------- |:----------- |:---------------------- | +| `*` | scalar, scalar | scalar | regular multiplication | +| `*` | scalar, vector | vector | scalar multiplication | +| `*` | vector, vector | *undefined* | | +| $\cdot$ | scalar, scalar | scalar | regular multiplication | +| $\cdot$ | scalar, vector | vector | scalar multiplication | +| $\cdot$ | vector, vector | scalar | dot product | +| $\times$ | scalar, scalar | scalar | regular multiplication | +| $\times$ | scalar, vector | undefined | | +| $\times$ | vector, vector | vector | cross product ($3$D) | + + +### Parameterized lines and planes + + +A line in two dimensions satisfies the equation $ax + by = c$. Suppose $a$ and $b$ are non-zero. This can be represented in vector form, as the collection of all points associated to the vectors: $p + t \vec{v}$ where $p$ is a point on the line, say $(0,c/b)$, and v is the vector $\langle b, -a \rangle$. We can verify, this for values of `t` as follows: + + +```{julia} +#| hold: true +@syms a b c x y t + +eq = c - (a*x + b*y) + +p = [0, c/b] +v = [-b, a] +li = p + t * v + +eq(x=>li[1], y=>li[2]) |> simplify +``` + +Let $\vec{n} = \langle a , b \rangle$, taken from the coefficients in the equation. We can see directly that $\vec{n}$ is orthogonal to $\vec{v}$. The line may then be seen as the collection of all vectors that are orthogonal to $\vec{n}$ that have their tail at the point $p$. + +::: {#fig-parameterized-line} +```{julia} +#| echo: false +gr() +let + O = (0,0) + P = (1,2) + V = (2,-1/2) + V′ = (1/2, 2) + n̂ = V′ ./norm(V′) + V̂ = V ./ norm(V) + + l(t) = P .+ t.* V + + x′, y′ = 4,4 + plot(; empty_style..., aspect_ratio=:equal) + plot!([O, (x′, 0)]; axis_style...) + plot!([O, (0,y′)]; axis_style...) + annotate!([ + (0.95*x′, 0, text(L"x", :top, :left)), + (0, 0.95*y′, text(L"y", :right)) + ]) + + scatter!([P]; marker=(5,:black)) + plot!([P, P.+V]; arrow=true, line=(:black,3)) + plot!([P, P .+ n̂]; arrow=true, line=(:black, 2)) + r = 1/7 + plot!([(P.+ r .* V̂), (P .+ r .* V̂ .+ r .* n̂), (P .+ r .* n̂)]; line=(:black, 1)) + + plot!([l(t) for t in range(-3/4, 1.5, 10)]; line=(:black, 1)) + + plot!([O, l(0)]; arrow=true, line=(:gray, 1, :dash)) + plot!([O, l(1.25)]; arrow=true, line=(:gray, 1, :dash)) + + annotate!([ + (P..., text(L"p", :top, :left)), + ((P .+ V./2)..., text(L"\vec{v}", :bottom)), + ((P .+ n̂ ./ 2)..., text(L"\hat{n}", :top, :left)), + ((l(0)./2)..., text(L"t=0", :top, :left)), + ((l(1.25)./2)..., text(L"t=5/4", :top, :left)), + ((l(1.25))..., text(L"p + t \vec{v}", :bottom, :left)) + + ]) + +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +Parameterized line through the point $p$ along vector $\vec{v}$. The line can be described by $l(t) = p + t\cdot \vec{v}$ or as all vector orthogonal to $\hat{n}$ anchored at $p$. +::: + + +In three dimensions, the equation of a plane is $ax + by + cz = d$. Suppose, $a$, $b$, and $c$ are non-zero, for simplicity. Setting $\vec{n} = \langle a,b,c\rangle$ by comparison, it can be seen that plane is identified with the set of all vectors orthogonal to $\vec{n}$ that are anchored at $p$. + + +::: {#fig-plane-parameterized} +```{julia} +#| echo: false +let + gr() + # cross product + O = (0, 0, 0) + P = (0, 0, 1) + u = (5/2, 2.05, -1.75) + v = (2, 1/3, 1/2) + kross(u,v)= tuple(cross(collect(u), collect(v))...) + + n = kross(v,u) + n̂ = 3 .* n ./ norm(n) + + plot(; empty_style...)#, aspect_ratio=:equal) + plot!(project.([O, (5, 0, 0)]); axis_style..., linealpha=0.5) + plot!(project.([O, (0, 5, 0)]); axis_style..., linealpha=0.5) + plot!(project.([O, (0, 0, 5)]); axis_style..., linealpha=0.5) + annotate!([ + (project((5, 0, 0))..., text(L"x",:top)), + (project((0, 5, 0))..., text(L"y",:top)), + (project((0, 0, 5))..., text(L"z",:left)), + ]) + + + + plot!(project.([P, P .+ u]); arrow=true, line=(:black, 1)) + plot!(project.([P, P .+ v]); arrow=true, line=(:black, 1)) + plot!(project.([P, P .+ n̂]); arrow=true, line=(:black, 1)) + + λ = 1.25 + pts = @. [P - λ*u - λ*v, P - λ*u + λ*v, P + λ*u + λ*v, P + λ*u - λ*v] + S = Shape(project.(pts)) + plot!(S; fill=(:gray90, 0.5), line=(:black, 1)) + + annotate!([ + (project(P .+ u./2)..., text(L"\vec{u}", :top)), + (project(P .+ v./2)..., text(L"\vec{v}", :top)), + (project(P .+ n̂./2)..., text(L"\hat{n}", :bottom, :right)), + (project(P)..., text(L"p", :top)) + ]) + + current() +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +A plane can be described as all vectors orthogonal to $\hat{n}$ which are anchored at a point $p$ or through a parameterization $p + s\vec{u} + t\vec{v}$. +::: + +First, let $p = (0, 0, d/c)$ be a point on the plane. We find two vectors $u = \langle -b, a, 0 \rangle$ and $v = \langle 0, c, -b \rangle$. Then any point on the plane may be identified with the vector $p + s\vec{u} + t\vec{v}$. We can verify this algebraically through: + + +```{julia} +#| hold: true +@syms a b c d x y z s t + +eq = d - (a*x + b*y + c * z) + +p = [0, 0, d/c] +u, v = [-b, a, 0], [0, c, -b] +pl = p + t * u + s * v + +subs(eq, x=>pl[1], y=>pl[2], z=>pl[3]) |> simplify +``` + +The above viewpoint can be reversed: + + +> a plane is determined by two (non-parallel) vectors and a point. + + + +The parameterized version of the plane would be $p + s \vec{u} + t \vec{v}$, as used above. + + +The equation of the plane can be given from $\vec{u}$ and $\vec{v}$. Let $\vec{n} = \vec{u} \times \vec{v}$. Then $\vec{n} \cdot \vec{u} = \vec{n} \cdot \vec{v} = 0$, from the properties of the cross product. As such, $\vec{n} \cdot (s \vec{u} + t \vec{v}) = 0$. That is, the cross product is orthogonal to any *linear* combination of the two vectors. This figure shows one such linear combination: + +```{julia} +#| echo: false +gr(); nothing +``` + +```{julia} +#| hold: true +u = [1,2,3] +v = [2,3,1] +n = u × v +p = [0,0,1] + +plot(legend=false) + +arrow!(p, u) +arrow!(p, v) +arrow!(p + u, v) +arrow!(p + v, u) +arrow!(p, n) + +s, t = 1/2, 1/4 +arrow!(p, s*u + t*v) +``` + + +```{julia} +#| echo: false +plotly(); nothing +``` + +So if $\vec{n} \cdot p = d$ (identifying the point $p$ with a vector so the dot product is defined), we will have for any vector $\vec{v} = \langle x, y, z \rangle = s \vec{u} + t \vec{v}$ that + + +$$ +\vec{n} \cdot (p + s\vec{u} + t \vec{v}) = \vec{n} \cdot p + \vec{n} \cdot (s \vec{u} + t \vec{v}) = d + 0 = d, +$$ + +But if $\vec{n} = \langle a, b, c \rangle$, then this says $d = ax + by + cz$, so from $\vec{n}$ and $p$ the equation of the plane is given. + + +In summary: + + +| Object | Equation | vector equation | +|:------ |:------------------:|:-------------------------------- | +| Line | $ax + by = c$ | line: $p + t\vec{u}$ | +| Plane | $ax + by + cz = d$ | plane: $p + s\vec{u} + t\vec{v}$ | + + +--- + + +##### Example + + +You are given that the vectors $\vec{u} =\langle 6, 3, 1 \rangle$ and $\vec{v} = \langle 3, 2, 1 \rangle$ describe a plane through the point $p=[1,1,2]$. Find the equation of the plane. + + +The key is to find the normal vector to the plane, $\vec{n} = \vec{u} \times \vec{v}$: + + +```{julia} +#| hold: true +u, v, p = [6,3,1], [3,2,1], [1,1,2] +n = u × v +a, b, c = n +d = n ⋅ p +"equation of plane: $a x + $b y + $c z = $d" +``` + +##### Example: orthogonal + +A line is described by a point $P=(a,b)$ and a vector $\vec{v} = \langle v_1, v_2 \rangle$ through $r(t) = P + t \vec{v}$. + +A *normal* to the line is given by $\vec{n} = \langle -v_2, v_1 \rangle$. By construction, the value of $\vec{v} \cdot \vec{n}$ is $0$. + +The line can also be described in terms of orthogonality by the equation + +$$ +\vec{n} \cdot (\vec{x} - P) = 0, +$$ + +where we treat $P$ as a vector for purposes of subtraction. That is, the line is comprised of all vectors anchored at $P$ orthogonal to $\vec{n}$. + +Clearly, as $r(t) - P = \vec{v}$ we have $\vec{n} \cdot r(t) = 0$. Further, if $\vec{x}$ satisfies $\vec{n} \cdot (\vec{x} - P) = 0$ then again by flipping coordinates and taking a minus sign, we must have $\vec{x} - P$ is a multiple of $\langle v_1, v_2 \rangle = \vec{v}$. + + +Furthermore, suppose $P$ is a point in $R^3$ with two vectors $\vec{v}$ and $\vec{w}$ which are not parallel. Then the plane $P + s\vec{v} + t\vec{w}$ formed has a normal given by $\vec{n} = \vec{v} \times \vec{w}$. But +$\vec{n} \cdot ((P + s\vec{v} + t\vec{w}) - P) = s\vec{n} \cdot \vec{v} + t \vec{n} \cdot \vec{w} = 0$ so again, we have the plane described as well by" + +$$ +\vec{n} \cdot (\vec{x} - P) = 0. +$$ + +If $\vec{n} = \langle a,b,d \rangle$ then from $\vec{n}\cdot x = \vec{n} \cdot P$ this becomes $ax + by + cz = d = \vec{n}\cdot P$, as we used in the last example. + +##### Example: distance of a point + +Consider a line in $R^2$ and a point, $Q$, not on the line. How far is the nearest point on the line to $Q$? + +::: {#fig-distance-pt-line} +```{julia} +#| echo: false +gr() +let + # plot two vectors + P,Q = (3/2,1/2), (2, 2) + v = (1,1) + n = (-1, 1) ./ sqrt(2) + r(t) = P .+ t .* v + O = (0, 0) + plot(; empty_style..., aspect_ratio=:equal) + plot!([O, (3, 0)]; axis_style...) + plot!([O, (0,3)]; axis_style...) + annotate!([ + (3, 0, text(L"x", :top)), + (0, 3, text(L"y", :right)), + ]) + plot!([P, P .+ n]; arrow=true, line=(:black, 2)) + plot!([P, P .+ v]; arrow=true, line=(:black, 2)) + plot!([r(t) for t in range(-1, 1.4, 3)]; line=(:black, 1)) + scatter!([P, Q]; marker=(5,)) + + a = n ⋅ (Q .- P) + plot!([Q, Q .- a .* n ]; line=(:black, 1, :dash)) + plot!([P, P .+ a .* n]; arrow=true, line=(:black, 1, :dash)) + plot!([P .+ a .* n, Q]; arrow=true, line=(:black, 1, :dash)) + plot!([P, Q]; line=(:black, 1, :dash)) + + annotate!([ + (P..., text(L"P", :top, :left)), + (Q..., text(L"Q", :bottom, :right)), + ((P .+ v ./2)..., text(L"\vec{v}", :top, :left)), + ((P .+ n ./ 2)..., text(L"\hat{n}", :top, :right)), + ((P .+ (Q .- P) ./ 2 )..., text(L"\vec{w}", :top, :left)), + ((P .+ (a.*n) .+ (v ./2))..., + text(L"\|\vec{w}\cdot\hat{v}\|", :bottom; rotation=atand(1,1))), + ((Q .- (a/2).* n)..., + text(L"\|\vec{w}\cdot\hat{n}\|", :bottom; rotation=atand(-1,1))), + ]) + +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +How far is point $Q$ to the line going through $P$ in direction $\vec{v}$? +::: + + +Suppose the line goes through the point $P$ and is in direction $\vec{v}$. Let $\hat{n}$ be a unit normal vector to $\vec{v}$ and $\hat{v}$ be the unit vector in direction $\vec{v}$. + +Then projection of $\vec{w}$ on $\vec{v}$ decomposes $\vec{w}$: + +$$ +\vec{w} = (\vec{w}\cdot\hat{v}) \hat{v} + a \hat{n} +$$ + +The length of $\text{proj}_{\vec{w}}(\vec{v})$ has been seen to be $\|\vec{w}\cdot\hat{v}\|$. The length of $a$ by a *similar* reason is $\|\vec{w} \cdot \hat{n}\|$. This is the length sought, so the distance from a point to a line is given by + +$$ +\| \hat{n} \cdot \vec{PQ} \|. +$$ + + +:::{.callout-note appearance="minimal"} +## Distance of point to a line and a plane +Let $\hat{n}$ be normal to a line (in $R^2$) or plane (in $R^3$) which goes through a point $P$. Then the distance from a point $Q$ to the line or plane is given by +$$ +\text{dist}(Q) = \| \hat{n} \cdot \vec{PQ} \|. +$$ +::: + + +##### Example: intersection + +In $R^3$ consider a plane through a point $P=(1,2,3)$ with normal vector $\vec{n} = \langle 1, 1/2, 1/4\rangle$. Suppose a line goes through points $A=(2,3,1)$ and $B=(3,1,2)$. Where does this line intersect the plane? + +We have the line is parameterized by $\vec{r}(t) = B + t \vec{AB}$ and the plane is described by $\vec{n} \cdot (\vec{x} - P) = 0$. The intersection point must be a $t$ that satisfies $\vec{n} \cdot (\vec{r}(t) - P) = 0$ + +We have: + +```{julia} +P, A, B = [1,2,3], [2,3,1], [3,1,2] +n = [1, 1//2, 1//4] +@syms t +𝑟(t) = B + t * (B - A) +t₀ = only(solve(n ⋅ (𝑟(t) -P) ~ 0, t)) +𝑟(t₀) +``` + +##### Example: intersection + +In $R^3$ two non-parallel planes will intersect in a line. How to describe that line? + +Let the planes be described by points $P_1$ and $P_2$ with normal vectors $\vec{n_1}$ and $\vec{n_2}$. The line will lie in each of the two planes, so any point on the line will satisfy $\vec{n_i} \cdot (\vec{x} - P)= 0$ for $i=1,2$. The vector $\vec{v} = \vec{n_1} \times \vec{n_2}$ is perpendicular to both $\vec{n_1}$ and $\vec{n_2}$, so the line is in the direction of $\vec{v}$. To describe the line we need a point $Q$ on the line, then the description is $Q + t \vec{v}$. + +Fix the $z$ coordinate of $Q$ to be $0$. Then we can solve for $Q$ in general through two linear equations in $x$ and $y$: + +```{julia} +@syms n₁[1:3]::real, n₂[1:3]::real, p₁[1:3]::real, p₂[1:3]::real, x::real, y::real +q = [x, y, 0] +solve((n₁ ⋅ (q - p₁) ~ 0, n₂ ⋅ (q - p₂) ~ 0), (x, y)) +``` + ## Matrices @@ -647,8 +1358,8 @@ The left hand sides are in the form of a dot product, in this case $\langle a,b $$ \begin{align*} -3x &+ 4y &- 5z &= 10\\ -3x &- 5y &+ 7z &= 11\\ + 3x &+ 4y &- 5z &= 10\\ + 3x &- 5y &+ 7z &= 11\\ -3x &+ 6y &+ 9z &= 12, \end{align*} $$ @@ -923,50 +1634,13 @@ u, v = [1,1,2], [3,5,8] reshape(u,(1,3)) * v ``` -## Cross product +##### Example: The cross product as a matrix operation -In three dimensions, there is a another operation between vectors that is similar to multiplication, though we will see with many differences. -Let $\vec{u}$ and $\vec{v}$ be two $3$-dimensional vectors, then the *cross* product, $\vec{u} \times \vec{v}$, is defined as a vector with length: - -$$ -\| \vec{u} \times \vec{v} \| = \| \vec{u} \| \| \vec{v} \| \sin(\theta), -$$ - -with $\theta$ being the angle in $[0, \pi]$ between $\vec{u}$ and $\vec{v}$. Consequently, $\sin(\theta) \geq 0$. - - -The direction of the cross product is such that it is *orthogonal* to *both* $\vec{u}$ and $\vec{v}$. There are two such directions, to identify which is correct, the [right-hand rule](https://en.wikipedia.org/wiki/Cross_product#Definition) is used. This rule points the right hand fingers in the direction of $\vec{u}$ and curls them towards $\vec{v}$ (so that the angle between the two vectors is in $[0, \pi]$). The thumb will point in the direction. Call this direction $\hat{n}$, a normal unit vector. Then the cross product can be defined by: - - -$$ -\vec{u} \times \vec{v} = \| \vec{u} \| \| \vec{v} \| \sin(\theta) \hat{n}. -$$ - -:::{callout-note} -## Note -The right-hand rule is also useful to understand how standard household screws will behave when twisted with a screwdriver. If the right hand fingers curl in the direction of the twisting screwdriver, then the screw will go in or out following the direction pointed to by the thumb. - -::: - -The right-hand rule depends on the order of consideration of the vectors. If they are reversed, the opposite direction is determined. A consequence is that the cross product is **anti**-commutative, unlike multiplication: - - -$$ -\vec{u} \times \vec{v} = - \vec{v} \times \vec{u}. -$$ - -Mathematically, the definition in terms of its components is a bit involved: - - -$$ -\vec{u} \times \vec{v} = \langle u_2 v_3 - u_3 v_2, u_3 v_1 - u_1 v_3, u_1 v_2 - u_2 v_1 \rangle. -$$ - -There is a matrix notation that can simplify this computation. If we *formally* define $\hat{i}$, $\hat{j}$, and $\hat{k}$ to represent unit vectors in the $x$, $y$, and $z$ direction, then a vector $\langle u_1, u_2, u_3 \rangle$ could be written $u_1\hat{i} + u_2\hat{j} + u_3\hat{k}$. With this the cross product of $\vec{u}$ and $\vec{v}$ is the vector associated with the *determinant* of the matrix +There is a matrix notation that can simplify the cross-product computation. If we *formally* define $\hat{i}$, $\hat{j}$, and $\hat{k}$ to represent unit vectors in the $x$, $y$, and $z$ direction, then a vector $\langle u_1, u_2, u_3 \rangle$ could be written $u_1\hat{i} + u_2\hat{j} + u_3\hat{k}$. With this the cross product of $\vec{u}$ and $\vec{v}$ is the vector associated with the *determinant* of the matrix $$ @@ -977,42 +1651,6 @@ v_1 & v_2 & v_3 \end{bmatrix} $$ -From the $\sin(\theta)$ term in the definition, we see that $\vec{u}\times\vec{u}=0$. In fact, the cross product is $0$ only if the two vectors involved are parallel or there is a zero vector. - - -In `Julia`, the `cross` function from the `LinearAlgebra` package implements the cross product. For example: - - -```{julia} -a = [1, 2, 3] -b = [4, 2, 1] -cross(a, b) -``` - -There is also the *infix* unicode operator `\times[tab]` that can be used for similarity to traditional mathematical syntax. - - -```{julia} -a × b -``` - -We can see the cross product is anti-commutative by comparing the last answer with: - - -```{julia} -b × a -``` - -Using vectors of size different than $n=3$ produces a dimension mismatch error: - - -```{julia} -#| error: true -[1, 2] × [3, 4] -``` - -(It can prove useful to pad $2$-dimensional vectors into $3$-dimensional vectors by adding a $0$ third component. We will see this in the discussion on curvature in the plane.) - Let's see that the matrix definition will be identical (after identifications) to `cross`: @@ -1033,286 +1671,6 @@ M[2,:] × M[3,:] --- -Consider this extended picture involving two vectors $\vec{u}$ and $\vec{v}$ drawn in two dimensions: - - -```{julia} -u₁ = [1, 2] -v₁ = [2, 1] -p₁ = [0,0] - -plot(aspect_ratio=:equal) -arrow!(p₁, u₁) -arrow!(p₁, v₁) -arrow!(u₁, v₁) -arrow!(v₁, u₁) - -puv₁ = (u₁ ⋅ v₁) / (v₁ ⋅ v₁) * v₁ -porth₁ = u₁ - puv₁ -arrow!(puv₁, porth₁) -``` - -The enclosed shape is a parallelogram. To this we added the projection of $\vec{u}$ onto $\vec{v}$ (`puv`) and then the *orthogonal* part (`porth`). - - -The *area* of a parallelogram is the length of one side times the perpendicular height. The perpendicular height could be found from `norm(porth)`, so the area is: - - -```{julia} -norm(v₁) * norm(porth₁) -``` - -However, from trigonometry we have the height would also be the norm of $\vec{u}$ times $\sin(\theta)$, a value that is given through the length of the cross product of $\vec{u}$ and $\hat{v}$, the unit vector, were these vectors viewed as $3$ dimensional by adding a $0$ third component. In formulas, this is also the case: - - -$$ -\text{area of the parallelogram} = \| \vec{u} \times \hat{v} \| \| \vec{v} \| = \| \vec{u} \times \vec{v} \|. -$$ - -We have, for our figure, after extending `u` and `v` to be three dimensional the area of the parallelogram: - - -```{julia} -u₂ = [1, 2, 0] -v₂ = [2, 1, 0] -norm(u₂ × v₂) -``` - ---- - - -This analysis can be extended to the case of 3 vectors, which---when not co-planar---will form a *parallelepiped*. - - -```{julia} -u₃, v₃, w₃ = [1,2,3], [2,1,0], [1,1,2] -plot() -p₃ = [0,0,0] - -plot(legend=false) -arrow!(p₃, u₃); arrow!(p₃, v₃); arrow!(p₃, w₃) -arrow!(u₃, v₃); arrow!(u₃, w₃) -arrow!(v₃, u₃); arrow!(v₃, w₃) -arrow!(w₃, u₃); arrow!(w₃, v₃) -arrow!(u₃ + v₃, w₃); arrow!(u₃ + w₃, v₃); arrow!(v₃ + w₃, u₃) -``` - -The volume of a parallelepiped is the area of a base parallelogram times the height of a perpendicular. If $\vec{u}$ and $\vec{v}$ form the base parallelogram, then the perpendicular will have height $\|\vec{w}\| \cos(\theta)$ where the angle is the one made by $\vec{w}$ with the normal, $\vec{n}$. Since $\vec{u} \times \vec{v} = \| \vec{u} \times \vec{v}\| \hat{n} = \hat{n}$ times the area of the base parallelogram, we have if we dot this answer with $\vec{w}$: - - -$$ -(\vec{u} \times \vec{v}) \cdot \vec{w} = -\|\vec{u} \times \vec{v}\| (\vec{n} \cdot \vec{w}) = -\|\vec{u} \times \vec{v}\| \| \vec{w}\| \cos(\theta), -$$ - -that is, the area of the parallelepiped. Wait, what about $(\vec{v}\times\vec{u})\cdot\vec{w}$? That will have an opposite sign. Yes, in the above, there is an assumption that $\vec{n}$ and $\vec{w}$ have a an angle between them within $[0, \pi/2]$, otherwise an absolute value must be used, as volume is non-negative. - - -:::{.callout-note} -## Orientation -The triple-scalar product, $\vec{u}\cdot(\vec{v}\times\vec{w})$, gives the volume of the parallelepiped up to sign. If the sign of this is positive, the $3$ vectors are said to have a *positive* orientation, if the triple-scalar product is negative, the vectors have a *negative* orientation. - -::: - -#### Algebraic properties - - -The cross product has many properties, some different from regular multiplication: - - - * scalar multiplication: $(c\vec{u})\times\vec{v} = c(\vec{u}\times\vec{v})$ - * distributive over addition: $\vec{u} \times (\vec{v} + \vec{w}) = \vec{u}\times\vec{v} + \vec{u}\times\vec{w}$. - * *anti*-commutative: $\vec{u} \times \vec{v} = - \vec{v} \times \vec{u}$ - * *not* associative: that is there is no guarantee that $(\vec{u}\times\vec{v})\times\vec{w}$ will be equivalent to $\vec{u}\times(\vec{v}\times\vec{w})$. - * The triple cross product $(\vec{u}\times\vec{v}) \times \vec{w}$ must be orthogonal to $\vec{u}\times\vec{v}$ so lies in a plane with this as a normal vector. But, $\vec{u}$ and $\vec{v}$ will generate this plane, so it should be possible to express this triple product in terms of a sum involving $\vec{u}$ and $\vec{v}$ and indeed: - - -$$ -(\vec{u}\times\vec{v})\times\vec{w} = (\vec{u}\cdot\vec{w})\vec{v} - (\vec{v}\cdot\vec{w})\vec{u}. -$$ - ---- - - -The following shows the algebraic properties stated above hold for symbolic vectors. First the linearity of the dot product: - - -```{julia} -@syms s₄ t₄ u₄[1:3]::real v₄[1:3]::real w₄[1:3]::real - -u₄ ⋅ (s₄ * v₄ + t₄ * w₄) - (s₄ * (u₄ ⋅ v₄) + t₄ * (u₄ ⋅ w₄)) |> simplify -``` - -This shows the dot product is commutative: - - -```{julia} -(u₄ ⋅ v₄) - (v₄ ⋅ u₄) |> simplify -``` - -This shows the linearity of the cross product over scalar multiplication and vector addition: - - -```{julia} -u₄ × (s₄* v₄ + t₄ * w₄) - (s₄ * (u₄ × v₄) + t₄ * (u₄ × w₄)) .|> simplify -``` - -(We use `.|>` to broadcast `simplify` over each component.) - - -The cross product is anti-commutative: - - -```{julia} -u₄ × v₄ + v₄ × u₄ .|> simplify -``` - -but not associative: - - -```{julia} -u₄ × (v₄ × w₄) - (u₄ × v₄) × w₄ .|> simplify -``` - -Finally we verify the decomposition of the triple cross product: - - -```{julia} -(u₄ × v₄) × w₄ - ( (u₄ ⋅ w₄) * v₄ - (v₄ ⋅ w₄) * u₄) .|> simplify -``` - ---- - - -This table shows common usages of the symbols for various multiplication types: `*`, $\cdot$, and $\times$: - - -| Symbol | inputs | output | type | -|:--------:|:-------------- |:----------- |:---------------------- | -| `*` | scalar, scalar | scalar | regular multiplication | -| `*` | scalar, vector | vector | scalar multiplication | -| `*` | vector, vector | *undefined* | | -| $\cdot$ | scalar, scalar | scalar | regular multiplication | -| $\cdot$ | scalar, vector | vector | scalar multiplication | -| $\cdot$ | vector, vector | scalar | dot product | -| $\times$ | scalar, scalar | scalar | regular multiplication | -| $\times$ | scalar, vector | undefined | | -| $\times$ | vector, vector | vector | cross product ($3$D) | - - -##### Example: lines and planes - - -A line in two dimensions satisfies the equation $ax + by = c$. Suppose $a$ and $b$ are non-zero. This can be represented in vector form, as the collection of all points associated to the vectors: $p + t \vec{v}$ where $p$ is a point on the line, say $(0,c/b)$, and v is the vector $\langle b, -a \rangle$. We can verify, this for values of `t` as follows: - - -```{julia} -#| hold: true -@syms a b c x y t - -eq = c - (a*x + b*y) - -p = [0, c/b] -v = [-b, a] -li = p + t * v - -eq(x=>li[1], y=>li[2]) |> simplify -``` - -Let $\vec{n} = \langle a , b \rangle$, taken from the coefficients in the equation. We can see directly that $\vec{n}$ is orthogonal to $\vec{v}$. The line may then be seen as the collection of all vectors that are orthogonal to $\vec{n}$ that have their tail at the point $p$. - - -In three dimensions, the equation of a plane is $ax + by + cz = d$. Suppose, $a$, $b$, and $c$ are non-zero, for simplicity. Setting $\vec{n} = \langle a,b,c\rangle$ by comparison, it can be seen that plane is identified with the set of all vectors orthogonal to $\vec{n}$ that are anchored at $p$. - - -First, let $p = (0, 0, d/c)$ be a point on the plane. We find two vectors $u = \langle -b, a, 0 \rangle$ and $v = \langle 0, c, -b \rangle$. Then any point on the plane may be identified with the vector $p + s\vec{u} + t\vec{v}$. We can verify this algebraically through: - - -```{julia} -#| hold: true -@syms a b c d x y z s t - -eq = d - (a*x + b*y + c * z) - -p = [0, 0, d/c] -u, v = [-b, a, 0], [0, c, -b] -pl = p + t * u + s * v - -subs(eq, x=>pl[1], y=>pl[2], z=>pl[3]) |> simplify -``` - -The above viewpoint can be reversed: - - -> a plane is determined by two (non-parallel) vectors and a point. - - - -The parameterized version of the plane would be $p + t \vec{u} + s \vec{v}$, as used above. - - -The equation of the plane can be given from $\vec{u}$ and $\vec{v}$. Let $\vec{n} = \vec{u} \times \vec{v}$. Then $\vec{n} \cdot \vec{u} = \vec{n} \cdot \vec{v} = 0$, from the properties of the cross product. As such, $\vec{n} \cdot (s \vec{u} + t \vec{v}) = 0$. That is, the cross product is orthogonal to any *linear* combination of the two vectors. This figure shows one such linear combination: - - -```{julia} -#| hold: true -u = [1,2,3] -v = [2,3,1] -n = u × v -p = [0,0,1] - -plot(legend=false) - -arrow!(p, u) -arrow!(p, v) -arrow!(p + u, v) -arrow!(p + v, u) -arrow!(p, n) - -s, t = 1/2, 1/4 -arrow!(p, s*u + t*v) -``` - -So if $\vec{n} \cdot p = d$ (identifying the point $p$ with a vector so the dot product is defined), we will have for any vector $\vec{v} = \langle x, y, z \rangle = s \vec{u} + t \vec{v}$ that - - -$$ -\vec{n} \cdot (p + s\vec{u} + t \vec{v}) = \vec{n} \cdot p + \vec{n} \cdot (s \vec{u} + t \vec{v}) = d + 0 = d, -$$ - -But if $\vec{n} = \langle a, b, c \rangle$, then this says $d = ax + by + cz$, so from $\vec{n}$ and $p$ the equation of the plane is given. - - -In summary: - - -| Object | Equation | vector equation | -|:------ |:------------------:|:-------------------------------- | -| Line | $ax + by = c$ | line: $p + t\vec{u}$ | -| Plane | $ax + by + cz = d$ | plane: $p + s\vec{u} + t\vec{v}$ | - - ---- - - -##### Example - - -You are given that the vectors $\vec{u} =\langle 6, 3, 1 \rangle$ and $\vec{v} = \langle 3, 2, 1 \rangle$ describe a plane through the point $p=[1,1,2]$. Find the equation of the plane. - - -The key is to find the normal vector to the plane, $\vec{n} = \vec{u} \times \vec{v}$: - - -```{julia} -#| hold: true -u, v, p = [6,3,1], [3,2,1], [1,1,2] -n = u × v -a, b, c = n -d = n ⋅ p -"equation of plane: $a x + $b y + $c z = $d" -``` ## Questions @@ -1393,6 +1751,76 @@ val = abs((u × v) ⋅ w) numericq(val) ``` +###### Question + +A parallelogram is formed by vectors $\vec{v}$ and $\vec{w}$. + +:::{#fig-parallelogram-question} +```{julia} +#| echo: false +gr() +let + # plot two vectors + P,Q = (1,2), (2, 1) + O = (0,0) + plot(; empty_style..., xlim=(0, 3.5)) + plot!([O, (3, 0)]; axis_style...) + plot!([O, (0,3)]; axis_style...) + + plot!([O, O .+ P]; arrow=true, line=(:black, 2)) + plot!([O, O .+ Q]; arrow=true, line=(:black, 2)) + plot!([Q, Q .+ P]; arrow=true, line=(:black, 1, :dash)) + plot!([P, Q .+ P]; arrow=true, line=(:black, 1, :dash)) + plot!([O, Q .+ P]; arrow=true, line=(:black, 1, :dash)) + plot!([P,Q]; arrow=true, line=(:red, 2)) + annotate!([ + (3, 0, text(L"x", :top)), + (0, 3, text(L"y", :right)), + (P..., text(L"\vec{w}", :top, :left)), + (Q..., text(L"\vec{v}", :top, :left)), + ((P .+Q)..., text(L"\vec{v}+\vec{w}", :top, :left)) + + ]) +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +Parallelogram formed by two vectors $\vec{v}$ and $\vec{w}$. What is desription of red diagonal? +::: + +One diagonal is given by $\vec{v} + \vec{w}$. What is the other (as in the figure)? + +```{julia} +#| echo: false +choices = [ +L"\vec{v} \cdot \vec{w}", +L"\vec{v} \times \vec{w}", +L"\vec{v} - \vec{w}", +L"\vec{v} + \vec{w}", +] +radioq(choices, 3) +``` + +What is the area of the parallelogram? + + +```{julia} +#| echo: false +choices = [ +L"\vec{v} \cdot \vec{w}", +L"\vec{v} \times \vec{w}", +L"\vec{v} - \vec{w}", +L"\vec{v} + \vec{w}", +] +radioq(choices, 2) +``` + + ###### Question @@ -1446,11 +1874,11 @@ radioq(choices, answ) ###### Question -Let $\vec{u}$ and $\vec{v}$ be 3-dimensional **unit** vectors. What is the value of +Let $\hat{u}$ and $\hat{v}$ be 3-dimensional **unit** vectors. What is the value of $$ -(\vec{u} \times \vec{v}) \cdot (\vec{u} \times \vec{v}) + (\vec{u} \cdot \vec{v})^2? +(\hat{u} \times \hat{v}) \cdot (\hat{u} \times \hat{v}) + (\hat{u} \cdot \hat{v})^2? $$ ```{julia} @@ -1603,6 +2031,116 @@ radioq(choices, answ) ###### Question +In the figure, the tangent line to the unit circle for a given $\theta$ is given. + +```{julia} +#| echo: false +gr() +let + empty_style = (xaxis = ([], false), + yaxis = ([], false), + legend=false) + + @syms s θ + xx = (cos(θ), sin(θ)) + xx′ = diff.(xx, θ) + yy(s) = xx .+ s .* xx′ + + # x₀ + sx = only(solve(yy(s)[2] ~ 0, s)) + x₀ = first(yy(sx)) + + # y₀ + sy = only(solve(yy(s)[1] ~ 0, s)) + y₀ = last(yy(sy)) + + # plot with x-y axis + p = plot(; empty_style..., aspect_ratio=:equal) + plot!([(0, -2), (0, 2)]; arrow=true, line=(:gray, 1)) + plot!([(0, 0), (2, 0)]; arrow=true, line=(:gray, 1)) + + + θs = range(0, 2pi, 200) + plot!(sincos.(θs); line=(:black, 1)) + + θ₀ = 50*pi/180 + plot!([(0,0), reverse(sincos(θ₀))]; line=(:black, 1)) + + tl(x) = float(sin(θ₀) + last(xx′)(θ => θ₀) / first(xx′)(θ => θ₀) * (x - cos(θ₀))) + + x′ = -1/4 + plot!(tl, x′, 2) + + r′ = 1/6 + θs = range(0, θ₀, 100) + xys = [(r′*cos(t), r′*sin(t)) for t ∈ θs] + plot!(xys; line=(:gray, 1)) + + annotate!([ + (2r′*cos(θ₀/2), 2r′*sin(θ₀/2), text(L"θ")), + (float(x₀(θ=>θ₀)), 0, text(L"x_0", :top)), + (0, float(y₀(θ=>θ₀)), text(L"y_0", :right)), + (1/2*cos(θ₀), 1/2 * sin(θ₀), text(L"1", :bottom)) + ]) + current() +end +``` + +```{julia} +#| echo: false +plotly() +nothing +``` + +Using `SymPy`, find the values for $x_0$ and $y_0$. + +For $x_0$, this value might be of use: + +```{julia} +@syms s θ +r = [cos(θ), sin(θ)] +v = diff.(r, θ) +tl(s) = r .+ (s * v) # parametric description of the tangent line + +sₓ = only(solve(last(tl(s)) ~ 0, s)) +``` + +(Simplify `tl(sₓ)`.) + + +What is the value of $x_0$? + +```{julia} +#| echo: false +choices = [ + L"\cos(\theta)", + L"\sin(\theta)", + L"\frac{1}{\cos(\theta)}", + L"\frac{1}{\sin(\theta)}", + L"-\tan(θ)", + L"\frac{1}{\tan(\theta)}" +] +radioq(choices, 3) +``` + +What is the value of $y_0$? + +```{julia} +#| echo: false +choices = [ + L"\cos(\theta)", + L"\sin(\theta)", + L"\frac{1}{\cos(\theta)}", + L"\frac{1}{\sin(\theta)}", + L"-\tan(θ)", + L"\frac{1}{\tan(\theta)}" + +] +radioq(choices, 4) +``` + +###### Question + Give a geometric reason for this identity: