Building functions¶
Declare the shape and structure of a function with L, G, and @function. The derivative
wrappers, such as gradient, then create functions from that declaration. See the
functions guide for examples and the
derivatives guide for choosing a derivative.
Declared trees¶
Tree ¶
A pytree declaration whose leaves are Expr symbolically and NumPy arrays numerically.
A tree is its structure: only G introduces a tuple, so a one-leaf tree is the bare leaf
and never a one-element tuple. See L for what that means at a call site.
Source code in src/scaly/function/tree.py
symbols ¶
relabel ¶
with_types ¶
resolved ¶
Check traced output types against this declaration and resolve inferred shapes.
Source code in src/scaly/function/tree.py
index ¶
Return the flat index for name, or raise with the declared choices.
is_symbolic ¶
Whether value has at least one leaf and every leaf is an Expr.
This is the leaf-kind half of Function.__call__'s dispatch. It deliberately ignores
structure so that a wrongly-shaped tree is reported by flatten_symbolic against the
declared names instead of being rejected here as a kind mismatch.
Source code in src/scaly/function/tree.py
is_numerical ¶
Whether no leaf of value is an Expr.
The numerical side is the fallback: array-likes are coerced by flatten_numerical, so a
leaf only has to not be symbolic. Values with no leaves land here and are reported as a
structure error rather than as a mixed call.
Source code in src/scaly/function/tree.py
flatten_symbolic ¶
flatten_numerical ¶
L ¶
Declare one named tensor.
The declared name is external metadata and need not match the local name used by a decorated
function body. Pass a TensorType to set dtype or differentiability explicitly.
A single leaf is passed and returned unpacked. An L input tree takes the tensor itself,
not (tensor,), and an L output tree returns the tensor itself, not a one-element tuple.
Do not destructure a single-leaf result: (y,) = fn(x) does not raise, it iterates the
returned tensor along its first axis exactly as NumPy would.
Source code in src/scaly/function/tree.py
G ¶
G(a: Tree[SA, NA], b: Tree[SB, NB], c: Tree[SC, NC], d: Tree[SD, ND]) -> Tree[tuple[SA, SB, SC, SD], tuple[NA, NB, NC, ND]]
G(a: Tree[SA, NA], b: Tree[SB, NB], c: Tree[SC, NC], d: Tree[SD, ND], e: Tree[SE, NE]) -> Tree[tuple[SA, SB, SC, SD, SE], tuple[NA, NB, NC, ND, NE]]
G(a: Tree[SA, NA], b: Tree[SB, NB], c: Tree[SC, NC], d: Tree[SD, ND], e: Tree[SE, NE], f: Tree[SF, NF]) -> Tree[tuple[SA, SB, SC, SD, SE, SF], tuple[NA, NB, NC, ND, NE, NF]]
The decorator¶
function ¶
function(inputs: Tree[SI, NI], outputs: Tree[SO, NO], /, *, name: str | None = None) -> Callable[[Callable[[SI], SO]], Function[SI, NI, SO, NO]]
Trace a callable over declared input and output pytrees.
Source code in src/scaly/function/api.py
Derivative requests¶
Pass these request objects to Function.factory when you need several outputs or derivatives in
one function. For a single derivative, the named wrappers below are usually more convenient.
DerivSpec
dataclass
¶
Base class for typed requests passed to Function.factory.
Source code in src/scaly/function/model.py
Jac
dataclass
¶
Bases: DerivSpec
Dense Jacobian d of / d wrt.
Source code in src/scaly/function/factory.py
Grad
dataclass
¶
Bases: DerivSpec
Gradient of a scalar output.
Source code in src/scaly/function/factory.py
Hess
dataclass
¶
Bases: DerivSpec
Dense Hessian of a scalar output.
Source code in src/scaly/function/factory.py
SpJac
dataclass
¶
Bases: DerivSpec
Compact nonzero Jacobian values, with the sparsity that indexes them.
Source code in src/scaly/function/factory.py
SpHess
dataclass
¶
Bases: DerivSpec
Compact nonzero Hessian values, with the sparsity that indexes them.
Source code in src/scaly/function/factory.py
Fwd
dataclass
¶
Bases: DerivSpec
Seeded forward mode: J(of, wrt) @ fwd:wrt.
Source code in src/scaly/function/factory.py
Adj
dataclass
¶
Bases: DerivSpec
Seeded reverse mode: J(of, wrt).T @ lam:of.
Source code in src/scaly/function/factory.py
Named wrappers¶
The common derivative functions accept either an Expr and an Expr input, or a Function, an output name, and an input name.
jacobian ¶
jacobian(source: Expr | Function, *args: Expr | str, wrt: Expr | str | None = None, of: str | None = None, name: str | None = None) -> Expr | Function
Build a dense Jacobian for an Expr or a named Function output.
Source code in src/scaly/function/api.py
gradient ¶
gradient(source: Expr | Function, *args: Expr | str, wrt: Expr | str | None = None, of: str | None = None, name: str | None = None) -> Expr | Function
Build a gradient for an Expr or a named Function output.
Source code in src/scaly/function/api.py
hessian ¶
hessian(source: Expr | Function, *args: Expr | str, wrt: Expr | str | None = None, of: str | None = None, name: str | None = None) -> Expr | Function
Build a Hessian for an Expr or a named Function output.
Source code in src/scaly/function/api.py
sparse_jacobian ¶
sparse_jacobian(source: Expr | Function, *args: Expr | str, wrt: Expr | str | None = None, of: str | None = None, name: str | None = None) -> SparseJacobian | Function
Build compact nonzero Jacobian values for an Expr or a named Function output.
Source code in src/scaly/function/api.py
sparse_hessian ¶
sparse_hessian(source: Expr | Function, *args: Expr | str, wrt: Expr | str | None = None, of: str | None = None, name: str | None = None, triangle: Triangle = 'full') -> SparseJacobian | Function
Build compact nonzero Hessian values for an Expr or a named Function output.
triangle selects the symmetric pattern returned by the sparse Hessian: "full" keeps
every entry, while "lower" and "upper" keep one triangle in the full pattern's order.
Source code in src/scaly/function/api.py
forward ¶
forward(fn: Function[SI, NI, SO, NO], of: str, wrt: str, *, name: str | None = None) -> Function[tuple[SI, Expr], tuple[NI, np.ndarray], Expr, np.ndarray]
Create a seeded forward-mode Function computing J(of, wrt) @ fwd:wrt.
Source code in src/scaly/function/api.py
adjoint ¶
adjoint(fn: Function[SI, NI, SO, NO], of: str, wrt: str, *, name: str | None = None) -> Function[tuple[SI, Expr], tuple[NI, np.ndarray], Expr, np.ndarray]
Create a seeded reverse-mode Function computing J(of, wrt).T @ lam:of.
Source code in src/scaly/function/api.py
lagrangian_hessian ¶
lagrangian_hessian(fn: Function[SI, NI, SO, NO], wrt: str, *, name: str | None = None, aux_name: str = 'gamma') -> Function[tuple[SI, SO], tuple[NI, NO], Expr, np.ndarray]
Create the dense Hessian of all outputs weighted by the declared output tree.
Source code in src/scaly/function/api.py
sparse_lagrangian_hessian ¶
sparse_lagrangian_hessian(fn: Function[SI, NI, SO, NO], wrt: str, *, name: str | None = None, aux_name: str = 'gamma', triangle: Triangle = 'full') -> Function[tuple[SI, SO], tuple[NI, NO], Expr, np.ndarray]
Create compact values for the weighted Hessian of all declared outputs.