This guide accompanies Real Analysis Review. It supplies the complete definitions, proofs and computations behind the shorter handout. Start with quadratic coordinates, sets and sequences, continuity and derivatives, convexity, or Taylor and finite differences. Linear algebra definitions and factorization diagnostics have their primary home in Linear Algebra Review and SciPy Basics.
# Load the numerical tools and the course's shared figure style.
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import mpmath as mp
from scipy import linalg
from matplotlib import cm
if 'google.colab' in sys.modules:
import urllib.request
urllib.request.urlretrieve('https://raw.githubusercontent.com/ndcbe/optimization/main/notebooks/helper.py', 'helper.py')
else:
sys.path.insert(0, '../')
import helper
helper.set_plotting_style()Quadratic objectives in eigenvector coordinates¶
For a real symmetric , consider
The symmetric spectral theorem gives , with and . Define the coordinates and the transformed function . The function value is preserved; the coordinate vector changes. Write . Then
Each column of supplies a coordinate direction. Diagonal removes cross terms. See Biegler (2010), §2.2.2, Eqs.(2.8)–(2.10), pp.22–23.
Stationary points and square completion¶
Stationarity requires for every . Let . A stationary point exists exactly when for every . In that case
Setting the free coordinates to zero selects one representative; it does not establish uniqueness. If a null coordinate has , moving along that coordinate makes the affine term arbitrarily positive or negative.
For every , the full square completion is
Consequently, with ,
This formula also describes the case with no stationary point: the null-coordinate linear term remains. It avoids dividing by a zero eigenvalue.
Curvature and global classification¶
The exact eigenvalue signs give the following cases. For a singular matrix, the compatibility condition is on .
| Eigenvalues of | Stationary points | Global behavior |
|---|---|---|
| all positive | unique global minimum | bounded below |
| all negative | unique global maximum | bounded above |
| both signs, none zero | unique saddle | unbounded above and below |
| some zero, remaining positive, compatible | affine family of global minima | flat along the null space |
| some zero, remaining negative, compatible | affine family of global maxima | flat along the null space |
| some zero, both signs, compatible | affine family of saddles | unbounded above and below |
| all zero and | every point is stationary, a minimum and a maximum | constant function |
| singular and incompatible | no stationary point | unbounded above and below along a null direction |
A stationary point is a saddle here when arbitrarily close points have both larger and smaller values. In a compatible singular case, its family has dimension . These conclusions follow directly from the square completion. See Biegler (2010), pp.23–25.

All four pictured objectives have and ; their eigenvectors are rotated by 30 degrees. They compare signs, while the separate conditioning picture compares positive eigenvalue magnitudes. For a positive-definite quadratic, contour semiaxes at a fixed positive objective increment are proportional to .
Numerical analysis and plotting helper¶
The helper below requires an explicitly symmetric real matrix and uses the symmetric eigensolver. Its relative threshold identifies numerically small eigenvalues. It analyzes the thresholded model and prints the residual in the original stored system. Neither thresholding nor a small residual proves the exact rank of a nearly singular matrix. If the thresholded stationarity equations are incompatible, the code draws the surface about a plotting center and does not mark that center as a stationary point.
def quad_analyze(c, a, B):
"""Plot a real symmetric quadratic and report a numerical stationary candidate.
Returns a dictionary with the eigenpairs, threshold, residual, and candidate.
A None candidate means the thresholded stationarity equations are incompatible;
exact rank and compatibility near the threshold require further analysis.
"""
if np.iscomplexobj(c) or np.iscomplexobj(a) or np.iscomplexobj(B):
raise ValueError('The quadratic coefficients must be real')
a = np.asarray(a, dtype=float)
B = np.asarray(B, dtype=float)
if a.ndim != 1 or B.shape != (a.size, a.size) or a.size == 0:
raise ValueError('a must be a nonempty vector and B a matching square matrix')
if not np.isfinite(c) or not np.all(np.isfinite(a)) or not np.all(np.isfinite(B)):
raise ValueError('All coefficients must be finite')
if not np.array_equal(B, B.T):
raise ValueError('B must be symmetric; form the symmetric part explicitly if intended')
eigenvalues, V = linalg.eigh(B)
abar = V.T @ a
scale = float(np.max(np.abs(eigenvalues)))
threshold = a.size * np.finfo(float).eps * scale
small = np.abs(eigenvalues) <= threshold
rhs_tolerance = a.size * np.finfo(float).eps * np.linalg.norm(a)
compatible = bool(np.all(np.abs(abar[small]) <= rhs_tolerance))
zcenter = np.zeros(a.size)
zcenter[~small] = -abar[~small] / eigenvalues[~small]
center = V @ zcenter
residual = a + B @ center
candidate = center.copy() if compatible else None
print('B =\n', B, '\na =', a, '\nc =', c)
print('eigenvalues =', eigenvalues, '\neigenvectors (columns) =\n', V)
print('transformed linear coefficient =', abar)
print('near-zero threshold =', threshold)
print('numerically small eigenvalues =', eigenvalues[small])
if candidate is None:
print('Thresholded stationarity equations are incompatible; no stationary marker is drawn.')
print('Plot center =', center)
else:
print('Numerical stationary candidate =', candidate)
if np.any(small):
print('Free coordinates in the thresholded model are set to zero for this representative.')
print('gradient at center =', residual)
print('gradient 2-norm =', np.linalg.norm(residual))
if a.size == 2:
grid = np.linspace(-5., 5., 81)
X1, X2 = np.meshgrid(center[0] + grid, center[1] + grid)
F = c + a[0]*X1 + a[1]*X2 + .5*(B[0,0]*X1**2 + 2*B[0,1]*X1*X2 + B[1,1]*X2**2)
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X1, X2, F, cmap=cm.viridis, linewidth=0)
if candidate is not None:
value = c + a @ candidate + .5*candidate @ B @ candidate
ax.scatter(*candidate, value, marker='o', color='#D55E00', edgecolor='black', s=65,
label='numerical stationary candidate')
ax.legend(fontsize=10)
ax.set(xlabel='$x_1$', ylabel='$x_2$', zlabel=r'$f(\mathbf{x})$')
plt.show()
return dict(eigenvalues=eigenvalues, eigenvectors=V, transformed_linear=abar,
threshold=threshold, small_eigenvalues=small,
candidate=candidate, plot_center=center, gradient=residual)Example 2.8 in Biegler (2010)¶
c = 0
a = np.array([1, 1])
B = np.array([[2, 1], [1, 2]])
quad_analyze(c, a, B)B =
[[2. 1.]
[1. 2.]]
a = [1. 1.]
c = 0
eigenvalues = [1. 3.]
eigenvectors (columns) =
[[-0.70710678 0.70710678]
[ 0.70710678 0.70710678]]
transformed linear coefficient = [0. 1.41421356]
near-zero threshold = 1.3322676295501878e-15
numerically small eigenvalues = []
Numerical stationary candidate = [-0.33333333 -0.33333333]
gradient at center = [2.22044605e-16 2.22044605e-16]
gradient 2-norm = 3.1401849173675503e-16

{'eigenvalues': array([1., 3.]),
'eigenvectors': array([[-0.70710678, 0.70710678],
[ 0.70710678, 0.70710678]]),
'transformed_linear': array([0. , 1.41421356]),
'threshold': np.float64(1.3322676295501878e-15),
'small_eigenvalues': array([False, False]),
'candidate': array([-0.33333333, -0.33333333]),
'plot_center': array([-0.33333333, -0.33333333]),
'gradient': array([2.22044605e-16, 2.22044605e-16])}Activity 1¶
Classify the stationary point for .
# Add your solution hereActivity 2¶
Classify the stationary point for .
Hint: needs to be symmetric.
# Add your solution hereSets, sequences, regularity and convexity¶
The definitions below use finite-dimensional Euclidean spaces and the 2-norm unless another norm is specified. The full proofs support the handout activities.
Balls, neighborhoods, interior, boundary and closure¶
For and , the open and closed balls are
A set is open if every has a ball . A neighborhood of a point is an open set containing that point. In particular, an open ball is a neighborhood; a neighborhood need not be a ball.

For :
is an interior point if some ball about it is contained in ; the interior is .
is a boundary point if every ball about it meets both and its complement; the boundary is .
is in the closure if every ball about it meets .
Thus . The interior is the largest open subset of ; the closure is the smallest closed set containing . A boundary point need not belong to : for , the boundary is and the closure is .

See Nocedal & Wright (2006), pp.620–621. The empty set and the whole space are both open and closed; these properties are not opposites.
Sequences, subsequences and closed sets¶
A sequence assigns a point to each positive integer . It converges to if
A subsequence has indices . A limit point of a sequence is the limit of one of its subsequences. A convergent sequence has exactly one limit point. The nonconvergent sequence has the two limit points and , obtained from the even and odd subsequences. See Nocedal & Wright (2006), pp.617–618.
A set is closed if its complement is open. Equivalently, it contains every limit of every convergent sequence of its points.
Proof that closed sets contain such limits. Suppose , , and . The open complement contains a ball disjoint from . Convergence puts every sufficiently late iterate in the smaller ball of radius , hence in both and its complement, a contradiction. Therefore .
Converse. If , choose . This sequence converges to . A set containing all such limits therefore contains its closure and is closed. This also proves the sequence characterization of closure. See Nocedal & Wright (2006), pp.620–621.

Bounded and compact sets¶
is bounded if some satisfies for every . It is compact if every sequence in has a subsequence converging to a point of . In , compactness is equivalent to being closed and bounded. The finite-dimensional hypothesis matters. See Nocedal & Wright (2006), pp.620–621.

The four sets below are subsets of . Convexity means that the entire segment between any two member points remains in the set; its formal definition and proof examples appear below.

| Set | Open | Closed | Bounded | Compact | Convex |
|---|---|---|---|---|---|
| yes | no | yes | no | yes | |
| no | yes | yes | yes | yes | |
| no | yes | no | no | yes | |
| no | yes | yes | yes | no |
For the annulus, and belong to the set, but their midpoint does not. For the open disk, approaches a missing boundary point. In the quadrant, has no convergent subsequence.
Weierstrass theorem and a minimizing sequence¶
A continuous real-valued function on a nonempty compact set attains a minimum and a maximum. See Rapcsák, “Smooth Nonlinear Nonconvex Optimization,” in Encyclopedia of Optimization, 2nd ed. (2009), p.3623. The cited statement gives the minimum; applying it to the negative function gives the maximum.
Here is the complete sequential argument. Write .
If is finite, choose with . If , choose . These choices are permitted by the definition of infimum.
Compactness supplies a subsequence . Continuity implies , a finite real number.
The alternative contradicts that finite limit. Hence is finite, and the same subsequence has function values tending to . Uniqueness of a real limit gives .
The maximum follows from the minimum of . This is a compactness-plus-continuity proof, not a derivative test.
Without the hypotheses the conclusion can fail. The function on has no minimum; on has infimum zero but no minimizer. Compactness alone is insufficient: on , define and for . Its infimum is zero, is not attained, and the function is discontinuous at zero.

Limits and continuity on a domain¶
Let . At an accumulation point of , the limit is if
The function is continuous at if the same implication, with , holds for all with . It is continuous on when it is continuous at every point of . The domain is part of the definition. See Biegler (2010), Def.2.9, p.25; Nocedal & Wright (2006), Eq.(A.38), p.623.

The formula is continuous on , and in particular on . It is undefined at zero. Since is unbounded near zero, no assigned finite value at zero gives a continuous extension. This does not make the function discontinuous at a point outside its stated domain.
Lipschitz continuity and derivative bounds¶
is Lipschitz continuous on if one finite constant satisfies
The constant is selected before the pair of points. It may depend on the set . Local Lipschitz continuity at an interior point means that such a neighborhood exists. This uses Nocedal & Wright (2006), Eq.(A.42), p.624; the quantifier order in Biegler’s Def.2.10, p.25, does not impose a single constant on the set.


The continuous function is not Lipschitz on . Setting and would require , hence for every , which is impossible. On ,
Thus works there. The derivative becomes unbounded toward zero, consistent with the first result.
More generally, a differentiable scalar function with along every segment in a convex set is Lipschitz there, provided the function is continuous on each segment and differentiable in its interior. Apply the scalar mean value theorem along the segment and Cauchy–Schwarz. Conversely, where an -Lipschitz function is differentiable, taking directional limits gives . Lipschitz continuity does not require differentiability everywhere; is an example.
Derivatives, gradients, Hessians and level sets¶
For a scalar function, when the limit exists; the second derivative is the derivative of . For at an interior point, the coordinate partial derivatives are
The gradient is the column of first partials and the Hessian collects second partials:
Differentiability at means that the linear model has a remainder negligible relative to the step:
Existence of all coordinate partials alone does not imply this property. A function is if its first partials exist and are continuous, and if its second partials exist and are continuous. For a differentiable function, the two-sided directional derivative is
A real function has a symmetric Hessian. This permits real eigenvalues, an orthogonal eigenbasis and symmetric factorizations. Cholesky additionally requires positive definiteness; symmetry alone is insufficient. Symmetry also permits storing one triangle, containing entries rather than ; the factor tends to one half as grows. See Biegler (2010), Defs.2.11–2.12, pp.25–27; Nocedal & Wright (2006), pp.626–628.

For , a level set is and a sublevel set is . At a regular point with nonzero gradient, differentiate to obtain . This proves the normal-direction statement; a zero gradient does not specify a normal direction.

Mean value and implicit function theorems¶
If is continuous on and differentiable on , with , then
For a scalar-valued function on a neighborhood of a segment from to , apply this theorem to . Then . See Nocedal & Wright (2006), Eqs.(A.54)–(A.55), p.629.
There need not be one common mean-value point for a vector-valued function. For on , the two components would require and , respectively. Those values of differ. The integral form used for gradients below avoids that claim.
Implicit function theorem. Let be near , with and nonsingular there. Then product neighborhoods exist on which the nearby roots are exactly the graph of a unique function with . Using the course’s derivative arrays, whose row indexes the input component,
The dimensions are , and , respectively; evaluate the derivative arrays at . The formula follows by differentiating . See Nocedal & Wright (2006), Thm.A.2, p.631.
For near , , so the local branch is and . There is another branch near ; local uniqueness near does not assert a unique root globally. At the nonsingularity hypothesis fails.

Convex combinations, hulls, half-spaces and polyhedra¶
A convex combination of is with and . Their convex hull is the set of all these combinations. A set is convex if
The convex hull is convex: a convex combination of two combinations has nonnegative coefficients summing to one. Any convex set containing all the original points contains every finite convex combination, by induction. Hence the hull is the smallest convex set containing them. See Nocedal & Wright (2006), p.621; Nesterov (2018), pp.141–142.

For , a hyperplane is . The two closed half-spaces use and . The normal is perpendicular to the hyperplane. A polyhedron is an intersection of finitely many half-spaces and hyperplanes, equivalently after writing an equality as two inequalities. A polyhedron can be empty or unbounded.



Proof for a half-space. If and , then
A hyperplane uses the same computation with equality. Applying the inequality row by row proves the polyhedron is convex. Lecture 2 is the primary handout home for the half-space and intersection convexity proofs. The existing Introduction to Constrained Nonlinear Optimization guide collects the general intersection proof and convex-program formulation checklist. See Nocedal & Wright (2006), p.8; Nesterov (2018), Def.3.1.4, p.159.
Rays and cones¶
Using the positive-scaling convention, the ray through is . A cone satisfies
This convention does not require the origin. A convex cone is also a convex set. The generated set contains the origin and is a convex cone: nonnegative scaling and convex combinations preserve nonnegative coefficients. The set is a cone but is not convex; the points and have a midpoint outside it. See Nocedal & Wright (2006), Eq.(A.36) and pp.621–622.

A convex half-space need not be a cone¶
Convex combinations keep a point in a half-space, but positive scaling can leave it. For
we have for , whereas . Thus is convex and is not a cone.

More generally, for , the closed half-space is a cone under the positive-scaling definition exactly when . If , multiplying the inequality by any preserves it. If , choose the boundary point . For , has functional value ; for , has value . Either case violates positive-scaling closure. This argument also applies under the convention that permits a cone to exclude the origin.
Convex functions and the first-order characterization¶
Let be convex. A function is convex if for all and ,
It is strictly convex if the inequality is strict whenever . On an open convex domain, a differentiable function is convex exactly when
Strict convexity is equivalent to the strict first-order inequality for distinct points. The excluded equal-point case matters: equality always holds at . See Biegler (2010), Def.2.13, p.27, with the distinct-point qualification in Nocedal & Wright (2006), p.8; Nesterov (2018), Thm.2.1.2, pp.62–63.

First-order inequality implies the chord inequality¶

Set . Apply the first-order inequality twice, both times based at :
Multiply these inequalities by and , both positive, and add. The gradient term is zero because
The remaining inequality is precisely the chord inequality. Strict first-order inequalities give the strict chord inequality for distinct endpoints.
Chord inequality implies the first-order inequality¶

Fix and write .
Convexity gives .
Subtract and divide by the positive :
Let . Differentiability at makes the left side tend to . A weak inequality survives the limit, giving the first-order inequality. Continuity of the gradient is not needed for this step.
A strict inequality does not automatically survive a limit. For the strict result, first obtain the weak supporting inequality just proved. At a distinct pair, strict convexity and that support bound imply
Subtract and divide by to get the strict first-order inequality. These arguments also explain why negating a first-order inequality at one pair of points does not justify applying the failure at two prescribed directions.
Hessians, strong convexity and quasi-convexity¶
For a function on an open convex domain, convexity is equivalent to everywhere. Necessity follows by applying the supporting inequality to , adding, dividing by and taking . This gives for every .
For sufficiency, the exact integral Taylor remainder is
A positive-semidefinite Hessian makes the integral nonnegative. Pointwise positive definiteness makes it positive for , so it is sufficient for strict convexity. It is not necessary: is strictly convex but has second derivative zero at zero.
A differentiable function on a convex domain is m-strongly convex, , if
for every segment in its domain. In the case this is equivalent to the uniform bound . A positive-definite Hessian at every point alone does not supply one uniform . For example, has positive second derivative everywhere on , but the infimum of its second derivative is zero as . See Nesterov (2018), Def.2.1.3 and Thm.2.1.11, pp.74–75; this corrects the pointwise-Hessian condition in Biegler’s Def.2.13.


For , , , and
| Property on | Test for | Result |
|---|---|---|
| convex | for all | yes |
| strictly convex | the displayed positive gap for every | yes |
| strongly convex | would require for all | no, since |
A function is quasi-convex if each sublevel set is convex. Every convex function is quasi-convex: if , convexity yields

See Nesterov (2018), Lemma2.2.5, p.101. The converse fails. For , the sublevel set for is
It is empty for and all of for . Every case is convex, but when . In contrast, is not quasi-convex: at level its sublevel set is two disjoint intervals, with between and .

On , , , , and distinguish the nested classes strongly convex, strictly convex, convex and quasi-convex, respectively.

Order notation and exact Taylor formulas¶
For sequences with eventually, means that some finite bounds for every sufficiently large . The notation means . Analogously, as , means for sufficiently small nonzero ; means . For example, and , but is not . See Nocedal & Wright (2006), pp.631–632.
The relevant limit is usually clear from context: an error concerns , while an operation count concerns . Constants and units remain relevant. Order one in alone does not guarantee three correct digits at . Convergence-rate definitions belong in the algorithm lectures that use them, rather than another rate table here.
Scalar expansion¶
If is near , its finite expansion is
This statement does not assert convergence of an infinite Taylor series to . See LeVeque (2007), §1.1, p.5 and §1.5, p.10.

Scalar-valued multivariate mean-value forms¶
Suppose the entire segment , , lies in a neighborhood where is . Then some satisfies
If is there, some satisfies
The two points need not be the same. Both statements are exact. To prove them, apply the corresponding one-dimensional theorem to , using and . See Biegler (2010), Thm.2.14, pp.27–28 and its errata; the extraneous Hessian transpose in the printed formula is removed.
Integral forms¶
Componentwise fundamental theorem of calculus gives the exact vector identity
Integrating the scalar derivative twice also gives
For the first formula, differentiate each component of and integrate from zero to one. For the second, integrate the change in , then interchange the order over the triangular region . Neither argument asserts a common vector mean-value point.
For the symmetric quadratic, and , so the second-order Taylor model is exact with no remainder. The integral of is , recovering the quadratic term directly.
Finite differences, truncation and evaluation error¶
Assume is near and . Forward, backward and central approximations are
Taylor expansion gives and . For central differences, write both expansions before subtracting:
The constant and second-order terms cancel. Thus and . With the expansion to the cubic term, the leading central error is . See Nocedal & Wright (2006), §8.1, pp.195–197.

Why a smaller step can give a worse derivative¶
If each function evaluation has absolute error bounded by , the evaluation contribution is at most for a one-sided formula and for central differences, before accounting for arithmetic and argument-rounding errors. Subtracting nearby computed function values can expose those errors. In particular, a floating-point sum can round back to .
A useful scale model is
Differentiate the model to obtain . The orders are for one-sided differences and for central differences, with best modeled errors of orders and . Constants depend on function/derivative scales. When the evaluation scale is order one and is of unit-roundoff size, these suggest steps around 10-8 and 10-5.3 in binary64. They are scale estimates, not universal optimal steps or exact measured minima.
For a full gradient in variables, a reused base value gives evaluations for forward differences; central differences use . This cost comparison concerns gradients built by finite differences, not every derivative-free algorithm.
Noisy functions and component scaling¶
If simulation or iterative-solve error dominates roundoff, use its evaluation-error scale in the model. Shrinking below that noise scale can make the derivative less useful. For forward differences, a practical component magnitude is , with a positive typical variable scale supplied by the modeler; the typical scale avoids a zero step at . A signed perturbation or a different formula may be required at a bound or domain edge. See Dennis & Schnabel (1996), §5.4, Eqs.(5.4.8)–(5.4.10), pp.96–98. The corresponding central scaling has a cube-root dependence under its smooth error model.
Executed experiment¶
The cells below evaluate at and with binary64 function calls and arithmetic. The derivative reference is evaluated at 100 decimal digits and checked at 160. Thus the reported error compares the actual stored derivative approximation with the analytic derivative, not with a rounded binary64 reference. The plot is built one curve at a time; the final figure and archived data are also used by the lecture notes.
The step grid is , four points per decade including both endpoints. Measured minima are restricted to this finite grid and can vary with the numerical library. The table prints every formula’s minimizing grid step and error for both evaluation points.
def finite_difference_experiment(point):
"""Measure binary64 exp differences against a converged high-precision derivative."""
steps = np.power(10., np.arange(-16., .25, .25))
base = float(np.exp(point))
plus = np.exp(point + steps)
minus = np.exp(point - steps)
approximations = {
'forward': (plus-base)/steps,
'backward': (base-minus)/steps,
'central': (plus-minus)/(2*steps),
}
def measure(digits):
with mp.workdps(digits):
reference = mp.exp(mp.mpf(float(point)))
return {name:[float(abs(mp.mpf(float(value))-reference)) for value in values]
for name,values in approximations.items()}
errors = measure(100)
repeated = measure(160)
for name in errors:
assert np.array_equal(errors[name], repeated[name])
with mp.workdps(100):
reference_text = mp.nstr(mp.exp(mp.mpf(float(point))), 95)
return {'a':float(point),'h':steps.tolist(),'f_a':base,
'f_plus':plus.tolist(),'f_minus':minus.tolist(),
'approximations':{name:values.tolist() for name,values in approximations.items()},
'errors':errors,'derivative_reference':reference_text}
results = {'function':'exp','cases':[finite_difference_experiment(1.),finite_difference_experiment(10.)],
'reference_digits':[100,160], 'step_grid':'10**arange(-16,0.25,0.25)',
'error':'absolute error against the analytic derivative of exp at the stored point'}
summary_rows = []
for case in results['cases']:
h = np.asarray(case['h'])
for method, errors in case['errors'].items():
errors = np.asarray(errors)
index = int(np.argmin(errors))
window = (h>=1e-4)&(h<=1e-1)&(errors>0)
slope = float(np.polyfit(np.log10(h[window]),np.log10(errors[window]),1)[0])
summary_rows.append({'a':case['a'],'formula':method,'step_at_grid_minimum':float(h[index]),
'minimum_absolute_error':float(errors[index]),'truncation_slope':slope})
results['summary'] = summary_rows
helper.save_results('finite-difference-error',results,
notebook='notebooks/6-dev/Math-Primer-2.ipynb',
source_cells=[('notebooks/6-dev/Math-Primer-2.ipynb','results:finite-difference-error')],
description='Binary64 exponential differences at 1 and 10 with 100/160-digit analytic derivative references',
solver='NumPy exp and arithmetic; mpmath analytic references',quiet=True)
display(pd.DataFrame(summary_rows))case = results['cases'][0]
fig, ax = plt.subplots(figsize=(7.6,4.8))
ax.loglog(case['h'],case['errors']['forward'],label='forward',color='black',linestyle='-',marker='s',markevery=4,ms=5)
ax.set(xlabel='step size h',ylabel="absolute error in f'(1)",title='Forward difference: exp at a=1')
ax.legend(); ax.grid(which='major',alpha=.25)
fig.tight_layout(); plt.show()
case = results['cases'][0]
fig, ax = plt.subplots(figsize=(7.6,4.8))
for method,color,style,marker in [('forward','black','-','s'),('backward','#0072B2','--','o')]:
ax.loglog(case['h'],case['errors'][method],label=method,color=color,linestyle=style,marker=marker,markevery=4,ms=5)
ax.set(xlabel='step size h',ylabel="absolute error in f'(1)",title='One-sided differences: exp at a=1')
ax.legend(); ax.grid(which='major',alpha=.25)
fig.tight_layout(); plt.show()
# Canonical plot: only archived results are needed to reproduce it.
case = results['cases'][0]
fig, ax = plt.subplots(figsize=(7.6,5.1))
for method,color,style,marker in [('forward','black','-','s'),
('backward','#0072B2','--','o'),
('central','#E69F00','-.','^')]:
ax.loglog(case['h'],case['errors'][method],label=method,color=color,linestyle=style,
marker=marker,markevery=3,markersize=5,linewidth=2)
ax.set(xlabel='step size h',ylabel="absolute error in f'(1)",
title='Exponential at a=1; analytic derivative reference',xlim=(1e-17,3),ylim=(1e-13,1e2))
ax.legend(fontsize=12)
ax.grid(which='major',alpha=.25)
fig.tight_layout()
helper.save_figure(fig,'finite-difference-error',quiet=True)
plt.show()
Read and extend the experiment¶
Compare the actual minimizing steps and errors in the table with the order estimates. A grid minimum need not occur at the model’s exact optimum.
Read the right-hand slopes from the three curves and compare them with the computed regression slopes. On the left, cancellation and argument rounding produce a jagged branch, not an exact straight line.
Compare with in the table. The derivative and function scale grow by , so absolute-error statements change even when the formulas have the same truncation orders.
Original test: exponential at 1¶
Use the three rows with a=1 in the executed table. They report the measured minima on this run’s grid. The central formula uses a larger best grid step and achieves a lower absolute error than the one-sided formulas in this example.
Variant: exponential at 10¶
The three a=10 rows are computed by the same function, grid and reference procedure. They replace historical hand-entered guesses. Library changes can alter the final digits and the location of a grid minimum; read the actual output.
Another test function¶
To study a different function, supply both its evaluation routine and its analytic derivative reference. Reusing exp(a) as the reference after changing the function would measure the wrong error. State the function, point, precision, domain and step grid with the results.
Discussion¶
Explain which change would alter the truncation constant, the function-evaluation noise, or the number of evaluations. Use those quantities to select a step range; a single best step is not valid for every function, variable scale or solver tolerance.