# rsomics-rda
Redundancy Analysis (RDA) of a response table against explanatory constraints —
a Rust port of `skbio.stats.ordination.rda`.
RDA is constrained linear ordination: the response matrix `Y` (samples ×
species) is fitted to the explanatory variables `X` (samples × variables) by
multivariate linear regression, then PCA is run on the fitted values to give the
*canonical* (constrained) axes. A second PCA on the residuals gives the
*unconstrained* axes. It is the canonical cousin of PCA, used when an ordination
should be driven by measured environmental gradients.
## Usage
```
rsomics-rda <response.tsv> --constraints env.tsv [--scaling 1|2] [--scale-y] [-o out.tsv]
```
Both inputs are labelled TSV: an empty top-left cell, column IDs on the header
row, then one row per sample (`row_id <tab> v1 <tab> v2 …`). The two tables must
share the same samples in the same row order.
* `--scaling 1` — distance biplot (default); sample distances approximate their
fitted Euclidean distances.
* `--scaling 2` — correlation biplot; focuses on relationships among species.
* `--scale-y` — standardise response columns to unit variance before centring
(use when species are not dimensionally homogeneous).
Output is a flat TSV with `# eigenvalues`, `# samples`, `# species`,
`# biplot`, and `# site_constraints` blocks; axes are labelled `RDA1`, `RDA2`, …
The first axes are canonical (one per constraint dimension), the remainder are
the unconstrained residual axes.
## Origin
This crate is a Rust port of scikit-bio's `skbio.stats.ordination.rda`
(`_redundancy_analysis.py`, function `rda`), reusing its centring (`scale`),
SVD-rank (`svd_rank`), and correlation (`corr`) helpers from
`skbio/stats/ordination/_utils.py`. scikit-bio is BSD-3-Clause, so its source was
read and is cited directly.
Method: Legendre, P. & Legendre, L. (1998/2012). *Numerical Ecology*, §11.1
(redundancy analysis) — DOI [10.1016/B978-0-444-53868-0.50009-5](https://doi.org/10.1016/B978-0-444-53868-0.50009-5).
The linear algebra (regression projection, SVD of fitted values and residuals)
uses [faer](https://crates.io/crates/faer), a pure-Rust SIMD-accelerated backend.
Eigenvalues and proportion explained match scikit-bio to ~1e-9; sample/species
/biplot/site-constraint scores match to ~1e-6 after per-axis sign alignment
(ordination axis signs are arbitrary). Test fixtures are independently generated.
License: MIT OR Apache-2.0.
Upstream credit: [scikit-bio](https://github.com/scikit-bio/scikit-bio) (BSD-3-Clause).