0 2025/inner-outer-0620 When I first learned about vector spaces and their dot and cross products, I felt that something was missing from the explanations. I didn’t feel like I got a good intuition, and the cross product in particular felt mysterious and clunky; why did it have to give another vector, and why does it only seem to work in three dimensions? This blog post is an answer for past me. Get your feet wet by building a better intuition for deriving the dot product, then discover a generalization of the cross product that works in any dimension, not just 3D.
I assume basic familiarity with dot products and cross products— this post does not do a good job of explaining them if you’ve never seen them before!
Let’s start with the inner/dot product, the more familiar of the two. You may have seen it defined as \vec a \cdot \vec b = a_x b_x + a_y b_y + \cdots,
but I want to approach it from the side of pure geometry first instead of using coordinates.
Forget about writing vectors as lists of numbers for a second, and simply think of them as directions and magnitudes,
or arrows in space. We will start from the definition that a dot product is the scalar value of projecting one vector onto the other and
multiplying the resulting lengths:
\begin{document}
\usetikzlibrary{quotes,angles}
\begin{tikzpicture}[scale=3]
\draw[line width=0.25mm,->] (0, 0) coordinate (o) -- (1, 0.5) coordinate (b) node[anchor=west] {$\vec b$};
\draw[line width=0.25mm,->] (0, 0) -- (2, 0) coordinate(a) node[anchor=west] {$\vec a$}
pic["$\theta$",draw=black,-,angle eccentricity=1.2,angle radius=1cm] {angle=a--o--b};
\draw[dashed] (1, 0.5) -- (1, 0);
\end{tikzpicture}
\end{document}\vec a \cdot \vec b = |a| |b| \cos\theta.
From here, let us consider the properties that this has. The definition of |a| |b| \cos \theta suggests a few things:
\vec a \cdot \vec b = \vec b \cdot \vec a since \cos is even.\left(\alpha \vec a\right) \cdot \left(\beta \vec b\right) = \alpha \beta \left(\vec a \cdot \vec b\right).\cos 90^\circ = 0.\vec a \cdot \vec a = |a|^2 since \cos 0^\circ = 1.By thinking about it for a bit longer, we also get that it should be distributive:
\begin{document}
\begin{tikzpicture}[scale=3]
\draw[line width=0,fill=red!20] (0, 0) -- (1.5, 1) -- (1.5, 0) -- cycle;
\draw[line width=0,fill=blue!20] (1.5, 1) -- (2, 0.75) -- (2, 0) -- (1.5, 0) -- cycle;
\draw[->] (0, 0) coordinate (o) -- (2.5, 0) coordinate (a) node[anchor=west] {$\vec a$};
\draw[->] (0, 0) to[edge label=$\vec b$] (1.5, 1) coordinate (b);
\draw[->] (b) to[edge label=$\vec c$] (2, 0.75) coordinate (c);
\draw[->,dashed] (0, 0) -- (c) node[pos=0.75, above, sloped] {$\vec b + \vec c$};
\end{tikzpicture}
\end{document}\vec a \cdot \left(\vec b + \vec c\right) = \vec a \cdot \vec b + \vec a \cdot \vec c
These properties of the dot product actually already imply the Pythagorean theorem! From our definition of the dot product,
we know that \vec a \cdot \vec a = |a|^2. We then want to write our vector \vec a as a linear combination
of two orthonormal basis vectors \hat x and \hat y:
\vec a = \alpha_x \hat x + \alpha_y \hat y.
Here, orthonormal just means that they are perpendicular,
with \hat x \cdot \hat y = 0, and they have a length of 1, with \hat x \cdot \hat x = \hat y \cdot \hat y = 1. If we just expand the dot product,
\begin{align*} |a|^2 &= \vec a \cdot \vec a \\ &= \left(\alpha_x \hat x + \alpha_y \hat y\right) \cdot \left(\alpha_x \hat x + \alpha_y \hat y\right) \\ &= \alpha_x^2 \left(\hat x \cdot \hat x\right) + \alpha_y \left(\hat y \cdot \hat y\right) + 2 \alpha_x \alpha_y \cancelto{0}{\left(\hat x \cdot \hat y\right)} \\ &= \boxed{\alpha_x^2 + \alpha_y^2}. \end{align*}
Hey the 3rd line seems highly suggestive of the law of cosines… And indeed, if we draw a triangle of tip-to-tail vector addition with the vectors
\vec c = \vec a - \vec b, we can see that
\vec c \cdot \vec c = |a|^2 + |b|^2 - |a||b|\cos\theta.
Now for the fun part! Once again, I will start from pure geometry without any reference to coordinates, but instead of starting
directly from the cross product, let’s start with the wedge product \vec a \wedge \vec b. It’s a generalization of the
cross product and it’s subtly different, but it fundamentally does the same thing and has the advantage of also working in 2D where things are easier to explain.
Whereas the inner product looks inwards and is about projecting vectors onto each other, the outer product extends outwards and is about
the space spanned by the two vectors. We will define the outer product \vec a \wedge \vec b as the parallelogram formed
by the vectors \vec a and \vec b:
\begin{document}
\usetikzlibrary{quotes,angles}
\begin{tikzpicture}[scale=3]
\draw[fill=blue!20,line width=0mm] (0,0) -- (1.5, 1) -- (3.5, 1) -- (2, 0) -- cycle;
\draw[line width=0.25mm,->] (0, 0) coordinate (o) -- (1.5, 1) coordinate (b) node[midway,above] {$\vec b$};
\draw[line width=0.25mm,->] (0, 0) -- (2, 0) coordinate(a) node[midway,below] {$\vec a$}
pic["$\theta$",draw=black,-,angle eccentricity=1.2,angle radius=1cm] {angle=a--o--b};
\draw[dashed] (1.5, 1) -- (1.5, 0);
\draw (2, 0.5) node {$\vec a \wedge \vec b$};
\end{tikzpicture}
\end{document}Just trust that this thing “is a parallelogram” for now; we can still make precise mathematical statements with this. For example, we know the area of the parallelogram:
\left|\vec a \wedge \vec b\right| = |a| |b| \sin\theta.
This gives us a nice symmetry with the case of the dot product, but beware! \cos\left(-\theta\right) = \cos \theta, but \sin\left(-\theta\right) = -\sin \theta.
Instead of being commutative, the wedge product is anti-commutative, where \vec a \wedge \vec b = - \left(\vec b \wedge \vec a\right).
We have this sense of “negative area,” or maybe more accurately orientation, where our parallelogram can either be face-up (positive) or face-down (negative).
Which side is positive and which is negative is just a matter of arbitrary convention (right hand rule!),
but if you’ve studied cross products or matrix determinants before, this concept will be familiar.
Like the dot product, it turns out that the wedge product works nicely with scalar multiplication and is both left-distributive and right-distributive.
You can draw the diagrams to convince yourself of this as an exercise (I’m too lazy to make another tikz diagram).
Also, since the area of the parallelogram vanishes as vectors become parallel (and \sin 0^\circ = 0), we have \vec a \wedge \vec a = 0.
Ok, that was a lot. Let’s work through an example of taking a wedge product in 2D: Let \vec a = \alpha_x \hat x + \alpha_y \hat y and
\vec b = \beta_x \hat x + \beta_y \hat y.
\begin{align*} \vec a \wedge \vec b &= \left(\alpha_x \hat x + \alpha_y \hat y\right)\wedge \left(\beta_x \hat x + \beta_y \hat y\right) \\ &= \alpha_x \beta_x \cancelto{0}{\left(\hat x \wedge \hat x\right)} + \alpha_x \beta_y \left(\hat x \wedge \hat y\right) + \alpha_y \beta_x \left(\hat y \wedge \hat x\right) + \alpha_y \beta_y \cancelto{0}{\left(\hat y \wedge \hat y\right)} \\ &= \boxed{(\alpha_x \beta_y - \alpha_y \beta_x)\left(\hat x \wedge \hat y\right)} \end{align*}
Hey! That’s the formula for the determinant of the 2x2 matrix \begin{vmatrix} \alpha_x & \beta_x \\ \alpha_y & \beta_y\end{vmatrix}. Neat! Also notice
how the terms that go to 0 in this expansion are exactly the opposite of the terms that went to 0 when we did this with the inner product.
What we’ve discovered here is a bivector, aka a 2-form. It’s just an upgraded version of a vector (which we also call a 1-form), where
instead of having an oriented 1D length, we have an oriented 2D area. Where vectors have a length and a direction,
bivectors have an area and an orientation. While this orientation can only be one of two possibilities (like heads or tails) in a 2D vector space,
in 3D you have the freedom to face any direction you want! This is how a bivector ties into what you already know about the cross product:
the cross product \vec a\times \vec b gives you a vector perpendicular to the parallelogram formed by
\vec a and \vec b, with magnitude equal to its area. All along, that vector was just acting as a proxy for the 2-form.
Later, we will see how you can use the Hodge dual to go between the vector of the cross product and the 2-form of the wedge product.
Naturally, since we’ve started counting, we can keep doing wedge products and extend this to volumes, hypervolumes, etc. That number you see in front of “-form”
is called the grade, and it tells you the dimension of the object you’re working with. Keep in mind the difference between the dimension of the object
and the dimension of the vector space you’re working in; you can have a 2D sheet of paper in your 3D room.
If we are careful to avoid the \vec a \wedge \vec a = 0 case, in general we have a rule that
j\text{-form} \wedge k\text{-form} = (j+k)\text{-form}.
The \vec a \wedge \vec a = 0 case is analogous to having linearly dependent columns in a matrix, which makes the determinant go to 0 immediately. At this point,
I will also make the claim without justification that the wedge product is associative. Also note that the wedge product with a scalar will just
be normal scalar multiplication.
To fully understand the connection between the wedge product and the cross product, we must understand the Hodge dual.
Let’s take the example of a 2D space and consider what objects (k\text{-forms}) we can build from the wedge product of vectors.
Terminology note here: these k\text{-forms} are called blades if they can be written as the wedge product of some vectors directly,
while n\text{-forms} more generally are linear combinations of blades.
Grade k | Name | Basis Blades | No. Basis Blades n |
|---|---|---|---|
| 0 | Scalar | \{1\} | 1 |
| 1 | Vector | \{\hat x, \hat y\} | 2 |
| 2 | Bivector | \{\hat x \wedge \hat y\} | 1 |
The space of 1\text{-forms} (vectors) in 2D is spanned by \hat x and \hat y,
while the space of 2\text{-forms} (bivectors) is spanned by only a single element \hat x \wedge \hat y since there’s
only one real way that areas can be oriented.
What does this look like in three dimensions?
Grade k | Name | Basis Blades | No. Basis Blades n |
|---|---|---|---|
| 0 | Scalar | \{1\} | 1 |
| 1 | Vector | \{\hat x, \hat y, \hat z\} | 3 |
| 2 | Bivector | \{\hat x \wedge \hat y, \hat y \wedge \hat z, \hat x \wedge \hat z\} | 3 |
| 3 | Trivector | \{\hat x \wedge \hat y \wedge \hat z\} | 1 |
Hey it’s nice and symmetrical! It turns out we end up getting a Pascal’s triangle structure, as
the number of basis blades of grade k is equal to \binom{N}{k}, where N is the dimension
of the overall vector space. You can see that we are taking all N of the basis vectors and choosing k
of them to include in each of our basis blades.
The case of the trivector in 3D and the bivector in 2D
are special, as there is only one element of that grade. We can pair them up with the scalars, and so we call them
pseudoscalars. To match with the scalar unit (aka the number 1), we say that the pseudoscalar unit \mathbb{1} is the
result of taking the wedge product of every basis vector. In 2D, \mathbb 1 = \hat x \wedge \hat y, and in 3D \mathbb 1 = \hat x \wedge \hat y \wedge \hat z.
In general, there is an easy mapping from
k\text{-forms} to (N-k)\text{-forms}, and this mapping is the Hodge dual: the Hodge dual of X is written \ast X.
This takes scalars to trivectors (and vice versa) and vectors to biectors (and vice versa),
and it is how you go from the cross product to the wedge product. We have (loosely) that \vec a \times \vec b = \ast\left(\vec a \wedge \vec b\right).
More specifically, the Hodge dual \ast X of some unit k\text{-blade} X where |X| = \det X = 1 is the (N-k)\text{-blade} such that
X \wedge \ast X = \ast 1 = \mathbb{1}.
Remember that in 3D, the pseudoscalar \mathbb{1} = \hat x \wedge \hat y \wedge \hat z.
Ok, this is not the real definition of the hodge star, but you can look on Wikipedia for the real version.
The gist is that more generally, we have that X \wedge \ast X = |X|^2 (\ast 1),1 and the hodge star is
a linear operator. Because it’s a linear operator, we can just take the hodge dual of the basis blades
individually to get the overall hodge dual of the object we’re working with. Let’s take a look at the hodge dual in 3D:
\begin{align*} \ast \hat x &= \hat y \wedge \hat z \\ \ast \hat y &= -\hat x \wedge \hat z \\ \ast \hat z &= \hat x \wedge \hat y \end{align*}
The dual of a vector is a bivector! But what about in 2D, where the dual of a vector is another vector?
\begin{align*} \ast \hat x &= \hat y \\ \ast \hat y &= -\hat x \end{align*}
Huh! The Hodge dual is clearly not a self-inverse: if we apply it twice in this case, we pick up a minus sign. But what did
it do geometrically? This is a 90-degree counterclockwise rotation! We’ve moved the x-axis to the y-axis, and the y-axis to the -x-axis.
More generally, we get a sense for the geometric meaning
of the Hodge dual: the Hodge dual gives you the space perpendicular to what you have now. If you have a vector, you get the
bivector in 3D, and you literally get a perpendicular vector in 2D.
Now for some bonus content to make Dr. Adler’s MVC class make sense. Recall the gradient theorem, the divergence theorem, and Stokes’ theorem:
\int^a_b \nabla F \cdot \mathrm{d}\ell = F(a)-F(b)
\iint \nabla \times \vec F \cdot \mathrm{d}S = \oint \vec F \cdot \mathrm{d}\ell
\iiint \nabla \cdot \vec F\,\mathrm{d}A = \iint \vec F \cdot \mathrm{d}S
Now that we understand the wedge product, we can begin to understand generalized Stokes:
\int_\Omega \mathrm{d}\omega = \int_{\partial \Omega} \omega
where the \mathrm{d} is the exterior derivative defined as
\mathrm{d}F = \sum_i \frac{\partial F}{\partial x_i} \wedge \hat x_i.
We sum over all the (orthonormal) basis vectors \hat x_i. Note the difference between x_i, the coordinate for the ith basis vector,
and \hat x_i, the basis vector itself. We can understand what the exterior derivative does with this table:
| Input to Exterior Derivative | Operation (Up to Hodge Dual) | Result |
|---|---|---|
| Scalar Field | Gradient \nabla | Vector Field |
| Vector Field | Curl \nabla \times | Bivector Field |
| Bivector Field | Divergence \nabla \cdot | Pseudoscalar Field |
| Pseudoscalar Field | N/A | Just 0 |
The exterior derivative always increases the grade of the field by 1. You can verify algebraically that taking the exterior derivative is equivalent to these operations (maybe I’ll write up a full explanation of this later). Anyways, from the definition of the exterior derivative, we get the identity that
d^2 = 0.
For our derivation, let’s expand:
\begin{align*} d^2 F &= \sum_i \frac{\partial}{\partial x_i} \left(\sum_j \frac{\partial F}{\partial x_j} \wedge \hat x_i\right) \wedge \hat x_i \\ &= \sum_i \sum_j \frac{\partial^2 F}{\partial x_ix_j} \wedge x_i \wedge x_j \end{align*}
We see that the terms are 0 when i = j in the sum from the property that a\wedge a = 0, and since a \wedge b = - b \wedge a, all the
remaining terms can be paired with an opposite that exactly cancels it out! While the wedge product anti-commutes, the partial derivative operators
commute (Clairaut’s theorem). From this singular statement that d^2 = 0, we get these two identities:
\nabla \times \nabla F = 0,\qquad \nabla \cdot \nabla \times \vec F = 0.
You might have noticed that to take a divergence, we must Hodge dual our vector field first to get a bivector field, then Hodge dual our result again to get back to a scalar from a pseudoscalar. Thus it is useful to define a codifferential operator:
\delta = (-1)^{\text{something}} \ast \mathrm{d} \ast.
Ok, this is actually wrong and will sometimes give you the wrong sign but close enough.
The codifferential operator also has the property that \delta^2 = 0 since the Hodge dual will (mostly) cancel with itself.
With this, we can write the Laplacian as
\begin{align*} \nabla^2 F &= (\mathrm{d} + \delta)^2 F = \mathrm{d}\delta F + \delta\mathrm{d} F \\ &= \begin{cases} \nabla \cdot \nabla F & \qquad \text{scalar } F \\ \nabla \left(\nabla \cdot \vec F\right) - \nabla \times \nabla \times \vec F & \qquad \text{vector } \vec{F} \end{cases} \end{align*}
You can verify this algebraically again (but I don’t want to). The negative sign is from the detail of the real definition of the codifferential that I’m glossing over. I also probably want to go over the geometric connection for curl, div, grad more in this post.
Turns out the Hodge dual actually depends on the metric for the inner product. Huh, learned that while researching this. ↩