model#

ndoptimize.model(parameters, *, inputs, cache=True)[source]#

Compile a function as a model which ndoptimize.least_squares() can fit, with the given names for its parameters and inputs.

A model function, function(x, parameters, f, jacobian), writes the model evaluated at the points x, an array of shape (num_points, num_inputs) with a column for each input, for the given parameters, an array of shape (num_parameters,), into f, an array of shape (num_points,), and its derivatives with respect to the parameters into jacobian, an array of shape (num_points, num_parameters). It returns nothing.

The function is compiled with Numba in nopython mode, with this fixed signature. The fitting kernel takes the function as a typed function pointer, so a single compiled kernel serves every model and is cached on disk.

Scalar functions such as math.exp() should come from math, since they are the ones Numba compiles for every target.

Parameters:
  • parameters (Sequence[str]) – The names of the parameters, in the order of the parameters array and of the columns of the jacobian array. ndoptimize.least_squares() checks the initial guess against their number, since the compiled function does not check its indices.

  • inputs (Sequence[str]) – The names of the inputs, in the order of the columns of the x array, such as ("x",) for a function of one variable, or ("lower", "upper") for a function of the edges of a bin. ndoptimize.least_squares() and ndoptimize.evaluate() check the last axis of x against their number, for the same reason.

  • cache (bool) – Whether to cache the compiled function on disk, so that later processes need not compile it again. Numba compiles the global arrays a function reads into it as constants, and the cache does not notice when they change, so a model which reads globals computed at run time should not be cached. Neither can a model which is not defined in a file, such as one defined in the interactive interpreter.

Return type:

Callable[[Callable[[ndarray, ndarray, ndarray, ndarray], None]], Model]

Examples

A straight line, \(f(x) = a + b x\).

import ndoptimize

@ndoptimize.model(parameters=("intercept", "slope"), inputs=("x",))
def line(x, parameters, f, jacobian):
    a, b = parameters[0], parameters[1]
    for i in range(x.shape[0]):
        f[i] = a + b * x[i, 0]
        jacobian[i, 0] = 1
        jacobian[i, 1] = x[i, 0]

line
Model(parameters=('intercept', 'slope'), inputs=('x',))