Skip to content

mccube._formulae

Defines cubature formulae for integrating functions over the regions (measure spaces) defined as AbstractRegions.

builtin_cubature_registry module-attribute ¤

builtin_cubature_registry: set[type[AbstractCubature]] = all_subclasses(AbstractCubature)

A searchable registry of all cubature formulae, in the current scope, that are subclasses of mccube.AbstractCubature.

AbstractCubature ¤

Bases: Module, Generic[_Region]

Abstract base class for cubature formulae.

A concrete implementation of this class allows one to construct the points and weights of a pre-defined cubature formula over some specified integration region (measure space).

Example
class Formula(AbstractCubature):
    degree = 3
    sparse = False

    @cached_property
    def weights(self):
        ...

    @cached_property
    def points(self):
        ...

    @cached_property
    def point_count(self):
        ...

region = mccube.GaussianRegion(5)
formula = Formula(region)
# Formula(region=GaussianRegion(dimension=5))

Attributes:

  • region (_Region) –

    an AbstractRegion (measure space) of a specified dimension.

  • degree (int) –

    the degree \(m\) of polynomials, defined over the region, for which the cubature formulae is an exact integrator (with respect to the measure \(\mu\)).

  • sparse (bool) –

    indicates if the cubature points have a sparsity structure.

weights abstractmethod cached property ¤

A PyTree of Cubature weights \(\lambda_j \in \mathbb{R}_+\) for the measure \(\mu\).

points abstractmethod cached property ¤

A PyTree of Cubature points \(x_j \in \Omega\) for the measure \(\mu\).

point_count abstractmethod cached property ¤

point_count: IntScalarLike

Cubature point count \(k\).

stacked_weights cached property ¤

stacked_weights: CubatureWeights

weights stacked into a single vector.

stacked_points cached property ¤

stacked_points: CubaturePoints

points stacked into a single matrix.

__call__ ¤

Approximately integrate some function \(f\) over the integration region.

Computes the cubature formula \(Q[f] = \sum_{j=1}^{k} \lambda_j f(x_j)\).

Parameters:

Returns:

Source code in mccube/_formulae.py
def __call__(
    self,
    integrand: Callable[[CubaturePoints], RealScalarLike],
) -> tuple[RealScalarLike, CubatureWeights]:
    r"""Approximately integrate some function $f$ over the integration region.

    Computes the cubature formula $Q[f] = \sum_{j=1}^{k} \lambda_j f(x_j)$.

    Args:
        integrand: the jax transformable function to integrate.

    Returns:
        Approximated integral and stacked weighted evaluations of $f$ at each
            vector $x_j$.
    """
    return evaluate_cubature(self.weights, self.points, integrand)

AbstractGaussianCubature ¤

Bases: AbstractCubature[GaussianRegion]

Abstract base class for cubature formula that are valid for the GaussianRegion.

The Gaussian region is assumed to have the "probabilist's" Hermite measure.

Warning

Here it is assumed that the Gaussian measure is the normalized "probabilist's" Hermite weight (to be consistent with [@victoir2004]). However, other authors, such as [@stroud1971], assume the measure is the "physicist's" Hermite measure. Cubature formulae defined with respect to the later measure must be appropriately rescaled to be compatible with the measure assumed here.

Reference: [@victoir2004]
@article{victoir2004,
  title   = {Asymmetric Cubature Formulae with Few Points in High Dimension for
             Symmetric Measures},
  author  = {Victoir, Nicolas},
  year    = {2004},
  journal = {SIAM Journal on Numerical Analysis},
  volume  = {42},
  number  = {1},
  pages   = {209-227},
  doi     = {10.1137/S0036142902407952},
}
Reference: [@stroud1971]
@book{stroud1971,
  title     = {Approximate Calculation of Multiple Integrals},
  author    = {Stroud, A. H.},
  year      = {1971},
  publisher = {Prentice-Hall},
  pages     = {431},
  isbn      = {9780130438935},
  url       = {https://archive.org/details/approximatecalcu0000stro_b8j7}
}

Hadamard ¤

Bases: AbstractGaussianCubature

Degree 3 Gaussian cubature from [@victoir2004].

Reference: [@victoir2004]
@article{victoir2004,
  title   = {Asymmetric Cubature Formulae with Few Points in High Dimension for
             Symmetric Measures},
  author  = {Victoir, Nicolas},
  year    = {2004},
  journal = {SIAM Journal on Numerical Analysis},
  volume  = {42},
  number  = {1},
  pages   = {209-227},
  doi     = {10.1137/S0036142902407952},
}

point_count cached property ¤

point_count: IntScalarLike

Cubature point count \(k = 2^{\lceil{\log_2 d}\rceil + 1}\).

StroudSecrest63_31 ¤

Bases: AbstractGaussianCubature

Degree 3 Gaussian cubature from [@stroudSecrest1963], listing \(E_n^{r^2}\) 3-1 (pg315) in [@stroud1971].

Reference: [@stroudSecrest1963]
@article{stroudSecrest1963,
  title     = {Approximate Integration Formulas for Certain Spherically
               Symmetric Regions},
  author    = {Stroud, A. H. and Secrest, Don},
  year      = {1963},
  journal   = {Mathematics of Computation},
  number    = {82},
  pages     = {105--135},
  publisher = {American Mathematical Society},
  volume    = {17},
  issn      = {00255718, 10886842},
  url       = {http://www.jstor.org/stable/2003633}
}
Reference: [@stroud1971]
@book{stroud1971,
  title     = {Approximate Calculation of Multiple Integrals},
  author    = {Stroud, A. H.},
  year      = {1971},
  publisher = {Prentice-Hall},
  pages     = {431},
  isbn      = {9780130438935},
  url       = {https://archive.org/details/approximatecalcu0000stro_b8j7}
}

point_count cached property ¤

point_count: IntScalarLike

Cubature point count \(k = 2d\).

StroudSecrest63_32 ¤

Bases: AbstractGaussianCubature

Degree 3 Gaussian cubature from [@stroudSecrest1963], listing \(E_n^{r^2}\) 3-2 (pg316) in [@stroud1971].

This formula is identical to the mccube.Hadamard formula for dimensions less than four. For all other dimensions, mccube.Hadamard is strictly more efficient.

Reference: [@stroudSecrest1963]
@article{stroudSecrest1963,
  title     = {Approximate Integration Formulas for Certain Spherically
               Symmetric Regions},
  author    = {Stroud, A. H. and Secrest, Don},
  year      = {1963},
  journal   = {Mathematics of Computation},
  number    = {82},
  pages     = {105--135},
  publisher = {American Mathematical Society},
  volume    = {17},
  issn      = {00255718, 10886842},
  url       = {http://www.jstor.org/stable/2003633}
}
Reference: [@stroud1971]
@book{stroud1971,
  title     = {Approximate Calculation of Multiple Integrals},
  author    = {Stroud, A. H.},
  year      = {1971},
  publisher = {Prentice-Hall},
  pages     = {431},
  isbn      = {9780130438935},
  url       = {https://archive.org/details/approximatecalcu0000stro_b8j7}
}

point_count cached property ¤

point_count: IntScalarLike

Cubature point count \(k = 2^d\).

StroudSecrest63_52 ¤

Bases: AbstractGaussianCubature

Degree 5 Gaussian cubature from [@stroudSecrest1963], listing \(E_n^{r^2}\) 5-2 (pg317) in [@stroud1971].

Reference: [@stroudSecrest1963]
@article{stroudSecrest1963,
  title     = {Approximate Integration Formulas for Certain Spherically
               Symmetric Regions},
  author    = {Stroud, A. H. and Secrest, Don},
  year      = {1963},
  journal   = {Mathematics of Computation},
  number    = {82},
  pages     = {105--135},
  publisher = {American Mathematical Society},
  volume    = {17},
  issn      = {00255718, 10886842},
  url       = {http://www.jstor.org/stable/2003633}
}
Reference: [@stroud1971]
@book{stroud1971,
  title     = {Approximate Calculation of Multiple Integrals},
  author    = {Stroud, A. H.},
  year      = {1971},
  publisher = {Prentice-Hall},
  pages     = {431},
  isbn      = {9780130438935},
  url       = {https://archive.org/details/approximatecalcu0000stro_b8j7}
}

point_count cached property ¤

point_count: IntScalarLike

Cubature point count \(k = 2d^2 + 1\).

StroudSecrest63_53 ¤

Bases: AbstractGaussianCubature

Degree 5 Gaussian cubature from [@stroudSecrest1963], listing \(E_n^{r^2}\) 5-3 (pg317) in [@stroud1971]. Valid for regions with dimension d > 2.

Reference: [@stroudSecrest1963]
@article{stroudSecrest1963,
  title     = {Approximate Integration Formulas for Certain Spherically
               Symmetric Regions},
  author    = {Stroud, A. H. and Secrest, Don},
  year      = {1963},
  journal   = {Mathematics of Computation},
  number    = {82},
  pages     = {105--135},
  publisher = {American Mathematical Society},
  volume    = {17},
  issn      = {00255718, 10886842},
  url       = {http://www.jstor.org/stable/2003633}
}
Reference: [@stroud1971]
@book{stroud1971,
  title     = {Approximate Calculation of Multiple Integrals},
  author    = {Stroud, A. H.},
  year      = {1971},
  publisher = {Prentice-Hall},
  pages     = {431},
  isbn      = {9780130438935},
  url       = {https://archive.org/details/approximatecalcu0000stro_b8j7}
}

point_count cached property ¤

point_count: IntScalarLike

Cubature point count \(k = 2^d + 2d\).

evaluate_cubature ¤

Evaluate a cubature formula for a given integrand \(f\).

Parameters:

Returns:

Source code in mccube/_formulae.py
def evaluate_cubature(
    weights: CubatureWeightsTree,
    points: CubaturePointsTree,
    integrand: Callable[[CubaturePoints], RealScalarLike],
) -> tuple[RealScalarLike, CubatureWeights]:
    r"""Evaluate a cubature formula for a given integrand $f$.

    Args:
        weights: cubature formula weights $\lambda_j$.
        points: cubature formula points $x_j$.
        integrand: function $f$ to integrate.

    Returns:
        Computed integral and the weighted evaluation points $\lambda_j f(x_j)$.
    """
    eval_points = jtu.tree_map(
        jax.vmap(lambda c, x: c * integrand(x), [None, 0]), weights, points
    )
    eval_points = jnp.hstack(eval_points)
    return jnp.sum(eval_points), eval_points

search_cubature_registry ¤

search_cubature_registry(region: AbstractRegion, degree: int | None = None, sparse_only: bool = False, minimal_only: bool = False, searchable_formulae: Collection[type[AbstractCubature]] = builtin_cubature_registry) -> list[AbstractCubature]

Returns a list of cubature formulae of a specified degree for a given region.

Example
result = search_cubature_registry(mccube.GaussianRegion(2), degree=3)
# [StroudSecrest63_31(...), StroudSecrest63_32(...), Hadamard(...)]

result = search_cubature_registry(mccube.GaussianRegion(10), minimal_only=True)
# [StroudSecrest63_31(...)]

Parameters:

  • region (AbstractRegion) –

    the region for which the cubature formulae must be of degree \(m\).

  • degree (int | None, default: None ) –

    the required degree \(m\) of cubature formulae. Ignored if none.

  • sparse_only (bool, default: False ) –

    if to only select cubature formulae with sparse cubature points.

  • minimal_only (bool, default: False ) –

    if to only return formulae with minimal point count.

  • searchable_formulae (Collection[type[AbstractCubature]], default: builtin_cubature_registry ) –

    collection from which to search for suitable cubature formulae.

Source code in mccube/_formulae.py
def search_cubature_registry(
    region: AbstractRegion,
    degree: int | None = None,
    sparse_only: bool = False,
    minimal_only: bool = False,
    searchable_formulae: Collection[type[AbstractCubature]] = builtin_cubature_registry,
) -> list[AbstractCubature]:
    """Returns a list of cubature formulae of a specified degree for a given region.

    Example:
        ```python
        result = search_cubature_registry(mccube.GaussianRegion(2), degree=3)
        # [StroudSecrest63_31(...), StroudSecrest63_32(...), Hadamard(...)]

        result = search_cubature_registry(mccube.GaussianRegion(10), minimal_only=True)
        # [StroudSecrest63_31(...)]
        ```

    Args:
        region: the region for which the cubature formulae must be of degree $m$.
        degree: the required degree $m$ of cubature formulae. Ignored if none.
        sparse_only: if to only select cubature formulae with sparse cubature points.
        minimal_only: if to only return formulae with minimal point count.
        searchable_formulae: collection from which to search for suitable cubature
            formulae.
    """
    selected_formulae = list()
    minimum_point_count = float("inf")
    for f in searchable_formulae:
        # Try to instantiate the formula in order to establish a point count.
        try:
            formula = f(region)
        except ValueError:
            continue
        degree_condition = (f.degree != degree) and (degree is not None)
        sparse_condition = sparse_only and not f.sparse
        if degree_condition or sparse_condition:
            continue
        current_point_count = formula.point_count
        if minimal_only:
            if current_point_count > minimum_point_count:
                continue
            elif current_point_count < minimum_point_count:
                selected_formulae = [formula]
                minimum_point_count = current_point_count
            else:
                selected_formulae.append(formula)
        else:
            selected_formulae.append(formula)
    return sorted(selected_formulae, key=lambda f: f.point_count)  # pyright: ignore