Skip to content
Specular Differentiation

specular.calculation.gradient

gradient(f, x, h=None)

Evaluate the specular gradient of a scalar-valued function. Also available as specular.gradient.

Parameters

Name Description
f Callable taking a one-dimensional real vector and returning a real scalar.
x Nonempty one-dimensional array-like of finite real coordinates.
h Finite, positive, concrete real scalar shared by all coordinates, or None for automatic coordinatewise selection. Default: None.

Returns

A vector of shape (n,), where n is the length of x. The return value is a NumPy array for NumPy and Numba, or a JAX array for JAX.

Notes

Each component is the specular derivative along one coordinate direction. The center value is evaluated once. With h=None, coordinate j uses eps(dtype)**(1/3) * max(1, abs(x[j])).

An explicit h is validated before evaluating f. Concrete samples must be finite and distinct; a very small valid step can still lose accuracy. The callback must support the selected backend, and JAX requires a static explicit step under transformations. See the calculation guide for these limitations.

The result is the unnormalized gradient. Normalization for SPEG is handled by make_direction.

Examples

import numpy as np
from specular.calculation import gradient

print(gradient(lambda x: np.sum(x * x), [1.0, 2.0, 3.0]))
# approximately [2, 4, 6]
Source code in specular/calculation.py
73
74
75
76
77
78
79
80
81
82
83
84
def gradient(f: Any, x: Any, h: Any = None) -> Any:
    """Evaluate a specular gradient with the selected backend.

    If ``h`` is omitted, a separate step is selected for each coordinate from
    the backend dtype and coordinate scale. An explicit ``h`` must be a
    concrete, finite, positive real scalar and is validated before ``f`` is
    evaluated.
    """

    validated_h = None if h is None else _positive_step(h)
    backend = _get_selected_backend()
    return backend.gradient(f, x, validated_h)