# cluster_algebra

Cluster algebras with quiver mutation and compatible Poisson structures.

## Mathematical background

A **cluster algebra** (Fomin–Zelevinsky) is a commutative algebra generated by **cluster variables** grouped into overlapping **clusters** of size N. Starting from an initial seed (Q, **x**) consisting of a quiver Q and an initial cluster **x** = (x₁, …, xₙ), new seeds are obtained by **mutation** at a vertex k:

- The cluster variable xₖ is replaced by x'ₖ via the exchange relation: `xₖ · x'ₖ = ∏_{i→k} xᵢ + ∏_{k→j} xⱼ`
- The quiver is updated: for each path i → k → j, add an arrow i → j; reverse all arrows incident to k; cancel 2-cycles.

Cluster variables are represented as fractions `(numerator, denominator)` of `SemiRing` elements — subtraction-free expressions built from the initial seed.

## Modules

### `ClusterAlgebra<N, VertexLabel, EdgeLabel, Coeffs>`

A cluster algebra of rank N backed by a `Quiver`. The seed is stored as an array of `(numerator, denominator)` pairs indexed in the same order as `vertices_sorted`.

```rust
let mut alg = ClusterAlgebra::<2, _, _, i32>::new(
    quiver,
    [("alpha", 5), ("beta", 7)].into_iter().collect(),
    |n| format!("__gen_{n}"),
)?;
alg.mutate(&"alpha");
let [(a_num, a_den)] = alg.view_cluster(["alpha"]); // (8, 5)
```

Key methods:
- `mutate(&vertex)` — mutate at a mutable vertex; updates both the quiver and the cluster variables
- `freeze` / `unfreeze` — frozen vertices participate in exchange relations but cannot be mutated
- `view_cluster([v₁, …, vₘ])` — read off the current `(numerator, denominator)` for the given vertices

### `PoissonClusterAlgebra<N, VertexLabel, EdgeLabel, Coeffs, BaseRing>`

A `ClusterAlgebra` equipped with a compatible log-canonical (quadratic) Poisson structure. The bracket `{xᵢ, xⱼ} = λᵢⱼ xᵢ xⱼ` is stored as a skew-symmetric N×N matrix `lambda` over `BaseRing`.

Under mutation at k, the Poisson matrix transforms covariantly:
```text
λ'_{kj} = -λ_{kj} + Σ_{i: B_{ik}>0} B_{ik} · λ_{ij}
```
where `B_{ik}` is the net arrow count from i to k in the pre-mutation quiver.

```rust
let mut palg = PoissonClusterAlgebra::from(alg);
palg.set_bracket(&"alpha", &"beta", 1i64);
palg.mutate(&"alpha");
palg.poisson_coefficient(&"alpha", &"beta"); // Some(-1)
```

Key methods:
- `set_bracket(&v1, &v2, value)` — set `λ_{v1,v2} = value` and `λ_{v2,v1} = -value`
- `poisson_coefficient(&v1, &v2)` — read `λ_{v1,v2}`
- `mutate` — mutates the cluster algebra and updates `lambda` simultaneously

## Dependencies

- [`quiver_algebra`](../quiver_algebra/README.md) — `Quiver` and `SemiRing` from the parent module
