Skip to content

Optimizer bindings

The C and Python APIs call the original functions in Optimization.Common, FirstOrder, Local, Constrained and Global. They preserve method constructors, callbacks, result diagnostics, default options, evaluation budgets and explicit stochastic seeds. The low-level optimizer-state ABI below remains available alongside the structured solver API.

Include hmath_optimization.h in C or C++. In Python, use from hmath import optimization. These operations use binary64, matching the original Double functions. There is no implicit FP32 optimizer implementation.

GradientMethod

The mathematical methods and enumeration order are unchanged:

Haskell C Python optimization.GradientMethod
GradientDescent HMATH_GRADIENT_DESCENT GRADIENT_DESCENT
Momentum HMATH_MOMENTUM MOMENTUM
Nesterov HMATH_NESTEROV NESTEROV
AdaGrad HMATH_ADAGRAD ADAGRAD
RMSProp HMATH_RMSPROP RMSPROP
AdaDelta HMATH_ADADELTA ADADELTA
Adam HMATH_ADAM ADAM
AdamW HMATH_ADAMW ADAMW
AMSGrad HMATH_AMSGRAD AMSGRAD
AdaMax HMATH_ADAMAX ADAMAX
Nadam HMATH_NADAM NADAM
RAdam HMATH_RADAM RADAM

initialize_optimizer / hmath_initialize_optimizer

Original: initializeOptimizer.

hmath_status hmath_initialize_optimizer(
    hmath_context *context, ptrdiff_t dimension, hmath_optimizer_state **out);

optimization.initialize_optimizer(dimension) and optimization.OptimizerState(dimension) construct the same state.

Parameter Meaning
dimension Number of parameters, represented as Haskell Int. Negative values retain the original InvalidArgument "negative optimizer dimension" error. Zero is valid.
context C cancellation context, or NULL. Checked before entry.
out C address receiving one owned state reference on success; untouched on failure.

The result is an immutable state with zero initial moments/history. A state holds the Haskell runtime alive. hmath_runtime_shutdown returns HMATH_BUSY while any state remains alive.

optimizer_step / hmath_optimizer_step

Original: optimizerStep.

hmath_status hmath_optimizer_step(
    hmath_context *context, hmath_gradient_method method, double rate,
    const hmath_optimizer_state *state,
    const double *parameters, size_t parameter_count,
    const double *gradient, size_t gradient_count,
    double *out_parameters, size_t out_capacity,
    hmath_optimizer_state **out_state);

Python: optimization.optimizer_step(method, rate, state, parameters, gradient).

Parameter Meaning
method Original GradientMethod constructor; see the table above.
rate Positive finite learning rate. No default is introduced.
state Live state returned by initialization or a previous step.
parameters Current parameters, in parameter order.
gradient Gradient components in the same order. The binding does not compute or modify the gradient.
parameter_count, gradient_count C lengths of the corresponding readable buffers.
context C cancellation context, or NULL; checked before entry.
out_parameters, out_capacity C writable result buffer and its capacity in doubles. Capacity must be at least parameter_count.
out_state C address receiving one owned reference to the new state.

Python returns (new_parameters, new_state); C writes those same two results. The original state is unchanged and may be reused to branch a computation. All output memory must be disjoint from the inputs and other outputs. On failure both C outputs remain untouched. Inputs are borrowed only for the call; each thread must retain a state reference while using it. Independent calls can share an immutable state, but must use separate output buffers.

Original constants remain unchanged: β₁ = 0.9, β₂ = 0.999, ε = 10⁻⁸; RMSProp/AdaDelta use ρ = 0.9, and AdamW uses weight decay 0.01. Nesterov in this function applies the original corrected momentum direction; it does not perform the look-ahead objective evaluation of minimizeGradient.

Non-finite parameters, gradients, state or results return the original NonFiniteResult. Nonpositive rates or mismatched dimensions return the original InvalidArgument "optimizer rate or state shape". A Haskell MathError is status 11 in C and HMathError with status == 11 in Python; the error message retains the constructor and payload. Invalid C pointers/enum representations, insufficient buffer capacity and allocation failures are separate binding errors.

State ownership

hmath_optimizer_state_retain(state) adds a reference; hmath_optimizer_state_release(state) releases one. Both accept NULL as a no-op. Final release frees the Haskell state and its runtime reservation. Never use a released state or release the last reference concurrently with a call using it.

Python state.close() is idempotent. A with state: block closes that reference on exit; the destructor is a fallback. A closed state rejects further steps with ValueError. Each returned state is independently owned.

from hmath import optimization

with optimization.initialize_optimizer(2) as initial:
    parameters, updated = optimization.optimizer_step(
        optimization.GradientMethod.ADAM,
        0.01,
        initial,
        [1.0, -2.0],
        [2.0, -4.0],
    )
    with updated:
        assert len(parameters) == 2
        assert parameters[0] < 1.0
        assert parameters[1] > -2.0

See also: original Haskell optimizer API, C runtime and errors, numeric bindings.

Solver records and options

from hmath import optimization as opt

options = opt.OptimizeOptions(
    max_iterations=1000,
    max_evaluations=20000,
    tolerance=1e-8,
    learning_rate=0.01,
)
result = opt.minimize_quasi_newton(
    opt.BFGS,
    options,
    lambda point: sum(x*x for x in point),
    lambda point: [2*x for x in point],
    [1.0, -2.0],
)
print(result.point, result.value, result.converged)

default_optimize_options() returns the original defaults shown above. Options are immutable Python records; create another OptimizeOptions to change them. The source validates options inside the relevant operation. Constructor calls do not invent stricter validation.

Record Fields, in constructor order
OptimizeOptions max_iterations: iteration budget; max_evaluations: evaluation budget; tolerance: stopping tolerance; learning_rate: positive update rate
OptimizeResult point: final parameter vector; value: objective; gradient_norm: original solver's residual diagnostic; iterations: source iteration count; evaluations: source evaluation count; converged: original stopping flag
LPResult point: primal variables; value: objective; basis: retained zero-based basis indices; iterations: source pivot count
EarlyStopping best_score: None or best score; stale_steps: stale observation count; stopped: stop flag

The opt_*, lp_*, best_score, stale_steps and stopped functions expose original record selectors as well. They are equivalent to reading the matching record field. A result's diagnostic is solver specific: scalar minimization reports bracket width, projected/proximal methods report a mapping residual, and global methods report spread or step size. A global convergence flag does not certify global optimality. Some algorithms return their incumbent with converged=False on exhaustion; others return NonConvergence. Those original choices and evaluation-accounting rules remain unchanged.

Callbacks and returned functions

Source/Python type Python arguments Successful result
Objective point scalar float
Gradient point vector
Hessian point rows of a matrix
ResidualFunction point residual vector
JacobianFunction point Jacobian rows
Projection point projected vector
Proximal operator rate, point vector
Iterate monitor OptimizeResult bool; False stops the original monitor-based minimizer

minimize_scalar alone passes a scalar to its objective. Python callbacks return ordinary values or raise a structured MathError to return the original Left branch. Such failures remain recoverable by the original solver; for example, feasible barrier backtracking retries a rejected DomainError. Unexpected Python exceptions abort the call and are re-raised after temporary native values are cleaned up.

mini_batch_gradient(gradients) returns a callable original gradient; weighted_objective(weights, objectives) returns a callable original objective. They evaluate lazily when called. Use the returned function as a context manager or call .close(); its callback references remain alive transitively. Empty batches, wrong gradient lengths and invalid weights retain original errors. A callback may call other HMath operations reentrantly. It must not request final runtime shutdown.

All these original solvers operate on Double. Supplying Python or C float32 values does not select an FP32 solver. Vectors/matrices are lists of binary64 values at this API, with no added rectangularization, truncation or finite-value checks. Exact generic transpose accepts shared Value elements (including integers, rationals, strings and structured native values) and preserves the original ragged-list behavior.

Methods and solver contracts

Learning schedules are ConstantRate(rate), StepDecay(initial_rate, period, decay), ExponentialDecay(initial_rate, decay), CosineAnnealing(maximum, minimum, period) and Warmup(steps, base). learning_rate(schedule, step) calls the original schedule validation and formula, including nesting. early_stopping(patience, min_delta, value, state) minimizes the observed score and returns the next immutable state.

Scalar methods are GoldenSection, TernarySearch, BrentSearch; the finite bracket must satisfy lower < upper. Quasi-Newton methods are BFGS, LBFGS(memory), DFP, SR1. Newton methods are Newton, NewtonCG, TrustRegion(radius), Dogleg(radius); Hessians are supplied explicitly. Least-squares losses are SquaredLoss, HuberLoss(scale), CauchyLoss(scale), SoftL1(scale); least_squares also takes the original positive damping value. nelder_mead and powell need only an objective. nonlinear_cg takes an objective and gradient.

stochastic_gradient makes one pass over the explicit gradients in order, returning (point, OptimizerState); ordering/shuffling remain caller owned. projected_gradient projects each update. proximal_gradient and fista call the supplied proximal operator. coordinate_descent requires nonempty blocks that partition the zero-based parameter indices exactly once. No additional momentum constants or tuning parameters are introduced by the binding.

Constraints are Equality(objective, gradient) for g(x) = 0 and LessEqual(objective, gradient) for g(x) <= 0. feasibility returns the maximum absolute equality or positive inequality violation. constrained_minimize accepts QuadraticPenalty, LogBarrier, InteriorPoint, AugmentedLagrangian; barrier methods require strictly feasible inequality-only initial points. slsqp takes explicit Hessians; cobyla takes constraint objectives without derivative callbacks and an initial radius.

linear_programming minimizes cost·x with A x <= rhs and x >= 0, including phase I for negative right-hand sides. revised_simplex instead uses its original equality-form feasible-basis contract: provide a full row-rank matrix and a valid feasible basis, with indices into its columns. quadratic_programming minimizes 0.5*xᵀ*H*x + costᵀ*x under A x <= rhs; its budget bounds dense active-set enumeration. These are the original bounded dense reference algorithms. pareto_front returns zero-based indices of nondominated minimization vectors. weighted_objective keeps each supplied objective and its original weight validation.

Global methods are SimulatedAnnealing, DifferentialEvolution, GeneticAlgorithm, ParticleSwarm, CMAES. global_minimize requires a population size of at least four and finite (lower, upper) bounds with lower < upper. Its seed is the exact original unsigned 64-bit seed, including values above 2⁵³. basin_hopping additionally takes temperature, hop count and an in-bounds initial vector; it performs original local Nelder–Mead descents. No global RNG, system entropy or replacement stochastic implementation is used.

Structured C and C++ solver API

Include hmath_optimization.h (which includes hmath_optimization_all.h). Every named structured wrapper follows the source argument order in the tables below:

hmath_status hmath_optimization_minimize_quasi_newton(
    hmath_context *context,
    const hmath_value *method,
    const hmath_value *options,
    const hmath_value *objective,
    const hmath_value *gradient,
    const hmath_value *initial,
    hmath_value **out);

Arguments use shared immutable Values: scalar Double, Int index, exact Word64 scalar seed, lists/tuples, or opaque original records and method constructors. Constructor wrappers end in _create. Selectors return copied Values; numerical solvers return an OptimizeResult or LPResult Value. Release every owned output with hmath_value_release. Inputs are borrowed for the call; immutable sharing across threads is allowed when each user retains its own live reference. Final release must not race a call using the same last reference. Output pointer storage must be disjoint from inputs and remains untouched on failure.

Create function Values with hmath_optimization_callback(context, role, function, userdata, out). Roles are 0 objective, 1 gradient/projection, 2 Hessian/Jacobian, 3 proximal operator, 4 monitor. The C callback receives one borrowed Value: a parameter list, a (rate, point) tuple for role 3, or a result record for role 4. A scalar-minimization objective receives [x] in C. Return one owned Value reference on success (retain a borrowed input before returning it). On HMATH_MATH_ERROR, fill the hmath_math_error wire; other failures abort the operation. Function pointers, userdata and borrowed error buffers must remain valid until consumed; pointers/userdata used in a derived function or constraint remain live until its final release. Calls are synchronous and may reenter HMath; callback/thread safety remains the caller's responsibility.

hmath_optimization_function_apply invokes a returned function Value with an array of argument Values. hmath_optimization_state_import and _state_export convert between a structured state Value and the compatible low-level hmath_optimizer_state handle; each conversion returns independent ownership. All live native Values and optimizer states reserve the Haskell runtime.

Named function mapping

The following signatures give the exact argument order. Python None denotes a source Nothing/unit as appropriate; all source checked errors use the structured error contract above. For full mathematical formulas and source validation conditions, follow the defining Haskell module for each group.

Common

Original Haskell reference.

Python callable or constructor Result C wrapper
OptimizeOptions(max_iterations, max_evaluations, tolerance, learning_rate) OptimizeOptions hmath_optimization_optimize_options_create
default_optimize_options() OptimizeOptions hmath_optimization_default_optimize_options
OptimizeResult(point, value, gradient_norm, iterations, evaluations, converged) OptimizeResult hmath_optimization_optimize_result_create
EarlyStopping(best_score, stale_steps, stopped) EarlyStopping hmath_optimization_early_stopping_create
ConstantRate(rate) LearningRate hmath_optimization_constant_rate_create
StepDecay(initial_rate, period, decay) LearningRate hmath_optimization_step_decay_create
ExponentialDecay(initial_rate, decay) LearningRate hmath_optimization_exponential_decay_create
CosineAnnealing(maximum, minimum, period) LearningRate hmath_optimization_cosine_annealing_create
Warmup(steps, base) LearningRate hmath_optimization_warmup_create
Armijo LineSearch hmath_optimization_armijo_create
StrongWolfe LineSearch hmath_optimization_strong_wolfe_create
checked_options(options) None hmath_optimization_checked_options
checked_point(point) None hmath_optimization_checked_point
checked_value(objective, point) Double hmath_optimization_checked_value
checked_gradient(gradient, point) Vector hmath_optimization_checked_gradient
check_budget(options, evaluations) None hmath_optimization_check_budget
dot(left, right) original field/helper value hmath_optimization_dot
add(left, right) original field/helper value hmath_optimization_add
sub(left, right) original field/helper value hmath_optimization_sub
outer(left, right) original field/helper value hmath_optimization_outer
norm(values) Double hmath_optimization_norm
scale(factor, values) Vector hmath_optimization_scale
identity(dimension) Matrix hmath_optimization_identity
mat_vec(matrix, vector) Vector hmath_optimization_mat_vec
mat_mul(left, right) Matrix hmath_optimization_mat_mul
transpose(rows) GenericMatrix hmath_optimization_transpose
solve_dense(matrix, rhs) Vector hmath_optimization_solve_dense
result(iterations, evaluations, converged, objective, gradient, point) OptimizeResult hmath_optimization_result
learning_rate(schedule, step) Double hmath_optimization_learning_rate
early_stopping(patience, min_delta, value, state) EarlyStopping hmath_optimization_early_stopping
line_search(method, budget, objective, gradient, point, direction, value, point_gradient) original tuple hmath_optimization_line_search
opt_max_iterations(value) original field/helper value hmath_optimization_opt_max_iterations
opt_max_evaluations(value) original field/helper value hmath_optimization_opt_max_evaluations
opt_tolerance(value) original field/helper value hmath_optimization_opt_tolerance
opt_learning_rate(value) original field/helper value hmath_optimization_opt_learning_rate
opt_point(value) original field/helper value hmath_optimization_opt_point
opt_value(value) original field/helper value hmath_optimization_opt_value
opt_gradient_norm(value) original field/helper value hmath_optimization_opt_gradient_norm
opt_iterations(value) original field/helper value hmath_optimization_opt_iterations
opt_evaluations(value) original field/helper value hmath_optimization_opt_evaluations
opt_converged(value) original field/helper value hmath_optimization_opt_converged
best_score(value) original field/helper value hmath_optimization_best_score
stale_steps(value) original field/helper value hmath_optimization_stale_steps
stopped(value) original field/helper value hmath_optimization_stopped

FirstOrder

Original Haskell reference.

Python callable or constructor Result C wrapper
GradientMethod.GRADIENT_DESCENT GradientMethod hmath_optimization_gradient_descent_create
GradientMethod.MOMENTUM GradientMethod hmath_optimization_momentum_create
GradientMethod.NESTEROV GradientMethod hmath_optimization_nesterov_create
GradientMethod.ADAGRAD GradientMethod hmath_optimization_ada_grad_create
GradientMethod.RMSPROP GradientMethod hmath_optimization_rms_prop_create
GradientMethod.ADADELTA GradientMethod hmath_optimization_ada_delta_create
GradientMethod.ADAM GradientMethod hmath_optimization_adam_create
GradientMethod.ADAMW GradientMethod hmath_optimization_adam_w_create
GradientMethod.AMSGRAD GradientMethod hmath_optimization_ams_grad_create
GradientMethod.ADAMAX GradientMethod hmath_optimization_ada_max_create
GradientMethod.NADAM GradientMethod hmath_optimization_nadam_create
GradientMethod.RADAM GradientMethod hmath_optimization_r_adam_create
initialize_optimizer(dimension) OptimizerState hmath_optimization_initialize_optimizer
optimizer_step(method, rate, state, parameters, gradient) original tuple hmath_optimization_optimizer_step
minimize_gradient(method, options, objective, gradient, initial) OptimizeResult hmath_optimization_minimize_gradient
minimize_gradient_with_callback(monitor, method, options, objective, gradient, initial) OptimizeResult hmath_optimization_minimize_gradient_with_callback
stochastic_gradient(method, rate, gradients, initial) original tuple hmath_optimization_stochastic_gradient
mini_batch_gradient(gradients) owned callable hmath_optimization_mini_batch_gradient
projected_gradient(options, objective, gradient, project, initial) OptimizeResult hmath_optimization_projected_gradient
proximal_gradient(options, objective, gradient, prox, initial) OptimizeResult hmath_optimization_proximal_gradient
fista(options, objective, gradient, prox, initial) OptimizeResult hmath_optimization_fista
coordinate_descent(blocks, options, objective, gradient, initial) OptimizeResult hmath_optimization_coordinate_descent

Local

Original Haskell reference.

Python callable or constructor Result C wrapper
GoldenSection ScalarMethod hmath_optimization_golden_section_create
TernarySearch ScalarMethod hmath_optimization_ternary_search_create
BrentSearch ScalarMethod hmath_optimization_brent_search_create
minimize_scalar(method, options, objective, lower, upper) OptimizeResult hmath_optimization_minimize_scalar
BFGS QuasiNewton hmath_optimization_bfgs_create
DFP QuasiNewton hmath_optimization_dfp_create
SR1 QuasiNewton hmath_optimization_sr1_create
LBFGS(memory) QuasiNewton hmath_optimization_lbfgs_create
minimize_quasi_newton(method, options, objective, gradient, initial) OptimizeResult hmath_optimization_minimize_quasi_newton
Newton NewtonMethod hmath_optimization_newton_create
NewtonCG NewtonMethod hmath_optimization_newton_cg_create
TrustRegion(radius) NewtonMethod hmath_optimization_trust_region_create
Dogleg(radius) NewtonMethod hmath_optimization_dogleg_create
minimize_newton(method, options, objective, gradient, hessian, initial) OptimizeResult hmath_optimization_minimize_newton
nonlinear_cg(options, objective, gradient, initial) OptimizeResult hmath_optimization_nonlinear_cg
SquaredLoss Loss hmath_optimization_squared_loss_create
HuberLoss(scale) Loss hmath_optimization_huber_loss_create
CauchyLoss(scale) Loss hmath_optimization_cauchy_loss_create
SoftL1(scale) Loss hmath_optimization_soft_l1_create
least_squares(loss, damping, options, residual, jacobian, initial) OptimizeResult hmath_optimization_least_squares
nelder_mead(options, objective, initial) OptimizeResult hmath_optimization_nelder_mead
powell(initial_step, options, objective, initial) OptimizeResult hmath_optimization_powell

Constrained

Original Haskell reference.

Python callable or constructor Result C wrapper
Equality(objective, gradient) Constraint hmath_optimization_equality_create
LessEqual(objective, gradient) Constraint hmath_optimization_less_equal_create
feasibility(constraints, point) Double hmath_optimization_feasibility
QuadraticPenalty PenaltyMethod hmath_optimization_quadratic_penalty_create
LogBarrier PenaltyMethod hmath_optimization_log_barrier_create
InteriorPoint PenaltyMethod hmath_optimization_interior_point_create
AugmentedLagrangian PenaltyMethod hmath_optimization_augmented_lagrangian_create
constrained_minimize(method, options, objective, gradient, constraints, initial) OptimizeResult hmath_optimization_constrained_minimize
LPResult(point, value, basis, iterations) LPResult hmath_optimization_lp_result_create
linear_programming(budget, tolerance, cost, matrix, rhs) LPResult hmath_optimization_linear_programming
revised_simplex(budget, tolerance, cost, matrix, rhs, basis) LPResult hmath_optimization_revised_simplex
quadratic_programming(budget, tolerance, hessian, cost, matrix, rhs) OptimizeResult hmath_optimization_quadratic_programming
slsqp(options, objective, gradient, hessian, constraints, initial) OptimizeResult hmath_optimization_slsqp
cobyla(initial_radius, options, objective, constraints, initial) OptimizeResult hmath_optimization_cobyla
weighted_objective(weights, objectives) owned callable hmath_optimization_weighted_objective
pareto_front(points) list[int] hmath_optimization_pareto_front
lp_point(value) original field/helper value hmath_optimization_lp_point
lp_value(value) original field/helper value hmath_optimization_lp_value
lp_basis(value) original field/helper value hmath_optimization_lp_basis
lp_iterations(value) original field/helper value hmath_optimization_lp_iterations

Global

Original Haskell reference.

Python callable or constructor Result C wrapper
SimulatedAnnealing GlobalMethod hmath_optimization_simulated_annealing_create
DifferentialEvolution GlobalMethod hmath_optimization_differential_evolution_create
GeneticAlgorithm GlobalMethod hmath_optimization_genetic_algorithm_create
ParticleSwarm GlobalMethod hmath_optimization_particle_swarm_create
CMAES GlobalMethod hmath_optimization_cmaes_create
global_minimize(method, population_size, seed, options, bounds, objective) OptimizeResult hmath_optimization_global_minimize
basin_hopping(seed, temperature, hops, options, bounds, objective, initial) OptimizeResult hmath_optimization_basin_hopping