Brick walls are there for a reason. The brick walls are not there to keep us out. The brick walls are there to show how badly we want something. Because the brick walls are there to stop the people who don’t want something badly enough. They are there to keep out the other people, Randy Pausch.
💫 “The best way to predict the future is to create it.” — Peter Drucker
In mathematics, sets are isolated islands of objects. To build a thriving mathematical universe, we must build bridges between them. A function is the most important type of bridge we can build.
Before we can define a function, we must quickly recall the Cartesian Product. If $A$ and $B$ are two sets, their Cartesian product $A \times B$ is the set of all possible ordered pairs $(a, b)$ where $a \in A$ and $b \in B$, e.g., $\{1, 2\} \times \{\text{red}, \text{yellow}, \text{blue}\} = \{(1, \text{red}), (1, \text{yellow}), (1, \text{blue}), (2, \text{red}), (2, \text{yellow}), (2, \text{blue})\}$.
A relation $R$ is simply any subset of this Cartesian product ($R \subseteq A \times B$).
A function is a highly restricted, specific type of relation.
Definition: A function $f$ from a set $A$ to a set $B$ (denoted $f: A \to B$) is a relation that assigns to every single element in the domain $A$ exactly one element in the codomain $B$. Functions are also called maps or mappings (Figure 1.a).
In the language of ordered pairs, a function is a subset of $A \times B$ in which every element $a$ in the domain $A$ must be paired with exactly one element $b$ in the codomain $B$. In other words, it satisfies two absolute rules:
If $(a, b)$ belongs to our function, we write $f(a) = b$. We call $a$ the argument (or input) and $b$ the value (or output). A way of representing the set of ordered pairs which define a function is to use one of these notations: $\{(x,y) \vert{} y = f(x), x \in X\}$ or $\{(x, f(x)) \vert{} x \in X\}$.
Think of a function as a vending machine.
A function is most often denoted by letters such as $f, g$, or $h$. A function takes an input element from a set $A$ (the domain, sometimes written $X$) and produces an output in the set $B$ (the codomain, sometimes writtesn $Y$). We can imagine it as some sort of black box, device, or machine that does some kind of computation or transformation (Figure 1.b). You put some object into its input funnel, then the function machine will process that object or argument and turn it into some other object or value, which comes out as output.
Understanding the anatomy of a function requires precise terminology:
Crucial Distinction: The Range is a subset of the Codomain, $f(A) \subseteq B$. They are not always equal!
For example, let $f: \mathbb{R} \to \mathbb{R}$ be defined by $f(x) = x^2$.
The Domain is all real numbers. The Codomain is all real numbers. However, because squaring a real number never produces a negative, the Range is only the non-negative real numbers ($\mathbb{R}^+$). The function never “hits” the negative half of the codomain.
A function is well-defined if it perfectly obeys the two rules of functions. It is ill-defined if it breaks either rule.
Examples of Well-Defined Functions:
Examples of Ill-Defined Functions:
We classify functions based on how the Domain maps into the Codomain.
Injective (One-to-One). An injective function guarantees that distinct inputs produce distinct outputs. It never maps two different elements of the domain to the same element in the codomain. Formally: If $f(a_1) = f(a_2)$, then $a_1 = a_2$. In other words, if we pick any element from the codomain, it is either connected to exactly one or no elements from the domain.
Examples: $f(x) = 2x$, $g(x) = 2x + 1$ are both injective, but $f(x) = x^2$ is not, because $f(-2) = 4$ and $f(2) = 4$. Two inputs hit the same target.
Any strictly monotonic function — one that is always strictly increasing or strictly decreasing — is guaranteed to be injective (e.g., $e^x$).
Surjective (Onto). A surjective function hits everything. It guarantees that the Range is exactly equal to the Codomain. Formally: For every $y \in B$, there exists at least one $x \in A$ such that $f(x) = y$.
$f: \mathbb{R} \to \mathbb{R}$ where $f(x) = 2x$ is surjective. For any target $y$, you can hit it by inputting $x = \frac{y}{2}$. $f: \mathbb{R} \to \mathbb{R}$ where $f(x) = x^2$ is not surjective (it never hits negatives). However, if we shrink the codomain, $g: \mathbb{R} \to \mathbb{R}^+$ where $g(x) = x^2$ is surjective!
$f: \mathbb{R} \to \mathbb{R}$ defined by $f(x) = \frac{1}{x^2+1}$ is neither injective ($f(1) = f(-1) = \frac{1}{2}$) nor surjective (there is no $x \in \mathbb{R}$ with $\frac{1}{x^2+1} = 2$, since this implies $1 = 2x^2 + 2 \implies x^2=\frac{-1}{2} \implies x=\sqrt{\frac{-1}{2}}, x ∈\mathbb{R}$ — a contradiction $\bot$).
Bijective. A bijective function is a perfect one-to-one pairing between two sets. It is both injective and surjective. Every element in the domain maps to exactly one unique element in the codomain, and every element in the codomain is hit exactly once.
Examples: $f: \mathbb{R} \to \mathbb{R}$ where $f(x) = x^3$ is bijective. Any lineal function over the real numbers, $f: \mathbb{R} \to \mathbb{R},f(x) = ax + b$ with $a \ne 0$ is a bijection. $g: \mathbb{R} \to (\frac{-\pi}{2}, \frac{\pi}{2})$, given by $g(x) = \arctg(x)$ is bijective, too.
The Pigeonhole Principle is a profound observation in combinatorics that relies entirely on the definitions of injective and surjective functions.
The Pigeonhole principle states that if you put $n$ items into $m$ containers, and $n > m$, then at least one container must hold more than one item.
In the formal language of functions, let $A$ (the items) and $B$ (the containers) be finite sets, and let $f: A \to B$ be a function.
Theorem: In any city containing more than 200,000 people, there are absolutely guaranteed to be at least two people with the exact same number of hairs on their head.
Proof:
Biologists estimate that the absolute maximum number of hairs on a human head is roughly $150,000$.
Let $A$ be the set of citizens in our city. We are given $\vert{}A\vert{} > 200,000$. Let $B$ be the set of all possible hair counts on a human head. $B = \{0, 1, 2, \dots, 150,000\}$. Thus, $\vert{}B\vert{} = 150,001$.
Let $f: A \to B$ be the function that maps a citizen to their exact hair count.
Because $\vert{}A\vert{} > \vert{}B\vert{}$, the Pigeonhole Principle dictates that $f$ cannot be injective. Therefore, there must exist at least two distinct citizens, $x$ and $y$, such that $f(x) = f(y)$.
We have mathematically proven that at least two people share the exact same number of hairs, without having to count a single head! $\blacksquare$
Computer Science Connection: The Pigeonhole Principle is the mathematical reason why hash collisions are unavoidable in cryptography and software engineering. A hash function takes an infinite amount of possible inputs (like any file on a computer) and maps it to a finite, fixed-length code. Because the domain of files ($\vert{}A\vert{} = \infty$) is vastly larger than the codomain of fixed-length codes ($\vert{}B\vert{}$ is finite), the function cannot be injective. There will always be two different files that produce the exact same hash code.