Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

SignalRecommended path
Matrix operations on > 1 000 × 1 000 datandarray + BLAS, or nalgebra
Machine learning / automatic differentiationcandle, burn, or tch
Large sparse datasprs or domain-specific crates
Web API payloads needing serde but no mathstay with matten
Mixed messy data → clean numeric → arithmeticstay 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.