The dot product turns two vectors into one number. Compute it by multiplying matching coordinates and adding, or as length times length times the cosine of the angle, and see from the law of cosines why the two recipes always agree.
Compute the dot product of two vectors with any number of entries by multiplying matching coordinates and adding.
Compute the same number in the plane as length times length times the cosine of the angle between the arrows.
Derive from the law of cosines that the two recipes always agree.
Read the sign of a dot product as an acute, right or obtuse angle, and its size as a length times a shadow.
Use the four algebraic rules of the dot product to expand and simplify expressions.
In review. The maths and code on this page are checked by automated tests on every change, but an independent reader has not signed it off yet. Spot a mistake or a confusing step? Tell us.
The question
An artificial neuron starts with one small sum: multiply each input by its weight and add the results. A search engine scores a document against your query in the same way. Why should “multiply matching numbers and add” say anything about whether two arrows point the same way?
Intuition
The dot product takes two vectors and gives back one number. There are two recipes for that number, and at first sight they have nothing to do with each other.
M02.3.1-F1
One number, two recipes. On the left, pair up the entries, multiply and add. On the right, multiply the two lengths and the cosine of the angle between the arrows. Both give 10.
Way 1, by coordinates. Pair up the entries, multiply each pair and add: \(4 \cdot 1 + 2 \cdot 3 = 10\). This is plain arithmetic, and it works for lists of any length.
Way 2, by geometry. Multiply the two lengths and the cosine of the angle between the arrows: \(\sqrt{20} \cdot \sqrt{10} \cdot \cos 45^\circ = 10\).
Way 1 is how a computer does it. Way 2 says what the number means. The cosine is 1 when two arrows point the same way, 0 when they stand at a right angle, and \(-1\) when they point in opposite directions. So the dot product is large and positive when two long arrows agree, zero when they are perpendicular, and negative when they oppose each other.
This lesson shows that the two recipes always give the same number. The vectors \(\vect{a} = (4, 2)\) and \(\vect{b} = (1, 3)\) in the figure are the running pair of this module.
Build it up
Step 1. Pair, multiply, add. For \(\vect{a} = (a_1, a_2)\) and \(\vect{b} = (b_1, b_2)\) the dot product is \(\vect{a} \cdot \vect{b} = a_1 b_1 + a_2 b_2\). The answer is a number, not a vector, so it is also called the scalar product. With more entries the pairing just carries on: \((1, 2, 3) \cdot (4, -5, 6) = 4 - 10 + 18 = 12\).
Step 2. A vector dotted with itself gives its length squared. Take \(\vect{a} \cdot \vect{a} = 4 \cdot 4 + 2 \cdot 2 = 20\). By Pythagoras, the arrow \((4, 2)\) has length \(\sqrt{4^2 + 2^2} = \sqrt{20}\). So \(\vect{a} \cdot \vect{a}\) is the length of \(\vect{a}\), squared. With \(\norm{\vect{a}}\) for the length of \(\vect{a}\), as in lesson M02.1.2, this reads \(\vect{a} \cdot \vect{a} = \norm{\vect{a}}^2\). The next lesson is about this.
Step 3. The sign says which way. Keep \(\vect{a}\) fixed and turn \(\vect{b}\). From the tip of \(\vect{b}\), drop a perpendicular onto the line through \(\vect{a}\). The piece of that line from the origin to the foot of the perpendicular is the shadow of \(\vect{b}\) on \(\vect{a}\).
M02.3.1-F2
The sign of the dot product, read from the shadow. An acute angle gives a shadow that points along \(\vect{a}\) and a positive number. A right angle gives no shadow and zero. An obtuse angle gives a shadow that points against \(\vect{a}\) and a negative number.
Step 4. The size is a length times a shadow. In the first panel the shadow of \(\vect{b}\) ends at \((2, 1)\), so its length is \(\sqrt{5}\). The length of \(\vect{a}\) is \(\sqrt{20}\), and \(\sqrt{20} \cdot \sqrt{5} = \sqrt{100} = 10\): the dot product again. The shadow is the side of a right triangle next to the angle \(\theta\), and the hypotenuse of that triangle is \(\vect{b}\). So the shadow has length \(\norm{\vect{b}} \cos\theta\), counted as negative when it points against \(\vect{a}\). That turns “length times shadow” into
The two vectors must have the same number of entries.
Four algebraic rules. For all vectors \(\vect{a}, \vect{b}, \vect{c}\) in \(\R^n\) and every number \(k\):
Order does not matter.\(\vect{a} \cdot \vect{b} = \vect{b} \cdot \vect{a}\), because \(a_i b_i = b_i a_i\) in every term.
It spreads over a sum.\(\vect{a} \cdot (\vect{b} + \vect{c}) = \vect{a} \cdot \vect{b} + \vect{a} \cdot \vect{c}\). Term \(i\) of the left side is \(a_i (b_i + c_i) = a_i b_i + a_i c_i\). Adding up the first pieces gives \(\vect{a} \cdot \vect{b}\) and adding up the second pieces gives \(\vect{a} \cdot \vect{c}\).
Numbers pull out.\((k\vect{a}) \cdot \vect{b} = k\,(\vect{a} \cdot \vect{b})\), because term \(i\) is \((k a_i) b_i = k\,(a_i b_i)\) and \(k\) is a common factor of the whole sum.
A vector with itself.\(\vect{a} \cdot \vect{a} = a_1^2 + \cdots + a_n^2 = \norm{\vect{a}}^2\). A sum of squares is never negative, and it is zero only when every \(a_i\) is zero.
By rule 1, rules 2 and 3 work in either slot. Together they let us multiply out brackets as in school algebra. We need one such expansion straight away:
The first step uses rules 2 and 3 in the first slot. The second uses them in the second slot. The last uses rule 1: \(\vect{b} \cdot \vect{a}\) is the same number as \(\vect{a} \cdot \vect{b}\).
NoteResult: the two recipes agree
Let \(\vect{a}\) and \(\vect{b}\) be non-zero vectors in the plane or in space, and let \(\theta\) be the angle between them, from \(0^\circ\) to \(180^\circ\). Then
Derivation. Draw \(\vect{a}\) and \(\vect{b}\) from the origin. The arrow from the tip of \(\vect{b}\) to the tip of \(\vect{a}\) is \(\vect{a} - \vect{b}\). The three arrows close a triangle.
M02.3.1-F3
The triangle behind the proof. Its third side is \(\vect{a} - \vect{b}\), and the law of cosines ties the three side lengths to the angle \(\theta\).
Work out the squared length of the third side in two ways.
With geometry. The law of cosines for a triangle with sides \(\norm{\vect{a}}\) and \(\norm{\vect{b}}\) that meet at the angle \(\theta\) (derived in the box below) says
Subtract \(\norm{\vect{a}}^2 + \norm{\vect{b}}^2\) from both sides. What is left is \(-2\,\norm{\vect{a}}\,\norm{\vect{b}}\cos\theta = -2\,\vect{a} \cdot \vect{b}\). Divide by \(-2\):
Lengths are never negative, so the sign of the dot product is the sign of \(\cos\theta\): positive for an acute angle, zero for a right angle, negative for an obtuse one. That is Step 3.
Go deeper: where the law of cosines comes from
To keep the lines short, write \(a\) for the length \(\norm{\vect{a}}\) and \(b\) for the length \(\norm{\vect{b}}\). Turn the page until \(\vect{a}\) lies along the positive horizontal axis, and flip it over if \(\vect{b}\) then points below the axis. Turning and flipping change no length and no angle. The tip of \(\vect{a}\) is now at \((a, 0)\). The tip of \(\vect{b}\) is at \((b\cos\theta,\; b\sin\theta)\): that is what cosine and sine mean on a circle of radius \(b\). Pythagoras gives the squared distance between the two tips:
using \(\cos^2\theta + \sin^2\theta = 1\) in the last line. With the lengths written out again, this is \(\norm{\vect{a}}^2 + \norm{\vect{b}}^2 - 2\,\norm{\vect{a}}\,\norm{\vect{b}}\cos\theta\), the law of cosines. The argument never asks for a real triangle, so it also covers \(\theta = 0^\circ\) and \(\theta = 180^\circ\), where the arrows lie along one line. At \(\theta = 90^\circ\) the last term vanishes and the law of cosines becomes Pythagoras.
In four or more dimensions there is no protractor. Two arrows from the origin still lie in one flat plane, so the same triangle exists, and lesson M02.3.3 turns the formula round to define the angle.
Frontier note: dot products inside a transformer
The attention step of a transformer is built from dot products. Each word asks a question, a query vector, and every word offers a key vector. The model takes the dot product of the query with every key, divides by the square root of the key dimension and turns the scores into weights with a softmax (Vaswani et al., 2017, Section 3.2.1). A large dot product means “this key answers my query”, so that word receives more of the attention.
Worked example
Compute \(\vect{a} \cdot \vect{b}\) for \(\vect{a} = (4, 2)\) and \(\vect{b} = (1, 3)\), both ways.
M02.3.1-F4
Two routes through the numbers. Route 1 never mentions an angle. Route 2 never pairs up coordinates. They meet at 10.
Route 2. The lengths are \(\norm{\vect{a}} = \sqrt{4^2 + 2^2} = \sqrt{20}\) and \(\norm{\vect{b}} = \sqrt{1^2 + 3^2} = \sqrt{10}\). For the angle, measure each arrow from the horizontal axis. The arrow \(\vect{a}\) rises 2 for every 4 across, so its angle has tangent \(2/4\), which is \(26.57^\circ\). The arrow \(\vect{b}\) rises 3 for every 1 across: tangent 3, which is \(71.57^\circ\). The angle between them is \(71.57^\circ - 26.57^\circ = 45^\circ\), and \(\cos 45^\circ = 1/\sqrt{2}\). So
Read the shadow. The shadow of \(\vect{b}\) on \(\vect{a}\) has length \(\norm{\vect{b}}\cos\theta = \sqrt{10}/\sqrt{2} = \sqrt{5} \approx 2.24\), and \(\norm{\vect{a}} \cdot \sqrt{5} = \sqrt{20} \cdot \sqrt{5} = 10\). The other way round, the shadow of \(\vect{a}\) on \(\vect{b}\) has length \(\sqrt{20}/\sqrt{2} = \sqrt{10}\), and \(\norm{\vect{b}} \cdot \sqrt{10} = 10\) again. This is rule 1 as a picture.
Three quick ones.\((4, 2) \cdot (-1, 2) = -4 + 4 = 0\): perpendicular. \((4, 2) \cdot (-2, 1) = -8 + 2 = -6\): an obtuse angle. And in three dimensions \((1, 2, 3) \cdot (4, -5, 6) = 4 - 10 + 18 = 12\).
Use a rule. Let \(\vect{c} = (-2, 1)\). Then \(\vect{b} + \vect{c} = (-1, 4)\) and \(\vect{a} \cdot (\vect{b} + \vect{c}) = -4 + 8 = 4\). Rule 2 predicts \(\vect{a} \cdot \vect{b} + \vect{a} \cdot \vect{c} = 10 + (-6) = 4\). It checks.
Code
From scratch first, with vectors as plain tuples.
def dot(a, b):"""Multiply matching entries and add."""iflen(a) !=len(b):raiseValueError("the two vectors need the same number of entries") total =0for x, y inzip(a, b): total += x * yreturn totala, b = (4, 2), (1, 3)print("a . b =", dot(a, b), " a . a =", dot(a, a))print("right angle:", dot(a, (-1, 2)), " obtuse:", dot(a, (-2, 1)))print("three entries:", dot((1, 2, 3), (4, -5, 6)))
a . b = 10 a . a = 20
right angle: 0 obtuse: -6
three entries: 12
Now the second recipe. The angle of each arrow comes from atan2, which never looks at a dot product. Python measures angles in radians, so the code converts to degrees only for printing.
import mathdef length(v):return math.sqrt(dot(v, v))alpha = math.atan2(a[1], a[0]) # direction of abeta = math.atan2(b[1], b[0]) # direction of btheta = beta - alphaprint("directions:", round(math.degrees(alpha), 2), "and", round(math.degrees(beta), 2), "degrees")print("angle between:", round(math.degrees(theta), 6), "degrees")print("length x length x cosine:", round(length(a) * length(b) * math.cos(theta), 10))print("shadow of b on a:", round(length(b) * math.cos(theta), 4))
directions: 26.57 and 71.57 degrees
angle between: 45.0 degrees
length x length x cosine: 10.0
shadow of b on a: 2.2361
The library version. NumPy writes the dot product of two arrays as a @ b or np.dot(a, b). The loop then tests the four rules, and the agreement of the two recipes, on random vectors.
import numpy as npa, b = np.array([4, 2]), np.array([1, 3])print("a @ b =", a @ b, " np.dot(a, b) =", np.dot(a, b))print("a * b =", a * b, " entry by entry: a list, not a dot product")rng = np.random.default_rng(0)for _ inrange(1000): u, v, w = rng.normal(size=(3, 5)) # three vectors with five entries k = rng.normal()assert np.isclose(u @ v, v @ u) # rule 1assert np.isclose(u @ (v + w), u @ v + u @ w) # rule 2assert np.isclose((k * u) @ v, k * (u @ v)) # rule 3assert u @ u >=0# rule 4 p, q = rng.normal(size=(2, 2)) # two arrows in the plane angle = np.arctan2(q[1], q[0]) - np.arctan2(p[1], p[0])assert np.isclose(p @ q, np.linalg.norm(p) * np.linalg.norm(q) * np.cos(angle))print("four rules and both recipes agree on 1000 random cases")
a @ b = 10 np.dot(a, b) = 10
a * b = [4 6] entry by entry: a list, not a dot product
four rules and both recipes agree on 1000 random cases
Finally, the neuron of the opening question. Its first step is a dot product plus one number.
This module’s interactive, the projection explorer, lives in lesson M02.3.4. You can already read most of it. Drag \(\vect{b}\) round \(\vect{a}\) and watch the dot product pass through zero exactly when the angle passes \(90^\circ\), and watch the shadow flip to the other side of the origin.
Pitfalls
M02.3.1-F5
Wrong beside right. Multiplying entry by entry is only the first half of a dot product. The second half, adding, is what turns a list into one number.
“To multiply two vectors, multiply the entries that sit in the same place.”
That gives \((4, 6)\), which is still a list. The dot product goes on to add: \(4 + 6 = 10\). NumPy runs both without complaint: a * b is the entry-by-entry product and a @ b is the dot product. It is an easy slip to make in machine-learning code, and it can go unnoticed because the shapes still fit.
“A big dot product means the two vectors point the same way.”
A dot product grows with length as well as with agreement. Scale \(\vect{b}\) by 10 and \(\vect{a} \cdot (10\vect{b}) = 100\), yet the angle is still \(45^\circ\). A recommender that scores items by a raw dot product will favour items with long vectors, whatever their direction. To compare directions alone, divide by both lengths. That is the cosine similarity of lesson M02.3.3.
You cannot cancel a vector from a dot product. With \(\vect{a} = (4, 2)\), both \(\vect{b} = (1, 3)\) and \(\vect{c} = (3, -1)\) give 10. Equal dot products only say that \(\vect{b}\) and \(\vect{c}\) have the same shadow on \(\vect{a}\). Their difference, \((-2, 4)\), is perpendicular to \(\vect{a}\): \(4 \cdot (-2) + 2 \cdot 4 = 0\).
Check yourself
Recall
1. Compute \((3, -1) \cdot (2, 5)\).
Show answer
\(3 \cdot 2 + (-1) \cdot 5 = 6 - 5 = 1\).
2. State the two recipes for the dot product.
Show answer
Multiply matching coordinates and add: \(a_1 b_1 + \cdots + a_n b_n\). Or multiply the two lengths and the cosine of the angle between the arrows: \(\norm{\vect{a}}\,\norm{\vect{b}}\cos\theta\).
3. What does the sign of \(\vect{a} \cdot \vect{b}\) tell you about the angle between the arrows?
Show answer
Positive means acute, zero means a right angle, negative means obtuse.
4. What is \(\vect{a} \cdot \vect{a}\)?
Show answer
The length of \(\vect{a}\), squared: \(\norm{\vect{a}}^2 = a_1^2 + \cdots + a_n^2\).
5. Which theorem about triangles links the two recipes?
Show answer
The law of cosines, applied to the triangle with sides \(\vect{a}\), \(\vect{b}\) and \(\vect{a} - \vect{b}\).
Exercises
1.★ Let \(\vect{u} = (2, -3, 1)\) and \(\vect{v} = (4, 1, -2)\). Compute \(\vect{u} \cdot \vect{v}\). Is the angle between them acute, right or obtuse?
Show solution
\(\vect{u} \cdot \vect{v} = 2 \cdot 4 + (-3) \cdot 1 + 1 \cdot (-2) = 8 - 3 - 2 = 3\). The dot product is positive, so the angle is acute.
2.★★ (a) Compute \((3, 0) \cdot (2, 2)\) by both recipes. (b) Find the number \(t\) that makes \((t, 2)\) perpendicular to \((3, -1)\).
Show solution
(a) By coordinates: \(3 \cdot 2 + 0 \cdot 2 = 6\). By geometry: the lengths are \(3\) and \(\sqrt{2^2 + 2^2} = \sqrt{8}\). The arrow \((3, 0)\) lies along the horizontal axis and \((2, 2)\) lies on the diagonal, so the angle is \(45^\circ\). Then \(3 \cdot \sqrt{8} \cdot \tfrac{1}{\sqrt{2}} = 3 \cdot \sqrt{4} = 6\). They agree.
(b) Perpendicular means the dot product is zero: \((t, 2) \cdot (3, -1) = 3t - 2 = 0\), so \(t = \tfrac{2}{3}\). Check: \(\tfrac{2}{3} \cdot 3 + 2 \cdot (-1) = 2 - 2 = 0\).
3.★★★ Use the four rules to show that, for any two vectors, \(\norm{\vect{a} + \vect{b}}^2 + \norm{\vect{a} - \vect{b}}^2 = 2\,\norm{\vect{a}}^2 + 2\,\norm{\vect{b}}^2\). Check it with \(\vect{a} = (4, 2)\) and \(\vect{b} = (1, 3)\). What does it say about a parallelogram?
Show solution
By rule 4 and the same expansion as in the lesson, with a plus sign in place of the minus,
The lesson showed \(\norm{\vect{a} - \vect{b}}^2 = \norm{\vect{a}}^2 - 2\,\vect{a} \cdot \vect{b} + \norm{\vect{b}}^2\). Add the two lines. The terms \(+2\,\vect{a} \cdot \vect{b}\) and \(-2\,\vect{a} \cdot \vect{b}\) cancel, which leaves \(2\,\norm{\vect{a}}^2 + 2\,\norm{\vect{b}}^2\).
Check: \(\vect{a} + \vect{b} = (5, 5)\) has squared length 50, and \(\vect{a} - \vect{b} = (3, -1)\) has squared length 10. The sum is 60, and \(2 \cdot 20 + 2 \cdot 10 = 60\).
The vectors \(\vect{a} + \vect{b}\) and \(\vect{a} - \vect{b}\) are the two diagonals of the parallelogram with sides \(\vect{a}\) and \(\vect{b}\). So the squares of the two diagonals add up to the squares of the four sides. This is called the parallelogram law.
Summary card
One number, two recipes: coordinates compute it, geometry explains it.
Sources. Each was opened and checked against this lesson on 12 November 2026.
OpenStax, Calculus Volume 3, Section 2.3, The Dot Product. The definition by components (equation 2.3), the four properties (Theorem 2.3) and the formula \(\vect{u} \cdot \vect{v} = \norm{\vect{u}}\,\norm{\vect{v}}\cos\theta\) (Theorem 2.4), which the book also proves from the law of cosines.
Grant Sanderson, Dot products and duality, 3Blue1Brown, Linear Algebra, chapter 9. The reading of the dot product as the length of a projection times the length of the other vector, negative when the projection points the opposite way and zero when the vectors are perpendicular.
NumPy, numpy.dot. For two 1-D arrays it is the inner product of vectors.