3. Functions, graphs, and the transformations that matter
Calculus studies functions, so this lesson pins down what one is and stocks the shelf with the handful you'll differentiate for the rest of the course. If you're comfortable with domains, composition, inverses, and shifting a graph around, skim it and move on.
Two things here genuinely matter later, though, so don't skip them: domains, because a function's edge cases are exactly where limits get interesting, and composition, because the chain rule is nothing but composition read backwards.
What a function is
A function f from a set D (the domain) assigns to each input exactly one output. The "exactly one" is the whole content of the definition. Graphically it's the vertical line test: any vertical line meets the graph at most once.
x^2 + y^2 = 1 is not a function of x — the input 0 has two outputs, \pm 1. It's a perfectly good curve, and in §2 we'll differentiate it anyway using implicit differentiation, precisely because the curve is fine even though the function isn't.
The range is the set of values that actually come out. Domain is a constraint you're given; range is something you usually have to work out.
The library
Almost everything in this course is built from these:
| Family | Form | Domain | Notes |
|---|---|---|---|
| Polynomial | a_nx^n + \cdots + a_0 | all \mathbb{R} | smooth everywhere, no surprises |
| Rational | p(x)/q(x) | q(x) \neq 0 | vertical asymptotes at the zeros of q |
| Root | \sqrt[n]{x} | x \ge 0 if n even | \sqrt{x} has an infinite slope at 0 |
| Exponential | b^x, b>0 | all \mathbb{R} | always positive; range (0,\infty) |
| Logarithm | \log_b x | x > 0 | inverse of the above |
| Trigonometric | \sin x, \cos x, \tan x | \tan excludes \pi/2 + k\pi | periodic |
| Absolute value | \lvert x\rvert | all \mathbb{R} | continuous but not differentiable at 0 |
| Piecewise | different rules on different pieces | as declared | the joins are where things go wrong |
The last two rows are where the interesting failures live. \lvert x \rvert is the standard example of a function that is perfectly continuous and still has no derivative at a point, and piecewise definitions are how we manufacture discontinuities on demand.
Finding a domain
Only three things exclude a point, and you'll check for them reflexively by the end of §1:
- Division by zero. \dfrac{1}{x-3} excludes x = 3.
- Even root of a negative. \sqrt{x-2} needs x \ge 2.
- Log of a non-positive. \ln(5-x) needs x < 5.
Combine them by intersecting. For
f(x) = \frac{\sqrt{x-2}}{\ln(5-x)}
we need x \ge 2, and x < 5, and \ln(5-x) \neq 0 — that last one excludes 5 - x = 1, i.e. x = 4. Domain: [2,4) \cup (4,5).
That third condition is the one people miss. A denominator being defined isn't enough; it also has to be nonzero.
Composition
(f \circ g)(x) = f(g(x)): do g, then feed the result to f. Order matters, usually a lot.
With f(x) = x^2 and g(x) = x + 3:
f(g(x)) = (x+3)^2 \qquad g(f(x)) = x^2 + 3
Different functions entirely.
The domain of a composition needs both stages to be legal: x must be in the domain of g, and g(x) must be in the domain of f. For f(x) = \sqrt{x} and g(x) = x - 4, the composition \sqrt{x-4} needs x \ge 4 even though g alone is happy anywhere.
Learn to see composition in the wild, because that's the skill the chain rule runs on. \sin(x^2) is \sin of a square. \sqrt{1 + e^x} is a square root of (one plus an exponential). Decomposing an expression into "outer function of inner function" is 90% of differentiating it.
Inverses
f^{-1} undoes f: f^{-1}(f(x)) = x. It exists only if f is one-to-one — no two inputs share an output — which graphically is the horizontal line test.
f(x) = x^2 on all of \mathbb{R} has no inverse: 2 and -2 both map to 4, so f^{-1}(4) has no single answer. Restrict the domain to x \ge 0 and it does: \sqrt{x}. Every inverse trig function you'll meet in §2 is manufactured by exactly this trick — chop the domain down until the function is one-to-one, then invert.
Two facts to carry forward:
- The graph of f^{-1} is the graph of f reflected across y = x, because reflecting swaps the roles of input and output.
- f^{-1}'s domain is f's range, and vice versa.
That reflection is why the derivative of an inverse is the reciprocal of the original's derivative — flipping the axes flips rise-over-run. §2 makes it precise.
The four transformations
Given the graph of f, you can read off a whole family without plotting anything:
| Change | Effect | Direction |
|---|---|---|
| f(x) + c | shift up c | as expected |
| f(x + c) | shift left c | opposite |
| a \cdot f(x) | stretch vertically by a | as expected |
| f(ax) | compress horizontally by a | opposite |
| -f(x) | reflect across the x-axis | |
| f(-x) | reflect across the y-axis |
The rule with no exceptions: changes outside f do what they say; changes inside f do the opposite.
Inside-the-function changes feel backwards until you ask when rather than what. For f(x-3) to produce the value that f produced at 0, you need x = 3 — the event happens 3 units later, so the graph moves right. Compressing is the same story: f(2x) reaches f's x = 10 behaviour already at x = 5.
Order matters when you combine them. f(2x + 6) = f(2(x+3)) is a compression by 2 and a shift left by 3 — not left by 6. Factor before you read.
Even and odd
f is even if f(-x) = f(x) (symmetric about the y-axis: x^2, \cos x), and odd if f(-x) = -f(x) (symmetric through the origin: x^3, \sin x). Most functions are neither.
This looks decorative and isn't. In §4, integrating an odd function over a symmetric interval [-a, a] gives exactly zero — the halves cancel — and an even one gives twice the half. Spotting parity converts hard integrals into trivial ones, and it's how the Fourier series in §8 decides which coefficients vanish.
Doing it in Python
Transformations, checked rather than asserted:
def f(x):
return x * x
print(f"{'x':>5} {'f(x)':>8} {'f(x-3)':>8} {'f(x)+2':>8} {'f(2x)':>8} {'-f(x)':>8}")
for x in (-2, -1, 0, 1, 2, 3, 4, 5):
print(f"{x:>5} {f(x):>8} {f(x - 3):>8} {f(x) + 2:>8} {f(2 * x):>8} {-f(x):>8}")
print("\nf(x-3) is 0 at x=3, not x=-3: inside the function, the shift is backwards")
Domains are a property you can probe:
from math import log, sqrt
def f(x):
return sqrt(x - 2) / log(5 - x)
for x in (1.0, 2.0, 3.0, 4.0, 4.5, 5.0, 6.0):
try:
print(f"x={x:<5} f(x) = {f(x):.4f}")
except (ValueError, ZeroDivisionError) as e:
print(f"x={x:<5} undefined -- {type(e).__name__}")
print("\ndomain is [2,4) U (4,5): sqrt needs x>=2, log needs x<5, and log(1)=0 kills x=4")
Composition, and how it fails:
from math import sqrt
def outer(x):
return sqrt(x)
def inner(x):
return x - 4
print(f"{'x':>4} {'inner(x)':>10} {'outer(inner(x))':>18}")
for x in (0, 2, 4, 8, 13):
y = inner(x)
ok = f"{outer(y):.4f}" if y >= 0 else "undefined"
print(f"{x:>4} {y:>10} {ok:>18}")
print("\ninner is fine everywhere; the composition still needs x >= 4")
Worked example
Sketch y = -2\sqrt{x + 1} + 3 starting from y = \sqrt{x}.
Peel the expression from the inside out, and apply the transformations in that order:
- \sqrt{x+1} — inside, so shift left 1. The curve now starts at (-1, 0).
- 2\sqrt{x+1} — outside, stretch vertically by 2.
- -2\sqrt{x+1} — outside, reflect across the x-axis. It now goes down and right.
- -2\sqrt{x+1} + 3 — outside, shift up 3. The corner lands at (-1, 3).
Domain x \ge -1; the function starts at 3 and decreases forever.
Check one point instead of trusting four steps: at x = 3, -2\sqrt{4} + 3 = -4 + 3 = -1. And the untransformed \sqrt{x} at the corresponding input x = 4 is 2, which the recipe sends to -2(2) + 3 = -1. Agreed.
Your turn
1. Domain of g(x) = \dfrac{\ln(x+2)}{\sqrt{9 - x^2}}.
2. With f(x) = \dfrac{1}{x} and g(x) = x - 1, find f \circ g and g \circ f and both domains.
3. Is h(x) = x^3 - x even, odd, or neither? What about x^3 - x + 1?
Solutions
1. Three conditions:
- \ln(x+2) needs x + 2 > 0, so x > -2.
- \sqrt{9 - x^2} needs 9 - x^2 \ge 0, so -3 \le x \le 3.
- The denominator is also divided by, so 9 - x^2 \neq 0, tightening that to -3 < x < 3.
Intersecting: \boxed{(-2, 3)}.
2. f(g(x)) = \dfrac{1}{x-1}, defined for x \neq 1.
g(f(x)) = \dfrac{1}{x} - 1, defined for x \neq 0.
Different functions with different domains — a clean reminder that composition doesn't commute.
3. h(-x) = (-x)^3 - (-x) = -x^3 + x = -(x^3 - x) = -h(x), so x^3 - x is odd.
Adding the constant destroys it. If k(x) = x^3 - x + 1 then k(-x) = -x^3 + x + 1, while -k(x) = -x^3 + x - 1. Those differ, and k(-x) \ne k(x) either, so k is neither.
The general fact: a nonzero constant term makes odd symmetry impossible, because odd functions must satisfy f(0) = -f(0), hence f(0) = 0.
Check yourself in code
Classify functions by symmetry, numerically.
For each function, test f(-x) against f(x) and -f(x) at the sample points
0.3, 0.7, 1.1, 1.9, 2.6. Report even if f(-x) = f(x) everywhere,
odd if f(-x) = -f(x) everywhere, else neither. Compare with a tolerance of
10^{-12}.
Print exactly this:
x**2 even
x**3 odd
x**2 + x neither
cos(x) even
sin(x) odd
exp(x) neither
from math import cos, sin, exp
SAMPLES = (0.3, 0.7, 1.1, 1.9, 2.6)
TOL = 1e-12
funcs = [
("x**2", lambda x: x ** 2),
("x**3", lambda x: x ** 3),
("x**2 + x", lambda x: x ** 2 + x),
("cos(x)", cos),
("sin(x)", sin),
("exp(x)", exp),
]
for name, f in funcs:
# even if f(-x) == f(x) at every sample, odd if f(-x) == -f(x), else neither
print(f"{name:<13} ...")
from math import cos, sin, exp
SAMPLES = (0.3, 0.7, 1.1, 1.9, 2.6)
TOL = 1e-12
funcs = [
("x**2", lambda x: x ** 2),
("x**3", lambda x: x ** 3),
("x**2 + x", lambda x: x ** 2 + x),
("cos(x)", cos),
("sin(x)", sin),
("exp(x)", exp),
]
for name, f in funcs:
is_even = all(abs(f(-x) - f(x)) < TOL for x in SAMPLES)
is_odd = all(abs(f(-x) + f(x)) < TOL for x in SAMPLES)
kind = "even" if is_even else "odd" if is_odd else "neither"
print(f"{name:<13} {kind}")
A function is a rule with exactly one output per input; its domain is where that rule survives; composition stacks rules and the chain rule will read that stack backwards. Transformations outside the function behave, transformations inside run backwards, and parity is a free simplification you should always check for.
Next: exponentials and logarithms, and the specific number e that calculus keeps insisting on.