44. Bilinear forms
§23.0's linear functionals took one vector argument. This lesson takes two, and names the resulting object precisely: a bilinear form — the general pattern behind the dot product (§20.0), general inner products (§20.1), and quadratic forms (§21.3) all at once, minus the one restriction (positive definiteness) that made those special cases.
Definition
A bilinear form on V is a function B:V\times V\to\mathbb{R} that is linear in each argument separately:
B(\vec u+\vec u',\vec v)=B(\vec u,\vec v)+B(\vec u',\vec v),\qquad B(c\vec u,\vec v)=cB(\vec u,\vec v)
and identically in the second slot. Every bilinear form on \mathbb{R}^n has the form B(\vec x,\vec y)=\vec x^TA\vec y for some matrix A (not necessarily symmetric) — this is §21.3's quadratic-form matrix, generalized: a quadratic form was the special case B(\vec x,\vec x), and this lesson studies B with two independent arguments instead of one repeated one.
§20.1's three inner-product axioms are exactly: bilinearity (shared with every bilinear form here), symmetry (B(\vec u,\vec v)=B(\vec v,\vec u), equivalent to A=A^T), and positive definiteness (B(\vec v,\vec v)>0 for \vec v\neq\vec0, §21.2's condition on A). So: an inner product is a symmetric positive definite bilinear form — the general theory this lesson develops, with two extra conditions layered on top.
Symmetric and antisymmetric parts
Any bilinear form splits uniquely into a symmetric and antisymmetric piece, exactly like §16.2's matrix analogue:
B(\vec x,\vec y)=\underbrace{\tfrac12\big(B(\vec x,\vec y)+B(\vec y,\vec x)\big)}_{\text{symmetric}}+\underbrace{\tfrac12\big(B(\vec x,\vec y)-B(\vec y,\vec x)\big)}_{\text{antisymmetric}}
matching A=\tfrac12(A+A^T)+\tfrac12(A-A^T) at the matrix level. The quadratic form B(\vec x,\vec x) only ever sees the symmetric part: the antisymmetric part of A always contributes exactly 0 to \vec x^TA\vec x (check directly: if A^T=-A, then \vec x^TA\vec x=(\vec x^TA\vec x)^T=\vec x^TA^T\vec x=-\vec x^TA\vec x, forcing \vec x^TA\vec x=0). This is precisely why §21.3 could restrict attention to symmetric A from the start without losing any generality — the antisymmetric part of any quadratic form's matrix is invisible to the form itself.
The matrix of a bilinear form, relative to a basis
Given a basis \{\vec v_1,\dots,\vec v_n\}, the matrix of B relative to this basis has entries A_{ij}=B(\vec v_i,\vec v_j) — by bilinearity, this single grid of numbers determines B on every pair of vectors, exactly as §18.1's standard matrix determined a whole linear transformation from its action on a basis. Changing basis transforms A by A'=P^TAP (not P^{-1}AP, §19.3's similarity transform — a bilinear form transforms differently from a linear transformation, since it has two vector slots to change coordinates in, not one) — this is called congruence, distinct from similarity.
Doing it in Python
import numpy as np
A = np.array([[2., 3.], [1., 4.]]) # not symmetric -- a general bilinear form
def B(x, y):
return x @ A @ y
u, v = np.array([1., 2.]), np.array([3., -1.])
print("B(u, v) =", B(u, v))
print("B(v, u) =", B(v, u), " (different, since A is not symmetric)")
# Split into symmetric and antisymmetric parts
A_sym = (A + A.T) / 2
A_anti = (A - A.T) / 2
print("\nA_sym =")
for row in A_sym.tolist():
print(row)
print("A_anti =")
for row in A_anti.tolist():
print(row)
# Confirm the antisymmetric part contributes nothing to the quadratic form
x = np.array([2., -3.])
print("\nx^T A_anti x =", round(float(x @ A_anti @ x), 10))
B(u, v) = 1.0
B(v, u) = 15.0 (different, since A is not symmetric)
A_sym =
[2.0, 2.0]
[2.0, 4.0]
A_anti =
[0.0, 1.0]
[-1.0, 0.0]
x^T A_anti x = 0.0
Confirming congruence, A'=P^TAP, changes a symmetric form's matrix under a change of basis:
import numpy as np
A = np.array([[2., 1.], [1., 3.]]) # symmetric bilinear form
P = np.array([[1., 1.], [0., 1.]]) # change of basis (not orthogonal)
A_prime = P.T @ A @ P
print("A' = P^T A P =")
for row in A_prime.tolist():
print(row)
print("still symmetric:", bool(np.allclose(A_prime, A_prime.T)))
A' = P^T A P =
[2.0, 3.0]
[3.0, 7.0]
still symmetric: True
Worked example
Given B(\vec x,\vec y)=2x_1y_1+3x_1y_2-x_2y_1+x_2y_2, find its matrix A, and split it into symmetric and antisymmetric parts.
Reading coefficients directly (A_{ij} multiplies x_iy_j):
A=\begin{pmatrix}2&3\\-1&1\end{pmatrix}
A_{\text{sym}}=\frac12\left[\begin{pmatrix}2&3\\-1&1\end{pmatrix}+\begin{pmatrix}2&-1\\3&1\end{pmatrix}\right]=\frac12\begin{pmatrix}4&2\\2&2\end{pmatrix}=\begin{pmatrix}2&1\\1&1\end{pmatrix}
A_{\text{anti}}=\frac12\left[\begin{pmatrix}2&3\\-1&1\end{pmatrix}-\begin{pmatrix}2&-1\\3&1\end{pmatrix}\right]=\frac12\begin{pmatrix}0&4\\-4&0\end{pmatrix}=\begin{pmatrix}0&2\\-2&0\end{pmatrix}
\boxed{A_{\text{sym}}=\begin{pmatrix}2&1\\1&1\end{pmatrix},\quad A_{\text{anti}}=\begin{pmatrix}0&2\\-2&0\end{pmatrix}}
Sanity check. A_{\text{sym}}+A_{\text{anti}}=\begin{pmatrix}2&3\\-1&1\end{pmatrix}=A ✓. Quadratic form check: \vec x^TA_{\text{anti}}\vec x=2x_1x_2-2x_2x_1=0 for any \vec x ✓ — confirming the general "antisymmetric part vanishes on the diagonal" claim directly, with actual coefficients rather than an abstract argument.
Your turn
1. Is B(\vec x,\vec y)=x_1y_2-x_2y_1 symmetric, antisymmetric, or neither? (This is the 2D determinant/cross-product form.)
2. For A=\begin{pmatrix}1&2\\2&1\end{pmatrix} (already symmetric), what is A_{\text{anti}}?
3. True or false: a bilinear form's matrix is basis-independent, just like a linear functional's coefficients.
Solutions
1. Antisymmetric. B(\vec y,\vec x)=y_1x_2-y_2x_1=-(x_1y_2-x_2y_1)=-B(\vec x,\vec y). (Geometrically, B(\vec x,\vec y) is the signed area of the parallelogram spanned by \vec x,\vec y — §16.4's determinant, viewed as a bilinear form in two vector arguments rather than as a function of a single matrix.)
2. A_{\text{anti}}=0 (the zero matrix). A symmetric matrix already equals its own transpose, so A-A^T=0 directly — the antisymmetric part of any symmetric form is always exactly zero, consistent with "the quadratic form only sees the symmetric part" having nothing left to discard here.
3. False. This is exactly the "matrix of a bilinear form, relative to a basis" section's point: A depends on the chosen basis, and changes under congruence (A'=P^TAP) when the basis changes — matching §17.3's coordinate vectors and §18.1's standard matrices, both of which were also basis-dependent, not basis-independent objects.
Check yourself in code
For A=\begin{pmatrix}3&1\\2&4\end{pmatrix}, compute the symmetric and antisymmetric parts and confirm they sum back to A.
Print exactly this:
A_sym =
[3.0, 1.5]
[1.5, 4.0]
A_anti =
[0.0, -0.5]
[0.5, 0.0]
sum == A: True
import numpy as np
A = np.array([[3., 1.], [2., 4.]])
A_sym = (A + A.T) / 2
A_anti = (A - A.T) / 2
print("A_sym =")
for row in A_sym.tolist():
print(row)
# print A_anti the same way, then whether A_sym + A_anti equals A
import numpy as np
A = np.array([[3., 1.], [2., 4.]])
A_sym = (A + A.T) / 2
A_anti = (A - A.T) / 2
print("A_sym =")
for row in A_sym.tolist():
print(row)
print("A_anti =")
for row in A_anti.tolist():
print(row)
print("sum == A:", bool(np.allclose(A_sym + A_anti, A)))
A bilinear form B(\vec x,\vec y)=\vec x^TA\vec y is linear in each argument separately, with the dot product, general inner products (§20.1), and quadratic forms (§21.3) all special cases once symmetry and positive definiteness are added back. Every bilinear form splits into symmetric and antisymmetric parts, and only the symmetric part survives in a quadratic form — the reason §21.3 could assume symmetry from the outset with no loss of generality.
Next, adv: extending "pairs of vectors in" to "many vectors in, or even vectors out" — a first look at tensor products and multilinear algebra.