/** * BFGS quasi-Newton minimization of `f: ℝⁿ → ℝ`. * * Maintains an approximate inverse Hessian `H` (started at the identity) and * updates it after every accepted step via the classic BFGS formula: * * s = x_{k+1} − x_k, y = g_{k+1} − g_k, ρ = 1 / (yᵀs) * H ← (I − ρ s yᵀ) H (I − ρ y sᵀ) + ρ s sᵀ * * The update is skipped (H left unchanged) when `yᵀs ≤ 1e-12` — a near-zero * or negative curvature pairing would make H indefinite. The search direction * is `d = −H g`, accepted via a backtracking Armijo line search (`c1 = 1e-4`, * starting step `α = 1`, halved up to 50 times). * * `opts.bounds`, if supplied, turns this into a lightweight **projected** * BFGS: after every accepted step each coordinate is clipped into its * `[lo, hi]` range. This is NOT the full active-set L-BFGS-B method (no * distinction between free/active variables in the Hessian update) — it is a * simple, effective projection that keeps the iterate feasible. * * Complements the derivative-free `minimize` (Nelder–Mead): BFGS converges * superlinearly on smooth functions using gradient information (analytic or * numeric), at the cost of assuming enough smoothness for the gradient/line * search to behave. * * @packageDocumentation */ type f64 = number; /** Options for {@link bfgs}. */ export interface BfgsOptions { /** * Analytic gradient `∇f(x)`. If omitted, a central-difference gradient is * used with per-coordinate step `h_i = max(1, |x_i|) · cbrt(machine eps)`. */ grad?: (x: number[]) => number[]; /** * Box constraints `[lo_i, hi_i]` per coordinate. After each accepted step, * `x` is clipped into these bounds (projected BFGS — a lightweight * approximation of L-BFGS-B, not the full active-set method). */ bounds?: [f64, f64][]; /** Convergence tolerance on `‖g‖∞` (default 1e-8). */ tol?: f64; /** Maximum iterations (default 500). */ maxIter?: number; } /** Result of {@link bfgs}. */ export interface BfgsResult { /** The minimizer. */ x: number[]; /** `f(x)` at the minimizer. */ fval: f64; /** Number of iterations performed. */ iterations: number; /** Whether `‖g‖∞ < tol` was reached within `maxIter`. */ converged: boolean; } /** * Minimize `f: ℝⁿ → ℝ` from `x0` via BFGS quasi-Newton with an Armijo * backtracking line search. Uses `opts.grad` if supplied, else a local * central-difference gradient. `opts.bounds` clips each accepted step * (projected BFGS, not full L-BFGS-B). * * @example * bfgs((v) => (1 - v[0]) ** 2 + 100 * (v[1] - v[0] ** 2) ** 2, [-1.2, 1]) * // => { x: ~[1, 1], fval: ~0, ... } */ export declare function bfgs(f: (x: number[]) => number, x0: number[], opts?: BfgsOptions): BfgsResult; export {}; //# sourceMappingURL=bfgs.d.ts.map