diff --git a/README.md b/README.md index c498019..bb703ad 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ [![](https://img.shields.io/badge/docs-quarto-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAABDCAMAAADwFEhBAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB2lBMVEUAAABxvP90vP9zu/90u/90u/90u/90u/91uv91vP9zuv91v/91uv91u/9zvP90u/90uv92uv+As/91u/91u/90u/90u/90vP+Aqv90u/91u/9zuv90uf90u/90u/90u/9zuf9ttv90u/90u/91vP8A//92uv90u/95tv9zuv90u/90vP9zuv90u/91uv91u/90u/90vP90uf9zvP90u/93vv90u/90u/93u/9qv/90u/9zu/91vP90u/90vP95vP9Vqv90u/90u/91u/90u/90uf+Av/91u/90u/9xvf90u/91vP92vv90u/+AgP90u/9zu/91vP9vvP90u/90uv90u/94tP90u/9zvP90uv90u/90u/91u/90vP9zu/90uv91u/90uv9zvP9zuv9xu/9zvP90u/90u/90vP9zvP90uf9xxv90u/90uv90u/9zvf90u/90u/90u/90uv91uv90vP90uf90u/91vP90u/9wuP9zu/9zvP9zuv90u/92v/90uv90vP9yvP90uv90u/9mzP91u/90vP90u/92vP90vP9zvP90u/90u/90u/90u/9yuv91uv90u/91vP91u/90u/90u/9zu/91vf90u/90u/91u/90u//////Zz6urAAAAnHRSTlMAImOdxOv+4LqQWRgwjt/NdxoKadL8uUQGcOjJTUvbvygOpfh2ATTaFV3kLnPvP4P3ckJb8Cv12Q8M16ibWjkTA8+VYvshBJdWG8OBJ+ICfzyMF9FR/RGERauW9LHBvqfHhp9vLTWwqWdUFgm1kU8f+taeXCWIC+FI7BmHUInVHOO9JraiBa9950HMaulA5chOVbQ9pObcUiN1k23io9BOAAAAAWJLR0SdBrvysQAAAAd0SU1FB+cIFgIIE8103aAAAAEhelRYdFJhdyBwcm9maWxlIHR5cGUgeG1wAAAokXVSS3LFIAzbc4oegcjGJsdJH7DrTJc9fmWSvqR5LZ78bCNLIunr4zO9xRJIkodX2bxa82zNiqstyPFtD+suUZMG2GJqw2BFtj3/7B4AcjphmHyPLaVqKxlZxYZzI7IUdFFeGZCeN+QIUgDBTbYC1aR2m78Xg0N1ZWTZOHP4XOjOJvQ5wjFkkTUCI0kWMAHe2w7Cp/hKWNL2ihYDonxyuTNStZJcTJhYp7SVLnQyPBroCzibTgRDGvEL6Bpe00VUANlfsianftrNd/pnjYKPPSFtmSaOV+pPAT8DNg1nViuH7EOBdDr1SCfq/413bzCu7uzmpKs716M9m+Nw1aI2sy9/XVTSN0+AmxnAMJeGAAAAAW9yTlQBz6J3mgAAAipJREFUWMPt11lb00AYBeDPhXGDVpEiorhQKkWsglYFrRJFq6KiAkpVXFHR1qXuirvivqK4nx9r0tRCIEln5rvlXOXi5L3Ikzl5QuSVKVOnTS8BrEuIGTNnzZ5DaiktC8BOzshFBOfOkwbK51egkFHDTKhygZRQtbAa8DDMLFpcnKhZAvgZwNJl/sLyWqCYgXBdxIdYUQ8JA6iMehINYcgZWNnoQawSkDUQW+1KrAHkDTTVuBDNUDLQtHYCsU4oGoivH0c0boCqgY0tDqJ1E9QNbHYYCegY2DKG2Cr0jJK2AmFsg56B7QWjHbrGjp15IhnQNrArb+yGvhHeYxsdDAN7c8Q+cIz9nVbjAMvAQasR5BmHzEKX4BndZqEHPOPwEaJepoEU0VGu0UxUwTWOER3nGn1kgGucoMk4YwjuMz1JVM01ThGd5hpniM5yjQaifq5xjug804ibY2jEeMYFqzHAMy5ajUssI5S2GpkYx7hsv6pXOMZV27iW1Teud+bPzA194+b/c3crq2vUJwuH97aukRodgDt39YyBsStyT+gY9wcdU/RAwxAPnXOW7FA3Ho3fxOhjVaPPmDCsT56qGc8yLuv8PKBivCh3nfjBbnlj6KXHd6LllaQReu39VxjpD8sYb96SX0rfFTdqo+Sf5PsP/kbwIxVPa90nb+Pzl4gEYaZq+GvWzYgnvskBdtLtI9+dxo/Ez4yKYOdXz+8/Q9bFSNnfVFr9fpX8A/gO4x9ExakgAAAAUGVYSWZNTQAqAAAACAACARIAAwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAABDoAMABAAAAAEAAABDAAAAAEC2TfoAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDgtMjJUMDI6MDg6MTgrMDA6MDDjF9jVAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA4LTIyVDAyOjA4OjE4KzAwOjAwkkpgaQAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0wOC0yMlQwMjowODoxOSswMDowMGMoSgIAAAARdEVYdGV4aWY6Q29sb3JTcGFjZQAxD5sCSQAAABJ0RVh0ZXhpZjpFeGlmT2Zmc2V0ADM4rbi+IwAAABd0RVh0ZXhpZjpQaXhlbFhEaW1lbnNpb24ANjeFsWfdAAAAF3RFWHRleGlmOlBpeGVsWURpbWVuc2lvbgA2N1gnvlgAAAASdEVYdHRpZmY6T3JpZW50YXRpb24AMber/DsAAAAASUVORK5CYII=)](https://peekxc.github.io/primate/) - [![build_macos](https://img.shields.io/github/actions/workflow/status/peekxc/primate/build_macos.yml?logo=apple&logoColor=white)](https://github.com/peekxc/primate/actions/workflows/build_macos.yml) [![build_windows](https://img.shields.io/github/actions/workflow/status/peekxc/primate/build_windows.yml?logo=windows&logoColor=white)](https://github.com/peekxc/primate/actions/workflows/build_windows.yml) [![build_linux](https://img.shields.io/github/actions/workflow/status/peekxc/primate/build_linux.yml?logo=linux&logoColor=white)](https://github.com/peekxc/primate/actions/workflows/build_linux.yml) - [![Python versions](https://img.shields.io/badge/python-%E2%89%A5%203.8-blue.svg)](https://github.com/peekxc/primate/actions) - + + `primate`, short for **Pr**obabalistic **I**mplicit **Ma**trix **T**race **E**stimator, is a Python package that provides estimators of quantities derived from [matrix functions](https://en.wikipedia.org/wiki/Analytic_function_of_a_matrix); that is, matrices parameterized by functions: diff --git a/docs/basic/install.html b/docs/basic/install.html index fb0bd97..fef6d54 100644 --- a/docs/basic/install.html +++ b/docs/basic/install.html @@ -355,7 +355,8 @@

Installation

Platform support

-

Platform-specific wheels are currently built with cibuildwheel and uploaded to PyPI. These enable primate to be installed on supported architecture / CPython implementations without compilation. As of 12/29/23, native primate wheels are buitl for the following platforms:

+ +

For certain platforms, primate can be installed from PyPi without compilation. As of 12/29/23, native primate wheels are built for the following platforms:

@@ -402,11 +403,12 @@

Platform support

-

Wheels are currently built with cibuildwheel. Currently no support is offered for PyPy, 32-bit runtimes, or unsupported versions of CPython. If your platform isn’t on this list, feel free to make an issue requesting support.

+

Wheels are currently built with cibuildwheel. Currently no support is offered for PyPy, 32-bit systems, or unsupported versions of CPython.

+

If your platform isn’t on this table but you would like it to be supported, feel free to make an issue.

Compiling from source

-

To install the package from its source distribution, a C++20 compiler is required; the current builds are all built with some variant of clang. For platform- and compiler-specific settings, consult the build scripts and CI configuration files.

+

To install the package from its source distribution, a C++20 compiler is required; the current builds are all built with some variant of clang, preferably version 15.0 or higher. For platform- and compiler-specific settings, consult the build scripts and CI configuration files.

C++ Installation

@@ -445,7 +447,7 @@

C++ Installation

Footnotes

    -
  1. Single-thread execution only; ARM-based OSX runners come stocked with Apple’s clang, which doesn’t natively ship with libomp.dylib, though this may be fixable. Feel free to file an PR if you can get this working.↩︎

  2. +
  3. Single-thread execution only; ARM-based OSX runners compile with Apple’s clang, which doesn’t natively ship with libomp.dylib, though this may be fixable. Feel free to file an PR if you can get this working.↩︎

  4. Single-thread execution only; primate depends on OpenMP 4.5+, which isn’t supported on any Windows compiler I’m aware of.↩︎

diff --git a/docs/basic/integration.html b/docs/basic/integration.html index f19fbdd..20f7c8d 100644 --- a/docs/basic/integration.html +++ b/docs/basic/integration.html @@ -337,8 +337,7 @@

On this page

@@ -364,8 +363,6 @@

Integration

-
-

Python usage

primate supports a variety of matrix-types of the box, including numpy ndarray’s, compressed sparse matrices (a lá SciPy), and LinearOperators—the latter enables the use of matrix free operators.

Outside of the natively types above, the basic requirements for any operator A to be used with e.g. the Lanczos method in primate are:

    @@ -402,7 +399,6 @@

    Python usage

    ) ## True ``` --> -

C++ usage

Similarly, to get started calling any matrix-free function provided by primate on the C++ side, such hutch or lanczos, simply pass any type with .shape() and .matvec() member functions:

diff --git a/docs/basic/performance.html b/docs/basic/performance.html index 4e22577..6c65a74 100644 --- a/docs/basic/performance.html +++ b/docs/basic/performance.html @@ -342,7 +342,7 @@

Performance

primate provides a variety of efficient algorithms for estimating quantities derived from matrix functions. These algorithms are largely implemented in C++ to minimize overhead, and for some computational problems primate can out-perform the standard algorithms for estimating spectral quantities by several orders of magnitude. Nonetheless, there are some performance-related caveats to be aware of.

-
+
from scipy.linalg import toeplitz
 from primate.trace import hutch 
 
@@ -386,7 +386,7 @@ 

Performance

a, b = lanczos(T, deg=499, orth=150) np.sum(np.abs(eigvalsh_tridiagonal(a,b)))
-
+
import timeit 
 timeit.timeit(lambda: hutch(A, maxiter=20, deg=5, fun="log", quad="fttr"), number = 1000)
 timeit.timeit(lambda: np.sum(np.log(np.linalg.eigvalsh(A))), number = 1000)
diff --git a/docs/basic/todo.html b/docs/basic/todo.html index 6c6a3d0..f9379ec 100644 --- a/docs/basic/todo.html +++ b/docs/basic/todo.html @@ -323,7 +323,7 @@ -
+
# a, b = 0.8, 2
 # x = np.random.uniform(low=0, high=10, size=40)
 # eps = np.random.normal(loc=0, scale=1.0, size=40)
diff --git a/docs/basic/usage.html b/docs/basic/usage.html
index b40068d..8ca1bea 100644
--- a/docs/basic/usage.html
+++ b/docs/basic/usage.html
@@ -360,7 +360,7 @@ 

primate usage - quickstart

Below is a quick introduction to primate. For more introductory material, theor

To do trace estimation, use functions in the trace module:

-
+
import primate.trace as TR
 from primate.random import symmetric
 A = symmetric(150)  ## random positive-definite matrix 
@@ -370,12 +370,12 @@ 

primate usage - quickstart

print(f"XTrace: {TR.xtrace(A):6f}") ## Epperly's algorithm
Actual trace: 75.697397
-Girard-Hutch: 75.386523
+Girard-Hutch: 75.284468
 XTrace:       75.697398

For matrix functions, you can either construct a LinearOperator directly via the matrix_function API, or supply a string to the parameter fun describing the spectral function to apply. For example, one might compute the log-determinant as follows:

-
+
from primate.operator import matrix_function
 M = matrix_function(A, fun="log")
 
@@ -388,14 +388,14 @@ 

primate usage - quickstart

## M = matrix_function(A, fun=np.log)
logdet(A):  -148.321844
-GR approx:  -147.600540
+GR approx:  -148.272202
 XTrace:     -148.315937

Note in the above example you can supply to fun either string describing a built-in spectral function or an arbitrary Callable. The former is preferred when possible, as function evaluations will generally be faster and hutch can also be parallelized. Multi-threaded execution of e.g. hutch with arbitrary functions is not currently allowed due to the GIL, though there are options available, see the integration docs for more details.

For ‘plain’ operators, XTrace should recover the exact trace (up to roundoff error). For matrix functions f(A), there will be some inherent inaccuracy as the underlying matrix-vector multiplication is approximated with the Lanczos method.

In general, the amount of accuracy depends both on the Lanczos parameters and the type of matrix function. Spectral functions that are difficult or impossible to approximate via low-degree polynomials, for example, may suffer more from inaccuracy issues than otherwise. For example, consider the example below that computes that rank:

-
+
## Make a rank-deficient operator
 ew = np.sort(ew)
 ew[:30] = 0.0
@@ -407,25 +407,25 @@ 

primate usage - quickstart

print(f"XTrace: {TR.xtrace(M)}")
Rank:       120
-GR approx:  145.9887237548828
+GR approx:  145.36611938476562
 XTrace:     143.97018151807674

This is not so much a fault of hutch or xtrace as much as it is the choice of approximation and Lanczos parameters. The sign function has a discontinuity at 0, is not smooth, and is difficult to approximate with low-degree polynomials. One workaround to handle this issue is relax the sign function with a low-degree “soft-sign” function: \mathcal{S}_\lambda(x) = \sum\limits_{i=0}^q \left( x(1 - x^2)^i \prod_{j=1}^i \frac{2j - 1}{2j} \right)

Visually, the soft-sign function looks like this:

-
+
from primate.special import soft_sign, figure_fun
 show(figure_fun("smoothstep"))
-
+