https://github.com/pierre-24/arma-einsum
An implementation of einsum() compatible with Armadillo
https://github.com/pierre-24/arma-einsum
armadillo armadillo-library cpp
Last synced: 3 months ago
JSON representation
An implementation of einsum() compatible with Armadillo
- Host: GitHub
- URL: https://github.com/pierre-24/arma-einsum
- Owner: pierre-24
- Created: 2026-04-03T18:10:01.000Z (4 months ago)
- Default Branch: dev
- Last Pushed: 2026-04-04T14:36:20.000Z (3 months ago)
- Last Synced: 2026-04-04T14:42:00.051Z (3 months ago)
- Topics: armadillo, armadillo-library, cpp
- Language: C++
- Homepage:
- Size: 35.2 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `arma-einsum`
A lightweight (and [limited](#notes--limitations)) implementation of NumPy’s [`einsum()`](https://numpy.org/doc/stable/reference/generated/numpy.einsum.html) for C++, built on top of Armadillo.
It enables expressive tensor-style operations (dot products, traces, contractions, etc.) using a compact Einstein summation notation.
## Notes & Limitations
- Requires C++20
- Requires support of [`std::format`](https://github.com/paulkazusek/std_format_cheatsheet/blob/main/README.md#requirement) (i.e., GCC >= 13.1 or clang >= 14). It is however possible to use another equivalent library (see below).
- Supports OMP.
- Due to the use of Armadillo, only supports outputs up to **rank-2 (matrices)**.
- No support for:
- Ellipsis (`...`)
- Broadcasting (NumPy-style)
- Can partially optimize the execution path using a "greedy" algorithm.
## Installation
Just copy [`arma_einsum.hpp`](arma_einsum.hpp) into your project and make sure Armadillo is properly set up, with OpenMP enabled.
```cpp
#define ARMA_USE_OPENMP
#include
#include "arma_einsum.hpp"
```
That’s it: no build system changes or additional dependencies required.
If you want to use older compilers where `std::format` is not available, you can switch to a library with an equivalent function, e.g., [`fmt`](https://github.com/fmtlib/fmt) (Boost's [`format`](https://www.boost.org/doc/libs/latest/libs/format/doc/format.html) should also work).
For example, for `fmt`, [install it](https://fmt.dev/12.0/get-started/) and use
```cpp
#include
#define ARMA_EINSUM_FORMAT fmt::format
```
before including `arma_einsum.hpp`.
See [this example](./example-meson/main_fmt.cpp).
If you want to use a Meson wrap file instead, check [the example](example-meson).
## Usage
```cpp
armaeinsum::einsum_mat("equation", operand1, operand2, ...);
armaeinsum::einsum_mat_opt(level, "equation", operand1, operand2, ...);
```
The latter will be faster, but might generate intermediate results.
### Parameters
- **`T`**: Any floating point type supported by Armadillo (mixing types is not supported).
- **`level`**: level of optimization for the path, for the moment only `armaeinsum::Greedy` is available.
- **`equation`**: A string describing the Einstein summation (see below).
- **`operands`**: A variadic list of Armadillo objects:
- `arma::Col`
- `arma::Row`
- `arma::Mat`
- `arma::Cube`
### Equation Format
The equation string follows standard Einstein summation notation:
```
"indices[,indices...][->output_indices]"
```
### Rules
- Input operands are separated by commas:
```
"ij,jk"
```
- Repeated indices are **summed over** (contraction).
- Non-repeated indices define the output dimensions (in order of appearance).
- You can explicitly define the output using `->`:
```
"ij,jk->ik"
```
- If `->` is omitted, output indices are inferred automatically, in alphabetical order (thus `"ji"` is `"ji->ij""`).
- **The output must be representable as a `arma::Mat`**.
## Examples
Assume:
- `a`, `b` are vectors (`arma::Col` or `arma::Row`)
- `A`, `B` are matrices (`arma::Mat`)
| Expression | Description |
|-----------------------|-------------------------------|
| `("i,i", a, b)` | Dot product |
| `("i,j->ij", a, b)` | Outer product |
| `("ii", A)` | Trace |
| `("ij->ji", A)` | Transpose |
| `("ij->", A)` | Sum of all elements |
| `("ij,j", A, a)` | Matrix-vector multiplication |
| `("ik,kj", A, B)` | Matrix-matrix multiplication |
## Development
[Issues](https://github.com/pierre-24/arma-einsum/issues) and [pull requests](https://github.com/pierre-24/arma-einsum/pull/) are welcomed :)
To help, you can start by [forking the repository](https://github.com/pierre-24/arma-einsum/fork), and then
```bash
git clone git@github.com:YOUR_USERNAME/arma-einsum.git
cd arma-einsum
```
It is recommended to use the [Meson](https://mesonbuild.com/) build system:
```bash
# setup
meson setup _build
# compile
meson compile -C _build
# run test suites
OMP_NUM_THREADS=4 meson test -C _build
# run benchmark
OMP_NUM_THREADS=4 meson test --benchmark --verbose -C _build
```
You can also check linting via [`cpplint`](https://github.com/cpplint/cpplint) using:
```bash
pip install cpplint # optional: use virtualenv
make lint
```