archimedes.approximation.Function¶

class archimedes.approximation.Function(
coefficients: ndarray,
space: FunctionSpace,
)¶

A specific element of a FunctionSpace:

\[f(x) = \sum_{i=1}^n c_i \, \phi_i(x)\]

A Function is a callable object that can be evaluated with typical function-call syntax, e.g., f(x). Evaluation supports both numeric and symbolic evaluation for any function space.

A limited set of arithmetic operations is supported:

  • Addition of two Function objects on the same space.

  • Subtraction of two Function objects on the same space.

  • Scalar multiplication and division of a Function object.

  • Negation of a Function object.

Supported operations are exact and closed on the function space. That is, the result of any of the above is exactly representable in the original function space.

Multiplication between two Function objects is generally not closed on the function space, and so is not supported via operator overloading (“dunder” __mul__ methods). However, since the function space in which a pointwise product is representable can be determined exactly, the operation is supported via the dedicated multiply() method.

Similarly, derivative and anti-derivative (indefinite integral) operations are supported and generally return Function objects in the minimal containing function space. For example, the derivative of a polynomial of degree n is a polynomial of degree n-1. The returned space can be overridden by manually specifying a different target space.

The dot product of two Function objects is implemented in terms of numerical quadrature, exactly integrating the product of the two functions. The dot product of vector-valued functions also contracts over the vector components and unconditionally returns a scalar value.

Other math operations can be implemented via L2-projection of the function. For example, pointwise division of two functions can be approximated by f.space.project(lambda x: f(x) / g(x)). Note that this is an approximation, not an exact representation in the original function space.

A Function is implemented as a [struct](#archimedes.struct), making it compatible with flattening, unflattening, mapping, and other tree operations. The “children” of the struct are the coefficients and the space and the space itself. Note that function spaces are themselves structs, so flattening the function may include boundary endpoint data.

This is useful for variable-endpoint problems, but not desirable when the domain endpoints are fixed. In this case, a typical approach is to work directly with the coefficient array, reconstructing or replacing the full Function object as needed.

Parameters:
  • coefficients (ndarray) – Expansion coefficients, shape (n_basis,) for a scalar-valued function or (n_basis, m) for one mapping to an m-vector.

  • space (FunctionSpace) – The space this function belongs to, defining its basis and domain.

Methods

antiderivative([order, boundary, space])

The order-th antiderivative \(F^{(-\mathrm{order})}\).

derivative([deriv, space])

The deriv-th derivative \(f^{(k)}\), as a Function.

dot(other[, quad_rule])

Inner product with another Function on the same space.

integrate([a, b])

Definite integral \(\int_a^b f(x)\,dx\).

multiply(other[, space])

Pointwise product \((fg)(x) = f(x) g(x)\).

norm([quad_rule])

Compute the norm \(\lVert f \rVert = \sqrt{\langle f, f \rangle}\).

replace(**updates)

Returns a new object replacing the specified fields with new values.

Attributes

coefficients

space

__init__(
coefficients: ndarray,
space: FunctionSpace,
) → None¶
antiderivative(
order: int = 1,
boundary: str = 'left',
space: FunctionSpace | None = None,
) → Function¶

The order-th antiderivative \(F^{(-\mathrm{order})}\).

The antiderivative is numerically exact and is the dual of derivative() (i.e. an indefinite integral). The result is returned in the smallest space that represents it. For a polynomial family, that space is larger than this one, since integrating raises the degree.

This behavior can be overridden by manually passing a specific result space, in which case the exact antiderivative is projected onto the specified space.

An indefinite integral is unique only up to an additive constant (per order), so the antiderivative must be “pinned” at a domain boundary. The pinned value is determined by the boundary argument by defining the antiderivative to vanish at the specified boundary:

  • "left" (default) gives \(F(x) = \int_a^x f(t)\,dt\).

  • "right" gives \(F(x) = \int_b^x f(t)\,dt = -\int_x^b f(t)\,dt\).

Parameters:
  • order (int, optional) – Number of times to integrate. Default 1.

  • boundary ({"left", "right"}, optional) – Domain endpoint at which the antiderivative (and its lower derivatives, for order > 1) vanishes. Default "left".

  • space (FunctionSpace, optional) – Result space, overriding the automatic one.

Returns:

The antiderivative, in the result space, with coefficients of shape (n_basis,) or (n_basis, m) matching this function.

Return type:

Function

Raises:
  • NotImplementedError – If this function’s space has no integral-space construction.

  • ValueError – If the domain has no finite endpoints to anchor at, or if an explicit space is the wrong size.

derivative(
deriv=1,
space: FunctionSpace | None = None,
) → Function¶

The deriv-th derivative \(f^{(k)}\), as a Function.

The result is returned in the smallest space that represents it exactly. For a polynomial family, this result space is smaller than the original, since differentiating lowers the degree.

This behavior can be overridden by manually passing a specific result space, in which case the exact derivative is projected onto the specified space.

For the derivative sampled at points rather than as a Function, prefer using f(x, deriv=k) to f.derivative(k)(x).

Parameters:
  • deriv (int or tuple of int, optional) – Derivative order; a multi-index (one order per dimension) for a function of several variables, a plain order otherwise. Default 1.

  • space (FunctionSpace, optional) – Result space, overriding the automatic one.

Returns:

The derivative, in the result space, with coefficients of shape (n_basis,) or (n_basis, m) matching this function.

Return type:

Function

dot(
other: Function,
quad_rule: QuadratureRule | None = None,
)¶

Inner product with another Function on the same space.

Computes \(\langle f, g \rangle\) for functions \(f\) and \(g\) on the same space.

Unlike the multiplication operator, this is well-defined for any pair of Function objects on the same space, since the result is always a scalar. For vector-valued functions, the inner product contracts over components.

Parameters:
  • other (Function) – The other operand, on the same space as this function.

  • quad_rule (QuadratureRule, optional) – Quadrature rule to approximate the integral with. Defaults to this space’s quadrature.

Returns:

The inner product.

Return type:

float

integrate(a: float | None = None, b: float | None = None)¶

Definite integral \(\int_a^b f(x)\,dx\).

Wherever antiderivative() is defined for this space, the integral evaluates \(F(b) - F(a)\) (exact to quadrature roundoff) for any \(a\) and \(b\) within the domain.

If antiderivative() isn’t defined, the whole-domain integral (a=None, b=None) is still available, computed directly from the quadrature rule of this function’s FunctionSpace.

Parameters:
  • a (float, optional) – Integration bounds. Default: the domain’s endpoints.

  • b (float, optional) – Integration bounds. Default: the domain’s endpoints.

Returns:

Shape () for a scalar-valued function, (m,) for a vector-valued one.

Return type:

ndarray or float

Raises:
  • NotImplementedError – If this function’s space has no integral-space construction and a and/or b are not None.

  • ValueError – If the domain has no finite endpoints to integrate over.

multiply(
other: Function,
space: FunctionSpace | None = None,
) → Function¶

Pointwise product \((fg)(x) = f(x) g(x)\).

In general, the product of two basis expansions does not lie in either operand’s space, so the result is returned in a larger one. For polynomial families, the product space has n_1 + n_2 - 1 degrees of freedom and represents the product exactly.

This behavior can be overridden by manually passing a specific result space, in which case the exact product is projected onto the specified space.

Parameters:
  • other (Function) – The other factor. Must be on a compatible space (see FunctionSpace).

  • space (FunctionSpace, optional) – Result space, overriding the automatic one.

Returns:

The product, in the result space.

Return type:

Function

norm(
quad_rule: QuadratureRule | None = None,
)¶

Compute the norm \(\lVert f \rVert = \sqrt{\langle f, f \rangle}\).

See dot().

replace(**updates) → T¶

Returns a new object replacing the specified fields with new values.