alphaFeedback

WorksMathematics

Branch-Extended Automatic Differentiation

AI contributions
  • AI agents
View details
Ancillary data
1 code link
View

Abstract

We present branch-extended automatic differentiation (BEAD), a software package that provides information about inactive branches of piecewise-differentiable functions, intended for use in nonsmooth optimization algorithms. BEAD is implemented in Python, building on the popular JAX framework. For supported nonsmooth operations such as abs and max, BEAD identifies alternative branches within tolerance from the given input, and computes gradients of the resulting branches extended to the given input. Such information has been previously used for robust optimization methods, but has required error-prone and tedious manual differentiation, unlike BEAD, which is fully automated for functions written in NumPy-like JAX code. Our experiments show that our approach is as accurate as manually written derivative code, and offers more flexibility in modifying the function and choosing between branch-discovery rules. While we were originally motivated by the manifold sampling algorithm for nonsmooth composite objectives, we also integrate BEAD branch-extension gradients into a nonsmooth BFGS-SQP solver. On two small nonsmooth test problems, the resulting path-aware search resolves failures or substantially reduces the number of evaluations required by the BFGS-SQP solver.

Introduction

Automatic differentiation (AD) applies the chain rule of calculus to functions expressed as computer programs and is a standard way to obtain derivatives without manually writing or maintaining separate derivative code [1]. For a smooth program, differentiating its execution trace produces the derivative of the represented function (with some caveats in the presence of roundoff, iterative solvers, and other implementation details, see [2] for an overview). Scientific codes, however, often involve continuous but nonsmooth operations such as an absolute value, a pointwise minimum or a pointwise maximum. When such operations appear as primitives in a function, the function typically becomes piecewise smooth; derivatives do not exist in the mathematical sense at inputs that lie exactly on a kink in the piecewise smooth structure. In a computer program, such nonexistence is often represented at a low abstraction level as a branch that switches control flow at such inputs. At higher abstraction levels, this nonexistence occurs at branch points, an intermediate (set of) value(s) at which a primitive enters one of several mathematically valid branches in defining the primal function.

As a motivating example of branches and branch points, consider an implementation of the maximum of two scalars aa and bb:

def max(a, b):
    if(a>=b) return a
    else return b

This code consistently returns aa when a=ba=b, an arbitrary branch: an equally valid implementation returns bb instead:

def max(a, b):
    if(a<=b) return b
    else return a

For every instance where the max primitive appears in a program, the forward execution consistently follows one of two branches. Conventional AD evaluates the derivative of the primal function determined by the corresponding execution trace. However, users of the derivative program, especially practitioners of optimization, may want information about alternative branches not taken by the implementation. We will clarify our intentions later, but note that the execution trace associated with alternative branches may have vastly different derivatives [3, 4]. A user may also want derivatives corresponding to alternative branches that were nearly followed within a prescribed tolerance; that is, for small eps>0\mathrm{eps}>0, replacing the first implementation of the max primitive with

def max(a, b):
    if(a + eps >=b) return a
    else return b

would have admitted an alternative branch for the same function input.

To overcome this limitation of conventional AD, we introduce branch-extended automatic differentiation (BEAD). At a given function input, BEAD records the branch taken at supported nonsmooth primitives such as abs and max, identifies alternative branches within a prescribed tolerance, and replays the program once per path through branches—an assignment of one branch at every branch point—thereby locking those branches. Each replay defines a smooth branch extension at the query input, differentiable by ordinary JAX AD [5]. The output is a set of branch-extension gradients rather than only the gradient of the default path. BEAD returns tolerance- and program-dependent branch-extension gradients; these need not form a classical generalized derivative, as discussed in § 2.2.

Our implementation and test cases are mostly motivated by manifold sampling, a derivative-free optimization method that relies on composite objective functions of a certain form, discussed further in § 2. However, BEAD’s applicability is not specific to composite objectives or derivative-free optimization, and we demonstrate some preliminary results with scalar-valued nonsmooth functions in the context of the constrained nonsmooth solver PyGRANSO [6, 7] in § 4.2. BEAD supports both local tolerances on intermediate values and input-scaled tolerances based on first-order input sensitivities, as described in § 3.2.

The contributions of this work are a record-and-replay formulation of BEAD, a JAX implementation for array operations that commonly appear in definitions of piecewise smooth functions, implementations of two branch-discovery rules, and an evaluation against manual implementations of branch-extension gradients from past work.

Background

We now review piecewise-smooth programs and existing generalized-derivative concepts. We then review BEAD’s connection to nonsmooth optimization methods.

Piecewise-smooth programs

A continuous piecewise-C1C^1 function is locally represented by finitely many smooth selection functions, with one or more selection functions active at a switching surface [8]. For input queries off the switching surfaces, ordinary AD of the execution trace returns the derivative of the locally unique selection function. For input queries on the switching surface, a single execution trace corresponds to only one selection function; it does not describe the other selection functions that determine nearby first-order behaviors of the piecewise-smooth function.

In related work, abs-normal form makes this switching structure explicit by representing piecewise-smooth functions using smooth operations connected by absolute-value switches [9]. It supports systematic piecewise-linearization and generalized algorithmic differentiation. BEAD is closely related but does not transform a function into abs-normal form, nor does it return a complete piecewise-linear local model of the function. Instead, it records the branch taken at each supported JAX primitive, identifies within-tolerance alternative branches, extends them to the current input, and applies ordinary AD to each, producing branch-extension values and gradients.

We list several other related works in piecewise-smooth programs here. Intensional derivatives formalize the derivatives computed by AD for piecewise-analytic programs and agree with ordinary derivatives almost everywhere [3]. Conservative fields provide a chain-rule-compatible set-valued calculus for broad classes of nonsmooth programs and support convergence analyses for stochastic-gradient methods [4, 10]. Automatic subdifferentiation seeks to compute a mathematically valid generalized subderivative for a qualified program [11]. These approaches primarily justify and select generalized derivative information, but do not provide information about alternative branches, which is required for robust nonsmooth optimization solvers that motivate this work.

Relationship to generalized derivatives

Several notions of generalized derivative exist [12, 13]. These generalized derivatives include Dini or Hadamard directional derivatives that describe a one-sided rate of change in a specified direction. The Bouligand, or B-, subdifferential ∂Bf(x)\partial_B f(x) collects limits of Jacobians from differentiable points in a neighborhood of a given point. For locally Lipschitz scalar functions, the Clarke subdifferential ∂Cf(x)\partial_C f(x) and Clarke generalized directional derivative represent the convex hull of limiting gradients and their support function, respectively. Convex subgradients are defined by global supporting inequalities for the epigraph of a convex function.

In general, BEAD computes none of these generalized derivatives. Given an input query xx, BEAD produces a finite set

Gτ(x)={∇fp(x):p∈Pτ(x)},\mathcal{G}_{\tau}(x) = \{\nabla f_p(x) : p \in\mathcal{P}_{\tau}(x)\},

where τ>0\tau> 0 is an absolute tolerance used in determining alternate branches, Pτ(x)\mathcal{P}_{\tau}(x) is the set of recorded paths through branches, and fpf_p is the branch extension obtained by locking path pp. The set Pτ(x)\mathcal{P}_{\tau}(x) depends on the program, supported primitives, and tolerance strategy. § 3.3 gives theoretical conditions under which G0(x)\mathcal{G}_0(x) contains ∂Bf(x)\partial_B f(x).

Moreover, with a positive tolerance τ>0\tau> 0, inactive smooth extensions are deliberately included in Pτ(x)\mathcal{P}_{\tau}(x), and so it is generally not the case when τ>0\tau> 0 that Gτ(x)\mathcal{G}_{\tau}(x) coincides with any of these generalized derivatives.

Another related approach is lexicographic differentiation [14], which computes directional derivatives for a provided sequence of infinitesimal perturbations. Lexicographic differentiation has been employed to find solutions of both systems of nonsmooth equations and parametric differential equations [15]. The directional nature of lexicographic differentiation distinguishes it from BEAD, which instead discovers a set of paths according to a finite tolerance and differentiates each corresponding branch extension separately.

Relationship to nonsmooth optimization methods

Various methods have been proposed for the solution of nonsmooth optimization problems, that is, optimization problems for which the objective function and possibly some constraints are nonsmooth functions of their inputs. The most robust of these methods generally employ a generalized derivative at points of nondifferentiability, or else construct approximations of generalized derivatives from conventional gradients at slightly perturbed points in neighborhoods of points of nondifferentiability. Bundle methods [16, 17, 18] use subgradients at various query points in the optimization domain to build and update cutting-plane models of objectives and constraints. Gradient sampling methods [19, 20] evaluate conventional gradients at randomly sampled points of differentiability near a given input and computes the gradients’ convex hull to approximate a Clarke subdifferential.

In contrast to the mechanisms of bundle methods and gradient sampling methods, both of which aggregate (sub)gradient information across multiple input points, BEAD considers a single input point and differentiates branch extensions identified from program structure. This mode of computation is particularly useful within the paradigm of manifold sampling [21, 22, 23, 24], which seeks to identify (a subset of) active manifolds defining a continuous selection at any given incumbent. Our motivating manifold-sampling problems have the composite form

minimize⁡x∈Rnf(x)=h(F(x)),(1)\begin{aligned} \underset{x\in\mathbb{R}^{n}}{\operatorname{minimize}}\quad f(x) &= h(F(x)), \tag*{(1)} \end{aligned}

where F:Rn→RpF:\mathbb{R}^{n}\to\mathbb{R}^{p} is expensive to evaluate and h:Rp→Rh:\mathbb{R}^{p}\to\mathbb{R} is a known, possibly nonsmooth scalar mapping. Manifold sampling builds separate models of the components of FF and uses values and gradients associated with active manifolds of hh; “activity” here generally corresponds to branch extensions. BEAD automates the path-identification and differentiation interface required by manifold sampling methods. We discuss benchmark problems further in § 4.

However, BEAD can be applied beyond manifold sampling methods. As a particular example, a finite BEAD set GT(x)\mathcal{G}_{\mathcal{T}}(x) can be employed to construct a cutting-plane model that would appear in a bundle method. The downstream bundle method may minimize the support function max⁡g∈GT(x)gTd\max_{g\in\mathcal{G}_{\mathcal{T}}(x)}g^{T}d when choosing a direction for use in a line-search or in a trust-region subproblem. This use case does not require a decomposition f=h∘Ff=h\circ F like manifold sampling is designed to exploit; instead, BEAD can be applied directly to a piecewise-smooth function and generate BEAD sets of practical utility.

Implementation

We now BEAD’s record-and-replay execution model, its branch-discovery rules, batched and compiled replay, and its user-facing API.

Design and execution model

BEAD is implemented as a Python package built on JAX [5]. BEAD does not replace or modify JAX’s differentiation machinery in any significant way. Instead, BEAD changes the behavior of the forward pass, generating multiple branch extensions that can then be differentiated normally. User code defining the primal function must import a NumPy-like wrapper module for a set of supported nonsmooth operations, as well as jax.numpy in order to define smooth operations.

A recording pass executes the user’s primal function once. At each supported nonsmooth primitive, BEAD records the executed branch and identifies alternative branches that are within a specified tolerance, to be defined in § 3.2. The implementation of BEAD distinguishes several types of primitives. Reduction extrema primitives, such as min and max, produce a scalar output and record the selected index together with other indices within tolerance of the extreme. A unary elementwise primitive, such as abs, records a sign branch at entries within tolerance of zero. Binary elementwise extrema primitives, such as minimum and maximum, record an operand branch at each array index. These branches are stored in small typed records and can have large downstream effects: elementwise primitives can induce exponentially many branch combinations when many entries are within tolerance simultaneously, whereas reduction extrema primitives produce a number of branches that grows, at most, linearly in the size of the input vector. These combinatorial issues should be taken into account when designing primal functions.

The recorded branches, that is the executed branches and alternative branches within tolerance taken together, define a PathSet. A single resolved path through branches within a PathSet fixes one branch at every branch point in the program; downstream code can refer to it by a path label string. The number of paths in a PathSet is generally exponential in the number of branch points that admit within-tolerance alternatives for a given input. To avoid instantiating an exponential number of paths in memory whenever possible, our implementation uniquely identifies each path by a single integer, which represents the position of that path in a sequence defined by the Cartesian product of the branches available at each branch point encountered in a program. A PathSet by default therefore only needs to store the available branches at each branch point separately, as opposed to storing all possible combinations.

PathSet objects also support set operations such as union and intersection. Such operations may destroy the Cartesian-product structure, in which case BEAD stores an explicit list of paths. Whether stored compactly or explicitly, evaluating every path requires work proportional to the number of paths, which is exponential in the number of branch points that admit alternatives within tolerance. Thus, users of BEAD may need to control the runtime or memory use of this approach either by judiciously reducing the tolerance or designing their problem in a way that ensures that the number of alternatives is sufficiently bounded. Future work might investigate, for example, automatic sampling strategies in BEAD in order to limit resource use when user-controlled remedies are apparently insufficient.

A replay pass executes the user program using the branches fixed by one resolved path in a PathSet. Thus, a replay pass changes the forward values produced by the supported nonsmooth primitives. Once those branches are locked, the replay pass is an ordinary smooth JAX program for that branch extension, wherever its elementary operations are smooth. BEAD can consequently apply jax.grad or jax.value_and_grad directly to the replayed function. In particular, BEAD does not implement a separate reverse pass or a custom derivative rule for each composite nonsmooth function; by changing the forward branches, JAX may compute the derivative of that branch extension automatically.

Figure 1 summarizes this execution model. Branch discovery is performed during forward execution, while each replay is an ordinary JAX computation that can be differentiated and compiled.

Record–replay example

Figure 1. Record–replay example. Recording identifies branches within tolerance at a maximum and an absolute value, producing four paths. Replaying the highlighted path replaces the original forward computation by fp4=g2−hf_{p_4}=g_2-h, after which ordinary JAX automatic differentiation returns the value and gradient of that branch extension. Multiple resolved paths can be evaluated by the compiled pipeline.

Branch discovery and path-set growth

Branch discovery is controlled by absolute and relative tolerances. We propose two explicit rules for branch discovery employing these tolerances. Every supported primitive has an associated scalar switching condition qq, computed from the intermediate value(s) that primitive takes. The sign of qq determines the branch taken at that branch point. For example, abs switches on the sign of its single input, while maximum switches on the sign of the difference between its two operands. BEAD applies each primitive’s qq consistently during both recording and replay of branches. Because each branch point is tested independently, a combination of branches recorded in Pτ(x)P_\tau(x) need not correspond to any single, jointly reachable input perturbation; the path set could include branches that can’t be reached by any nearby input; Theorem 3.2 is a small instance. The local branch-discovery rule admits the alternative branch when ∣q∣|q| is below a tolerance expressed in the units of that intermediate quantity. We implement such a rule as

∣q∣≤atol+rtol∣v∣,|q| \le\mathrm{atol}+\mathrm{rtol}|v|,

where vv is an operation-specific scale: the selected extremum for a reduction, the larger-magnitude operand for a binary extremum, and the input to an absolute value.

Such a test is generally inexpensive and easy to implement, but may not always behave in a way that is intuitive to a user; intermediate values and their sensitivity to function input perturbations may have vastly different scales from one another. As an alternative, it may be more intuitive to ask whether perturbing the function input within some small tolerance could flip the sign of qq. In other words, we search for alternative program paths that would be taken for some input within a small neighborhood around the current function input xx. Exact propagation of such a neighborhood through a nonlinear program, however, is a challenging problem. Interval methods can propagate bounds through a program, but may overestimate reachable ranges. Taylor models retain higher-order information at greater cost [25, 26].

Noting these challenges, BEAD employs an input-scaled branch-discovery rule to serve as a first-order approximation to the propagation of a neighborhood through a nonlinear program. Because qq is computed from the function input xx through the forward pass, it can be viewed as a scalar function q(x)q(x) of xx, with switching surface {x:q(x)=0}\{x : q(x) = 0\}. For an input ball ∥δ∥≤τ\lVert\delta\rVert\le\tau, the first-order range of the switching quantity is controlled by τ∥∇q(x)∥∗\tau\lVert\nabla q(x)\rVert_\ast, where ∥⋅∥∗\lVert\cdot\rVert_\ast is the dual norm. Forward-mode AD propagates input sensitivities through the program; BEAD uses the resulting magnitudes to estimate this scale and adjust the local tolerance. The sensitivities only guide branch discovery; replay gradients are still computed by ordinary JAX AD. This sensitivity-based approximation does not provide any strong bounds, as it deliberately neglects higher-order effects for nonlinear functions. Like the local rule, the input-scaled rule is a practical branch-discovery rule and generally does not correspond precisely to a generalized derivative.

Nonetheless, the first-order input-scaled rule corrects two failure modes of the local rule in the linear examples below. More generally, if qq has an LL-Lipschitz gradient on the input ball, then

q(x+δ)=q(x)+∇q(x)Tδ+R(δ),∣R(δ)∣≤L2∥δ∥2.q(x+\delta)=q(x)+\nabla q(x)^{T}\delta+R(\delta), \qquad\lvert R(\delta)\rvert\le\frac{L}{2}\lVert\delta\rVert^{2}.

The input-scaled rule models the linear term and neglects the remainder. If the switching quantity q(x)q(x) contracts input perturbations, the local rule may admit a branch whose switching surface is outside the input ball. If q(x)q(x) expands input perturbations, the local rule may reject a branch whose switching surface lies inside the ball. The input-scaled rule corrects both decisions for these linear examples. We illustrate an example of these behaviors in Figure 2.

Local and input-scaled branch discovery for two scalar linear switching quantities

Figure 2. Local and input-scaled branch discovery for two scalar linear switching quantities, using atol =τ=0.1=\tau=0.1 and rtol =0=0. In panel (a), contraction makes the local rule include an alternative whose switching point is outside the input ball. In panel (b), expansion makes the local rule miss an alternative whose switching point is inside the input ball. Scaling by ∣q′(x0)∣|q'(x_0)| gives the correct first-order decision in both examples because xx is scalar and the input norm is absolute value.

As an example of the mitigation strategies mentioned above, we present a policy specific to the abs function applied entrywise to a vector. When the vector contains kk entries that are near zero within tolerance, there are 2k2^k recorded paths, enumerated by a kk-fold Cartesian product of sign branches ±\pm. Naively, one could employ a policy, called via abs_policy="enumerate" in BEAD, that causes BEAD to record both signs ±\pm for each ambiguous entry. However, with the default abs_policy="zero", BEAD instead retains one compact representative branch whose recorded value is simply the absolute value, and the associated derivative is taken at zero at any ambiguous entry within tolerance τ\tau. This zero is not one of the two one-sided derivatives ±1\pm1 of abs; rather, it is the minimum-norm element of its Clarke subdifferential [−1,1][-1,1] at a tie, the standard representative when a single (sub)gradient is required, for example in a stationarity measure. The default policy avoids 2k2^k recorded paths in favor of one path, at the expense of a less informative Gτ(x)\mathcal{G}_{\tau}(x).

The absolute-value policy separates three decisions: which alternatives are discovered, how they are represented, and which resolved paths are evaluated. Other primitives with many within-tolerance alternatives could make the same separation; discovery, representation, and evaluation need not all be exhaustive. Future work involves topics such as lazy path generation, sampling, limits on retained paths, removal of duplicate or nearly identical gradients, compact representations of independent or convex derivative sets, and optimizer-guided selection of paths relevant to a search direction. Such policies should be studied in terms of downstream accuracy (e.g., in stationarity tests or optimization search directions), memory use, and runtime. Currently, abs is the only primitive that has such a policy implemented in BEAD, because other primitives did not demonstrate path-set explosion in our tests. Future work will study similar policies, for example, for the maximum and minimum primitive. These primitives in particular exhibit an explosion in the size of discovered path-sets when two compared input vectors have many indices that are equal in value or nearly equal in value.

Generalized derivatives at zero tolerance

We consider the special case of Gτ(x)G_\tau(x) where τ=0\tau=0. Every recorded path in P0(x)P_0(x) fixes one branch at each branch point, and so defines a smooth branch extension fpf_p that agrees with ff at xx. These branch extensions are selection functions in the sense of Scholtes [8]. To formalize a result about G0(x)G_0(x), we call a path (selection function) p∈P0(x)p\in P_0(x) essentially active if xx lies in the closure of the interior of {y:f(y)=fp(y)}\{y:f(y)=f_p(y)\}.

Proposition 3.1. Let every operation in the program defining ff be either continuously differentiable or else a supported nonsmooth primitive. Suppose branch discovery with τ=0\tau=0 successfully records all alternative branches at every branch point. That is, branch discovery records every branch that the program can execute at inputs arbitrarily close to xx. Suppose further that P0(x)P_0(x) is the Cartesian product of the recorded branches, every path of which is evaluated. Then

∂Bf(x)⊆G0(x)and∂Cf(x)⊆conv⁡G0(x),(2)\partial_B f(x) \subseteq G_0(x) \quad\text{and}\quad\partial_C f(x) \subseteq\operatorname{conv} G_0(x), \tag*{(2)}

and equality holds in the first inclusion if and only if every p∈P0(x)p\in P_0(x) satisfies ∇fp(x)=∇fp′(x)\nabla f_p(x)=\nabla f_{p'}(x) for some essentially active p′∈P0(x)p'\in P_0(x). In that case, equality holds in the second inclusion as well.

Proof. A recorded path fixes a branch at every branch point, so each fpf_p is a composition of continuously differentiable operations and is C1C^1 in some open neighborhood of xx. Let U1U_1 be the intersection of these finitely many neighborhoods.

We will show that ff is a selection of the family {fp}\{f_p\} near xx. Consider the execution of the program defining ff. At any branch point whose switching quantity qq is nonzero at the intermediate values entering the branch point (call these values v(x)v(x)), the same branch is executed for all values in an open neighborhood of v(x)v(x). By continuity of ff, this means the same branch will be executed for all yy in some open neighborhood of xx. Denote the intersection of these finitely many (corresponding to each branch point with nonzero intermediate values) open sets by U2U_2. On the other hand, at any branch point whose switching quantity qq vanishes at v(x)v(x), every alternative is recorded by assumption. Consider the open set U:=U1∩U2U := U_1 \cap U_2. We have both that x∈Ux \in U and for every y∈Uy \in U, the branches executed by the program at yy belong to some path p∈P0(x)p \in P_0(x), that is, f(y)=fp(y)f(y) = f_p(y). Thus ff is a continuous selection of the finite family of C1C^1 functions {fp}p∈P0(x)\{f_p\}_{p\in P_0(x)} on UU.

[8 Prop. 4.3.1] gives that ∂Bf(x)\partial_B f(x) is the set of gradients at xx of the essentially active members of this family, and that ∂Cf(x)\partial_C f(x) is its convex hull. Because every path in the full product is evaluated, G0(x)={∇fp(x):p∈P0(x)}G_0(x) = \{\nabla f_p(x) : p \in P_0(x)\}, which contains the gradients of the essentially active paths. This is the first inclusion in (2); taking convex hulls gives the second. Finally, G0(x)=∂Bf(x)G_0(x) = \partial_B f(x) exactly when every ∇fp(x)\nabla f_p(x) equals the gradient of some essentially active path, which is the stated criterion. Equality of the sets implies equality of their convex hulls. □

The following simple one-dimensional example shows the hypotheses of Theorem 3.1 can hold while equality in eq. (2) fails.

Example 3.2. For f(t)=t+max⁡{t,0}−max⁡{t,0}≡tf(t) = t + \max\{t, 0\} - \max\{t, 0\} \equiv t the two maxima form independent branch points in the program. Differentiating the four resulting paths gives G0(0)={0,1,2}G_0(0) = \{0, 1, 2\} against ∂Bf(0)={1}\partial_B f(0) = \{1\}. Here 0∈conv⁡G0(0)0 \in\operatorname{conv} G_0(0), so a method measuring stationarity by dist⁡(0,conv⁡G0(x))\operatorname{dist}(0, \operatorname{conv} G_0(x)) would report x=0x = 0 as stationary.

The hypotheses of Theorem 3.1 hold in BEAD when atol=rtol=0, tol_mode="local", and abs_policy="enumerate". With the default abs_policy="zero", they fail: G0(0)={0}G_0(0) = \{0\} for f(t)=∣t∣f(t) = |t|, against ∂Bf(0)={−1,1}\partial_B f(0) = \{-1, 1\}. The guarantees of Theorem 3.1 also fail for τ>0\tau> 0: a recorded branch need no longer agree with any executed branch at xx, and so fp(x)≠f(x)f_p(x) \ne f(x) is possible; the extensions then no longer form a selection family for ff.

Note that BEAD does not test essential activity, which Theorem 3.1 requires. For programs built from smooth operations and absolute values, the linear independence kink qualification (LIKQ) of abs-normal form [27 Def. 2] is a sufficient condition: under it, every sign combination at the active switches is realized on a set of positive measure [28 Cor. 7], so every recorded path is essentially active and equality holds in (2).

Batched and compiled replay

JAX supports JIT (just-in-time) compilation to accelerate the execution speed of functions and their gradient computation. JIT compilation introduces a tradeoff. The first call to JAX incurs tracing and compilation costs, whereas later calls can reuse the compiled program and avoid repeated Python dispatch. JAX usually needs to re-compile programs when their control flow or certain array dimensions change. To avoid frequent recompilations during the interactions of an optimization method with BEAD, our implementation pads the size of some data structures to the next power of two and removes padded results afterward. This performs some unused work but reduces the number of compiled batch shapes. Compiled replay functions are cached by the user function, operation layout, differentiated arguments, and auxiliary-output option. This optimization generally reduces replay overhead but is independent of the possibly combinatorial enumeration of recorded paths.

We call a collection of resolved paths that are evaluated together a path batch; a path batch is evaluated in batched replay. For a collection of paths with the same sequence of branch points, BEAD first validates their structure and converts their corresponding branches into dense JAX arrays. BEAD then applies jax.value_and_grad to one replay, uses jax.vmap to evaluate the resolved paths together, and applies jax.jit to compile the vectorized calculation.

User-facing API

The public interface follows JAX’s functional-transformation style. That is, each BEAD transformation accepts a Python function and returns a callable with the same user arguments. Supported nonsmooth operations are written using branch_extended_AD.numpy; smooth operations may use jax.numpy. Table 1 summarizes the layers of the API.

User goalTransformation
Discover within-tolerance pathsrecord
Evaluate one resolved pathreplay
Differentiate the default pathgrad, value_and_grad
Differentiate one resolved pathreplay_grad, replay_value_and_grad
Differentiate all discovered pathsall_value_and_grad
Evaluate known paths in one compiled callreplay_value_and_grad_batch

Table 1. Main BEAD transformations.

Listing 1 provides a demonstration of recording and replay. A recording pass returns the value for the default path along with a PathSet. Replay accepts one resolved path and returns the corresponding branch-extension value.

Listing 1: Recording and replaying within-tolerance paths.

import jax.numpy as jnp
import branch_extended_AD as bead
import branch_extended_AD.numpy as bnp

def h(z):
    return bnp.sum(bnp.maximum(z, 0.0))

z = jnp.array([0.0, 1.0, -2.0])
value, paths = bead.record(h, atol=1.0e-8)(z)

for path in paths:
    locked_value = bead.replay(h, path)(z)

Derivative transformations use the same path objects. The default path routines return the default-path derivative together with the paths discovered at the provided input. Replay routines evaluate one known path. When every recorded path is required, all_value_and_grad performs discovery and replay in one call.

Listing 2: Computing branch-extension gradients from resolved paths.

(value, default_grad), paths = bead.value_and_grad(h, atol=1.0e-8)(z)
branch_data = [bead.replay_value_and_grad(h, path)(z) for path in paths]
all_branch_data, paths = bead.all_value_and_grad(h, atol=1.0e-8)(z)

The options atol, rtol, tol_mode, and abs_policy dictate the scope of branch discovery. The options argnums and has_aux follow the corresponding JAX transformations. If a user employing BEAD has already collected resolved paths, they may use replay_value_and_grad_batch to evaluate the same resolved paths through the compiled batched replay rather than needing to rediscover them.

Test cases

We now discuss several use cases designed to probe the capabilities of BEAD, and note the capabilities’ alignment with our design intentions.

Manifold sampling

All manifold-sampling test cases use the composite form (1). A traditional derivative-free method will generally build and maintain one surrogate mfm_f to model the full objective f=h∘Ff = h \circ F. Manifold sampling instead builds and maintains separate models m1,…,mpm_1,\ldots,m_p, aggregated in the vector-valued model mFm_F, for the components F1,…,FpF_1,\ldots,F_p of FF and combines these pp models using the known structure of hh. The componentwise construction h∘mFh \circ m_F often provides a more accurate local model of ff than mfm_f.

When hh is nonsmooth, a manifold sampling method requires both function value and gradients for its active manifolds. For a rigorous definition of active manifold, we refer the reader again to [21, 22, 23, 24]. As a motivating example of the definition for the sake of understanding, for h(z)=∥z∥1h(z) = \lVert z\rVert_1, manifold identification reduces to labeling the signs of the entries of F(x)F(x). For a more complicated mapping, such as the censored-ℓ1\ell_1 loss

h(F(x))=∑i=1p∣di−max⁡{Fi(x),ci}∣,h(F(x)) = \sum_{i=1}^{p} \lvert d_i - \max\{F_i(x),c_i\}\rvert,

manual identification and differentiation are substantially more involved. BEAD automates this problem-specific work and reduces the risk of errors.

To test whether our AD-encoded hh functions are correct, we needed a test suite broad enough to exercise BEAD’s various tolerances and branch discovery policies. Rather than hand-selecting a handful of problem/hh combinations, we ran every smooth vector-valued function FF from a benchmark set against every hh we had previously hand-coded in the IBCDFO package [29].

For FF, we use the full set of 53 test problems from the Moré–Wild DFO benchmark collection [30]; problems include a reference starting point x0x_0. These problems span a low range of dimensions (2≤n≤12)(2 \le n \le12) and output dimensions 2≤p≤452 \le p \le45. The Moré–Wild benchmark is intentionally small in scale, because it is intended to represent the types of problems typically encountered in simulation-based optimization, where FF is very expensive to evaluate and so a single simplex gradient approximation (requiring n+1n+1 function evaluations) is cost-prohibitive.

As for hh, to really test the capabilities of BEAD, we defined nine different hh functions, listed in Table 2. For many of these hh functions (e.g., piecewise min/max functions) optimization regularly encounters points of nondifferentiability, making branch discovery of critical importance. Other hh functions (e.g., the piecewise-quadratic and censored-ℓ1\ell_1 losses) are compositions with so many branching locations that hand-differentiation can be impractical and error-prone.

NameFormula
one_normh(z)=∑i=1p∣zi∣h(z)=\sum_{i=1}^{p}|z_i|
pw_maximumh(z)=max⁡{z1,…,zp}h(z)=\max\{z_1,\ldots,z_p\}
pw_maximum_sqh(z)=max⁡{z12,…,zp2}h(z)=\max\{z_1^2,\ldots,z_p^2\}
pw_minimumh(z)=min⁡{z1,…,zp}h(z)=\min\{z_1,\ldots,z_p\}
pw_minimum_sqh(z)=min⁡{z12,…,zp2}h(z)=\min\{z_1^2,\ldots,z_p^2\}
quantileqq-th quantile of {z12,…,zp2}\{z_1^2,\ldots,z_p^2\}
max_plus_qvpmax⁡{z1,…,zp−1}+α∑i≥pmax⁡{zi,0}2\max\{z_1,\ldots,z_{p-1}\}+\alpha\sum_{i\geq p}\max\{z_i,0\}^2
censored_L1_lossh(z;c,d)=∑i=1p∣di−max⁡(zi,ci)∣h(z;c,d)=\sum_{i=1}^{p}|d_i-\max(z_i,c_i)|
piecewise_quadratich(z;Qj,zj,cj)=max⁡j{∥z−zj∥Qj2+cj}h(z;Q_j,z_j,c_j)=\max_j\left\{\lVert z-z_j\rVert_{Q_j}^2+c_j\right\}

Table 2. The nine hh functions used in the benchmark, each applied to z=F(x)∈Rpz=F(x)\in\mathbb{R}^p.

Two of the hh functions in Table 2 deserve discussion. In our tests, h_quantile is hardcoded to q=1q = 1, which makes it functionally identical to h_pw_minimum_squared; we therefore exclude h_quantile from the counted instances below to avoid redundancies. We keep h_quantile in Table 2 only to document the general quantile-based hh function.

Similarly, h_max_plus_quadratic_violation_penalty has its penalty weight α\alpha hardcoded to 0, and so it reduces to h_pw_maximum restricted to the first p−1p-1 components; we choose to keep this h(z)h(z) in the test set (and in the instance count) because it exercises a different code path even though its values coincide with h_pw_maximum.

The last two entries in Table 2 are not fixed functions but function factories: create_censored_L1_loss_hfun builds a one-sided censored ℓ1\ell_1 loss from problem-specific data (c,d)(c,d), following Womersley’s censored discrete linear ℓ1\ell_1 approximation setup [31], and create_piecewise_quadratic_hfun builds a max-of-quadratics surrogate from problem-specific (Qj,zj,cj)(Q_j,z_j,c_j) triples, as used in [23]. For both, we reuse the exact problem data that accompanied those papers’ own benchmark studies (the first random instance/seed for each of the 53 problems), rather than generating our own. This yields 53×8=42453\times8=424 benchmark problem instances.

Finally, we comment that many of these hh functions are unbounded for many of the FF instances on an unconstrained domain. For example, h(z)=min⁡{z1,…,zp}h(z)=\min\{z_1,\ldots,z_p\} composed with an unconstrained FF has no finite lower bound. To address this, we impose box constraints ℓ≤x≤u\ell\leq x\leq u around x0x_0 for all problems. We employ a simple, deterministic box centered at x0x_0, with a per-coordinate radius of

ri=max⁡(20,2∣x0,i∣),r_i=\max(20,2|x_{0,i}|),

so ℓi=x0,i−ri\ell_i=x_{0,i}-r_i and ui=x0,i+riu_i=x_{0,i}+r_i. The max with 20 matters because several Moré–Wild starting points have components at or near 0, and so a purely multiplicative radius would collapse to (almost) zero; scaling by ∣x0,i∣|x_{0,i}| matters because other starting points have components in the thousands, where a fixed radius would be far too tight to let a solver explore the domain. The function FF is not defined for all values in the above box-constrained domain. We observed overflows in FF for Meyer’s function (corresponding to problem 17) and Osborne’s second function (problems 36 and 37). For these three problems, we use a tighter box (ri=max⁡(5,∣x0,i∣)r_i=\max(5,|x_{0,i}|)) to guarantee that FF stays finite, instead of employing the radius we prescribed above.

For the IBCDFO test cases, we created an integration module that wraps the BEAD interface and adapts values, gradient matrices, and path labels to IBCDFO’s existing hh-function interface. The PyGRANSO experiments in the following Section use a similar adapter.

Other nonsmooth optimization methods

To verify that BEAD is useful beyond manifold sampling and the explicit composition h(F(x))h(F(x)), we also coupled its branch-extension gradients to PyGRANSO, a BFGS–SQP method for general nonsmooth constrained optimization from the NCVX software package [6, 7]. We replaced the single-gradient term in the local search model by the support function of the BEAD gradient set and used the corresponding worst-case directional derivative in the weak-Wolfe line search. We retained the original BFGS-SQP method as a baseline and also tested an intermediate variant that used BEAD gradients only in the stationarity test.

We used two small problems for which all within-tolerance paths can be enumerated. The first is the constrained nonsmooth Rosenbrock example

min⁡x1,x28∣x12−x2∣+(1−x1)2s.t.2x1≤1,2x2≤1,\min_{x_1,x_2} 8\lvert x_1^2-x_2\rvert+ (1-x_1)^2 \quad\text{s.t.}\quad\sqrt{2}x_1 \le1,\quad2x_2 \le1,

initialized at the infeasible kink (1,1)(1,1). Both the baseline BFGS-SQP method and the stationarity-only variant failed before accepting an iterate. Our extension employing BEAD gradients reached a feasible stationary point in 18 iterations and 42 function evaluations.

As a second example, we consider a three-variable one-dimensional total-variation denoising problem (the fused-lasso signal approximator)

min⁡x∑i=13(xi−bi)2+43∑i=12∣xi+1−xi∣,b=(0,2,0).\min_x \sum_{i=1}^{3}(x_i-b_i)^2+\frac{4}{3}\sum_{i=1}^{2}\lvert x_{i+1}-x_i\rvert,\quad b=(0,2,0).

Starting from (1,1,1)(1,1,1), the baseline required 15 iterations and 67 evaluations to terminate at a point near the solution (2/3,2/3,2/3)(2/3,2/3,2/3), using BEAD only for stationarity required 15 iterations and 43 evaluations, and our variant of the method required one iteration and three evaluations. This behavior can likely be explained by the structure of the problem; the initial point is already on the same manifold as the solution to the optimization problem, on which the selection function corresponding to the recorded path is quadratic. These two problems illustrate how BEAD’s path and branch-extension information ports to a general nonsmooth solver; with only two problems, they are meant to be illustrative and we do not claim they provide a broad performance comparison between the baseline and BEAD-based variants.

Results

We now compare BEAD against hand-coded derivatives to see understand how it affects optimizer performance and then study its runtime.

Hand-coded versus BEAD hh functions

As a direct consistency check, the automated gamma-example test compares function values and gradient matrices at generic and tie inputs using relative tolerance 10−610^{-6} and absolute tolerance 10−810^{-8}. The full benchmark below provides a broader downstream comparison across all eight pairs of hh functions. The remaining question is whether this equivalence translates to downstream performance: does employing BEAD hh functions in a manifold sampling algorithm, instead of the hand-coded ones, change the behavior of the optimization method significantly? We ran every (problem,h)(\text{problem},h) pair from the previous subsection twice – once with each version of hh – through the same manifold sampling solver, and compared the results using data profiles [30].

A data profile plots, for each solver, the fraction of problems solved as a function of computational budget, measured in simplex gradients (i.e., groups of n+1n+1 function evaluations, where nn is the number of variables for a given problem). We consider a problem instance to be solved after kk evaluations when the objective value f(xk)f(x_k) first satisfies

f(xk)≤fbest+κ(f(x0)−fbest),f(x_k) \le f_{\mathrm{best}} + \kappa\left(f(x_0) - f_{\mathrm{best}}\right),

where f(x0)f(x_0) is the starting value, fbestf_{\mathrm{best}} is the smallest objective value found by any solver on that instance across all evaluations, and κ>0\kappa> 0 is the convergence gate; gate governs the quality of the final optimizer result, while tolerance governs the proximity of input or intermediate values that determines which branches are taken during function evaluation. The gate is a purely function-value-based criterion, measuring how close each solver comes to the best observed value, and can be computed without gradient information.

In these experiments we use the local branch-discovery rule with rtol = 0, so the reported τ\tau values are the API parameter atol, the absolute tolerance controlling which alternative branches are considered. We investigated three values: τ=10−8\tau= 10^{-8} (our baseline, the tightest), 10−610^{-6} (looser), and 10−410^{-4} (much looser). This parameter directly affects BEAD’s runtime, because a looser tolerance means BEAD must track more within-tolerance paths. The set of discovered paths also affects the downstream optimizer behavior in a problem-dependent and scale-dependent way. A good choice of τ\tau is therefore specific to hh and to how hh is implemented; the three values with which we experiment are chosen to illustrate this sensitivity, not to prescribe a general value of τ\tau useful for all imaginable hh functions.

Figure 3 shows data profiles across all three tolerance values and both convergence gates. At the loose gate κ=10−3\kappa= 10^{-3} (panel (d)), the two curves are visually indistinguishable regardless of τ\tau, solving about 93% of the 424 problem instances within the iteration budget; the three tolerance settings produce essentially the same profile, so only one representative is shown. At the tighter gate κ=10−7\kappa= 10^{-7} (panels (a)–(c)), differences become visible: at τ=10−8\tau= 10^{-8}, BEAD and hand-coded performance are comparable; as τ\tau is loosened, the BEAD curve drops below hand-coded, reflecting the looser branch-discovery tolerance. Hand-coded performance is largely insensitive to τ\tau across this range.

Figure 3. Data profiles comparing hand-coded (solid blue) and BEAD (dashed red) hh functions across all 424 (problem, hh) instances. (a)–(c) Tight convergence gate κ=10−7\kappa= 10^{-7} at branch-discovery tolerances τ=10−8\tau= 10^{-8}, 10−610^{-6}, and 10−410^{-4}, respectively. (d) Loose gate κ=10−3\kappa= 10^{-3}: the profiles are indistinguishable across all three τ\tau values, so a single representative is shown.

The end result is that replacing a hand-derived hh with its BEAD counterpart does not meaningfully degrade the performance of manifold sampling at the loose gate or at our tightest tolerance τ=10−8\tau= 10^{-8}; performance degrades mildly at the tightest gate as τ\tau is loosened, but mirrors the coarser branch-discovery tolerance. This robustness check supports using automatically generated BEAD path and branch-extension gradient information in place of hand-coded derivatives.

Timing

In this section, we evaluate the runtime of BEAD, compared with the hand-coded gradients. BEAD’s branch discovery incurs bookkeeping overhead in each evaluation, and its current implementation records branches on every call rather than compiling it once with JAX’s JIT.

Table 3 reports the median wall-clock time per function evaluation for each hh, across three values of the branch-discovery tolerance τ\tau. Both hand-coded and BEAD derivatives are run at the same matched τ\tau in each column group, and all timings are restricted to runs that terminated normally (ran the full evaluation budget) for both versions, so the comparison is over the same amount of work.

hh functionτ=10−8\tau= 10^{-8} handτ=10−8\tau= 10^{-8} BEADτ=10−8\tau= 10^{-8} ratioτ=10−6\tau= 10^{-6} handτ=10−6\tau= 10^{-6} BEADτ=10−6\tau= 10^{-6} ratioτ=10−4\tau= 10^{-4} handτ=10−4\tau= 10^{-4} BEADτ=10−4\tau= 10^{-4} ratio
censored_L1_loss9.6635.743.707.3140.865.5914.6035.972.46
piecewise_quadratic7.9425.163.1713.1624.531.865.8433.105.67
max_plus_qvp7.7430.393.937.8134.124.377.1730.924.31
one_norm11.2630.072.6713.7538.222.7815.7445.242.87
pw_maximum7.0223.293.317.7225.103.257.0830.084.25
pw_maximum_sq8.5624.002.808.6529.113.366.9736.155.18
pw_minimum4.2915.293.566.2920.883.323.0025.568.53
pw_minimum_sq5.0718.113.575.5522.614.074.0526.066.43
overall (median)7.8424.583.147.7627.113.497.0332.014.56

Table 3. Median wall-clock time per function evaluation (ms), hand-coded vs. BEAD hh functions, across all dfo rows with normal termination, at matched branch-discovery tolerance τ\tau.

At τ=10−8\tau= 10^{-8}, the BEAD derivative is slower than the hand-coded derivative by a median factor of about 3×3\times. As τ\tau is loosened from 10−810^{-8} to 10−610^{-6} to 10−410^{-4}, the median ratio increases (3.1×→3.5×→4.6×3.1\times\rightarrow3.5\times\rightarrow4.6\times). Both implementations may return more gradients at looser tolerances, but their work differs: the hand-coded routines construct gradient columns directly, whereas BEAD records additional paths and replays each branch extension through JAX AD. The table shows that hand-coded median times remain comparatively stable while BEAD times increase. In the simulation-based optimization settings this benchmark represents (§ 4), FF is far more expensive to evaluate than any computation of derivatives of paths through hh and so this overhead is negligible.

Conclusions

We introduced BEAD, a Python package that collects gradient information for a set of paths through programs describing piecewise-differentiable functions evaluated at or near kinks. The package uses JAX, a popular Python framework, for the differentiation of each individual path.

We demonstrate the usefulness of BEAD on two benchmarks: a manifold-sampling benchmark where hand-coded manifold-identification logic was replaced with BEAD, resulting in comparable solver performance for objectives of the form h(F(x))h(F(x)); and PyGRANSO examples, showing that the same path and branch-extension gradient information can support a general nonsmooth optimizer.

The set BEAD returns is not in general a classical generalized derivative; Theorem 3.1 gives conditions on the program and the enumeration policy under which it contains the Bouligand subdifferential.

The main limitation of BEAD (as well as its hand-coded alternatives) is path-set growth. If a program contains multiple branch points with nearby alternatives (for example, max⁡(a,b)\max(a, b) with a≈ba \approx b), the total number of paths grows exponentially with the number of such branch points. We present one strategy specific to the abs function to mitigate this path explosion, but future work is needed to develop similar policies for other primitives, and evaluate them in terms of computational cost and the gradient information that they preserve.

Acknowledgments

This work was supported in part by the U.S. Department of Energy, Office of Science, Office of Advanced Scientific Computing Research, Scientific Discovery through Advanced Computing (SciDAC) Program through the FASTMath Institute under Contract No. DE-AC02-06CH11357.

The initial version of the BEAD software prototype was written by hand, but subsequently refactored, and its API and internal data structures redesigned with the help of AI coding agents. The test cases and experiments were selected by the authors, and testing and plotting scripts developed with the help of AI agents. AI agents were also used in the preparation of early drafts of the user manual and the manuscript, and subsequently heavily revised manually by the authors. The authors take full responsibility for the contents of the manuscript and software submission.

Software availability. The BEAD source code, tests, and examples are available in the project repository [32] under the MIT License.

References

  1. [1]Andreas Griewank and Andrea Walther. Evaluating Derivatives: Principles and Techniques of Algorithmic Differentiation. 2nd ed. Philadelphia, PA: Society for Industrial and Applied Mathematics, 2008. DOI: 10.1137/1.9780898717761.DOI
  2. [2]Jan Hückelheim, Harshitha Menon, William Moses, Bruce Christianson, Paul Hovland, and Laurent Hascoët. “A taxonomy of automatic differentiation pitfalls”. In: WIRES Data Mining and Knowledge Discovery 14.6 (2024), e1555. DOI: https://doi.org/10.1002/widm.1555.
  3. [3]Wonyeol Lee, Hangyeol Yu, Xavier Rival, and Hongseok Yang. “On Correctness of Automatic Differentiation for Non-Differentiable Functions”. In: Advances in Neural Information Processing Systems 33. 2020, pp. 6719–6730. DOI: 10.48550/arXiv.2006.06903.DOI
  4. [4]Jérôme Bolte and Edouard Pauwels. “A Mathematical Model for Automatic Differentiation in Machine Learning”. In: Advances in Neural Information Processing Systems 33. 2020, pp. 10809–10819. DOI: 10.48550/arXiv.2006.02080.DOI
  5. [5]James Bradbury, Roy Frostig, Peter Hawkins, Matthew James Johnson, Chris Leary, Dougal Maclaurin, George Necula, Adam Paszke, Jake VanderPlas, Skye Wanderman-Milne, and Qiao Zhang. JAX: Composable transformations of Python+NumPy programs. 2018. URL: http://github.com/jax-ml/jax.
  6. [6]Buyun Liang, Tim Mitchell, and Ju Sun. “NCVX: A General-Purpose Optimization Solver for Constrained Machine and Deep Learning”. In: (2022). DOI: 10.48550/arXiv.2210.00973.DOI
  7. [7]Frank E. Curtis, Tim Mitchell, and Michael L. Overton. “A BFGS-SQP Method for Nonsmooth, Nonconvex, Constrained Optimization and Its Evaluation Using Relative Minimization Profiles”. In: Optimization Methods and Software 32.1 (2017), pp. 148–181. DOI: 10.1080/10556788.2016.1208749.DOI
  8. [8]Stefan Scholtes. Introduction to Piecewise Differentiable Equations. New York, NY: Springer, 2012. DOI: 10.1007/978-1-4614-4340-7.DOI
  9. [9]Andreas Griewank. “On Stable Piecewise Linearization and Generalized Algorithmic Differentiation”. In: Optimization Methods and Software 28.6 (2013), pp. 1139–1178. DOI: 10.1080/10556788.2013.796683.DOI
  10. [10]Jérôme Bolte and Edouard Pauwels. “Conservative Set Valued Fields, Automatic Differentiation, Stochastic Gradient Methods and Deep Learning”. In: Mathematical Programming 188 (2021), pp. 19–51. DOI: 10.1007/s10107-020-01501-5.DOI
  11. [11]Sham Kakade and Jason D. Lee. “Provably Correct Automatic Subdifferentiation for Qualified Programs”. In: Advances in Neural Information Processing Systems 31. 2018, pp. 7125–7135. DOI: 10.48550/arXiv.1809.08530.DOI
  12. [12]Frank H. Clarke. Optimization and Nonsmooth Analysis. Philadelphia, PA: Society for Industrial and Applied Mathematics, 1990. DOI: 10.1137/1.9781611971309.DOI
  13. [13]R. Tyrrell Rockafellar and Roger J.-B. Wets. Variational Analysis. Berlin, Heidelberg: Springer, 1998. DOI: 10.1007/978-3-642-02431-3.DOI
  14. [14]Yurii Nesterov. “Lexicographic Differentiation of Nonsmooth Functions”. In: Mathematical Programming 104.2–3 (2005), pp. 669–700. DOI: 10.1007/s10107-005-0626-0.DOI
  15. [15]Kamil A. Khan and Paul I. Barton. “Generalized Derivatives for Solutions of Parametric Ordinary Differential Equations with Non-Differentiable Right-Hand Sides”. In: Journal of Optimization Theory and Applications 164.2 (2015), pp. 472–496. DOI: 10.1007/s10957-014-0581-9.DOI
  16. [16]Claude Lemaréchal. “An extension of Davidon methods to non differentiable problems”. In: Nondifferentiable Optimization. Ed. by M. L. Balinski and Philip Wolfe. Vol. 3. Mathematical Programming Study. Amsterdam: North-Holland, 1975, pp. 95–109. DOI: 10.1007/BFb0120700.DOI
  17. [17]Philip Wolfe. “A method of conjugate subgradients for minimizing nondifferentiable functions”. In: Nondifferentiable Optimization. Ed. by M. L. Balinski and Philip Wolfe. Vol. 3. Mathematical Programming Study. Amsterdam: North-Holland, 1975, pp. 145–173. DOI: 10.1007/BFb0120703.DOI
  18. [18]Jean-Baptiste Hiriart-Urruty and Claude Lemaréchal. Convex Analysis and Minimization Algorithms II: Advanced Theory and Bundle Methods. Vol. 306. Grundlehren der mathematischen Wissenschaften. Berlin, Heidelberg: Springer-Verlag, 1993. DOI: 10.1007/978-3-662-06409-2.
  19. [19]James V. Burke, Adrian S. Lewis, and Michael L. Overton. “A Robust Gradient Sampling Algorithm for Nonsmooth, Nonconvex Optimization”. In: SIAM Journal on Optimization 15.3 (2005), pp. 751–779. DOI: 10.1137/030601296.DOI
  20. [20]James V Burke, Frank E Curtis, Adrian S Lewis, Michael L Overton, and Lucas EA Simões. “Gradient sampling methods for nonsmooth optimization”. In: Numerical Nonsmooth Optimization: State of the Art Algorithms (2020), pp. 201–225. DOI: 10.1007/978-3-030-34910-3_6.DOI
  21. [21]Jeffrey Larson, Matt Menickelly, and Stefan M. Wild. “Manifold Sampling for ℓ₁ Nonconvex Optimization”. In: SIAM Journal on Optimization 26.4 (2016), pp. 2540–2563. DOI: 10.1137/15M1042097.DOI
  22. [22]Kamil A. Khan, Jeffrey Larson, and Stefan M. Wild. “Manifold Sampling for Optimization of Nonconvex Functions that are Piecewise Linear Compositions of Smooth Components”. In: SIAM Journal on Optimization 28.4 (2018), pp. 3001–3024. DOI: 10.1137/17M114741x.DOI
  23. [23]Jeffrey Larson, Matt Menickelly, and Baoyu Zhou. “Manifold Sampling for Optimizing Nonsmooth Nonconvex Compositions”. In: SIAM Journal on Optimization 31.4 (2021), pp. 2638–2664. DOI: 10.1137/20M1378089.DOI
  24. [24]Jeffrey Larson and Matt Menickelly. “Structure-Aware Methods for Expensive Derivative-Free Nonsmooth Composite Optimization”. In: Mathematical Programming Computation 16 (2024), pp. 1–36. DOI: 10.1007/s12532-023-00245-5.DOI
  25. [25]Ramon E. Moore, R. Baker Kearfott, and Michael J. Cloud. Introduction to Interval Analysis. Philadelphia, PA: Society for Industrial and Applied Mathematics, 2009. DOI: 10.1137/1.9780898717716.DOI
  26. [26]Kyoko Makino and Martin Berz. “Taylor Models and Other Validated Functional Inclusion Methods”. In: International Journal of Pure and Applied Mathematics 4.4 (2003), pp. 379–456.
  27. [27]Andreas Griewank and Andrea Walther. “First- and Second-Order Optimality Conditions for Piecewise Smooth Objective Functions”. In: Optimization Methods and Software 31.5 (2016), pp. 904–930. DOI: 10.1080/10556788.2016.1189549.DOI
  28. [28]Lukas Baumgärtner and Franz Bethke. “Computation of Generalized Derivatives for Abs-Smooth Functions by Backward Mode Algorithmic Differentiation and Implications to Deep Learning”. In: (2024). DOI: 10.48550/arXiv.2407.09639.DOI
  29. [29]Jeffrey Larson, Matt Menickelly, Jared P. O’Neal, and Stefan M. Wild. Interpolation-Based Composite Derivative-Free Optimization. 2026. DOI: https://doi.org/10.11578/dc.20240627.2. URL: https://github.com/POptUS/IBC DFO.
  30. [30]Jorge J. Moré and Stefan M. Wild. “Benchmarking Derivative-Free Optimization Algorithms”. In: SIAM Journal on Optimization 20.1 (2009), pp. 172–191. DOI: 10.1137/080724083.DOI
  31. [31]R. S. Womersley. “Censored Discrete Linear ℓ₁ Approximation”. In: SIAM Journal on Scientific and Statistical Computing 7.1 (1986), pp. 105–122. DOI: 10.1137/0907008.
  32. [32]POptUS. BEAD: Branch-Extended Automatic Differentiation. GitHub repository. URL: https://github.com/POptUS/branch_extended_AD (visited on 10/31/2026).

Paper details

vlnc:W_umpqbj8a
v1 · latestHistory (1)

published · Fresh — added to the Hub within the last 30 days

added ·

Usage

views · 0

downloads · 0

A view counts once per browser per day, a download each time the PDF is requested.

CC BY 4.0

Original source

  • Mathematics

AI agents · View statement →

Looking for related papers…
Contents