Numpy2AD
A pure Python package for source-to-source transformation of Numpy matrix expressions to reverse-mode, also referred to as adjoint, algorithmic differentiation code.
Algorithmic / Automatic Differentiation is the state of the art for computing derivatives in many fields of application, e.g. computational engineering, finance, and machine learning (backpropagation). For more details, this book is a good entry point to the subject.
Usage
Numpy2AD offers two modes of adjoint code generation.
-
In Expression Mode a given Numpy matrix expression string, e.g.
from numpy2ad import transform_expr print(transform_expr("D = A @ B + C"))
is transformed to its reverse-mode differentiation code:
""" v0 = A @ B D = v0 + C v0_a = np.zeros_like(v0) C_a += D_a v0_a += D_a B_a += A.T @ v0_a A_a += v0_a @ B.T """
The generated code can be easily pasted into the desired context, e.g. a Jupyter notebook, where the adjoints (partial derivatives)
A_a,B_a,C_a, andD_aare initialized. Expression mode is best suited for quick scripting and debugging. -
In Function Mode a given function, e.g.
def mma(A, B, C): return A @ B + C
is transformed to its adjoint function with modified signature:
from numpy2ad import transform print(transform(mma))
""" import numpy as np def mma_ad(A, B, C, A_a, B_a, C_a, out_a): v0 = A @ B out = v0 + C v0_a = np.zeros_like(v0) C_a += out_a v0_a += out_a B_a += A.T @ v0_a A_a += v0_a @ B.T return (out, A_a, B_a, C_a) """
The transformed code can also be conveniently exported as a Python module with the argument
out_file=...for validation and easier integration into your existing workflows.
Install
$ python -m pip install numpy2ad
Supported Matrix Operations
Numpy2Ad currently supports a limited but broadly applicable subset of Numpy matrix operations. We define a "matrix" as a two-dimensional numpy.ndarray. If not further specified, the operations are also valid for one-dimensional "vectors".
- Matrix Addition
C = A + Band SubtractionC = A - B - Matrix (Inner) Products
C = A @ B- Exception: Inner products between two vectors
c = a @ bas they result in a scalar.
- Exception: Inner products between two vectors
- Matrix Inverse
B = np.linalg.inv(A) - Matrix Transpose
B = A.T - Element-wise product
C = A * B- Note that dimension of
AandBmust match. Numpy's broadcasting rules are not considered during code generation, e.g. multiplying a scalar variable by a matrix will lead to incorrect derivative code.
- Note that dimension of
Limitations
- The adjoint compiler currently only generates first order, reverse-mode derivative code. Forward-mode ("tangents") ist not supported.
- The expression must be aliasing-free, i.e.
A = A @ Bis not allowed. - The input code must not contain any control flow (
if ... else), nested functions, loops, or other non-differentiable subroutines.
Demo, Tests, and Benchmarks
Check out /demo/example_problems.ipynb for a collection of matrix models that Numpy2AD was applied to and tested on. A more in-depth user guide can be found in /demo/tutorial.ipynb.
Tests of code generation and numerical correctness of derivatives, compared to naive finite differences, can be found in /tests/.
Furthermore, there are some simple runtime benchmarks for the MMA and GLS model in /benchmarks/.
Building the Package from Source
- Create a conda environment from the main directory
$ conda env create --file environment.yml ... $ conda activate numpy2ad
- Build and install the package locally
$ conda develop .
- Alternatively, you can also use
venvandpip:$ python -m venv env ... $ source env/bin/activate ... $ pip install -r dev_requirements.txt ... $ pip install -e .
Acknowledgements
This package was developed by Nicholas Book in close collaboration with Prof. Uwe Naumann and Simon Märtens of STCE at RWTH Aachen University, Germany.
License
MIT License, see LICENSE.txt.
Release files for numpy2ad 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| numpy2ad-0.1.1.tar.gz | 21.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| numpy2ad-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.4 kB
Release files / numpy2ad-0.1.1.tar.gz
| Download URL | numpy2ad-0.1.1.tar.gz |
|---|---|
| Size | 21.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
978bd83a08baa604002d1a28c4c833ab17401cbbf27b6f9b57cf29066d4a8793
|
|
BLAKE2b-256 checksum How to use checksums |
a9105f30e4ee130b711ad0c99a50fde92dfdc26350e5cb07d89b6d1a91e2db7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.0
|
Release files / numpy2ad-0.1.1-py3-none-any.whl
| Download URL | numpy2ad-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6205b46582e29369d9fd44e1a5fcf740501bc5170084bf82f65edcab95467a34
|
|
BLAKE2b-256 checksum How to use checksums |
97efc4e0c4c54b59a61b0417d2d5cfc88937a3e70900a9f0719bc43fd509795b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.0
|