Migration to specialised libraries
For the full narrative guide — when to stay vs. migrate, a target-selection matrix, and per-target playbooks — see the Production migration guide. This reference page is the quick, copy-paste companion: data-export snippets and minimal conversions.
matten is a starting point, not an endpoint. When a PoC graduates to
production or numerical performance becomes critical, migrate the data to a
specialised crate. This page shows how.
When to migrate
| Signal | Recommended path |
|---|---|
| Matrix operations on > 1 000 × 1 000 data | ndarray + BLAS, or nalgebra |
| Machine learning / automatic differentiation | candle, burn, or tch |
| Large sparse data | sprs or domain-specific crates |
| Web API payloads needing serde but no math | stay with matten |
| Mixed messy data → clean numeric → arithmetic | stay with matten dynamic |
Exporting data from matten
Every matten tensor exposes its flat row-major data. The simplest data-export
path is:
#![allow(unused)]
fn main() {
let flat: Vec<f64> = tensor.into_vec(); // consuming, no copy
// or
let flat: Vec<f64> = tensor.to_vec(); // borrowing clone
}
The shape is available as:
#![allow(unused)]
fn main() {
let shape: &[usize] = tensor.shape();
}
To ndarray
The bridge-first path uses the matten-ndarray crate (copies, numeric-only, rejects
dynamic tensors, preserves logical row-major order — see the
bridge contract):
#![allow(unused)]
fn main() {
use matten::Tensor;
use matten_ndarray::to_arrayd;
let t = Tensor::new(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], &[2, 3]);
let arr = to_arrayd(&t)?; // ArrayD<f64>, logical row-major
println!("{arr}");
}
Without the bridge crate, convert manually from the flat Vec<f64> plus shape:
#![allow(unused)]
fn main() {
use matten::Tensor;
use ndarray::ArrayD;
let t = Tensor::new(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], &[2, 3]);
let shape: Vec<usize> = t.shape().to_vec();
let flat: Vec<f64> = t.into_vec();
let arr = ArrayD::from_shape_vec(shape, flat).unwrap();
println!("{arr}");
}
ndarray supports BLAS-backed matrix multiplication, advanced indexing,
views, and strided arrays.
To nalgebra
#![allow(unused)]
fn main() {
use matten::Tensor;
use nalgebra::DMatrix;
let t = Tensor::new(vec![1.0, 2.0, 3.0, 4.0], &[2, 2]);
let flat: Vec<f64> = t.into_vec();
// DMatrix is column-major; transpose if needed
let mat = DMatrix::from_row_slice(2, 2, &flat);
println!("{mat}");
}
nalgebra provides static and dynamic matrices, LU/QR/SVD decomposition,
and linear algebra operations.
To candle (ML tensors)
#![allow(unused)]
fn main() {
use matten::Tensor;
// candle_core = { version = "0.x", features = ["..."] }
let t = Tensor::new(vec![1.0, 2.0, 3.0, 4.0], &[2, 2]);
// matten uses f64; convert to f32 if the Candle workflow wants f32.
let flat_f32: Vec<f32> = t.as_slice().iter().map(|&v| v as f32).collect();
let shape = t.shape().to_vec();
// let candle_t = candle_core::Tensor::from_vec(flat_f32, shape, &device)?;
println!("data ready for candle: {flat_f32:?}, shape: {shape:?}");
}
candle targets GPU-accelerated ML workflows (transformers, training loops).
Dynamic tensors: clean then migrate
If your data went through matten’s dynamic feature, convert to a numeric tensor
numeric first:
#![allow(unused)]
fn main() {
use matten::{Element, Tensor};
let raw = Tensor::from_csv_dynamic("1.0,2.0\n3.0,4.0\n")?;
let filled = raw.fill_none(Element::Float(0.0));
let numeric: Tensor = filled.try_numeric()?; // MattenError if non-numeric
let flat: Vec<f64> = numeric.into_vec(); // hand off
}
Allocation warning
matten clones on every reshape and slice. For large datasets,
migrate before performing many transformations:
#![allow(unused)]
fn main() {
// Prefer this pattern for large data:
let result = compute_in_matten(&small_data);
let flat = result.into_vec();
// then pass `flat` to ndarray/nalgebra for the heavy lifting
}
Compatibility promise (v0.x)
During v0.x, API changes are allowed but minimised after a release. The core
Tensor type, the public error model, and the panic-vs-Result split are stable
design decisions and will not change without a documented breaking change. See the
public API snapshot and the CHANGELOG for the exact
current export surface.
v1.0.0 requires explicit maintainer confirmation and a full public API
review. See the project CHANGELOG for migration notes on any breaking changes.