Why Unimodal Optimization Matters
Suppose a deterministic simulation reports the cost of choosing one scalar parameter: a delay, an operating point, or a position along a line. You can evaluate the cost, but derivatives are unavailable. If cost falls toward one valley and rises afterward, you can minimize it by repeatedly comparing two interior points and discarding a region that cannot improve the answer.
Ternary search places the probes at one third and two thirds of the current interval. Golden-section search chooses a different ratio so that, after a reduction, one old point and its function value can be reused. This matters when an objective call means running an expensive simulation rather than evaluating a small formula.
Both methods optimize a single real variable on a supplied bounded interval. They need a suitable unimodal shape and reliable comparisons; they do not discover all minima of an arbitrary landscape. The implementations below expose the interval, cached probes, best observed value, evaluation count, and stopping reason. The worked quadratic has a known analytic solution, allowing the search to be checked independently.
Keep an interval containing a minimizer, compare two interior objective values, and discard a side that cannot contain a better point under the stated unimodality assumption. Ternary search uses two fresh values per reduction; golden-section search reuses one value and needs only one new call after initialization.
Core Concepts and Terminology
We minimize a deterministic function $f:[a,b]\to\mathbb{R}$. For the guarantees in this lesson, assume continuity and a connected minimum set $[u,v]$: the function is strictly decreasing before $u$, constant on $[u,v]$, and strictly increasing after $v$. The minimum set may be a single point or touch a domain endpoint. A function flat only at its minimum is allowed, including a constant function; an arbitrary flat region above the minimum is not covered by our equality rules.
The current closed interval is $[l,r]$, with width $W=r-l$. It must retain at least one minimizer; retaining every point of a minimum plateau is unnecessary. For probes $l\lt x_1\lt x_2\lt r$, if $f(x_1)\lt f(x_2)$, at least one minimizer lies in $[l,x_2]$. If $f(x_1)\gt f(x_2)$, retain $[x_1,r]$. Equality permits retaining $[x_1,x_2]$ under the strict-sided shape assumption; golden-section search instead keeps $[l,x_2]$ to preserve its reuse geometry.
The location tolerance $\varepsilon\gt0$ applies to width: stop when $r-l\le\varepsilon$. The midpoint estimate is $\widehat{x}=l+(r-l)/2$. If the retained interval really contains a minimizer $x_{\min}$, then
$$\lvert\widehat{x}-x_{\min}\rvert\le\frac{r-l}{2}\le\frac{\varepsilon}{2}.$$
This is an interval-based location statement, conditional on the shape and comparisons being valid. It does not imply a particular error in objective value. The diagram shows the worked function $f(x)=(x-2.5)^2+1$, initially on $[0,9]$, whose exact minimum is $f(2.5)=1$.
| Term | Example | Role |
|---|---|---|
| Objective $f(x)$ | $(x-2.5)^2+1$ | Quantity being minimized; a black-box evaluation may be expensive |
| Unimodality assumption | Strict fall, optional minimum plateau, strict rise | Makes comparisons justify discarding an interval |
| Retained interval $[l,r]$ | After one ternary reduction, $[0,6]$ | Contains at least one minimizer when assumptions hold |
| Interior probes | Ternary first probes $3$ and $6$ | Give directional information without derivatives |
| Golden ratio fraction $\rho$ | $(\sqrt{5}-1)/2\approx0.618034$ | Retains a fixed fraction of width and enables one-value reuse |
| Width tolerance $\varepsilon$ | $0.75$ in the worked trace | Stops by location uncertainty, not by objective accuracy |
| Midpoint estimate | Ternary final midpoint $2.452675$ | Returned without spending another objective evaluation |
| Best observed sample | Ternary best sampled $x\approx2.518519$ | Has an actual recorded objective value; differs from the midpoint |
| Evaluation / reduction | Golden uses $7$ calls for $6$ reductions | Distinguishes objective cost from loop count |
| Floating-point stall | Adjacent binary64 numbers cannot hold two interior probes | A separate stopping reason, not successful tolerance convergence |
How Unimodal Optimization Works, Step by Step
- Validate the request. Require ordered finite endpoints, a positive finite absolute tolerance, a supported method, and valid iteration/evaluation caps. The demonstration limits endpoint magnitudes so subtraction and midpoint calculation cannot overflow.
- Check stopping conditions before spending evaluations. If width is already at most tolerance, return
CONVERGED. Otherwise, if the completed-reduction cap is reached, returnITER_LIMIT. A singleton interval therefore needs no objective calls. - Place two distinct interior probes. Ternary search uses $x_1=l+W/3$ and $x_2=r-W/3$. Golden-section search initializes $x_1=r-\rho W$ and $x_2=l+\rho W$, with
$$\rho=\frac{\sqrt{5}-1}{2},\qquad 1-\rho=\rho^2.$$
If rounding prevents $l\lt x_1\lt x_2\lt r$, return STALLED instead of looping without useful progress. 4. Obtain only the needed values. Ternary search evaluates both probes. Golden-section initially evaluates both and subsequently evaluates only the new probe; the reused coordinate and its cached value travel together. Refuse a call that would exceed the evaluation cap. Count a call that returns NaN or infinity, then return NONFINITE. 5. Choose the retained interval. Ternary search keeps $[l,x_2]$ when $f_1\lt f_2$, $[x_1,r]$ when $f_1\gt f_2$, and $[x_1,x_2]$ on equality. Golden-section keeps $[l,x_2]$ when $f_1\le f_2$, otherwise $[x_1,r]$. Check that represented width actually decreases before committing the change. 6. Record a completed reduction. The history contains old endpoints, both probes and values, new endpoints, the best valid sample seen so far, and the cumulative objective-call count. If either required value is unavailable, do not commit a reduction; an earlier valid sample can still update the best observed value. 7. Prepare golden reuse and repeat. If the left interval is retained, old $x_1,f_1$ become new $x_2,f_2$; compute a new left probe. If the right interval is retained, old $x_2,f_2$ become new $x_1,f_1$; compute a new right probe. Evaluate that new point only if another reduction is needed.
Why does the ratio work? After retaining $[l,x_2]$, its width is $\rho W$. The old left probe is at $l+(1-\rho)W=l+\rho^2W$, exactly the new right probe's ideal position $l+\rho(\rho W)$. This identity makes one value reusable. In floating point, preserve the old coordinate itself rather than recomputing a slightly different point and attaching the old value to it.
The best-observed score is updated only on a strict improvement, so equal values keep the earliest sample. It is nonincreasing for a minimization run. The midpoint and its unknown objective value need not improve monotonically. If you need $f(\widehat{x})$, make and account for a separate objective call.
flowchart TD
A["Validate interval, tolerance, method, and caps"] --> B{"Width at most tolerance?"}
B -->|Yes| C["Return CONVERGED"]
B -->|No| D{"Reduction cap reached?"}
D -->|Yes| E["Return ITER_LIMIT"]
D -->|No| F["Place ternary probes or prepare golden cached pair"]
F --> G{"Two distinct interior probes?"}
G -->|No| H["Return STALLED"]
G -->|Yes| I{"Needed evaluation fits budget?"}
I -->|No| J["Return EVAL_LIMIT with last committed interval"]
I -->|Yes| K["Call objective; count call"]
K --> L{"Finite value?"}
L -->|No| M["Return NONFINITE with last committed interval"]
L -->|Yes| N["Update best observed sample"]
N --> O{"More needed values?"}
O -->|Yes| I
O -->|No| P["Compare values and choose interval"]
P --> Q{"Represented width decreases?"}
Q -->|No| H
Q -->|Yes| R["Commit reduction and append trace row"]
R --> S["For golden: preserve reused point and value"]
S --> B
Worked Example with a Full Trace
Minimize $f(x)=(x-2.5)^2+1$ on $[0,9]$, with width tolerance $\varepsilon=0.75$, iteration cap $64$, and evaluation cap $128$. The true minimizer is $x=2.5$ and its objective value is $1$. There is no randomness or seed: the starting interval and all arithmetic determine the trace.
The tables below record every completed reduction. A probe cell is $(x,f(x))$; endpoint and value displays are rounded to nine decimal places, while comparisons use full binary64 precision. The last column records the best sampled coordinate and value, which can differ from the final midpoint.
Ternary search. The first probes are $3$ and $6$, with values $1.25$ and $13.25$, so the interval becomes $[0,6]$. The second probes are $2$ and $4$, with values $1.25$ and $3.25$; keep $[0,4]$, retaining the earlier best sample at $3$ on the tie between sampled objective values. Both probes in each subsequent row are fresh calls.
| Reduction | Old interval | Left probe $(x_1,f_1)$ | Right probe $(x_2,f_2)$ | Kept interval | Calls so far | Best observed $(x,f)$ |
|---|---|---|---|---|---|---|
| $1$ | $[0,9]$ | $(3,\,1.250000000)$ | $(6,\,13.250000000)$ | $[0,6]$ | $2$ | $(3,\,1.250000000)$ |
| $2$ | $[0,6]$ | $(2,\,1.250000000)$ | $(4,\,3.250000000)$ | $[0,4]$ | $4$ | $(3,\,1.250000000)$ |
| $3$ | $[0,4]$ | $(1.333333333,\,2.361111111)$ | $(2.666666667,\,1.027777778)$ | $[1.333333333,4]$ | $6$ | $(2.666666667,\,1.027777778)$ |
| $4$ | $[1.333333333,4]$ | $(2.222222222,\,1.077160494)$ | $(3.111111111,\,1.373456790)$ | $[1.333333333,3.111111111]$ | $8$ | $(2.666666667,\,1.027777778)$ |
| $5$ | $[1.333333333,3.111111111]$ | $(1.925925926,\,1.329561043)$ | $(2.518518519,\,1.000342936)$ | $[1.925925926,3.111111111]$ | $10$ | $(2.518518519,\,1.000342936)$ |
| $6$ | $[1.925925926,3.111111111]$ | $(2.320987654,\,1.032045420)$ | $(2.716049383,\,1.046677336)$ | $[1.925925926,2.716049383]$ | $12$ | $(2.518518519,\,1.000342936)$ |
| $7$ | $[1.925925926,2.716049383]$ | $(2.189300412,\,1.096534234)$ | $(2.452674897,\,1.002239665)$ | $[2.189300412,2.716049383]$ | $14$ | $(2.518518519,\,1.000342936)$ |
Golden-section search. The first probes are approximately $3.437694101$ and $5.562305899$; their values are $1.879270228$ and $10.377717418$, so keep $[0,5.562305899]$. The old left probe becomes the next right probe. Row $2$ evaluates only the new left point $2.124611797$, and the same one-value reuse continues.
| Reduction | Old interval | Left probe $(x_1,f_1)$ | Right probe $(x_2,f_2)$ | Kept interval | Calls so far | Best observed $(x,f)$ |
|---|---|---|---|---|---|---|
| $1$ | $[0,9]$ | $(3.437694101,\,1.879270228)$ | $(5.562305899,\,10.377717418)$ | $[0,5.562305899]$ | $2$ | $(3.437694101,\,1.879270228)$ |
| $2$ | $[0,5.562305899]$ | $(2.124611797,\,1.140916303)$ | $(3.437694101,\,1.879270228)$ | $[0,3.437694101]$ | $3$ | $(2.124611797,\,1.140916303)$ |
| $3$ | $[0,3.437694101]$ | $(1.313082304,\,2.408773618)$ | $(2.124611797,\,1.140916303)$ | $[1.313082304,3.437694101]$ | $4$ | $(2.124611797,\,1.140916303)$ |
| $4$ | $[1.313082304,3.437694101]$ | $(2.124611797,\,1.140916303)$ | $(2.626164608,\,1.015917508)$ | $[2.124611797,3.437694101]$ | $5$ | $(2.626164608,\,1.015917508)$ |
| $5$ | $[2.124611797,3.437694101]$ | $(2.626164608,\,1.015917508)$ | $(2.936141291,\,1.190219226)$ | $[2.124611797,2.936141291]$ | $6$ | $(2.626164608,\,1.015917508)$ |
| $6$ | $[2.124611797,2.936141291]$ | $(2.434588481,\,1.004278667)$ | $(2.626164608,\,1.015917508)$ | $[2.124611797,2.626164608]$ | $7$ | $(2.434588481,\,1.004278667)$ |
Ternary search completes $7$ reductions and $14$ evaluations, ending with interval $[2.189300412,2.716049383]$, width about $0.526748971$, and midpoint $2.452674897$. Its best observed sample is approximately $(2.518518519,1.000342936)$.
Golden-section completes $6$ reductions and $7$ evaluations, ending with interval $[2.124611797,2.626164608]$, width about $0.501552810$, and midpoint $2.375388203$. Its best observed sample is approximately $(2.434588481,1.004278667)$. Both intervals contain $2.5$ and satisfy the same width target. Golden uses fewer calls, while ternary happens to sample a lower objective value in this particular run; those are different comparisons.
Trace It by Hand
After golden-section row $2$, the interval is $[0,3.437694101]$. The retained point $2.124611797$ has value $1.140916303$. Predict which probe is new in row $3$, and which side will be discarded.
Reveal: the new left probe is $1.313082304$, with value $2.408773618$. Reuse $2.124611797$ as the right probe. Since the left value is larger, keep $[1.313082304,3.437694101]$. The cumulative evaluation count rises from $3$ to $4$, not to $5$.
Now stop after only $3$ objective calls. Golden has completed two reductions, so return EVAL_LIMIT with interval $[0,3.437694101]$ and best sample $(2.124611797,1.140916303)$. It has not met the $0.75$ width tolerance. Finally, suppose the first call succeeds but the second returns infinity: the original interval remains unchanged, both attempted calls are counted, and the first valid sample is still available.
Implementation in Python, C++, and Java
The three complete programs implement both methods with identical control flow and arithmetic order. The callback takes one real coordinate and returns one scalar objective value. The example objective is a quadratic; additional fixtures cover an endpoint minimum, a flat minimum set, resource limits, adjacent doubles, a non-finite result, and an interval that is already narrow.
Contract. Endpoints and tolerance must be finite; $-10^6\le l\le r\le10^6$ and $\varepsilon\gt0$. The method is exactly ternary or golden. The maximum number of completed reductions is an integer in $[0,256]$, and the evaluation cap is an integer in $[0,2000]$. These endpoint limits ensure safe width and midpoint arithmetic in this demonstration. Inputs outside those numeric ranges are rejected. The callback must be callable and deterministic for caching and unimodal-search guarantees; ordinary callback exceptions propagate to the caller. NaN or infinite returned values are handled with NONFINITE.
Result contains a status, final retained endpoints, midpoint, a has_best flag, best observed coordinate/value, completed-reduction count, attempted objective-call count, and the full history. The best fields are dummy zeroes when has_best is false. CONVERGED means only the represented width met tolerance; ITER_LIMIT, EVAL_LIMIT, STALLED, and NONFINITE report distinct incomplete outcomes. A failure preserves the last committed interval, but a valid call made before it can improve the best sample. The programs do not evaluate endpoints or the final midpoint automatically.
Stopping precedence is deliberate: width, then iteration cap, then representable interior probes, then evaluation availability and finiteness. An evaluation budget of zero therefore does not prevent returning CONVERGED for an already narrow interval. A call returning a non-finite value counts against the budget; a refused call does not. No interval update occurs until both comparison values are valid. A cache entry always consists of the exact sampled coordinate together with its value.
For $k\ge1$ fully completed reductions with valid finite evaluations and no partial failed comparison, ternary uses $2k$ objective calls and golden uses $k+1$. For $k=0$ caused by an already narrow interval, both use zero calls. Other zero- or partial-reduction outcomes can have calls already spent; for example, initialization can stop after one valid call or one valid and one non-finite call.
Each printed iteration reports the new interval and the best valid objective value observed so far. It does not label that value as $f(\text{midpoint})$. The returned trace also stores both probes and both comparison values. Six-decimal output is for readability; branches use the full values, so visually equal rounded prints need not imply an equality branch.
Use Python 3, C++14 or newer, and Java 17 or newer; save Java as Main.java. For reproducible C++ floating-point histories, compile with g++ -std=c++14 -O2 -ffp-contract=off main.cpp -o main and avoid unsafe floating-point transformations. The hard-coded binary64 golden fraction and explicit operation order produce identical sample output in all three languages.
Expected standard output, identical in all three languages:
ternary: CONVERGED, iterations=7, evaluations=14midpoint=2.452675, width=5.267490e-01, best=(2.518519,1.000343)i=1, interval=[0.000000,6.000000], best_x=3.000000, best_f=1.250000, evaluations=2i=2, interval=[0.000000,4.000000], best_x=3.000000, best_f=1.250000, evaluations=4i=3, interval=[1.333333,4.000000], best_x=2.666667, best_f=1.027778, evaluations=6i=4, interval=[1.333333,3.111111], best_x=2.666667, best_f=1.027778, evaluations=8i=5, interval=[1.925926,3.111111], best_x=2.518519, best_f=1.000343, evaluations=10i=6, interval=[1.925926,2.716049], best_x=2.518519, best_f=1.000343, evaluations=12i=7, interval=[2.189300,2.716049], best_x=2.518519, best_f=1.000343, evaluations=14golden: CONVERGED, iterations=6, evaluations=7midpoint=2.375388, width=5.015528e-01, best=(2.434588,1.004279)i=1, interval=[0.000000,5.562306], best_x=3.437694, best_f=1.879270, evaluations=2i=2, interval=[0.000000,3.437694], best_x=2.124612, best_f=1.140916, evaluations=3i=3, interval=[1.313082,3.437694], best_x=2.124612, best_f=1.140916, evaluations=4i=4, interval=[2.124612,3.437694], best_x=2.626165, best_f=1.015918, evaluations=5i=5, interval=[2.124612,2.936141], best_x=2.626165, best_f=1.015918, evaluations=6i=6, interval=[2.124612,2.626165], best_x=2.434588, best_f=1.004279, evaluations=7endpoint: CONVERGED, iterations=5, evaluations=6midpoint=0.225425, width=4.508497e-01, best=(0.278640,0.278640)i=1, interval=[0.000000,3.090170], best_x=1.909830, best_f=1.909830, evaluations=2i=2, interval=[0.000000,1.909830], best_x=1.180340, best_f=1.180340, evaluations=3i=3, interval=[0.000000,1.180340], best_x=0.729490, best_f=0.729490, evaluations=4i=4, interval=[0.000000,0.729490], best_x=0.450850, best_f=0.450850, evaluations=5i=5, interval=[0.000000,0.450850], best_x=0.278640, best_f=0.278640, evaluations=6minimum plateau: CONVERGED, iterations=5, evaluations=10midpoint=2.074074, width=3.950617e-01, best=(2.000000,0.000000)i=1, interval=[0.000000,4.000000], best_x=2.000000, best_f=0.000000, evaluations=2i=2, interval=[0.000000,2.666667], best_x=2.000000, best_f=0.000000, evaluations=4i=3, interval=[0.888889,2.666667], best_x=2.000000, best_f=0.000000, evaluations=6i=4, interval=[1.481481,2.666667], best_x=2.000000, best_f=0.000000, evaluations=8i=5, interval=[1.876543,2.271605], best_x=2.000000, best_f=0.000000, evaluations=10evaluation cap: EVAL_LIMIT, iterations=2, evaluations=3midpoint=1.718847, width=3.437694e+00, best=(2.124612,1.140916)i=1, interval=[0.000000,5.562306], best_x=3.437694, best_f=1.879270, evaluations=2i=2, interval=[0.000000,3.437694], best_x=2.124612, best_f=1.140916, evaluations=3iteration cap: ITER_LIMIT, iterations=2, evaluations=4midpoint=2.000000, width=4.000000e+00, best=(3.000000,1.250000)i=1, interval=[0.000000,6.000000], best_x=3.000000, best_f=1.250000, evaluations=2i=2, interval=[0.000000,4.000000], best_x=3.000000, best_f=1.250000, evaluations=4adjacent doubles: STALLED, iterations=0, evaluations=0midpoint=1.000000, width=2.220446e-16, best=NONEnonfinite: NONFINITE, iterations=0, evaluations=2midpoint=4.500000, width=9.000000e+00, best=(3.437694,1.879270)already narrow: CONVERGED, iterations=0, evaluations=0midpoint=1.000000, width=0.000000e+00, best=NONEchecks = PASS
Complexity, Correctness, and Invariants
Let initial width be $W_0=b-a$ and assume exact arithmetic, valid shape, finite reliable values, and no resource interruption. If $W_0\le\varepsilon$, no reduction is needed. Otherwise, a ternary inequality retains $2/3$ of the width and a ternary equality retains $1/3$, giving
$$W_k\le\left(\frac23\right)^kW_0,\qquad k_{\mathrm{ternary}}\le\left\lceil\frac{\log(W_0/\varepsilon)}{\log(3/2)}\right\rceil.$$
That upper bound is attained when every reduction takes an inequality branch. If every comparison ties, only $\lceil\log(W_0/\varepsilon)/\log3\rceil$ reductions are needed. Golden-section always retains fraction $\rho$ under this lesson's tie policy:
$$W_k=\rho^kW_0,\qquad k_{\mathrm{golden}}=\left\lceil\frac{\log(W_0/\varepsilon)}{\log(1/\rho)}\right\rceil.$$
Thus both need $O(\log(W_0/\varepsilon))$ reductions when reduction is necessary, but objective-call constants differ: $2k$ for ternary and $k+1$ for golden, for $k\ge1$. If each evaluation costs $C_f$, time is $O((C_f+1)k)$; with variable evaluation costs, charge their actual sum. Golden-section has linear convergence in interval width, not quadratic convergence in the estimate. Floating-point steps approximate these exact ratios and can stall before an arbitrarily small tolerance is reached.
Best, average, worst. The best request has an already narrow interval and uses constant work and zero evaluations. For a fixed nontrivial width target, golden's ideal reduction count is independent of function values; ternary lies between its all-tie and all-inequality bounds. An average ternary count requires a distribution over objectives or comparisons, which is not specified here. Worst-case mathematical work follows the logarithmic bounds; in the programs, explicit caps additionally limit reductions and calls, without implying success.
The interval-search core stores a constant number of scalars and uses $O(1)$ auxiliary space. These programs retain the entire history, so actual additional storage is $O(k)$, plus any memory owned by the objective. They are iterative and have no recursion stack. A slow callback can dominate runtime even with a small evaluation count.
Why interval elimination is correct. If $f(x_1)\lt f(x_2)$ and all minimizers were strictly to the right of $x_2$, the strict decreasing side would require $f(x_1)\gt f(x_2)$, a contradiction. Therefore retaining $[l,x_2]$ preserves some minimizer; the opposite inequality is symmetric. On equality, either the probes straddle the minimum set or both lie on it, because strict monotonicity excludes equality elsewhere on one side. Retaining $[x_1,x_2]$, or the larger left interval used by golden, preserves at least one minimizer. Induct from the initial interval, and geometric shrinkage yields the width target.
This proof assumes truthful comparisons of the specified function. Floating-point representation, noise, or an unsupported flat region can violate that premise. Numeric checks establish finite values, distinct probes, and progress; they cannot establish unimodality or certify comparison accuracy from a few black-box samples.
Location and value accuracy differ. If a retained interval contains a minimizer, the midpoint is within half its width of some minimizer. If $f$ is also $L$-Lipschitz, then $f(\widehat{x})-f_{\min}\le L\varepsilon/2$. If instead it is twice differentiable around an interior stationary minimizer and $0\le f''(x)\le M$ on the relevant segment, then $f(\widehat{x})-f_{\min}\le M\varepsilon^2/8$. These are additional assumptions, and neither bound is supplied just by calling the search routine. The best sampled value is a separate observed quantity, not an automatically certified value-error bound.
| Method | Evaluations / work model | Auxiliary space | Assumptions and useful distinction |
|---|---|---|---|
| Real ternary search | Up to $2\lceil\log(W_0/\varepsilon)/\log(3/2)\rceil$ calls when $W_0\gt\varepsilon$ | $O(1)$ core; $O(k)$ with this trace | Derivative-free; strict-sided unimodality supports equality handling |
| Golden-section search | $k+1$ calls for $k\ge1$ reductions; $k\approx\log(W_0/\varepsilon)/\log(1/\rho)$ | $O(1)$ core; $O(k)$ with this trace | Reuses one point/value; especially useful for expensive deterministic evaluations |
| Derivative-sign bisection | $O(\log(W_0/\varepsilon))$ derivative evaluations | $O(1)$ core | A suitable monotone derivative and endpoint handling; one sign locates the improving direction |
| Brent-style minimization | Problem-dependent; combines interpolation with bracket-preserving steps | $O(1)$ core | Often faster on smooth objectives; library bracket/bounds semantics must be checked |
| Uniform grid with $n$ samples | $O(n)$ evaluations | $O(1)$ if streamed | Simple global coverage at chosen resolution; between-sample behavior needs assumptions |
| Discrete unimodal search on $n$ ordered indices | $O(\log n)$ calls plus a constant-size final scan | $O(1)$ core | Integer rounding and final enumeration differ from real-valued stopping |
| Newton optimization | Often locally quadratic convergence with suitable derivatives and start | $O(1)$ in one dimension | Needs derivative information and safeguards; can leave the interval or converge poorly |
| Fibonacci interval search | Predetermined-budget interval reduction with reused values | $O(1)$ scalar state with suitable ratio generation | Useful when the number of available evaluations is fixed in advance |
The retained closed interval contains at least one minimizer as long as the strict-sided shape assumption and comparisons are valid; every committed reduction preserves that invariant and decreases width. Golden-section additionally preserves the identity between each reused coordinate and its cached value, so one new evaluation suffices for the next comparison.
Variants, Pitfalls, and Optimizations
Do not confuse weak unimodality with safe tie handling. Consider a continuous function that stays at value $1$ on $[0,0.8]$, decreases linearly to $0$ at $0.9$, and rises afterward. Its first ternary probes at $1/3$ and $2/3$ tie at $1$, but retaining the middle discards the true minimizer. Golden's equal-value left choice also discards it. A shape described merely as nonincreasing then nondecreasing can contain this trap; the stronger assumption at the start of this lesson excludes it.
Numerical ties can be false information. In binary64, evaluating $10^{20}+(x-0.9)^2$ on $[0,1]$ rounds away the small variation. Both methods see equal values and can discard $0.9$, although the underlying real-valued quadratic has its minimum there. CONVERGED then certifies only the represented width. Scaling the variable, removing a known large additive constant before computation, using higher precision, or using trustworthy error bounds can help; adding an arbitrary comparison epsilon does not restore the proof. Simulation noise likewise requires a statistical comparison model and usually repeated sampling rather than ordinary deterministic golden caching.
Choose a meaningful tolerance. An absolute location tolerance has the same units as $x$. A combined rule such as $r-l\le\varepsilon_{\mathrm{abs}}+\varepsilon_{\mathrm{rel}}\max(\lvert l\rvert,\lvert r\rvert)$ can be useful at different scales, but it is a different stopping policy from the code. Adjacent doubles may have no distinct interior pair; the sample near $1$ returns STALLED at width about $2.220446\times10^{-16}$ when the requested tolerance is the smallest positive subnormal. Increasing iterations cannot manufacture additional precision.
Preserve the cache exactly. Move an old coordinate together with its evaluated value. Recomputing its ideal golden coordinate can differ by one rounding unit, and reusing its old value at that new location is not an exact cache hit. Also avoid evaluating the pending new probe after tolerance is already met; that extra call wastes the very benefit golden-section is meant to provide. Objective exceptions, non-finite values, and evaluation limits must leave the last committed interval intact.
Bounded intervals and endpoints matter. The examples retain the original domain and allow the minimizer at an endpoint, as in $f(x)=x$ on $[0,5]$. The algorithm need not sample that endpoint, so its best sampled score will not necessarily equal the exact boundary optimum. If endpoint objective values are required for reporting, query and count them explicitly. A library's two-point bracket can instead be a starting pair for an expanding downhill search; it is not automatically a hard bound. In SciPy, bounded scalar minimization has a dedicated bounds interface, distinct from the bracket argument used by golden/Brent methods.
Use the right variant. To maximize, minimize $-f$ with finite, well-scaled arithmetic and reverse the final reported score. On integer domains, stop while a few candidate indices remain and evaluate all of them; real-width tolerances and rounded golden coordinates are not a replacement for that scan. With integer ternary probes, ensure they are distinct and each update strictly reduces the candidate range. If adjacent-value slope comparisons are available under a compatible strict-sided sequence model, binary search can be simpler. A derivative-sign method can halve a continuous interval when the derivative assumptions hold; Brent-style interpolation can improve practical speed on smooth objectives. Multimodal or high-dimensional objectives require additional structure or a different optimization strategy.
Validate the shape assumption, keep cached coordinates paired with their values, and distinguish width convergence from budget exhaustion or floating-point stalling. Equal rounded or noisy values do not prove that a minimizer lies between the probes, and a small interval alone does not certify objective-value accuracy.
Practice Problems and Real-World Use
Start with functions whose minimizers are independently known: shifted quadratics, absolute-value valleys, monotone objectives with endpoint minima, and functions flat only on their minimum set. Record every queried coordinate, verify nested intervals and progress, and check that no call is made outside the initial domain or beyond the evaluation cap. Test ties, zero budgets, already narrow intervals, failure on the second initialization call, and representability limits separately.
The programs were checked on 8,960 inputs per language, comprising $8{,}946$ valid requests and $14$ invalid numeric/method requests. Across a well-conditioned subset, analytic minimum sets checked $8{,}724$ final results and $170{,}674$ retained intervals. The full corpus included $172{,}306$ interval-update audits and $81{,}974$ exact golden probe/value-reuse checks, plus explicit non-finite, budget, subnormal, and false-equality cases. Four deliberate counterexamples reproduced loss of the intended real minimizer when the shape or reliable-comparison premise was absent; those are limitations demonstrated by the tests, not cases claimed to satisfy the convergence theorem. Python, C++, and Java matched all result/history floating-point fields bit for bit under the stated arithmetic settings and agreed on repeated runs. The C++ corpus also passed address/undefined-behavior instrumentation.
Primary background includes Michael Heath's golden-section teaching module and Jan Verschelde's numerical-analysis lecture. For library parameter semantics, consult the official SciPy scalar-minimization documentation. The exact tie policy, lazy evaluation timing, status contract, code, and numerical caveats in this lesson are specified directly here.
| Practice problem or application | Concrete task | Idea tested | Difficulty |
|---|---|---|---|
| Shifted quadratic | Reproduce both traces for $(x-2.5)^2+1$ | Interval elimination, call counts, analytic error check | Easy |
| Endpoint minimum | Minimize $f(x)=x$ on $[0,5]$ | Closed-domain optimum versus an interior sampled best | Easy |
| Minimum plateau | Minimize $\max(0,\lvert x-2\rvert-0.5)$ | Retain some minimizer; distinguish safe and unsafe flat regions | Medium |
| Expensive deterministic simulator | Wrap a one-parameter simulation with a proven single-valley operating interval | Evaluation budgeting and golden reuse | Medium |
| Convex geometric location on a line | Minimize a sum of distances over a specified line segment | Convexity, possible nondifferentiability, endpoint handling | Medium |
| Discrete cost array | Search a strict-sided valley of integer-indexed costs, then exhaust the final candidates | Integer progress and final enumeration | Medium |
| Floating-point stress laboratory | Try adjacent doubles, large additive offsets, NaN, and interrupted initialization | Status semantics and the limits of comparison information | Hard |
| Line-search comparison | Compare golden, derivative bisection, and safeguarded interpolation on justified intervals | Objective cost, derivative assumptions, width versus value accuracy | Hard |