From 1beb6a9ad56e46d05460bc5c226410bb62171fa2 Mon Sep 17 00:00:00 2001 From: saudzahirr Date: Thu, 2 Apr 2026 14:01:35 +0500 Subject: [PATCH] Update documentation for API, index, and theory sections to enhance clarity and provide a comprehensive overview of smolpack's functionality --- docs/api.md | 37 +++++++++++++++--- docs/index.md | 93 ++++++++++++++++++++++++++++---------------- docs/installation.md | 76 +++++++++++++++++------------------- docs/quickstart.md | 59 +++++++++------------------- docs/references.md | 40 ++++++------------- docs/theory.md | 35 ++++++++++++----- mkdocs.yml | 8 +++- 7 files changed, 189 insertions(+), 159 deletions(-) diff --git a/docs/api.md b/docs/api.md index c58d9f3..e1563ff 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,10 +1,22 @@ # API Reference -All public routines are exported via the `smolpack` Python module. +`smolpack` provides a Python interface to the SMOLPACK C library (Petras, 2001; 2003) +for sparse-grid Smolyak cubature. The numerical core is implemented in C and compiled +via `f2py`, providing near-native performance with a NumPy-based Python interface. +See the [Theory](theory.md) and [Quickstart](quickstart.md) for mathematical background +and usage examples. --- -## Overview +## Main Features + +- Sparse-grid cubature over $[0,1]^d$ for any dimension $1 \le d < 40$ +- Two solver variants: delayed and standard Clenshaw-Curtis Smolyak rules +- Simple integrand signature — any callable `f(dim, x) -> float` works +- Built-in function-evaluation counter via `get_count()` +- `print_stats` flag for runtime diagnostics + +## Solvers | Function | Underlying 1-D rule | Integrates | |---|---|---| @@ -133,7 +145,22 @@ print(f"Evaluations: {n}") --- -## References +## Example Workflows + +`smolpack` supports any callable integrand. You can: + +- Integrate smooth analytic functions in low to moderate dimensions +- Compare accuracy between `int_smolyak` and `cc_int_smolyak` at the same level +- Monitor the number of function evaluations with `get_count()` or `print_stats=True` +- Use lambda functions for quick interactive experiments + +See the [Quickstart](quickstart.md) for full code examples, including: + +- Exponential sum and product integrands +- High-dimensional integration (10-D) +- Genz oscillatory test functions +- Convergence study with increasing `qq` +- Solver comparison -See [References](references.md) for full citations of the Petras and Smolyak -papers underlying the algorithms. +All examples demonstrate both `int_smolyak` and `cc_int_smolyak`, along with +the `get_count()` and `print_stats` diagnostics. diff --git a/docs/index.md b/docs/index.md index f10dd5a..10e658f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,27 +1,24 @@ # smolpack -**Sparse-grid Smolyak cubature over $[0,1]^d$ for Python.** +**Multidimensional Quadrature Using Sparse Grids for Python** --- -## What is smolpack? +## Overview `smolpack` is a Python library for efficient numerical integration (cubature) over the unit hypercube $[0,1]^d$ using [Smolyak's algorithm](https://en.wikipedia.org/wiki/Sparse_grid) with -Clenshaw-Curtis quadrature rules. The numerical core is written in C and -compiled via `f2py`, giving near-native performance while providing a clean, -NumPy-based Python API. +Clenshaw-Curtis quadrature rules. The package allows you to **easily** and +**efficiently** integrate high-dimensional functions without the exponential +cost of classical tensor-product rules. -**Numerical integration** (quadrature in 1-D, cubature in higher dimensions) is -a fundamental problem in computational science. Standard tensor-product rules -scale exponentially with dimension — a 1-D rule with $n$ nodes becomes $n^d$ -nodes in $d$ dimensions, quickly making the computation intractable. Smolyak's -algorithm circumvents this *curse of dimensionality* by constructing **sparse -grids** that achieve comparable polynomial exactness with dramatically fewer -nodes. - -`smolpack` approximates integrals of the form: +Numerical integration in multiple dimensions is a fundamental problem in +computational science. Standard tensor-product rules scale exponentially with +dimension — a 1-D rule with $n$ nodes becomes $n^d$ nodes in $d$ dimensions, +quickly making the computation intractable. Smolyak's algorithm constructs +**sparse grids** that achieve comparable polynomial exactness with dramatically +fewer nodes. `smolpack` approximates integrals of the form: $$ I[f] = \int_{[0,1]^d} f(\mathbf{x})\,d\mathbf{x}, @@ -29,38 +26,68 @@ $$ using the Smolyak combination technique with Clenshaw-Curtis basic rules. -## Available solvers - -| Solver | Underlying 1-D rule | Characteristics | -|---|---|---| -| `int_smolyak` | Delayed Clenshaw-Curtis | Fewer function evaluations for a given accuracy level | -| `cc_int_smolyak` | Standard Clenshaw-Curtis | Classical nested rule (1, 3, 5, 9, 17, 33, 65, … nodes) | +## Requirements -!!! tip "Choosing a solver" - For most applications, start with `int_smolyak` — the delayed variant - achieves the same polynomial exactness with fewer integrand evaluations. - Use `cc_int_smolyak` when compatibility with the classical Clenshaw-Curtis - node hierarchy is required. +- [NumPy](http://www.numpy.org/) -## Quick example +## Example Usage ```python import numpy as np import smolpack + # Integrate exp(x1 + x2 + x3) over [0,1]^3 # Exact value: (e - 1)^3 ≈ 5.073214 +def exp_sum(dim, x): + return np.exp(np.sum(x)) -def my_func(dim, x): - return np.exp(np.sum(x)) +result = smolpack.int_smolyak(exp_sum, dim=3, qq=5) +print(f"Result = {result:.6f}") + +# Convergence with increasing level +exact = (np.e - 1.0) ** 3 +for qq in range(4, 9): + result = smolpack.int_smolyak(exp_sum, dim=3, qq=qq) + print( + f"qq={qq} k={qq - 3} result={result:.10f} error={abs(result - exact):.2e}" + ) +# Compare both solvers +r1 = smolpack.int_smolyak(exp_sum, dim=3, qq=7) +r2 = smolpack.cc_int_smolyak(exp_sum, dim=3, qq=7) +print(f"Delayed CC: {r1:.10f}") +print(f"Standard CC: {r2:.10f}") -result = smolpack.int_smolyak(my_func, dim=3, qq=5) -print(f"Integral ≈ {result:.6f}") +# Query function-evaluation count +n = smolpack.get_count() +print(f"Evaluations: {n}") ``` -## License +## Main Features + +1. **Sparse-grid cubature** over $[0,1]^d$ for dimensions $1 \le d < 40$. +2. Two solver variants: delayed and standard Clenshaw-Curtis Smolyak rules. +3. High-performance C core compiled via `f2py`, with a clean NumPy-based Python API. +4. Simple integrand signature — any callable `f(dim, x) -> float` works. +5. Built-in function-evaluation counter via `get_count()`. +6. `print_stats` flag for runtime diagnostics. + +## See Also + +- [NumPy](http://www.numpy.org/): Array library used for the integrand interface +- [SciPy](http://scipy.org): General scientific computing — complements `smolpack` for pre/post-processing +- [SMOLPACK C library](https://people.math.sc.edu/Burkardt/c_src/smolpack/smolpack.html): The original C implementation by Knut Petras, distributed by John Burkardt + +## Acknowledgements + +The author thanks [Knut Petras](https://people.math.sc.edu/Burkardt/c_src/smolpack/smolpack.html) +for the original SMOLPACK C library, which provides the numerical core of this +package and is distributed via [John Burkardt's page](https://people.math.sc.edu/Burkardt/c_src/smolpack/smolpack.html). + +## References -smolpack is distributed under the -[LGPL-2.1](https://github.com/eggzec/smolpack/blob/main/LICENSE) license. +- Smolyak, S., "Quadrature and Interpolation Formulas for Tensor Products of Certain Classes of Functions," *Doklady Akademii Nauk SSSR*, 4, 240–243, 1963. +- Petras, K., "Fast Calculation of Coefficients in the Smolyak Algorithm," *Numerical Algorithms*, 26(2), 93–109, 2001. +- Petras, K., "Smolyak Cubature of Given Polynomial Degree with Few Nodes for Increasing Dimension," *Numerische Mathematik*, 93(4), 729–753, 2003. diff --git a/docs/installation.md b/docs/installation.md index 4478280..11aeb04 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,7 +1,6 @@ # Installation -`smolpack` is distributed as a compiled wheel on PyPI and can also be installed -from source via GitHub. +`smolpack` can be installed from PyPI, GitHub, or built from source. --- @@ -16,30 +15,31 @@ For source builds you additionally need: - `meson` and `meson-python` build system - `numpy` (for `f2py` compilation) -## PyPI (recommended) +## [PyPI](https://pypi.org/project/smolpack) -### pip +For using the PyPI package in your project, add the following to your +configuration file: -```bash -pip install --upgrade smolpack -``` +=== "pyproject.toml" -### pyproject.toml dependency + ```toml + [project] + dependencies = [ + "smolpack" + ] + ``` -```toml -[project] -dependencies = [ - "smolpack" -] -``` +=== "requirements.txt" -### requirements.txt + ```text + smolpack + ``` -```text -smolpack -``` +### pip -## Package managers +```bash +pip install --upgrade smolpack +``` ### uv @@ -75,7 +75,7 @@ pdm add smolpack hatch add smolpack ``` -## Installing from source (GitHub) +## [git](https://github.com/eggzec/smolpack) Install the latest development version directly from the repository: @@ -85,8 +85,7 @@ pip install --upgrade "git+https://github.com/eggzec/smolpack.git#egg=smolpack" ### Building locally -Clone and build from source if you want to modify the C code or test -local changes: +Clone and build from source to modify the C code or test local changes: ```bash git clone https://github.com/eggzec/smolpack.git @@ -94,26 +93,24 @@ cd smolpack uv pip install . ``` -This invokes the `meson` build system to compile the C sources via -`f2py` and install the resulting extension module in development mode. +This invokes the `meson` build system to compile the C sources via `f2py` +and install the resulting extension module. !!! warning "C compiler required" - Source builds require a working C compiler. On most Linux - distributions install `gcc` + Source builds require a working C compiler. -```bash -# Debian/Ubuntu -sudo apt install gcc + ```bash + # Debian/Ubuntu + sudo apt install gcc -# Fedora -sudo dnf install gcc + # Fedora + sudo dnf install gcc -# macOS (Homebrew — Clang is pre-installed via Xcode Command Line Tools) -xcode-select --install -``` - -On Windows, install MSVC (Microsoft Visual C++) via Visual Studio Build Tools. This is required for source builds and matches the official Python and NumPy wheels. MinGW is not supported. + # macOS (Clang via Xcode Command Line Tools) + xcode-select --install + ``` + On Windows, install MSVC via Visual Studio Build Tools. MinGW is not supported. ## Verifying the installation @@ -129,8 +126,5 @@ print("smolpack is working! Integral:", result) ## Dependencies -| Package | Purpose | -|---|---| -| `numpy` | Array handling, `f2py` integration | - -No other runtime dependencies are required. +- Python >=3.10 +- [numpy](https://pypi.org/project/numpy) diff --git a/docs/quickstart.md b/docs/quickstart.md index 7326240..3429a28 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,35 +1,14 @@ # Quickstart This page walks through progressively richer examples of using `smolpack`. -Each example is self-contained and can be pasted into a Python script or -interactive session. +Each example is self-contained and can be pasted directly into a Python script +or interactive session. For mathematical background, see the [Theory](theory.md) section. --- -## Concepts +## Exponential sum (3-D) -Before diving in, here are the key ideas: - -1. **Define an integrand** — write a plain Python function that takes - `(dim, x)` and returns a `float`, where `x` is a 1-D NumPy array with - each component in $[0,1]$. -2. **Call a solver** — pass the function, the dimension, and the level - parameter to `int_smolyak` or `cc_int_smolyak`. -3. **Get the result** — the solver returns the approximate integral value. - -```python -import numpy as np -import smolpack - -result = smolpack.int_smolyak(my_func, dim=d, qq=q) -``` - ---- - -## Example 1: Exponential sum (3-D) - -The simplest non-trivial test — integrate $e^{x_1+x_2+x_3}$ over the unit -cube: +The simplest non-trivial test — integrate $e^{x_1+x_2+x_3}$ over the unit cube: $$ I = \int_{[0,1]^3} e^{x_1+x_2+x_3}\,dx = (e-1)^3 \approx 5.073214. @@ -48,7 +27,7 @@ result = smolpack.int_smolyak(exp_sum, dim=3, qq=5) print(f"Result = {result:.6f}") ``` -## Example 2: Constant function (sanity check) +## Constant function (sanity check) A constant integrand should return exactly 1 for any dimension: @@ -63,7 +42,7 @@ result = smolpack.int_smolyak(lambda d, x: 1.0, dim=10, qq=11) print(f"Result = {result:.12f}") # 1.000000000000 ``` -## Example 3: Comparing the two algorithms +## Comparing the two solvers Both solvers applied to the same integrand in 3-D: @@ -86,7 +65,7 @@ print(f"Standard CC: {r2:.10f} (error {abs(r2 - exact):.2e})") print(f"Exact: {exact:.10f}") ``` -## Example 4: Convergence with increasing `qq` +## Convergence with increasing `qq` The level parameter `qq` controls accuracy. The number of Smolyak stages is $k = qq - dim$; higher $k$ yields more accurate results at the cost of @@ -110,10 +89,9 @@ for qq in range(4, 10): ) ``` -## Example 5: Product integrand (separable) +## Product integrand (separable) -For the product $f(\mathbf{x}) = x_1 x_2 \cdots x_d$, the exact value is -$(1/2)^d$: +For the product $f(\mathbf{x}) = x_1 x_2 \cdots x_d$, the exact value is $(1/2)^d$: ```python import numpy as np @@ -130,10 +108,10 @@ exact = 0.5**dim print(f"Result = {result:.10f} (exact = {exact})") ``` -## Example 6: High-dimensional integration +## High-dimensional integration -Smolyak's strength is moderate- to high-dimensional problems. Here we -integrate the product of cosines in 10 dimensions: +Smolyak's strength is moderate- to high-dimensional problems. Here we integrate +the product of cosines in 10 dimensions: $$ \int_{[0,1]^{10}} \prod_{i=1}^{10} \cos(x_i)\,dx = \sin(1)^{10} \approx 1.5867 \times 10^{-4}. @@ -154,7 +132,7 @@ print(f"Result = {result:.10e}") print(f"Exact = {exact:.10e}") ``` -## Example 7: Genz oscillatory test function +## Genz oscillatory test function The [Genz test functions](https://www.math.wsu.edu/faculty/genz/software/software.html) are standard benchmarks for cubature methods. The oscillatory family is: @@ -177,7 +155,7 @@ result = smolpack.int_smolyak(genz_oscillatory, dim=5, qq=8) print(f"Oscillatory integral = {result:.8f}") ``` -## Example 8: Printing solver statistics +## Printing solver statistics Set `print_stats=True` to see function-call and weight-evaluation counts: @@ -193,7 +171,7 @@ def exp_sum(dim, x): result = smolpack.int_smolyak(exp_sum, dim=3, qq=5, print_stats=True) ``` -The counter can also be queried programmatically: +The counter can also be queried programmatically after any integration call: ```python n = smolpack.get_count() @@ -208,10 +186,9 @@ print(f"Function evaluations: {n}") at the cost of more integrand evaluations. !!! tip "When to use `cc_int_smolyak`" - The standard Clenshaw-Curtis variant uses the classical nested node - sequence. Prefer it when reproducibility against published sparse-grid - node tables is important, or when the integrand is extremely smooth and - benefits from the standard hierarchy. + Prefer the standard Clenshaw-Curtis variant when reproducibility against + published sparse-grid node tables is important, or when the integrand is + extremely smooth and benefits from the standard node hierarchy. !!! tip "Lambda functions" Lambda functions work as integrands for quick experiments: diff --git a/docs/references.md b/docs/references.md index 0d465ae..6791e4e 100644 --- a/docs/references.md +++ b/docs/references.md @@ -5,36 +5,18 @@ The original C library SMOLPACK was written by Knut Petras and is distributed via [John Burkardt's page](https://people.math.sc.edu/Burkardt/c_src/smolpack/smolpack.html). -## Bibliography +--- -1. **Smolyak, S.** - "Quadrature and Interpolation Formulas for Tensor Products of Certain - Classes of Functions." - *Doklady Akademii Nauk SSSR*, 4, 240–243, 1963. +- Smolyak, S., "Quadrature and Interpolation Formulas for Tensor Products of Certain Classes of Functions," *Doklady Akademii Nauk SSSR*, 4, 240–243, 1963. +- Petras, K., "Fast Calculation of Coefficients in the Smolyak Algorithm," *Numerical Algorithms*, 26(2), 93–109, 2001. +- Petras, K., "Smolyak Cubature of Given Polynomial Degree with Few Nodes for Increasing Dimension," *Numerische Mathematik*, 93(4), 729–753, 2003. +- Novak, E., Ritter, K., "High Dimensional Integration of Smooth Functions over Cubes," *Numerische Mathematik*, 75(1), 79–97, 1996. +- Novak, E., Ritter, K., "Simple Cubature Formulas with High Polynomial Exactness," *Constructive Approximation*, 15(4), 499–522, 1999. +- Genz, A., "A Package for Testing Multiple Integration Subroutines," in *Numerical Integration: Recent Developments, Software and Applications*, edited by P. Keast and G. Fairweather, Reidel, 1987, pp. 337–340. -2. **Petras, K.** - "Fast Calculation of Coefficients in the Smolyak Algorithm." - *Numerical Algorithms*, 26(2), 93–109, 2001. +--- -3. **Petras, K.** - "Smolyak Cubature of Given Polynomial Degree with Few Nodes for - Increasing Dimension." - *Numerische Mathematik*, 93(4), 729–753, 2003. +**Related Packages:** -## High-dimensional integration - -4. **Novak, E., Ritter, K.** - "High Dimensional Integration of Smooth Functions over Cubes." - *Numerische Mathematik*, 75(1), 79–97, 1996. - -5. **Novak, E., Ritter, K.** - "Simple Cubature Formulas with High Polynomial Exactness." - *Constructive Approximation*, 15(4), 499–522, 1999. - -## Cubature test problems - -6. **Genz, A.** - "A Package for Testing Multiple Integration Subroutines." - In: *Numerical Integration: Recent Developments, Software and Applications*, - edited by P. Keast and G. Fairweather. - Reidel, 1987, pp. 337–340. ISBN 9027725144. +- [NumPy](http://www.numpy.org/) +- [SciPy](http://scipy.org) diff --git a/docs/theory.md b/docs/theory.md index 04c0fb8..00ef56a 100644 --- a/docs/theory.md +++ b/docs/theory.md @@ -1,13 +1,22 @@ # Theory -This page covers the mathematical foundations behind `smolpack`: what -multidimensional integration is, why tensor-product rules fail at scale, and -how Smolyak's algorithm constructs sparse grids that overcome the curse of -dimensionality. +## Overview + +`smolpack` implements **Smolyak's sparse-grid cubature**, a method for approximating +multidimensional integrals of the form + +$$ +I[f] = \int_{[0,1]^d} f(\mathbf{x})\,d\mathbf{x} +$$ + +without succumbing to the exponential cost of tensor-product rules. The method is +particularly effective for smooth integrands in moderate dimensions ($d \lesssim 20$), +where it achieves near-optimal convergence rates with dramatically fewer function +evaluations than classical approaches. --- -## 1) Background: Multidimensional integration +## Background: Multidimensional integration **Cubature** is the numerical approximation of a multidimensional integral: @@ -45,7 +54,9 @@ Even for moderate $d$, tensor-product rules are computationally intractable. This exponential scaling is the **curse of dimensionality**, first identified by Richard Bellman in the context of dynamic programming. -## 2) Smolyak's algorithm +--- + +## Smolyak's algorithm In 1963, Sergey Smolyak proposed a construction that achieves polynomial exactness comparable to tensor-product rules while requiring dramatically @@ -92,7 +103,9 @@ dimension. rules. This is precisely the same degree of exactness that the corresponding tensor-product rule achieves, but with far fewer nodes. -## 3) Clenshaw-Curtis quadrature +--- + +## Clenshaw-Curtis quadrature The Smolyak construction requires a nested family of 1-D quadrature rules as its basic sequence. `smolpack` uses **Clenshaw-Curtis** rules, which are based @@ -129,7 +142,9 @@ same polynomial exactness with fewer total function evaluations. node counts but achieve the same polynomial exactness at the same level $q$. The delayed variant typically uses fewer nodes. -## 4) Parameters and constraints +--- + +## Parameters and constraints ### The level parameter $q$ @@ -161,7 +176,9 @@ Clenshaw-Curtis quadrature weights. The `print_stats` flag reports both the number of function evaluations $N$ and the number of weight evaluations performed during grid construction. -## 5) Error and convergence +--- + +## Error and convergence For sufficiently smooth integrands (functions with bounded mixed partial derivatives), the Smolyak cubature error satisfies: diff --git a/mkdocs.yml b/mkdocs.yml index 747f2f4..9ea48ec 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,8 +20,14 @@ markdown_extensions: - admonition - tables - fenced_code - - pymdownx.superfences + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format - pymdownx.highlight + - pymdownx.tabbed: + alternate_style: true - pymdownx.arithmatex: generic: true - toc: