Module procrustes

Source
Expand description

Procrustes alignment for cross-model embedding comparison (RFC-012 P10).

When switching embedding models (e.g., MentalRoBERTa → all-MiniLM), vectors from the old model are incompatible with the new model’s space. Procrustes alignment finds the optimal orthogonal rotation R that minimizes ||A - BR||² where A is the target space and B is the source.

§Algorithm

Given N corresponding vector pairs (a_i, b_i):

  1. Center both sets: A’ = A - mean(A), B’ = B - mean(B)
  2. Compute cross-covariance: M = A’^T B’
  3. SVD: M = U Σ V^T
  4. Rotation: R = V U^T
  5. Scale: s = trace(Σ) / trace(B’^T B’)
  6. Transform: b_aligned = s × (b - mean(B)) × R + mean(A)

§Example

use cvx_analytics::procrustes::{ProcrustesTransform, fit_procrustes};

let source = vec![vec![1.0, 0.0], vec![0.0, 1.0], vec![1.0, 1.0]];
let target = vec![vec![0.0, 1.0], vec![-1.0, 0.0], vec![-1.0, 1.0]];

let transform = fit_procrustes(&source, &target).unwrap();
let aligned = transform.apply(&[1.0, 0.0]);
// aligned should be close to [0.0, 1.0] (90° rotation)

Structs§

ProcrustesTransform
A fitted Procrustes transformation.

Functions§

apply_rotation 🔒
fit_procrustes
Fit a Procrustes transformation from source to target vectors.
jacobi_eigendecomposition 🔒
Jacobi eigendecomposition for symmetric matrices.
svd_jacobi 🔒
Simple Jacobi SVD for small-to-moderate matrices. Returns (U, singular_values, V^T).