# Tensorism
A Rust library built on top of [`ndarray`](https://crates.io/crates/ndarray) that provides a domain-specific language (DSL) for expressing tensor computations using named indexes.
## Goals
- Make multi-index array expressions **explicit**, **readable**, and **compositional**
- Remain compatible with the `ndarray` ecosystem
- Provide compile-time index checking via Ricci indexes
## Quick example
```rust
use ndarray::Array2;
use tensorism::new_ndarray;
// Generate a 2D array from indexed expressions
let x: Array2<f64> = new_ndarray! { for i j => a[i, j] + b[j] };
```
Index `i` ranges over the first dimension of `a`, while `j` ranges over the second dimension of `a` and the only dimension of `b` (which must be compatible).
## Features
### Array generation
A top-level `for ⟨indexes⟩ => ⟨body⟩` inside `new_ndarray!` generates a new `ndarray::Array` whose number of dimensions matches the number of indexes:
```rust
let y = new_ndarray! {
for i j k =>
if p[i, j] - 0.3 < 0.4 * q[j, k] {
r[j] * q[j, k] + 0.2
} else {
0.5 * s[i, j, k]
}
};
```
### Iterators and aggregation
When used as a sub-expression, `for ⟨indexes⟩ => ⟨body⟩` evaluates to a Rust iterator, enabling aggregations:
```rust
let x: i64 = new_ndarray! {
Iterator::sum(for i => Iterator::min(for j => a[i, j]).unwrap())
};
```
### Indexers
Tensorism supports special indexers inside bracket syntax:
- `rev: i` — iterates over the axis in reverse order
- `plain: ⟨expr⟩` — uses a fixed `usize` expression independent of iteration
- User-defined indexers via `Reindexing1`, `Reindexing2`, etc.
```rust
let array = new_ndarray! {
for i j => a[sorting_reindexing[i], rev: j] + b[j, plain: 3 * SIZE + 1]
};
```
### Aliases
Fresh index names can be bound using `let` inside `for` constructs:
```rust
let array = new_ndarray! {
for i j let k = reindexing2[rev: i, j] => x[k, j] + y[k]
};
```
### Conditionals
Nested `for` constructs support conditional guards with `if`:
```rust
let conditional_sum = new_ndarray! {
Iterator::sum(for i j if u[i] < v[i, j] => w[i, j] * u[i])
};
```
## Status
Tensorism is currently **experimental**. The evaluation strategy is primarily iterator-based, and the DSL may evolve in non-backward-compatible ways in future versions.
## License
MIT