I.5 · Mathematical Language
What does a function do with one input?
A function is a machine: one input goes in, steps are carried out in a fixed order, and exactly one output comes out. We follow a value through each step, find the inputs a machine refuses, ask which inputs give a chosen output, wire two machines together in both orders, and run a machine backwards.
A function as a machine:
Try a machine
A graph of y equals the square of x minus 2, drawn as a curve over the x-axis. The inputs the machine accepts are all real numbers; the outputs it can give are all numbers greater than or equal to 0. The marker at x equal to 4 has height 4.
- shift
- 2
- input
- 4
- after step 1: subtract 2
- 2
- after step 2: square
- 4
- output
- 4
- every input the machine accepts
- ℝ
- every output it can give
- [0, ∞)
- one-to-one: different inputs always give different outputs?
- no
= exact · ≈ rounded to 6 decimals · the domain is every input the machine accepts, the image every output it can give
- input x
- subtract 2
- square
- output f(x)
With f(x) = (x − 2)², the machine takes x = 4 and subtracts 2 to get 2, then squares it to get 4. The output is f(4) = 4: exactly one output for this one input.
| input | output |
|---|---|
from −5 to 5, whole numbers only
from −6 to 6, up to 2 decimal places
Try it before reading on. Leave the rule at “subtract 2, then square” and move the input to : the boxes read , then , then . Now move the input to . The output is the same, . Two different inputs gave one output, and that is allowed. Then pick the rule and drag the input to the left of : the machine stops at the square root and the point leaves the graph. By the end of the chapter you will know what a function is, how to find the inputs it accepts and the outputs it can give, how to chain two functions, and when a function can be run backwards.
Intuition: a machine with one slot
Think of a vending machine that takes one coin and gives one item. It does not matter how it works inside; what matters is the behaviour: put in the same coin and you get the same item, and there is never a coin that gives two items at once. A function is the mathematical version. It takes one input, performs a sequence of steps, and gives one output.
The picture of a pipeline is more than a metaphor. The rule is not a mysterious symbol; it is two instructions in order: subtract , then square. Evaluating means carrying them out on : , then . Reading a formula as a list of steps is the habit that this chapter builds, because every question about functions is a question about a step.
- What can go in? Some steps refuse some values: you cannot divide by or take the square root of a negative number. The inputs the whole machine accepts form its domain.
- What can come out? The outputs that really occur form the image.
- Which inputs give this output? Asking this runs the machine backwards. Sometimes there is one answer, sometimes two, sometimes none.
- What if I wire two machines together? The output of the first becomes the input of the second. The order matters.
This chapter uses the equations of the previous chapter (to find which inputs give an output you solve an equation, and to run a machine backwards you undo its steps in reverse order), the coordinate plane of the second chapter (the graph), and the squares and roots of the first.
Definition: function, domain, image, graph
Function. A function from a set to a set is a rule that assigns to every element of exactly one element of . We write and , and read as ” of ” (the output of for the input ). It is not the product of and .
Domain and codomain. is the domain: the inputs the function is defined on. is the codomain: the set the outputs are drawn from. A function is not just a formula; the formula together with its domain is what makes it a function. When no domain is stated, we take the largest set of real numbers for which every step can be carried out.
Image. The image of is the set of outputs that actually occur, . It can be smaller than the codomain. For with codomain the image is , because no square is negative.
Graph. The graph of is the set of points in the plane. A curve is the graph of a function exactly when every vertical line meets it at most once (the vertical line test): a second point above the same would be a second output.
Preimage. For a number , the inputs with are the preimages of . There can be none, one, or several. Finding them means solving the equation .
One-to-one and onto. is one-to-one (injective) when different inputs always give different outputs: no output has two preimages. is onto its codomain when every element of the codomain is an output: every output has at least one preimage. On a graph, “one-to-one” is the horizontal line test: every horizontal line meets the curve at most once.
Composition. For and , the composite is the function : apply first, then . Read it right to left.
Inverse. If is one-to-one with image , its inverse sends each output back to the one input that produced it, so and . The inverse exists exactly when is one-to-one onto its image. The notation is not .
Reading a rule as a pipeline
The stage at the top offers six rules, each one or two steps:
| rule | steps, in order | domain | image |
|---|---|---|---|
| () | multiply by | ||
| square, then multiply by | if , if | ||
| subtract , then square | |||
| add , then take the square root | |||
| subtract , then take the reciprocal | every real number except | every real number except | |
| subtract , then take the absolute value |
For the multiplier rules become the constant with domain and image .
The stage keeps every number exact: stays and stays , and the inspector says whether a value is exact or a rounded decimal. One flat state, the rule, the number and the input , produces everything you see: the boxes, the point, the dashed lines, the table and the verdict. Dragging the point changes only , so the curve itself does not move; changing or the rule redraws it.
When a step refuses, the pipeline stops there. The boxes after the refusal are marked “not reached”, the point drops to the -axis, and the verdict names the step and the reason. A function has no output at such an input; it is not “zero” and not “infinity”.
The shape of a shift
Compare with . The second is the first with the input moved before squaring: the machine subtracts , so the input must be larger to reach the same value. The graph moves to the right by , which feels backwards at first because of the minus sign. Test with the output : when .
Domain: where the machine refuses
A step refuses an input when it has no answer. There are two refusals in this chapter:
- the reciprocal of (no number multiplied by gives ), and
- the square root of a negative number (no real number squared is negative).
The domain of the whole machine is the set of inputs that no step refuses. Two ways to find it:
- Forwards: try an input and watch the pipeline, as the first stage does.
- Backwards: start from the last step and ask what it needs. needs , that is ; the set contains because . needs , that is . For a machine with two steps, pull the requirement of the last step back through the first.
The domain is the input side of the graph, the set of values that have a curve above or below them. At the edge of the curve starts with a filled dot at ; at the curve of has a gap, with a vertical dashed line (an asymptote) showing where it blows up.
A formula is not yet a function
The formulas and agree at every , and at the first divides by while the second gives . They are different functions because their domains differ. Cancelling the common factor is the same step that lost a root in the previous chapter: it is legal only where the factor is not .
Domain, image and the inputs that give an output
Fix a height and ask: which inputs give ? On the graph, draw the horizontal line at height and read the where it meets the curve.
Which inputs give this output?
Try an equation
A graph of y equals the square of x minus 2, with a horizontal line at height 4. The line meets the curve at 2 points. The part of the x-axis the machine accepts is all real numbers; the part of the y-axis it reaches is all numbers greater than or equal to 0.
- shift
- 2
- height of the line (an output)
- 4
- how many inputs x give f(x) = h
- 2 inputs
- input 1
- 0
- input 2
- 4
- every input the machine accepts
- ℝ
- every output it can give
- [0, ∞)
- one-to-one: different inputs always give different outputs?
- no
- every real number is an output?
- no
= exact · ≈ rounded to 6 decimals · f is one-to-one when no output has two inputs
The line y = 4 meets the graph at two points: the inputs x₁ = 0 and x₂ = 4 both give the output 4. A function may send two inputs to one output (never one input to two outputs), but then it is not one-to-one. The image of f is [0, ∞), not all of ℝ, so f is not onto ℝ.
from −5 to 5, whole numbers only
from −6 to 6, up to 2 decimal places
With the line at meets the curve twice, at and : both satisfy , because . At it touches once, at . At it misses, since a square is never negative: the equation has no solution. The preimages come from solving, not from reading the picture: the model solves exactly as for , and the picture confirms it.
Three consequences follow directly.
- The image is the set of heights that the line meets. For it is , the bar on the vertical axis.
- One-to-one fails when some height meets the curve twice. and are not one-to-one; (with ), and are.
- Onto fails when some height is missed. The line misses every curve whose image is . The curve misses as well: divided by any number is never , so the equation has no solution, and the image is without .
An important distinction: a function may send two inputs to one output (the horizontal line meets twice), but it may never send one input to two outputs (the vertical line would meet twice). The first is the case of ; the second is not a function at all.
Composition: one machine after another
Let and . The composite means first , then : . The composite means first , then : . At the first gives and ; the second gives and . Composition is not commutative: the order is part of the answer. The stage starts at , where but . The graph shows heights from to , so at the heights and are beyond its top edge: the stage then says so and gives the exact numbers beside the graph instead of drawing a dot.
Two machines in a row: and
Try a pair
A graph with two curves: y equals f of g of x, which is x squared applied after 2 x minus 1, and y equals g of f of x, the other order. At x equal to 0 the heights are 1 and minus 1.
- input
- 0
- g first: 2x − 1
- −1
- f ∘ g: g first, then f
- 1
- f first: x²
- 0
- g ∘ f: f first, then g
- −1
- inputs the composite f ∘ g accepts
- ℝ
- inputs the composite g ∘ f accepts
- ℝ
= exact · ≈ rounded to 6 decimals · f ∘ g means g first, then f
f ∘ g: g first, then f
- input x
- multiply by 2
- subtract 1
- g(x)
- square
- f(g(x))
g ∘ f: f first, then g
- input x
- square
- f(x)
- multiply by 2
- subtract 1
- g(f(x))
At x = 0, f(g(x)) = 1 but g(f(x)) = −1. The order matters: f ∘ g sends x through g first, g ∘ f through f first. These are different machines.
Domain of f ∘ g: ℝ
Domain of g ∘ f: ℝ
from −6 to 6, up to 2 decimal places
At the two orders happen to agree (both give ). Setting and simplifying gives , that is , so is the only input where they agree: agreement at one input does not make the two functions equal.
The domain of a composite
A composite can accept fewer inputs than its inner function. Take and . The function accepts every real number, but needs the output of to be allowed in : , so . The input is accepted by , gives , and the square root refuses it. In the stage the composite at is marked undefined while is fine. The domain of a composite is the part of the inner function’s domain whose outputs the outer function accepts.
A second trap: is not . At the square gives and the root gives , so . Choose and and set the input to to see it.
Running a machine backwards: the inverse
To find the inverse of , solve for : add to both sides, then divide by . The inverse is . Its steps are the original steps undone in the opposite order (the last step is undone first), and each undoing step is a balanced step from the previous chapter.
Running a machine backwards:
Try a machine
A graph of y equals 2 x minus 1, the dashed line y equals x, and the mirror image of the curve in that line. The mirror image of the curve in the dashed line y equals x is the graph of the inverse. The point x equal to 3, y equal to 5 and its mirror image are marked.
- input
- 3
- output
- 5
- is there an inverse function?
- yes
- the inverse applied to the output
- 3
- the round trip returns the input
- yes
- domain of f
- ℝ
- image of f (domain of the inverse)
- ℝ
= exact · ≈ rounded to 6 decimals · the inverse needs one input for every output
Forward: x to y
- input x
- multiply by 2
- subtract 1
- output y
Backward: y to x
- input y
- add 1
- multiply by 0.5
- output x
f(3) = 5, and the inverse sends 5 back to 3. The round trip f⁻¹(f(x)) returns x = 3 exactly. On the graph, (3, 5) and (5, 3) are mirror images in the line y = x.
from −6 to 6, up to 2 decimal places
The graph of the inverse is the mirror image of the graph of in the line . Swapping the roles of input and output swaps the coordinates of every point: if is on the graph of , then is on the graph of its inverse. In the stage the filled dot is and the hollow dot is its mirror image .
Not every function has an inverse. On all of the square sends and to the same output . A backward machine fed with would have to return both, and a function returns only one value. The mirror image of the parabola is a parabola on its side, which fails the vertical line test. The fix is to restrict the domain: if only is allowed, is the single preimage of and the inverse is the square root. A function has an inverse exactly when it is one-to-one (on the domain you chose), and the domain of the inverse is the image of the original. That is why restricting the inputs is not cheating: it changes the function.
Also look at and . The inverse of is the square for . The reciprocal is its own inverse: , so its graph is its own mirror image in .
Worked examples
Five complete solutions, each one a list of steps with the reason for each. They use only what this chapter defines, and each number you see is computed by the same model as the stages.
Worked examples: solve, then check
Choose a problem
A function is a rule that sends every input to exactly one output. This one says: subtract 2, then square.
Executable reference code
Run the Python examples below to follow the calculations step by step. First, functions as values: evaluate, compose, tabulate and invert.
# A function is a rule that sends every input to exactly one output. In Python a function is also a value: it can be passed
# to another function, stored in a list, or returned.
def shifted_square(x):
return (x - 2) ** 2 # subtract 2, then square
def square(x):
return x**2
def line(x):
return 2 * x - 1
def compose(outer, inner):
"""outer after inner: the output of `inner` becomes the input of `outer`."""
return lambda x: outer(inner(x))
print(shifted_square(-1), shifted_square(5)) # 9 9: two different inputs may share one output
print(compose(square, line)(3), compose(line, square)(3)) # 25 17: the order of the machines matters
inputs = list(range(-3, 4))
table = [(x, shifted_square(x)) for x in inputs]
print(table) # [(-3, 25), (-2, 16), (-1, 9), (0, 4), (1, 1), (2, 0), (3, 1)]
outputs = {y for _, y in table}
print(len(outputs), len(inputs)) # 6 7: fewer outputs than inputs, so the rule is not one-to-one and cannot be undone
# 2x - 1 multiplies by 2 and then subtracts 1. Its inverse undoes the steps in the opposite order: add 1, then halve.
def undo_line(y):
return (y + 1) / 2
print(undo_line(line(3))) # 3.0: the round trip returns the inputThen the domain. Python raises an exception exactly where the mathematics has no value, and NumPy returns nan instead, so the domain has to be written down.
import math
import numpy as np
# The domain of a function is the set of inputs for which the machine can finish. Python tells you the moment it cannot:
# a division by zero or a square root of a negative number raises an exception instead of returning a number.
def reciprocal_shift(x):
return 1 / (x - 2) # undefined where x - 2 = 0
def root_shift(x):
return math.sqrt(x + 3) # undefined where x + 3 < 0
def defined(f, x):
try:
f(x)
except (ZeroDivisionError, ValueError):
return False
return True
print([defined(reciprocal_shift, x) for x in (0, 1, 2, 3)]) # [True, True, False, True]: only x = 2 is refused
print([defined(root_shift, x) for x in (-4, -3, 0)]) # [False, True, True]: the edge x = -3 belongs to the domain
try:
math.sqrt(-1)
except ValueError as error:
print(error) # math domain error
# The domain of a composite is smaller than the domain of the inner function: sqrt(2x - 1) needs 2x - 1 >= 0, so x >= 1/2.
print([defined(lambda x: math.sqrt(2 * x - 1), x) for x in (0, 0.5, 1)]) # [False, True, True]
# NumPy applies the rule to a whole array. Invalid inputs become nan (not a number) rather than raising, so state the
# domain yourself with a mask, and say what to do outside it.
x = np.array([-4.0, -3.0, 0.0, 5.0])
inside = x + 3 >= 0
y = np.where(inside, np.sqrt(np.where(inside, x + 3, 0.0)), np.nan)
print(y.tolist()) # [nan, 0.0, 1.7320508075688772, 2.8284271247461903]
print(inside.tolist()) # [False, True, True, True]Finally the machine-learning picture: a model is a function of its input and of its parameters, the loss is a function of the parameters, and a layer is a composition.
# A model is a function of an input x that also depends on parameters: here f(x; w, b) = w*x + b. Training chooses the parameters,
# so the LOSS is a second function, this time of (w, b), with the data held fixed.
def model(x, w, b):
return w * x + b
data = [(0, 1), (1, 3), (2, 5), (3, 7)] # these points lie exactly on y = 2x + 1
def loss(w, b):
"""Mean squared error of the model on the data, as a function of the parameters."""
return sum((model(x, w, b) - y) ** 2 for x, y in data) / len(data)
print(loss(2, 1)) # 0.0: the right parameters
print(loss(1, 1)) # 3.5: errors 0, -1, -2, -3 give (0 + 1 + 4 + 9) / 4
print(loss(2, 0)) # 1.0: every prediction is 1 too low
# A neural-network layer is a composition: an affine map followed by an activation function.
def relu(z):
return max(z, 0.0)
def make_layer(w, b):
return lambda x: relu(model(x, w, b))
layer = make_layer(2.0, 1.0)
print(layer(-1.0), layer(2.0)) # 0.0 5.0: 2*(-1) + 1 = -1 is clipped to 0, and 2*2 + 1 = 5 passes through
print(relu(-3.0), relu(-1.0)) # 0.0 0.0: two inputs, one output, so relu cannot be undoneTwo remarks on the first file. compose(outer, inner) returns a new function: in Python a function is an ordinary value, which is what makes composition a one-line definition. And len(outputs) < len(inputs) is a finite version of “not one-to-one”: if the number of distinct outputs is smaller than the number of inputs, two inputs must share an output.
Explore: change the parameters
These questions have definite answers; check them against the stages.
- On the first stage choose with . Find two inputs between and that give the output . (They are and .)
- On the first stage choose with . At which step does the machine stop for , and what is the largest whole-number input it refuses?
- On the first stage choose with . Which input is refused, and what happens to the output as the input gets close to ?
- On the height stage choose . For which heights does the line meet the curve twice, once, and not at all?
- On the height stage choose . Does changing change how many inputs a given positive height has?
- On the composition stage choose and . Slide the input and look for an input other than at which the two orders give the same value. Is there one? (Solve to check.)
- On the composition stage choose and and set . What does the composite give, and which familiar function is it?
- On the inverse stage choose with every real input allowed and the input . Which other input has the same output, and where is its dot on the graph? Then restrict the inputs to and see what the mirror image becomes.
Common mistakes
Numerical considerations
The mathematics above is exact. A program computes with doubles, and a composition of exact inverses is not always the identity in doubles.
Squaring a square root. is exactly for every non-negative . In doubles, math.sqrt(2) ** 2 is 2.0000000000000004, because the root is rounded to the nearest double before it is squared. The reciprocal of a reciprocal is rounded twice: 1 / (1 / 49) is 49.00000000000001. And near a pole the cancellation in turns a tiny rounding error into a huge relative error. The table feeds the machine and prints the exact answer, which is , next to the double the program holds.
| computation | Python | exact value | double (what the program holds) | agree? |
|---|---|---|---|---|
| square of the root of 2 | math.sqrt(2) ** 2 | 2 | 2.0000000000000004 | ⚠ no |
| square of the root of 3 | math.sqrt(3) ** 2 | 3 | 2.9999999999999996 | ⚠ no |
| square of the root of 5 | math.sqrt(5) ** 2 | 5 | 5.000000000000001 | ⚠ no |
| square of the root of 10 | math.sqrt(10) ** 2 | 10 | 10.000000000000002 | ⚠ no |
| reciprocal of the reciprocal of 49 | 1 / (1 / 49) | 49 | 49.00000000000001 | ⚠ no |
| reciprocal of the reciprocal of 98 | 1 / (1 / 98) | 98 | 98.00000000000001 | ⚠ no |
| 1/(x − 2) at x = 2 + 1e-1 | 1 / ((2 + 1e-1) - 2) | 10 | 9.999999999999991 | ⚠ no |
| 1/(x − 2) at x = 2 + 1e-5 | 1 / ((2 + 1e-5) - 2) | 100000 | 99999.99999934487 | ⚠ no |
| 1/(x − 2) at x = 2 + 1e-10 | 1 / ((2 + 1e-10) - 2) | 10000000000 | 9999999172.59636 | ⚠ no |
| 1/(x − 2) at x = 2 + 1e-15 | 1 / ((2 + 1e-15) - 2) | 1000000000000000 | 1125899906842624 | ⚠ no |
| 1/(x − 2) at x = 2 + 1e-16 | 1 / ((2 + 1e-16) - 2) | 10000000000000000 | ZeroDivisionError | ⚠ no |
The domain does not announce itself in NumPy. math.sqrt(-1) raises a ValueError, but np.sqrt(-1.0) returns nan with only a warning, and nan then flows through every later step. The reference file masks the invalid inputs explicitly and says what to put there. A nan in a loss is nearly always a domain error upstream: a sqrt, a log or a division that received an input outside its domain.
Inverses are only as exact as the data. Undoing a transformation with its inverse, such as unstandardising a feature, can differ from the original in the last digit; compare with a tolerance (math.isclose), not ==.
Connections to engineering and machine learning
- A model is a function of its input and its parameters. A linear model takes an input and has parameters and . Training does not change ; it chooses . The reference file computes the loss as a second function, now of the parameters, with the data held fixed: the loss is at , at and at .
- A network is a composition. A layer applies an affine map and then an activation function, and a deep network composes many layers. The order matters for the reason in this chapter: and are different functions.
- Activations and invertibility. The ReLU function, , sends all negative numbers to , so it is not one-to-one and cannot be undone: information is lost. The reference file shows
relu(-3.0)andrelu(-1.0)both giving0.0. - Domains in code. The functions , and all have restricted domains. Machine learning code guards them (
np.maximum(x, eps), masks, clipped probabilities) because a single input outside the domain turns intonanorinf. - Undoing a transformation. Standardising a feature is an invertible function of the data. Its inverse exists when the scale is not , which is the restriction that made the earlier multiplication by impossible to undo. Likewise a probability can be mapped to an unbounded score and back by a pair of inverse functions, on the restricted domain where both are defined.
- Looking ahead. The next chapter surveys the families that appear again and again (lines, powers, exponentials, logarithms and more), and each of them has a domain, an image and, sometimes, an inverse.
Exercises
Answer each question and press Check. A wrong answer tells you which mistake it looks like. After one attempt you may open a worked solution.
Summary and checkpoints
- A function assigns to every input in its domain exactly one output. A formula without a domain is not yet a function; the domain is the set of inputs for which every step can be carried out.
- Read a rule as a pipeline of steps. The two refusals are the reciprocal of and the square root of a negative number; an input that is refused has no output.
- The image is the set of outputs that occur. To find the inputs that give an output , solve : there may be none, one or several.
- One input never gives two outputs; two inputs may share one. One-to-one means no output is shared (horizontal line test).
- In the function acts first. Composition is not commutative, and the domain of a composite can be smaller than the domain of the inner function.
- An inverse undoes the steps in the opposite order. It exists exactly when the function is one-to-one; restricting the domain can create one (the square root for on ). Its graph is the mirror image in . It is not .
- In code: write the domain down, do not compare a computed value with a pole using
==, and remember that NumPy turns domain errors intonansilently.
Checkpoints. You are ready to move on when you can, without looking:
- Evaluate at step by step, and say what the rule does to the input first.
- State the domain of and of , and say which step refuses.
- List the inputs that give the output under , and the image of .
- Compute and for and , and say which acts first in each.
- Explain why has no inverse on all of and what restriction gives it one.