Knowing one graph means knowing many
A student in Lagos and her cousin in Toronto compare the weather by video call. She thinks in degrees Celsius, he in Fahrenheit. The conversion
is a function: one input, exactly one output. Its graph is a straight line. To convert back, he needs the inverse function , whose graph is the first line reflected in the diagonal. If the forecast says " degrees warmer tomorrow", that is another function, . Doing one function after another is composition.
This lesson is about seeing functions whole. If you know the graph of , you know the graph of without plotting a single new point. If you know the graph of , you know the graph of for free. And from a formula like you will be able to predict where its graph shoots off to infinity and what it looks like far away.
A graph is a portrait of a function
In the lesson on functions we met a function as a rule that gives every input in its domain exactly one output. For real functions, we can draw all the pairs (input, output) at once as points in the plane. That picture is the graph.
The graph lets you read off properties at a glance:
- the domain is the shadow of the graph on the -axis, and the range is its shadow on the -axis;
- the zeros are where it meets the -axis;
- increasing means the graph climbs as you move right;
- a vertical line meets the graph of a function at most once (one input, one output) — the vertical line test;
- a horizontal line meets it at most once exactly when the function is injective — the horizontal line test — and that, we will prove, is what an inverse needs.
Definitions
Definition— real function, natural domain, graph
A real function assigns to each number in its domain exactly one real number . When a function is given only by a formula, its natural domain is the set of all real for which the formula makes sense. The graph of is the set of points
The range is the set of outputs .
For example, has natural domain , has natural domain , and every polynomial has natural domain .
Definition— increasing, even and odd
is strictly increasing on a set if implies for all (and strictly decreasing if it implies ). On a domain symmetric about , is even if for all , and odd if for all .
The graph of an even function is symmetric in the -axis (, , ). The graph of an odd function is symmetric under a half-turn about the origin (, , ). Most functions, such as , are neither.
Definition— composition and inverse
The composite is the function . Its natural domain is the set of in the domain of with in the domain of . A function is an inverse of if
We then write .
Definition— asymptotes and end behaviour (informal)
The line is a horizontal asymptote of if gets as close to as we like once is large enough (or once is negative enough); we write as (or ). The line is a vertical asymptote if grows beyond every bound as approaches from at least one side. The end behaviour of describes what does as .
These last definitions use the idea of a limit informally. It is made precise in calculus, and the Lean proof below uses the precise version.
A gallery of function families
Example— The basic shapes
- Linear : a straight line with slope (see linear relationships).
- Quadratic : a parabola (see quadratics).
- Powers : for even U-shaped and even; for odd S-shaped, odd and strictly increasing.
- Absolute value : a V with its corner at the origin; for and for .
- Square root on : half of a sideways parabola.
- Reciprocal on : a hyperbola with asymptotes and .
Example— A piecewise function: a block tariff
Many electricity and water utilities charge in blocks. Here is an illustrative tariff in the style used by several municipalities in southern Africa: the first kWh in a month cost per kWh and each further kWh costs . The monthly bill for kWh is
The two pieces agree at (both give ), so the graph has no jump, only a bend where the slope increases from to .
Example— A rational function
has natural domain . Dividing, . So:
- as , and : horizontal asymptote ;
- as , becomes huge, positive just to the right of and negative just to the left: vertical asymptote ;
- the zero is at , so ; the -intercept is .
Its graph is the hyperbola stretched and moved: right by and up by .
Example— Holes are not asymptotes
for every . Its graph is the line with the single point missing — a hole, not an asymptote. A zero of the denominator gives a vertical asymptote only if it does not cancel against the numerator.
Example— End behaviour of polynomials
For large the leading term wins. For ,
and the bracket tends to . So as and as , like , even though is positive.
Transforming graphs
Starting from the graph of :
| New function | What happens to the graph |
|---|---|
| moves up by | |
| moves right by | |
| stretches vertically by the factor (and reflects in the -axis if ) | |
| squeezes horizontally by the factor (and reflects in the -axis if ) |
Example— Building y = −2|x − 1| + 3 from y = |x|
Start with the V of , corner at . Replace by : the corner moves right to . Multiply by : the V flips upside down and becomes twice as steep. Add : the corner rises to . The result is an upside-down V with its peak at , crossing the -axis where , at and .
Example— The order matters
is : squeeze by and shift right by , not by . Always factor out first to read off .
Proofs
Theorem— Transformation rule
Let . A point lies on the graph of if and only if the point lies on the graph of . In particular (, ), the graph of is the graph of moved units to the right.
Proof
Write . If and , then , so : the moved point is on the graph of . Conversely, every point of the graph of arises this way, from the point with . So the graph of is exactly the image of the graph of under the move.
For the shift: the output that produces at input , the function produces when , that is, at — later by . That is why subtracting moves the graph to the right.
∎
Theorem— Inverses and bijections
A function has an inverse if and only if it is a bijection (injective and surjective). The inverse is then unique.
Proof
If is an inverse and , then , so is injective. Every equals , so is surjective. Conversely, if is a bijection, each is for exactly one . Define to be that ; then and . If is another inverse, then for every .
∎
Theorem— Strictly monotone functions are injective
If is strictly increasing (or strictly decreasing) on a set , then is injective on . So has an inverse from onto its range , and if is strictly increasing so is .
Proof
If in , say , then , so . For the inverse: let be in and suppose . Since is increasing, , that is, , a contradiction.
∎
This is how we invert functions that are not injective: restrict the domain to an interval where they are strictly monotone. is not injective on (), but it is strictly increasing on , and there its inverse is .
Theorem— The graph of the inverse is a reflection
If , then lies on the graph of if and only if lies on the graph of . So the graph of is the mirror image of the graph of in the line .
Proof
If then , so is on the graph of . If then . Finally, the reflection in the line is exactly the map : the midpoint of the two points lies on the line, and the segment joining them has direction , perpendicular to the line.
∎
Example— Finding an inverse by algebra
To invert (), solve for :
So , defined for . The value , the horizontal asymptote of , is not in the range of , and it becomes the vertical asymptote of . Reflection swaps the roles of horizontal and vertical.
Theorem— Even and odd parts
Every function can be written in exactly one way as with even and odd, namely
Proof
Existence: , , and .
Uniqueness: if , then is both even and odd, so and for every .
∎
For a polynomial, the even part collects the even powers and the odd part the odd powers: splits as .
Graphs, inverses and symmetry in Lean
We define the graph of a function as a set of pairs, exactly as in the definition:
/-- The **graph** of `f : ℝ → ℝ` is the set of points `(x, f x)` in the plane. -/
def graph (f : ℝ → ℝ) : Set (ℝ × ℝ) := {p | p.2 = f p.1}The transformation rule says that one set is the image of another under a map of the plane, written (fun p => …) '' graph f:
/-- **Shifting right.** The graph of `y = f(x − h)` is the graph of `y = f(x)` moved `h` units to
the **right**: it is the image of `graph f` under `(x, y) ↦ (x + h, y)`. (For `h > 0`, the input
`x − h` reaches the value `x₀` later, at `x = x₀ + h`.) -/
theorem graph_shift (f : ℝ → ℝ) (h : ℝ) :
graph (fun x => f (x - h)) = (fun p : ℝ × ℝ => (p.1 + h, p.2)) '' graph f := by
ext ⟨x, y⟩
simp only [graph, Set.mem_ofPred_eq, Set.mem_image, Prod.mk.injEq, Prod.exists]
constructor
· intro hy
exact ⟨x - h, y, hy, by ring, rfl⟩
· rintro ⟨u, v, hv, rfl, rfl⟩
simp [hv]/-- **The transformation rule.** For `b ≠ 0`, the graph of `y = a f(b(x − h)) + k` is the image
of the graph of `f` under `(x, y) ↦ (x/b + h, a y + k)`: squeeze horizontally by the factor `b`,
shift right by `h`, stretch vertically by `a`, shift up by `k`. -/
theorem graph_transform (f : ℝ → ℝ) (a b h k : ℝ) (hb : b ≠ 0) :
graph (fun x => a * f (b * (x - h)) + k) =
(fun p : ℝ × ℝ => (p.1 / b + h, a * p.2 + k)) '' graph f := by
ext ⟨x, y⟩
simp only [graph, Set.mem_ofPred_eq, Set.mem_image, Prod.mk.injEq, Prod.exists]
constructor
· intro hy
refine ⟨b * (x - h), f (b * (x - h)), rfl, ?_, hy.symm⟩
field_simp
ring
· rintro ⟨u, v, hv, rfl, rfl⟩
have hu : b * (u / b + h - h) = u := by field_simp; ring
rw [hu, hv]Inverses. Function.LeftInverse g f means for all , and Function.RightInverse g f means . Prod.swap is the map , the reflection in :
/-- **The graph of an inverse is a reflection.** If `g` undoes `f` and `f` undoes `g`, then the
graph of `g` is the graph of `f` with the coordinates swapped, that is, reflected in the line
`y = x`: `(x, y)` lies on the graph of `f` exactly when `(y, x)` lies on the graph of `g`. -/
theorem graph_inverse (f g : ℝ → ℝ) (hgf : Function.LeftInverse g f)
(hfg : Function.RightInverse g f) : graph g = Prod.swap '' graph f := by
ext ⟨x, y⟩
simp only [graph, Set.mem_ofPred_eq, Set.mem_image, Prod.exists, Prod.swap_prod_mk,
Prod.mk.injEq]
constructor
· intro hy
exact ⟨y, x, by rw [hy, hfg x], rfl, rfl⟩
· rintro ⟨u, v, hv, rfl, rfl⟩
rw [hv, hgf u]/-- **A function has an inverse exactly when it is a bijection.** This applies Mathlib's
`Function.bijective_iff_has_inverse`. -/
theorem bijective_iff_has_inverse (f : ℝ → ℝ) :
Function.Bijective f ↔ ∃ g, Function.LeftInverse g f ∧ Function.RightInverse g f :=
Function.bijective_iff_has_inverse/-- **A strictly increasing function is injective** on any set where it is strictly increasing.
If `x ≠ y`, one of them is smaller, say `x < y`; then `f x < f y`, so `f x ≠ f y`.
(Mathlib: `StrictMonoOn.injOn`.) -/
theorem injOn_of_strictMonoOn {f : ℝ → ℝ} {s : Set ℝ} (hf : StrictMonoOn f s) : Set.InjOn f s := by
intro x hx y hy hxy
rcases lt_trichotomy x y with hlt | heq | hgt
· exact absurd hxy (ne_of_lt (hf hx hy hlt))
· exact heq
· exact absurd hxy (ne_of_gt (hf hy hx hgt))/-- The same fact, as stated in Mathlib: this applies `StrictMonoOn.injOn`. On the interval
`[0, ∞)` the function `x ↦ x²` is strictly increasing, which is why it has an inverse there
(the square root), although it has none on all of `ℝ`. -/
theorem injOn_library {f : ℝ → ℝ} {s : Set ℝ} (hf : StrictMonoOn f s) : Set.InjOn f s :=
hf.injOn/-- **The inverse of a strictly increasing function is strictly increasing.** Suppose `y₁ < y₂`
but `g y₁ ≥ g y₂`. Applying the increasing function `f` gives `f (g y₁) ≥ f (g y₂)`, that is,
`y₁ ≥ y₂` — a contradiction. -/
theorem strictMono_inverse {f g : ℝ → ℝ} (hf : StrictMono f) (hfg : Function.RightInverse g f) :
StrictMono g := by
intro y₁ y₂ hy
by_contra hle
have h : f (g y₂) ≤ f (g y₁) := hf.monotone (not_lt.mp hle)
rw [hfg y₁, hfg y₂] at h
exact absurd hy (not_lt.mpr h)The rational function of the examples and its inverse, including the facts that never takes the value and never takes the value :
/-- **An inverse found by algebra.** `f(x) = (2x + 1)/(x − 3)` (for `x ≠ 3`) and
`g(y) = (3y + 1)/(y − 2)` (for `y ≠ 2`) undo each other. To find `g`, solve `y = (2x + 1)/(x − 3)`
for `x`: `y(x − 3) = 2x + 1`, so `x(y − 2) = 3y + 1`. The value `y = 2` is never taken by `f`:
it is the horizontal asymptote. -/
theorem mobius_inverse :
(∀ x : ℝ, x ≠ 3 → (2 * x + 1) / (x - 3) ≠ 2 ∧
(3 * ((2 * x + 1) / (x - 3)) + 1) / ((2 * x + 1) / (x - 3) - 2) = x) ∧
(∀ y : ℝ, y ≠ 2 → (3 * y + 1) / (y - 2) ≠ 3 ∧
(2 * ((3 * y + 1) / (y - 2)) + 1) / ((3 * y + 1) / (y - 2) - 3) = y) := by
constructor
· intro x hx
have hx3 : x - 3 ≠ 0 := sub_ne_zero.mpr hx
have hne : (2 * x + 1) / (x - 3) - 2 ≠ 0 := by
rw [div_sub' hx3]
exact div_ne_zero (by ring_nf; norm_num) hx3
refine ⟨fun h => hne (by rw [h]; ring), ?_⟩
rw [div_eq_iff hne]
field_simp
ring
· intro y hy
have hy2 : y - 2 ≠ 0 := sub_ne_zero.mpr hy
have hne : (3 * y + 1) / (y - 2) - 3 ≠ 0 := by
rw [div_sub' hy2]
exact div_ne_zero (by ring_nf; norm_num) hy2
refine ⟨fun h => hne (by rw [h]; ring), ?_⟩
rw [div_eq_iff hne]
field_simp
ringThe horizontal asymptote, stated with Mathlib's precise notion of limit (Tendsto … atTop (𝓝 2) reads "tends to as "). The proof follows the lesson: rewrite as for :
/-- **End behaviour:** `(2x + 1)/(x − 3) → 2` as `x → ∞`, so `y = 2` is a horizontal asymptote.
For `x ≠ 3`, `(2x + 1)/(x − 3) = 2 + 7/(x − 3)`, and `7/(x − 3) → 0` because `x − 3 → ∞`.
(The small library facts used are `tendsto_inv_atTop_zero` and the limit laws.) -/
theorem horizontal_asymptote :
Tendsto (fun x : ℝ => (2 * x + 1) / (x - 3)) atTop (𝓝 2) := by
have hden : Tendsto (fun x : ℝ => x - 3) atTop atTop :=
tendsto_atTop_add_const_right _ _ tendsto_id
have hsmall : Tendsto (fun x : ℝ => 7 * (x - 3)⁻¹) atTop (𝓝 0) := by
simpa using (tendsto_inv_atTop_zero.comp hden).const_mul 7
have hsum : Tendsto (fun x : ℝ => 2 + 7 * (x - 3)⁻¹) atTop (𝓝 2) := by
simpa using hsmall.const_add 2
refine hsum.congr' ?_
filter_upwards [eventually_gt_atTop 3] with x hx
have hx3 : x - 3 ≠ 0 := by linarith
field_simp
ringEven and odd functions use Mathlib's own definitions Function.Even and Function.Odd:
/-- **Every function is even plus odd.** For `f : ℝ → ℝ` put
`e(x) = (f(x) + f(−x))/2` and `o(x) = (f(x) − f(−x))/2`. Then `e` is even, `o` is odd and
`f = e + o`. (For `f(x) = eˣ` this gives `cosh` and `sinh`.) -/
theorem even_odd_decomposition (f : ℝ → ℝ) :
∃ e o : ℝ → ℝ, Function.Even e ∧ Function.Odd o ∧ ∀ x, f x = e x + o x := by
refine ⟨fun x => (f x + f (-x)) / 2, fun x => (f x - f (-x)) / 2, ?_, ?_, ?_⟩
· intro x
simp only [neg_neg]
ring
· intro x
simp only [neg_neg]
ring
· intro x
ring/-- **The splitting is unique.** If `e₁ + o₁ = e₂ + o₂` with `e₁, e₂` even and `o₁, o₂` odd, then
`d = e₁ − e₂ = o₂ − o₁` is both even and odd, so `d(x) = d(−x) = −d(x)`, forcing `d(x) = 0`. -/
theorem even_odd_unique {e₁ o₁ e₂ o₂ : ℝ → ℝ} (he₁ : Function.Even e₁) (he₂ : Function.Even e₂)
(ho₁ : Function.Odd o₁) (ho₂ : Function.Odd o₂) (h : ∀ x, e₁ x + o₁ x = e₂ x + o₂ x) :
e₁ = e₂ ∧ o₁ = o₂ := by
have hd : ∀ x, e₁ x - e₂ x = 0 := by
intro x
have h1 := h x
have h2 := h (-x)
rw [he₁ x, he₂ x, ho₁ x, ho₂ x] at h2
linarith
constructor
· funext x
linarith [hd x]
· funext x
linarith [hd x, h x]/-- **Odd times odd is even** — like `(−1)·(−1) = 1`. For example `x · x³ = x⁴`. This applies
Mathlib's `Function.Odd.mul_odd`. -/
theorem odd_mul_odd {f g : ℝ → ℝ} (hf : Function.Odd f) (hg : Function.Odd g) :
Function.Even (f * g) :=
hf.mul_odd hg/-- **Order matters:** with `f(x) = x + 1` and `g(x) = x²`, `g ∘ f ≠ f ∘ g`, because
`(g ∘ f)(1) = 4` but `(f ∘ g)(1) = 2`. -/
theorem comp_not_comm :
(fun x : ℝ => x ^ 2) ∘ (fun x : ℝ => x + 1) ≠ (fun x : ℝ => x + 1) ∘ (fun x : ℝ => x ^ 2) := by
intro h
have h1 := congrFun h 1
norm_num at h1Checking the rules, and inverting without a formula
"""Transformations of graphs and the even/odd splitting, checked exactly.
The lesson proves that the graph of y = a f(b(x - h)) + k is the graph of f
moved by the rule (x, y) -> (x/b + h, a y + k). Here we test that rule with
exact fractions on sample points, see which way y = f(x - 2) moves, and split
functions into even and odd parts, checking the parts on a grid of points.
"""
from fractions import Fraction
def transform(f, a, b, h, k):
"""The function x -> a f(b(x - h)) + k."""
return lambda x: a * f(b * (x - h)) + k
def move_point(point, a, b, h, k):
"""Where the transformation rule sends the point (x, y)."""
x, y = point
return (x / b + h, a * y + k)
def rule_holds(f, a, b, h, k, xs):
"""True if every moved point (x/b + h, a f(x) + k) lies on the new graph."""
g = transform(f, a, b, h, k)
for x in xs:
u, v = move_point((x, f(x)), a, b, h, k)
if g(u) != v:
return False
return True
def even_part(f):
"""x -> (f(x) + f(-x)) / 2."""
return lambda x: (f(x) + f(-x)) / 2
def odd_part(f):
"""x -> (f(x) - f(-x)) / 2."""
return lambda x: (f(x) - f(-x)) / 2
def parity(f, xs):
"""'even', 'odd', 'zero' or 'neither', judged on the points xs only.
A function that is both even and odd is 0 at every checked point.
"""
is_even = all(f(-x) == f(x) for x in xs)
is_odd = all(f(-x) == -f(x) for x in xs)
if is_even and is_odd:
return "zero"
return "even" if is_even else ("odd" if is_odd else "neither")
GRID = [Fraction(n, 4) for n in range(-12, 13)]
def main():
def f(x):
return x ** 3 - x
a, b, h, k = Fraction(-1), Fraction(2), Fraction(1), Fraction(3)
print("f(x) = x^3 - x and g(x) = -f(2(x - 1)) + 3; rule (x, y) ->"
" (x/2 + 1, -y + 3)")
for x in [-2, -1, 0, 1, 2]:
x = Fraction(x)
u, v = move_point((x, f(x)), a, b, h, k)
g = transform(f, a, b, h, k)
print(f" ({x}, {f(x)}) -> ({u}, {v}); g({u}) = {g(u)}")
print(f"rule holds on all {len(GRID)} grid points:",
rule_holds(f, a, b, h, k, GRID))
print()
def square(x):
return x * x
right = transform(square, 1, 1, 2, 0)
zeros = ", ".join(str(x) for x in GRID if right(x) == 0)
print(f"y = x^2 has its zero at x = 0; y = (x - 2)^2 has it at x = {zeros}:")
print(" replacing x by x - 2 moves the graph 2 units to the RIGHT.")
print()
print(f"parity on the grid {GRID[0]}..{GRID[-1]} (steps of 1/4):")
examples = [
("x^4 - 3x^2", lambda x: x ** 4 - 3 * x ** 2),
("x^3 - 5x", lambda x: x ** 3 - 5 * x),
("x^2 + x", lambda x: x ** 2 + x),
("1/(1 + x^2)", lambda x: 1 / (1 + x ** 2)),
("x/(1 + x^2) + 1", lambda x: x / (1 + x ** 2) + 1),
]
for name, fn in examples:
e, o = even_part(fn), odd_part(fn)
two = Fraction(2)
odd2 = f"({o(two)})" if o(two) < 0 else f"{o(two)}"
print(f" {name:16s} {parity(fn, GRID):8s} even part {parity(e, GRID):5s}"
f" odd part {parity(o, GRID):5s} f(2) = {e(two)} + {odd2}")
print()
print("Epistemic status: every value above is exact rational arithmetic, but")
print("only finitely many points are checked. A function could pass on the")
print("grid and fail elsewhere; the lesson's proofs (and the Lean versions)")
print("establish the transformation rule and the even/odd splitting for all")
print("real numbers.")
if __name__ == "__main__":
main()Checking a rule at points is evidence, not proof: a function could behave at the points we test and misbehave elsewhere. The proofs above, and their Lean versions, cover every real number.
Some functions are easy to invert by algebra. Others are not. is strictly increasing, so it has an inverse, but solving for requires the cubic formula. We can still evaluate the inverse to any accuracy by bisection: keep halving an interval that is guaranteed to contain the answer.
"""Inverting a function that has no simple formula for its inverse.
f(x) = x^3 + x is strictly increasing, so it is injective and has an inverse
on its whole range. To evaluate the inverse at y we search for the x with
f(x) = y by bisection, using exact fractions: each step halves an interval
that is guaranteed to contain the answer, so after n steps the error is at
most (initial width) / 2^n. The experiment also shows why x^2 needs its domain
restricted to [0, oo) before it can be inverted.
"""
from fractions import Fraction
def f(x):
"""The strictly increasing function x^3 + x."""
return x ** 3 + x
def bisect_inverse(func, y, lo, hi, steps):
"""Find x in [lo, hi] with func(x) = y for an increasing ``func``.
Requires func(lo) <= y <= func(hi). Returns (lo, hi) after ``steps``
halvings; the true x always lies in the returned interval.
"""
lo, hi = Fraction(lo), Fraction(hi)
if not func(lo) <= y <= func(hi):
raise ValueError("y is not between func(lo) and func(hi)")
for _ in range(steps):
mid = (lo + hi) / 2
if func(mid) <= y:
lo = mid
else:
hi = mid
return lo, hi
def inverse(y, steps=40):
"""Approximate f^(-1)(y) as the midpoint of the final bisection interval."""
bound = abs(Fraction(y)) + 1 # f(bound) >= bound >= |y|
lo, hi = bisect_inverse(f, Fraction(y), -bound, bound, steps)
return (lo + hi) / 2, (hi - lo) / 2
def collisions(func, points):
"""Pairs of different inputs among ``points`` with the same output."""
pts = sorted(set(points))
return [(a, b) for i, a in enumerate(pts) for b in pts[i + 1:]
if func(a) == func(b)]
def main():
print("f(x) = x^3 + x is strictly increasing, so it has an inverse g.")
print("g(y) by 40 steps of exact bisection; error bound = half-width:")
for y in [2, 10, 30, -10]:
x, err = inverse(y)
print(f" g({y:3d}) ~ {float(x):.12f} |error| <= {float(err):.1e}"
f" f(x) - y = {float(f(x) - y):.1e}")
print(" exact values: g(2) = 1, g(10) = 2, g(30) = 3, g(-10) = -2")
print()
print("reflection: (a, f(a)) on the graph of f gives (f(a), a) on g's:")
for a in [Fraction(1, 2), Fraction(3, 2)]:
x, err = inverse(f(a))
print(f" a = {a}: f(a) = {f(a)}, g(f(a)) ~ {float(x):.10f}"
f" (within {float(err):.1e} of {a})")
print()
grid = [Fraction(n, 2) for n in range(-6, 7)]
sq = collisions(lambda t: t * t, grid)
print(f"x^2 on -3..3 in steps of 1/2: {len(sq)} pairs with equal outputs,")
print(f" e.g. {sq[0][0]} and {sq[0][1]}: not injective, no inverse on R.")
pos = collisions(lambda t: t * t, [t for t in grid if t >= 0])
print(f" restricted to x >= 0: {len(pos)} collisions; the inverse is sqrt.")
print()
print("Epistemic status: bisection with exact fractions gives a rigorous")
print("enclosure: since f is increasing and continuous, the true inverse value")
print("lies in the final interval, so the error bound is guaranteed, not")
print("estimated. Only the printed decimals are rounded. The collision count")
print("is an exhaustive check of a finite grid, not a proof for all reals.")
if __name__ == "__main__":
main()Because the arithmetic is exact and is increasing and continuous, the error bounds here are guaranteed, not estimated. Each step halves the interval known to contain .
Explore: transformations, inverses and asymptotes
Use the sliders to transform (dashed reference) into . Predict where the corner goes before you move a slider. What does a negative do to a V shape, and why? (Hint: is even.)
Transforming y = |x|
Move the sliders and trace along the curves to read off values.
- y = a|b(x − h)| + k
- y = |x|
- y = a|b(x − h)| + k: y = 3
- y = |x|: y = 1
A function and its inverse are mirror images in the line . Trace along the curves: passes through , so the cube root passes through .
A function, its inverse and the mirror line
Move the sliders and trace along the curves to read off values.
- y = x³
- y = ∛x
- y = x
- y = x³: y = 1
- y = ∛x: y = 1
- y = x: y = 1
Finally the rational function , its horizontal asymptote , and its inverse . The horizontal asymptote of one is the vertical asymptote of the other.
A rational function and its inverse
Move the sliders and trace along the curves to read off values.
- y = (2x + 1)/(x − 3)
- inverse: y = (3x + 1)/(x − 2)
- y = 2
- y = (2x + 1)/(x − 3): y = −1.5
- inverse: y = (3x + 1)/(x − 2): y = −4
- y = 2: y = 2
Exercises
1. Functions and their graphs (precalculus)
Warm-upHumanHow is the graph of obtained from the graph of ?
2. Functions and their graphs (precalculus)
Warm-upHumanLet and . Compute .
3. Functions and their graphs (precalculus)
CoreHumanWhat is the natural domain of ?
4. Functions and their graphs (precalculus)
CoreHumanLet for . Which formula gives ?
5. Functions and their graphs (precalculus)
CoreHumanFind all vertical asymptotes of . Enter the set of numbers , for example {2, 5}.
6. Functions and their graphs (precalculus)
CoreHumanWhich of these functions are odd, meaning for every in the domain? Choose all that apply.
7. Functions and their graphs (precalculus)
StretchHumanThe function is strictly decreasing on and on . Which statement is true on its whole domain ?
8. Functions and their graphs (precalculus)
CoreFormalWhich Lean statement says that the graph of is the graph of moved units to the right? Here graph f is the set of points (x, f x), and F '' S is the image of the set S under the map F.
9. Functions and their graphs (precalculus)
StretchComputationalWrite inverse_value(f, y, lo, hi, steps) that evaluates the inverse of a strictly increasing function f at y by bisection. Assume f(lo) <= y <= f(hi). Repeat steps times: look at the midpoint mid; if f(mid) <= y the answer is in [mid, hi], otherwise in [lo, mid]. Return the midpoint of the final interval.
Common misconceptions
Misconception
"." The in means "undo ", not "one over". For , , but . At these are and .
Misconception
" moves the graph to the left." It moves it right. The new function reaches each old output units later: at it does what did at . The transformation rule above proves it.
Misconception
"Composition is commutative." With and , but ; at they give and . Even the domains can differ: is defined for , but only for . See composition.
Misconception
"A graph can never cross its horizontal asymptote." It can — the asymptote describes the far-away behaviour only. as , yet it equals at , where .
Misconception
"Every function has an inverse." Only bijections do. on has none, because . Its "inverse" is the inverse of restricted to .
Many ways of seeing
Set theory— A function is its graph
In set theory a function from to is a subset such that every appears in exactly one pair . The vertical line test is that definition drawn in the plane. The inverse of a bijection is obtained by swapping every pair, which is the reflection of the graph in the line .
Geometry— Transformations form a group
The moves with are transformations of the plane. Doing two of them in a row gives another of the same kind, each can be undone by another, and "do nothing" (, ) is one of them. So they form a group acting on graphs. Felix Klein's Erlangen programme (1872) proposed studying a geometry through the group of transformations that preserve it (see transformation geometry). From this point of view, and are "the same shape" because one transformation in the group carries one graph to the other.
Topology— Continuity and inverses on intervals
Topology explains why restricting to intervals works so well. A continuous function on an interval that is injective must be strictly monotone. The proof uses the intermediate value theorem: a continuous function that went up and then down would take some value twice. Moreover, the inverse of a continuous, strictly monotone function on an interval is again continuous. So the function is a homeomorphism between two intervals: a stretching of one line segment onto another without tearing. The bisection method in the computation section relies on the same intermediate value theorem.
Analysis— Asymptotes are limits
"The graph approaches " is shorthand for a precise statement: for every tolerance there is an such that whenever . For we can take . Analysts study such estimates systematically, and the end behaviour of polynomials ("the leading term wins") is the first example of comparing rates of growth (see introductory calculus).
Wonder Trails
Composition and inverses are the beginning of a much bigger story about arrows:
Wonder Trail · Optional · never gradedArrows that composeWhat do functions between sets, maps between groups and continuous maps between shapes have in common? What if we studied only the arrows?Follow the trailHistory and global context
- Graphs before functions. Around 1350, Nicole Oresme in Paris drew diagrams in which the "intensity" of a quality (such as speed) was plotted as a height above a line representing time.
- Coordinates. In the 1630s René Descartes and Pierre de Fermat independently connected equations with curves, founding analytic geometry.
- Functions as infinite expressions. In Kerala in the 14th and 15th centuries, Mādhava of Saṅgamagrāma and his successors expressed the sine, cosine and arctangent as infinite series. These were among the earliest descriptions of functions by power series.
- The word "function". Gottfried Wilhelm Leibniz used the word in the late 17th century for quantities attached to a curve. Johann Bernoulli (1718) and Leonhard Euler made it mean an expression built from a variable, and Euler introduced the notation in the 1730s.
- Arbitrary rules. In the 19th century, Nikolai Lobachevsky and Peter Gustav Lejeune Dirichlet (1830s) argued that a function may be any rule assigning outputs to inputs, given by a formula or not. That idea led to the set-theoretic definition used today.
Further reading
- I. M. Gelfand, E. G. Glagoleva and E. E. Shnol, Functions and Graphs (1969; English translation 1990) — a short, beautiful book on exactly this topic, written for school students.
- I. M. Gelfand and A. Shen, Algebra (1993).
- Sheldon Axler, Precalculus: A Prelude to Calculus (2009) — careful, with every definition and proof.
- Richard Courant and Herbert Robbins, What Is Mathematics? (1941), chapter VI on functions and limits.