Skip to content

Vector Spaces

So far vectors have been “things you can add and scale”. This section makes that precise, and the payoff is larger than it first appears: because the definition demands only addition and scaling, it admits objects that look nothing like arrows. Polynomials are vectors. Audio signals are vectors. Functions are vectors. Every theorem proved from the axioms applies to all of them at once.

The book builds up in two stages — first a group, then a vector space — and the intermediate stop is worth taking, because it isolates exactly which properties do which work.

  • What a group is, in four axioms, and which familiar sets fail which axiom.
  • The vector-space axioms, and what breaks if you drop each one.
  • Why “multiplying two vectors” is not defined, and what is defined instead.
  • What a subspace is, and the three-part test for one.
  • Why the solution set of Ax=0\mathbf{A}\mathbf{x} = \mathbf{0} is always a subspace and the solution set of Ax=b\mathbf{A}\mathbf{x} = \mathbf{b} never is.

A colour on a screen is three numbers — red, green, blue. Add two colours and you get a colour. Scale a colour by 0.50.5 and you get a dimmer colour. The set of colours is closed under these two operations, and that closure is what makes it a vector space rather than just a set of triples.

Now try the same with the set of colours that are “at least half red”, r0.5r \ge 0.5. Add two of them and you get r1.0r \ge 1.0 — outside the set. Closure fails, so it is not a subspace, even though it is a perfectly reasonable set of colours.

That is the whole idea of this page: which sets survive their own operations.

diagram Diagram mermaid

A group G=(G,)G = (\mathcal{G}, \otimes) is a set G\mathcal{G} with an operation :G×GG\otimes : \mathcal{G}\times\mathcal{G} \to \mathcal{G} satisfying:

#axiomin symbols
1Closurex,yG:  xyG\forall x, y \in \mathcal{G}:\; x \otimes y \in \mathcal{G}
2Associativityx,y,z:  (xy)z=x(yz)\forall x, y, z:\; (x \otimes y) \otimes z = x \otimes (y \otimes z)
3Neutral elemente  x:  xe=x\exists e \;\forall x:\; x \otimes e = x and ex=xe \otimes x = x
4Inverse elementx  y:  xy=e\forall x \;\exists y:\; x \otimes y = e and yx=ey \otimes x = e

If additionally xy=yxx \otimes y = y \otimes x for all x,yx, y, the group is Abelian (commutative).

The book’s own catalogue of near-misses is the fastest way to see what each axiom rules out:

set and operationgroup?what fails
(Z,+)(\mathbb{Z}, +)yes
(N0,+)(\mathbb{N}_0, +)noinverses — there is a neutral element 00, but no 3-3
(Z,)(\mathbb{Z}, \cdot)noinverses — neutral 11 exists, but 13Z\tfrac13 \notin \mathbb{Z}
(R,)(\mathbb{R}, \cdot)noinverses00 has none
(R{0},)(\mathbb{R}\setminus\{0\}, \cdot)yes, Abelian
(Rn,+)(\mathbb{R}^n, +) componentwiseyes, Abelianinverse is (x1,,xn)(-x_1,\dots,-x_n), neutral is (0,,0)(0,\dots,0)
(Rm×n,+)(\mathbb{R}^{m\times n}, +)yes, Abelian
(Rn×n,)(\mathbb{R}^{n\times n}, \cdot)noinverses — singular matrices have none

That last row is the interesting one. Closure and associativity come free from the definition of matrix multiplication, and In\mathbf{I}_n is a perfectly good neutral element. Only invertibility fails. Throw out the singular matrices and what remains is a group — the general linear group GL(n,R)GL(n, \mathbb{R}) — and because matrix multiplication does not commute, it is not Abelian.

So the four axioms are not a checklist to memorise. They are four independent ways a set can fail to be well behaved, and matrices fail exactly one of them.

A real vector space V=(V,+,)V = (\mathcal{V}, +, \cdot) is a set V\mathcal{V} with two operations,

+:V×VV(inner, a kind of addition)+ : \mathcal{V}\times\mathcal{V} \to \mathcal{V} \qquad\text{(inner, a kind of addition)} :R×VV(outer, a kind of scaling)\cdot : \mathbb{R}\times\mathcal{V} \to \mathcal{V} \qquad\text{(outer, a kind of scaling)}

satisfying:

  1. (V,+)(\mathcal{V}, +) is an Abelian group.
  2. Distributivity: λ(x+y)=λx+λy\lambda\cdot(\mathbf{x}+\mathbf{y}) = \lambda\cdot\mathbf{x} + \lambda\cdot\mathbf{y} and (λ+ψ)x=λx+ψx(\lambda + \psi)\cdot\mathbf{x} = \lambda\cdot\mathbf{x} + \psi\cdot\mathbf{x}.
  3. Associativity of the outer operation: λ(ψx)=(λψ)x\lambda\cdot(\psi\cdot\mathbf{x}) = (\lambda\psi)\cdot\mathbf{x}.
  4. Neutral element for the outer operation: 1x=x1\cdot\mathbf{x} = \mathbf{x}.

The elements of V\mathcal{V} are vectors; the neutral element of (V,+)(\mathcal{V}, +) is the zero vector 0\mathbf{0}; the λR\lambda \in \mathbb{R} are scalars.

Notice the two operations have different signatures. The inner one takes two vectors and returns a vector. The outer one takes a scalar and a vector. They are not two flavours of the same thing, and the axioms above are precisely the compatibility conditions between them.

Why axiom 4 is not redundant. It looks like it should follow from the others, and it does not. Take R2\mathbb{R}^2 with the perverse scaling λx:=0\lambda \cdot \mathbf{x} := \mathbf{0} for every λ\lambda. Distributivity holds (0=0+0\mathbf{0} = \mathbf{0} + \mathbf{0}), outer associativity holds, and (V,+)(\mathcal{V},+) is still an Abelian group. Only axiom 4 fails — and it must, or scaling could collapse everything and the structure would be useless. Each axiom is load-bearing.

Three vector spaces the book names: Rn\mathbb{R}^n with componentwise operations, Rm×n\mathbb{R}^{m\times n} with entry-wise operations, and C\mathbb{C} with the standard complex addition.

U=(U,+,)U = (\mathcal{U}, +, \cdot) is a vector subspace of VV when UV\mathcal{U} \subseteq \mathcal{V}, U\mathcal{U} \neq \emptyset, and UU is itself a vector space under the operations of VV restricted to U\mathcal{U}. Written UVU \subseteq V.

The good news is that almost everything is inherited. Associativity, distributivity, the neutral element — all hold for every element of V\mathcal{V}, hence for every element of any subset. So to check a subspace you need only:

  1. U\mathcal{U} \neq \emptyset, and in particular 0U\mathbf{0} \in \mathcal{U};
  2. closure under scaling: λR,xU:λxU\forall \lambda \in \mathbb{R}, \forall \mathbf{x} \in \mathcal{U}: \lambda\mathbf{x} \in \mathcal{U};
  3. closure under addition: x,yU:x+yU\forall \mathbf{x}, \mathbf{y} \in \mathcal{U}: \mathbf{x} + \mathbf{y} \in \mathcal{U}.

Three tests, and the book’s Figure 2.6 shows a subset of R2\mathbb{R}^2 failing each of them: two sets where closure is violated, one that does not contain 0\mathbf{0}, and only one genuine subspace.

Four facts worth having:

  • The trivial subspaces of any VV are VV itself and {0}\{\mathbf{0}\}.
  • The solution set of a homogeneous system Ax=0\mathbf{A}\mathbf{x} = \mathbf{0} is a subspace of Rn\mathbb{R}^n.
  • The solution set of an inhomogeneous system Ax=b\mathbf{A}\mathbf{x} = \mathbf{b} with b0\mathbf{b} \neq \mathbf{0} is not.
  • The intersection of arbitrarily many subspaces is a subspace.

The homogeneous/inhomogeneous split is the one to keep. Homogeneous solutions are closed: if Ax=0\mathbf{A}\mathbf{x} = \mathbf{0} and Ay=0\mathbf{A}\mathbf{y} = \mathbf{0} then A(x+y)=0\mathbf{A}(\mathbf{x}+\mathbf{y}) = \mathbf{0}. Inhomogeneous ones are not: adding two solutions gives A(x+y)=2bb\mathbf{A}(\mathbf{x}+\mathbf{y}) = 2\mathbf{b} \neq \mathbf{b}, and 0\mathbf{0} is not a solution at all. The inhomogeneous set is a subspace shifted off the origin — §2.3’s particular-plus-general shape, and §2.8’s affine subspace.

And the converse, which the book states as a closing remark: every subspace of Rn\mathbb{R}^n is the solution space of some homogeneous system. Subspaces and homogeneous systems are two descriptions of one thing.

Test three subsets of R2\mathbb{R}^2 against all three conditions.

U1={(x1,x2):x2=2x1}\mathcal{U}_1 = \{(x_1, x_2) : x_2 = 2x_1\} — the line x2=2x1x_2 = 2x_1.

testcheckverdict
contains 0\mathbf{0}0=200 = 2\cdot0pass
closed under scalingλ(x1,2x1)=(λx1,2λx1)\lambda(x_1, 2x_1) = (\lambda x_1, 2\lambda x_1), still of the formpass
closed under addition(x1,2x1)+(y1,2y1)=(x1+y1,2(x1+y1))(x_1, 2x_1)+(y_1, 2y_1) = (x_1+y_1, 2(x_1+y_1))pass

A subspace. Dimension 1 — a line through the origin.

U2={(x1,x2):x2=2x1+1}\mathcal{U}_2 = \{(x_1, x_2) : x_2 = 2x_1 + 1\} — the same line, shifted up.

testcheckverdict
contains 0\mathbf{0}020+1=10 \neq 2\cdot0 + 1 = 1fail

Not a subspace, and one failed test is enough. It is an affine subspace (§2.8).

U3={(x1,x2):x1x20}\mathcal{U}_3 = \{(x_1, x_2) : x_1 x_2 \ge 0\} — the first and third quadrants.

testcheckverdict
contains 0\mathbf{0}00=000\cdot0 = 0 \ge 0pass
closed under scaling(λx1)(λx2)=λ2x1x20(\lambda x_1)(\lambda x_2) = \lambda^2 x_1x_2 \ge 0pass
closed under addition(1,1)+(2,1)=(1,0)(1,1) + (-2,-1) = (-1, 0), and (1)(0)=00(-1)(0) = 0 \ge 0 ✓… but (2,1)+(1,3)=(1,2)(2,1) + (-1,-3) = (1,-2) with 1(2)=2<01\cdot(-2) = -2 < 0fail

Not a subspace. Note it passed two of three, which is why all three must be checked — and this is the shape of the book’s Figure 2.6 counterexamples.

Now the homogeneous versus inhomogeneous claim, concretely. For A=[11]\mathbf{A} = \begin{bmatrix}1 & 1\end{bmatrix}:

  • Ax=0\mathbf{A}\mathbf{x} = 0 has solutions {(t,t)}\{(t, -t)\}. Contains (0,0)(0,0) ✓; sum of (1,1)(1,-1) and (2,2)(2,-2) is (3,3)(3,-3) ✓. Subspace.
  • Ax=3\mathbf{A}\mathbf{x} = 3 has solutions {(t,3t)}\{(t, 3-t)\}. Contains (0,0)(0,0)? 0+0=030 + 0 = 0 \neq 3 ✗. Sum of (1,2)(1,2) and (0,3)(0,3) is (1,5)(1,5), and 1+5=631+5 = 6 \neq 3 ✗. Not a subspace — and it fails on both counts.

Two lines, both perfectly good sets of vectors. On the left the line passes through the origin, so the sum of two of its points stays on it. On the right the line is shifted up, and the sum leaves.

sketch Which line is a subspace? p5.js
Two vectors u, v are chosen on a line. Left case: the line passes through the origin, so u+v stays on it — a subspace. Right case: the line is shifted up, so u+v leaves it — not a subspace.

The white dot is the sum. On the left it never leaves the green line, however uu and vv move. On the right it is almost never on the red line — and “almost never” is enough: one violation disqualifies the set. Closure is a universally quantified statement, so a single counterexample settles it.

vector_spaces.py
import numpy as np
import itertools
 
rng = np.random.default_rng(0)
 
def is_subspace(sample, contains, trials=2000):
    """Empirically test the three subspace conditions on a candidate set.
 
    A pass here is evidence, not proof — closure is a statement about ALL
    elements. But a failure IS proof, because one counterexample is enough.
    """
    if not contains(np.zeros_like(sample[0])):
        return False, "does not contain the zero vector"
    for _ in range(trials):
        x, y = sample[rng.integers(len(sample))], sample[rng.integers(len(sample))]
        lam = float(rng.normal() * 3)
        if not contains(lam * x):
            return False, f"not closed under scaling: {lam:.3f} * {x} = {lam * x}"
        if not contains(x + y):
            return False, f"not closed under addition: {x} + {y} = {x + y}"
    return True, "passed every trial"
 
# Sample points of each candidate set, and a membership test for each.
t = rng.normal(size=400) * 3
 
sets = {
    "line x2 = 2*x1        ": (np.c_[t, 2 * t],
                               lambda v: np.isclose(v[1], 2 * v[0])),
    "line x2 = 2*x1 + 1    ": (np.c_[t, 2 * t + 1],
                               lambda v: np.isclose(v[1], 2 * v[0] + 1)),
    "quadrants x1*x2 >= 0  ": (np.array([[a, b] for a, b in
                                         zip(abs(t), abs(t) * rng.choice([1, 1]))]),
                               lambda v: v[0] * v[1] >= -1e-12),
    "solutions of x1+x2 = 0": (np.c_[t, -t],
                               lambda v: np.isclose(v[0] + v[1], 0)),
    "solutions of x1+x2 = 3": (np.c_[t, 3 - t],
                               lambda v: np.isclose(v[0] + v[1], 3)),
}
 
for name, (sample, member) in sets.items():
    ok, why = is_subspace(sample, member)
    print(f"{name} subspace: {str(ok):5s}  ({why})")
 
# ---- the general linear group: matrices fail exactly one group axiom ----
A = np.array([[1.0, 2.0], [3.0, 4.0]])       # invertible
B = np.array([[1.0, 2.0], [2.0, 4.0]])       # singular
print("\nclosure  : A@B is still 2x2      ->", (A @ B).shape == (2, 2))
print("assoc    : (AB)C == A(BC)         ->",
      np.allclose((A @ B) @ A, A @ (B @ A)))
print("neutral  : A @ I == A             ->", np.allclose(A @ np.eye(2), A))
print("inverse  : det(A) =", np.linalg.det(A), "-> invertible")
print("inverse  : det(B) =", np.linalg.det(B), "-> NO inverse, so not a group")
 
# ---- there is no vector multiplication --------------------------------
a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])
print("\nouter product a b^T shape:", np.outer(a, b).shape, "-> a MATRIX")
print("inner product a^T b      :", a @ b, "-> a SCALAR")
print("NumPy's a * b            :", a * b, "-> an operation the axioms do not define")
 
# ---- axiom 4 is not redundant -----------------------------------------
# Perverse scaling: lam . x := 0 for all lam. Check which axioms survive.
def bad_scale(lam, x):
    return np.zeros_like(x)
 
x, y = np.array([1.0, 2.0]), np.array([3.0, -1.0])
lam, psi = 2.0, 5.0
print("\nwith the perverse scaling lam.x := 0 :")
print("  distributive over vectors :", np.allclose(bad_scale(lam, x + y),
                                                   bad_scale(lam, x) + bad_scale(lam, y)))
print("  distributive over scalars :", np.allclose(bad_scale(lam + psi, x),
                                                   bad_scale(lam, x) + bad_scale(psi, x)))
print("  outer associativity       :", np.allclose(bad_scale(lam, bad_scale(psi, x)),
                                                   bad_scale(lam * psi, x)))
print("  1 . x == x  (axiom 4)     :", np.allclose(bad_scale(1.0, x), x), "  <- the only failure")
 
# ---- intersection of subspaces is a subspace --------------------------
# Two planes through the origin in R^3 meet in a line through the origin.
P1 = np.array([[1.0, 1.0, 1.0]])            # x1+x2+x3 = 0
P2 = np.array([[1.0, -1.0, 0.0]])           # x1-x2   = 0
both = np.vstack([P1, P2])
print("\ndim of plane 1  :", 3 - np.linalg.matrix_rank(P1))
print("dim of plane 2  :", 3 - np.linalg.matrix_rank(P2))
print("dim of the meet :", 3 - np.linalg.matrix_rank(both), "-> a line, still through 0")
text
line x2 = 2*x1         subspace: True   (passed every trial)
line x2 = 2*x1 + 1     subspace: False  (does not contain the zero vector)
quadrants x1*x2 >= 0   subspace: True   (passed every trial)
solutions of x1+x2 = 0 subspace: True   (passed every trial)
solutions of x1+x2 = 3 subspace: False  (does not contain the zero vector)
 
closure  : A@B is still 2x2      -> True
assoc    : (AB)C == A(BC)         -> True
neutral  : A @ I == A             -> True
inverse  : det(A) = -2.0000000000000004 -> invertible
inverse  : det(B) = 0.0 -> NO inverse, so not a group
 
outer product a b^T shape: (3, 3) -> a MATRIX
inner product a^T b      : 32.0 -> a SCALAR
NumPy's a * b            : [ 4. 10. 18.] -> an operation the axioms do not define
 
with the perverse scaling lam.x := 0 :
  distributive over vectors : True
  distributive over scalars : True
  outer associativity       : True
  1 . x == x  (axiom 4)     : False   <- the only failure
 
dim of plane 1  : 2
dim of plane 2  : 2
dim of the meet : 1 -> a line, still through 0
figure The book's Figure 2.6, redrawn with the failing operation shown matplotlib
Four panels showing subsets of the plane. A shaded square around the origin fails closure under scaling. A line through the origin passes all tests. A pair of shaded cones fails closure under addition. A single point away from the origin fails to contain zero. Four panels showing subsets of the plane. A shaded square around the origin fails closure under scaling. A line through the origin passes all tests. A pair of shaded cones fails closure under addition. A single point away from the origin fails to contain zero.
Only the line through the origin survives all three tests. Each other panel is annotated with the specific pair of vectors whose sum or scaling escapes the set.

Each failing panel carries the actual counterexample, and that is the point. “Not a subspace” is never a judgement call — it is a specific pair of vectors, or a specific scalar, that escapes. When you suspect a set is not a subspace, the productive move is to hunt for that witness rather than to reason about it abstractly.

The square panel is the one worth staring at. It contains 0\mathbf{0} and it is closed under addition of small enough vectors, which is why it feels like it should qualify. It fails on scaling: multiply any nonzero point by a large enough λ\lambda and you leave the square. A subspace must be closed under every real scalar, which forces it to be unbounded in every direction it contains at all. So a bounded set can never be a subspace unless it is just {0}\{\mathbf{0}\}.

structureoperationswhat it adds
groupone, \otimesclosure, associativity, neutral element, inverses
Abelian grouponeplus commutativity
vector spacetwo, ++ and \cdotscaling by scalars, compatible with addition
subspaceinheriteda subset closed under both, containing 0\mathbf{0}
affine subspace (§2.8)inheriteda subspace translated — no longer contains 0\mathbf{0}
convex set (§7.3)inheritedclosed under averages only, so it may be bounded

The last two rows are the ones people conflate. An affine subspace is a subspace moved; a convex set is closed under weighted averages rather than arbitrary combinations, which is why a disc is convex and not a subspace.

pch.quizTag Check yourself
  1. The set of n-by-n matrices under multiplication satisfies three of the four group axioms. Which one fails?

    pch.quizShowAnswer

    D — Existence of inverses — singular matrices have none — Closure and associativity follow from the definition of the product, and the identity is a perfectly good neutral element. Discarding the singular matrices leaves the general linear group, which is a group but not Abelian.

  2. Which is the correct statement about multiplying two vectors in R-n?

    pch.quizShowAnswer

    B — It is not defined; only the outer product giving a matrix and the inner product giving a scalar are — The book says so explicitly. Element-wise multiplication is common in programming languages but is not part of the vector-space structure, and neither defined product returns a vector.

  3. Why can a bounded set never be a subspace unless it is just the origin?

    pch.quizShowAnswer

    B — Because closure under scaling requires closure under arbitrarily large scalars, forcing an unbounded line through any nonzero member — Scaling must hold for every real lambda, including enormous ones. Any nonzero vector in the set therefore drags an entire infinite line in with it. This is what separates subspaces from the convex sets of section 7.3.

  4. The solution set of Ax = b with b nonzero is not a subspace. What is it?

    pch.quizShowAnswer

    B — A subspace translated off the origin, which section 2.8 calls an affine subspace — It is a particular solution plus the null space, which is section 2.3's particular-plus-general shape. Translating a subspace destroys the zero vector and closure, but keeps the flat shape.

Exercise 3 – Homogeneous versus inhomogeneous

Section titled “Exercise 3 – Homogeneous versus inhomogeneous”

Exercise 4 – A bounded set fails on scaling

Section titled “Exercise 4 – A bounded set fails on scaling”

Exercise 5 – The intersection of two subspaces

Section titled “Exercise 5 – The intersection of two subspaces”
  • A group has four axioms — closure, associativity, a neutral element, and inverses — and adding commutativity makes it Abelian.
  • The inverse is with respect to the operation, so it means x-x under addition and 1/x1/x under multiplication.
  • Square matrices under multiplication fail exactly one group axiom: inverses. Discarding the singular ones gives the general linear group, which is not Abelian.
  • A vector space has two operations with different signatures — an inner one taking two vectors, an outer one taking a scalar and a vector — plus the four compatibility conditions.
  • Every axiom is load-bearing: the perverse scaling that sends everything to zero satisfies distributivity and outer associativity, and fails only the rule that 1 times x is x.
  • There is no vector multiplication. Only the outer product, returning a matrix, and the inner product, returning a scalar.
  • A subspace needs three things — nonempty and containing the zero vector, closed under scaling, closed under addition — and checking only two accepts sets that fail.
  • A bounded set is never a subspace unless it is just the origin, because closure under scaling admits arbitrarily large scalars.
  • Homogeneous solution sets are subspaces; inhomogeneous ones are not — they are subspaces translated off the origin, which is the affine subspace of section 2.8.
  • The intersection of arbitrarily many subspaces is a subspace, and conversely every subspace of R-n is the solution space of some homogeneous system.
  • An empirical closure test can only disprove, because closure is universally quantified and a sample that misses the awkward region reports a false pass.

Next: when is a vector redundant? — Linear Independence.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading