Calculus is the language of change. Chemistry is full of quantities that vary with position, time, temperature, or pressure, and two questions come up again and again: how fast does a quantity change, which is a derivative, and how much of it accumulates, which is an integral. Later in the course the same two operations act on the functions that describe waves and, eventually, quantum states, so it pays to have them at your fingertips now. This page collects the essentials with a picture for each of the two ideas that matter most: the derivative as a slope and the integral as an area. In between sits a short section on partial derivatives, the small extension needed when a function depends on more than one variable, such as a wave that depends on both position and time.
Differentiation¶
The derivative as a slope¶
The derivative of at a point is the slope of the line tangent to the curve there. We build it from the slope of a secant line through two nearby points and then let those points merge:
As the spacing shrinks, the secant line pivots into the tangent line. Drag the slider below for at : the secant slope closes in on the true tangent slope 2.
The derivative is also the instantaneous rate of change: if is position, is velocity; if is concentration, is reaction rate. A function is differentiable only where it is smooth, so no corners, jumps, or vertical tangents.
The derivative as a step¶
Read the definition backwards and it becomes a recipe for moving along the curve. For a small step ,
Knowing the value and the slope at one position is enough to predict the value at a neighboring position: the derivative is the rate at which responds to a shift in . The green bar in the slider figure measures how far this prediction misses the true . For the miss is exactly , so halving the step quarters the error, and in the limit the prediction is perfect. That is what “linear approximation” means, and it is why a tangent line is the best straight-line stand-in for a curve near a point.
Higher derivatives predict farther: the Taylor series¶
The step recipe uses one derivative and works for small steps. Each further derivative extends the reach, and with all of them the prediction becomes exact for any smooth function:
The first two terms are the step recipe (the linear approximation). Adding the term corrects for the bending of the curve, and so on. The figure shows the partial sums for about : one derivative is good near the origin, seven derivatives track the curve for more than a full period.
Source
import numpy as np
import matplotlib.pyplot as plt
from math import factorial
x = np.linspace(-2 * np.pi, 2 * np.pi, 600)
fig, ax = plt.subplots(figsize=(7.5, 4))
ax.plot(x, np.sin(x), 'k', lw=2.5, label=r'$\sin x$')
for order, color in zip([1, 3, 5, 7], ['#d1495b', '#edae49', '#66a182', '#2e4057']):
poly = sum((-1)**(k // 2) * x**k / factorial(k) for k in range(1, order + 1, 2))
label = '1 derivative' if order == 1 else f'{order} derivatives'
ax.plot(x, poly, '--', color=color, lw=1.6, label=label)
ax.set_ylim(-2.5, 2.5)
ax.set_xlabel('x')
ax.set_xticks([-2 * np.pi, -np.pi, 0, np.pi, 2 * np.pi])
ax.set_xticklabels([r'$-2\pi$', r'$-\pi$', '0', r'$\pi$', r'$2\pi$'])
ax.axhline(0, color='gray', lw=0.6)
ax.legend(fontsize=8, loc='lower right', ncol=2)
ax.set_title('Fig.2 Taylor polynomials of sin x about 0: more derivatives reach farther')
plt.tight_layout()
plt.show()
Three expansions are worth knowing by heart, all about :
Truncating after the first non-trivial term gives the small-quantity approximations used throughout chemistry: , , , and . Keeping the term of any potential energy curve near its minimum is what turns a real vibrating bond into a harmonic oscillator.
Every derivative at one point is a piece of information about the function elsewhere, and the complete set determines the function everywhere. The sum has the shape of the exponential series, which is why one writes : exponentiating the derivative translates a function by . Later in the course the operator reappears, dressed as , as momentum, and this formula is the deep reason momentum and translation belong together.
Reading the first and second derivatives¶
Most of what a derivative tells you can be read off a graph without any formula. The first derivative reports the direction of the curve:
where rises, where falls, and the size of is the steepness.
where the tangent is horizontal: a maximum, a minimum, or a flat shelf. These are the stationary points, and finding them is how one locates the most probable position, the equilibrium bond length, or the lowest energy.
The second derivative is the derivative of the slope, so it reports how the slope itself is changing, that is, how the curve bends:
: the slope is increasing and the curve bends upward like a bowl. A stationary point there is a minimum.
: the slope is decreasing and the curve bends downward like a dome. A stationary point there is a maximum.
with a change of sign: an inflection point, where the bending switches direction.
The second and third bullets together are the second derivative test. The figure applies all of this to : the first derivative vanishes at , the second derivative is negative at -1 (maximum) and positive at +1 (minimum), and it changes sign at (inflection).
Source
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2.3, 2.3, 500)
f, fp, fpp = x**3 - 3 * x, 3 * x**2 - 3, 6 * x
UP, DOWN = '#66a182', '#d1495b'
fig, axes = plt.subplots(3, 1, figsize=(7, 8), sharex=True)
ax = axes[0]
ax.plot(x, f, 'k', lw=2.5)
ax.fill_between(x, -6, 6, where=fp > 0, color=UP, alpha=0.12)
ax.fill_between(x, -6, 6, where=fp < 0, color=DOWN, alpha=0.12)
for xc in (-1, 1):
ax.plot([xc - 0.4, xc + 0.4], [xc**3 - 3 * xc] * 2, color='#2e4057', lw=2)
ax.plot(xc, xc**3 - 3 * xc, 'o', color='#2e4057', ms=7)
ax.plot(0, 0, 's', color='#edae49', ms=7)
ax.text(-1, 2.6, 'maximum', ha='center', fontsize=9)
ax.text(1, -3.3, 'minimum', ha='center', fontsize=9)
ax.text(0.15, 0.4, 'inflection', fontsize=9, color='#b07d1a')
ax.text(-2.1, 3.6, 'rising', color=UP, fontsize=9)
ax.text(-0.3, 3.6, 'falling', color=DOWN, fontsize=9)
ax.text(1.5, 3.6, 'rising', color=UP, fontsize=9)
ax.set_ylim(-5, 5)
ax.set_ylabel(r'$f = x^3 - 3x$')
ax = axes[1]
ax.plot(x, fp, color='#2e4057', lw=2.5)
ax.axhline(0, color='gray', lw=0.8)
ax.plot([-1, 1], [0, 0], 'o', color='#2e4057', ms=7)
ax.fill_between(x, 0, fp, where=fp > 0, color=UP, alpha=0.25)
ax.fill_between(x, 0, fp, where=fp < 0, color=DOWN, alpha=0.25)
ax.text(-1.75, 1.5, r"$f' > 0$: rising", color=UP, fontsize=9)
ax.text(-0.6, 1.3, r"$f' < 0$: falling", color=DOWN, fontsize=9)
ax.set_ylabel(r"$f' = 3x^2 - 3$")
ax = axes[2]
ax.plot(x, fpp, color='#b07d1a', lw=2.5)
ax.axhline(0, color='gray', lw=0.8)
ax.plot(0, 0, 's', color='#edae49', ms=7)
ax.fill_between(x, 0, fpp, where=fpp > 0, color=UP, alpha=0.25)
ax.fill_between(x, 0, fpp, where=fpp < 0, color=DOWN, alpha=0.25)
ax.text(0.8, -6, r"$f'' > 0$: bends up (bowl)", color=UP, fontsize=9)
ax.text(-2.2, 6, r"$f'' < 0$: bends down (dome)", color=DOWN, fontsize=9)
ax.set_ylabel(r"$f'' = 6x$")
ax.set_xlabel('x')
fig.suptitle("Fig.3 Reading a curve from its derivatives: f' gives direction, f'' gives bending", y=0.995, fontsize=10)
plt.tight_layout()
plt.show()
Derivatives in motion: velocity and acceleration¶
When the variable is time, the two derivatives have names everyone knows. If is position, then is the velocity, how fast and in which direction, and is the acceleration, how the velocity is changing. Newton’s second law says that forces set the second derivative: the physics enters through the bending of the trajectory, not its slope. That is why equations of motion are second order and need two initial conditions, a position and a velocity.
The cleanest example is . Its velocity is and its acceleration is , so
The acceleration is proportional to minus the displacement: the higher the curve climbs, the harder it bends back toward zero. A function whose curvature is proportional to minus itself oscillates, and cosine and sine are exactly the functions that do this. This one relation is the harmonic oscillator, and the same structure returns in space instead of time: satisfies , which is why sines and cosines solve the wave equation met later on this page. In quantum mechanics the curvature of a wavefunction measures its kinetic energy, so a wigglier wave means a faster particle.
Source
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 4 * np.pi, 500)
fig, ax = plt.subplots(figsize=(7.5, 3.6))
ax.plot(t, np.cos(t), 'k', lw=2.5, label=r'position $x = \cos t$')
ax.plot(t, -np.sin(t), color='#2e4057', lw=1.8, label=r"velocity $x' = -\sin t$")
ax.plot(t, -np.cos(t), color='#d1495b', lw=1.8, ls='--', label=r"acceleration $x'' = -\cos t = -x$")
ax.axhline(0, color='gray', lw=0.6)
ax.set_xticks([0, np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi])
ax.set_xticklabels(['0', r'$\pi$', r'$2\pi$', r'$3\pi$', r'$4\pi$'])
ax.set_xlabel('t')
ax.set_ylim(-1.8, 1.8)
ax.legend(fontsize=8, loc='upper right', ncol=3)
ax.set_title('Fig.4 Cosine motion: the acceleration is the mirror image of the position')
plt.tight_layout()
plt.show()
Rules of differentiation¶
Example: a product with a composition inside¶
Differentiate . Attempt this before peeking at the solution. (Functions of exactly this shape describe vibrating molecules later in the course.)
Solution
Split into times and apply the product rule:
The chain rule handled the inner function inside the exponential. Setting gives and : a minimum at the origin flanked by two maxima.
The chain rule is the one you will use most
Almost every function you will meet in this course is a composition: , , . Each needs the chain rule. For , take the outer derivative times the inner derivative , giving .
Table of common derivatives¶
| Function | Derivative | Function | Derivative |
|---|---|---|---|
| 0 | |||
A few limits underlie these results: , , and the definition , which is exactly what makes its own derivative.
Solution
(chain rule), and the product plus chain rules give . The first derivative vanishes only at , where : the peak is a maximum. Setting gives : the inflection points where the bell curve changes from bending down to bending up. Remember this pair of points; when the Gaussian returns as a vibrational state they turn out to be the classical turning points.
Source
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 500)
g = np.exp(-x**2)
fig, ax = plt.subplots(figsize=(7.5, 4))
ax.plot(x, g, 'k', lw=2.5, label=r'$f = e^{-x^2}$')
ax.plot(x, -2 * x * g, color='#2e4057', lw=1.8, label=r"$f' = -2x\,e^{-x^2}$")
ax.plot(x, (4 * x**2 - 2) * g, color='#d1495b', lw=1.8, ls='--', label=r"$f'' = (4x^2 - 2)\,e^{-x^2}$")
ax.axhline(0, color='gray', lw=0.6)
xi = 1 / np.sqrt(2)
for xc in (-xi, xi):
ax.axvline(xc, color='#b07d1a', lw=1, ls=':')
ax.plot(xc, np.exp(-xc**2), 's', color='#edae49', ms=7)
ax.plot(0, 1, 'o', color='#2e4057', ms=7)
ax.text(0, 1.1, r"peak: $f' = 0$, $f'' < 0$", ha='center', fontsize=9)
ax.text(xi + 0.08, 0.72, r"inflection: $f'' = 0$", fontsize=9, color='#b07d1a')
ax.set_ylim(-2.3, 1.4)
ax.set_xlabel('x')
ax.legend(fontsize=8, loc='lower right')
ax.set_title('Fig.5 The Gaussian with its first two derivatives (a = 1)')
plt.tight_layout()
plt.show()
Functions of several variables¶
Partial derivatives¶
Most quantities in chemistry depend on more than one variable. The pressure of an ideal gas depends on both volume and temperature, , and the displacement of a plucked guitar string depends on where you look and when, . Graphically, a function of two variables is a surface over the plane, and a surface has no single slope: it can be steep along and nearly flat along .
The fix is to vary one variable at a time. The partial derivative of with respect to is the ordinary derivative along with every other variable frozen:
Nothing new is needed to compute one: treat the other variables as constants and apply the rules of the previous section. Geometrically, slicing the surface with the plane leaves an ordinary curve, and is the slope of that curve.
Source
import numpy as np
import matplotlib.pyplot as plt
f = lambda x, y: 4 - x**2 - y**2 / 4
fx = lambda x, y: -2 * x
fy = lambda x, y: -y / 2
x0, y0 = 1.0, 1.0
X, Y = np.meshgrid(np.linspace(-2, 2, 60), np.linspace(-3, 3, 60))
fig = plt.figure(figsize=(7.5, 5.5))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, f(X, Y), color='lightgray', alpha=0.35, linewidth=0)
xs = np.linspace(-2, 2, 100)
ys = np.linspace(-3, 3, 100)
ax.plot(xs, np.full_like(xs, y0), f(xs, y0), color='#d1495b', lw=2.5,
label=r'slice $y = 1$: slope is $\partial f/\partial x$')
ax.plot(np.full_like(ys, x0), ys, f(x0, ys), color='#66a182', lw=2.5,
label=r'slice $x = 1$: slope is $\partial f/\partial y$')
tx = np.array([x0 - 0.8, x0 + 0.8])
ax.plot(tx, np.full_like(tx, y0), f(x0, y0) + fx(x0, y0) * (tx - x0), '--', color='#d1495b', lw=1.5)
ty = np.array([y0 - 1.2, y0 + 1.2])
ax.plot(np.full_like(ty, x0), ty, f(x0, y0) + fy(x0, y0) * (ty - y0), '--', color='#66a182', lw=1.5)
ax.scatter([x0], [y0], [f(x0, y0)], color='k', s=40)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('f(x, y)')
ax.view_init(elev=25, azim=-60)
ax.legend(loc='upper left', fontsize=8)
ax.set_title('Fig.6 Partial derivatives are slopes of slices through the surface')
plt.tight_layout()
plt.show()
For the hill in the figure, and . At the marked point the surface drops four times faster along than along , which is why the red tangent is steeper than the green one.
Second and mixed partial derivatives¶
Differentiating twice along the same variable gives , written ; differentiating once along each gives the mixed partial , written . For every smooth function the order does not matter:
For the example above, whichever variable you differentiate first. This innocent-looking equality is the origin of the Maxwell relations of thermodynamics.
The chain rule on a sliding shape¶
The most important partial-derivative calculation in this course involves a function of the single combination . Take any smooth profile and a constant , and define
At the graph of is just the graph of ; at a later time the same shape has moved a distance to the right. So describes a shape sliding at speed without changing form. Its partial derivatives follow from the chain rule with the inner function , for which and :
Differentiate once more and every factor of appears again:
Eliminating between the two lines gives a relation that holds for every sliding shape, whatever is:
This is the classical wave equation. Here it emerged from calculus alone; in the waves lecture the same equation gets its physical meaning, and the shorthand and used there is the subscript notation introduced above. The same steps with give a shape sliding to the left and the identical relation, since enters only as .
Solution
(power rule in with frozen) and (linear in with frozen). Hence
This total differential adds up the change coming from each variable separately, one partial derivative per variable. It is the everyday tool of thermodynamics.
Integration¶
The integral as accumulated area¶
A definite integral measures the net area between a curve and the axis. We approximate that area with a Riemann sum of rectangles and let :
The plot shows the rectangles filling the area under on as grows from coarse to fine. The exact area is .
Source
import numpy as np
import matplotlib.pyplot as plt
f = lambda x: x**2
a, b = 0, 2
xs = np.linspace(a, b, 400)
fig, axes = plt.subplots(1, 3, figsize=(11, 3.6), sharey=True)
for ax, n in zip(axes, [4, 8, 32]):
edges = np.linspace(a, b, n + 1)
mids = 0.5 * (edges[:-1] + edges[1:]) # midpoint rule
dx = (b - a) / n
approx = np.sum(f(mids) * dx)
ax.bar(mids, f(mids), width=dx, align='center',
color='#66a182', edgecolor='white', alpha=0.7)
ax.plot(xs, f(xs), 'k', lw=2)
ax.set_title(f'n = {n}, sum = {approx:.3f}', fontsize=10)
ax.set_xlabel('x')
axes[0].set_ylabel('f(x)')
plt.suptitle('Fig.7 Riemann sums approaching the exact area 8/3 = 2.667 as n grows', y=1.04)
plt.tight_layout()
plt.show()
We can watch that convergence numerically:
import numpy as np
f = lambda x: x**2
a, b = 0.0, 2.0
for n in [4, 16, 64, 256, 1024]:
x = np.linspace(a, b, n + 1)
mids = 0.5 * (x[:-1] + x[1:])
approx = np.sum(f(mids) * (b - a) / n)
print(f"n = {n:5d} Riemann sum = {approx:.5f}")
exact = 8 / 3
print(f"\nexact value = {exact:.5f}")n = 4 Riemann sum = 2.62500
n = 16 Riemann sum = 2.66406
n = 64 Riemann sum = 2.66650
n = 256 Riemann sum = 2.66666
n = 1024 Riemann sum = 2.66667
exact value = 2.66667
Antiderivatives and the fundamental theorem¶
An antiderivative of satisfies . Because the derivative of a constant is zero, antiderivatives come as a family . The fundamental theorem of calculus ties the two halves of the subject together:
This is why we rarely compute Riemann sums by hand: finding an antiderivative turns an infinite sum into a single subtraction.
Table of indefinite integrals¶
| Function | Antiderivative | Function | Antiderivative |
|---|---|---|---|
Useful properties: reversing the limits flips the sign, , and integrals are linear, . For symmetric limits, an even function gives while an odd function gives , a shortcut that kills many quantum-mechanical integrals on sight.
Techniques of integration¶
Integration by parts is the reverse of the product rule, and it is the standard tool for integrals like or that appear constantly in expectation-value calculations.
For products of sines and cosines, the power-reduction and product-to-sum identities do the work:
These are exactly the integrals that enforce orthogonality of particle-in-a-box wavefunctions.
Solution
(a) With , the cosine integrates to zero over full half-periods, leaving . That is why box wavefunctions carry the prefactor .
(b) Integrate by parts twice (or recognize ): the answer is 2. In general , the workhorse of radial hydrogen integrals.
Problems¶
Problem 1: Differentiate a Gaussian¶
Differentiate with respect to .
Solution
Problem 2: Product and chain together¶
Differentiate .
Solution
Product rule, and the chain rule on :
Problem 3: A normalization integral¶
Evaluate .
Solution
Use with :
The sine term vanishes at both limits. This is the integral behind the particle-in-a-box normalization constant .
Problem 4: Integration by parts¶
Evaluate .
Solution
Let , , so and :
Problem 5: Symmetry shortcut¶
Without computing an antiderivative, evaluate .
Solution
The integrand is odd: replacing flips its sign. The integral over symmetric limits is therefore 0.
Problem 6: Mixed partial derivatives¶
For find and , then verify that the two mixed second derivatives agree.
Solution
With frozen, ; with frozen, .
Differentiating the first result with respect to and the second with respect to :
They match, as they must for any smooth function.
Problem 7: Verify a Riemann sum numerically¶
Modify the Riemann-sum code above to estimate and compare with the exact value 2.
Problem 8: Chain rule on a plane wave¶
Differentiate with respect to , and again to find .
Problem 9: A Gamma-function integral¶
Evaluate using integration by parts twice.
Problem 10: A standing shape¶
Show that satisfies . Compare with the relation obeyed by the sliding shape and read off the speed .