# Matamorph
A Rust library for seamless conversions between popular matrix
libraries: **ndarray**, **nalgebra**, **faer**, and **mdarray**.
## Features
The crate provides three types of conversions:
- **Owned conversions** : Create a new matrix with copied data
- **Immutable reference conversions** : Zero-copy read-only views
- **Mutable reference conversions** : Zero-copy read-write views
## Usage
Add this to your `Cargo.toml` (for conversion between `ndarray` and ` faer`):
```toml
[dependencies]
matamorph = { git = "https://gitlab.com/starcluster/matamorph", features = ["with-ndarray", "with-faer"]}
```
## Example
### Basic usage
```rust
use matamorph::own::MataConvertOwn;
use matamorph::ref_::MataConvertRef;
use matamorph::mut_::MataConvertMut;
// Owned conversion (copies data): ndarray → nalgebra
let a = ndarray::array![[1.0, 2.0], [3.0, 4.0]];
let b = a.to_nalgebra();
assert_eq!(b[(0, 1)], 2.0);
// Reference conversion (zero-copy): mdarray → faer
let c = mdarray::tensor![[5.0, 6.0], [7.0, 8.0]];
let d = c.view(.., ..).to_faer();
assert_eq!(d[(1, 0)], 7.0);
// Mutable reference conversion (zero-copy): ndarray → faer
let mut e = ndarray::array![[9.0, 10.0], [11.0, 12.0]];
let mut f = e.view_mut().to_faer();
f[(0, 0)] = 0.0;
assert_eq!(e[[0, 0]], 0.0); // Original is modified
```
### Memory Layout Considerations (nalgebra)
```rust
use matamorph::ref_::MataConvertRef;
// ⚠️ Warning: conversions to nalgebra from row-major references are transposed!
let g = ndarray::array![[1.0, 2.0], [3.0, 4.0]];
let h = g.view().to_nalgebra();
assert_eq!(h[(1, 0)], 2.0); // h is transposed: h[(row, col)] = g[(col, row)]
// But conversions FROM nalgebra preserve layout (no transposition)
let i = nalgebra::dmatrix![1.0, 2.0; 3.0, 4.0];
let i_view = i.view((0,0), (2,2));
let j = i_view.to_ndarray();
assert_eq!(j[[0, 1]], 2.0); // No transposition
assert_eq!(i[(0, 1)], 2.0); // Same element accessed
// Similarly, conversions between column-major crates (faer ↔ nalgebra) preserve layout
let k = faer::mat![[1.0, 2.0], [3.0, 4.0]];
let l = k.as_ref().to_nalgebra();
assert_eq!(l[(1, 0)], 3.0); // No transposition
assert_eq!(k[(1, 0)], 3.0); // Same element accessed
// Finally note that conversion of references with nalgebra does not support
// rectangular matrices due to the way memory is represented. Use a "owned" conversion instead.
```
## License
MIT OR Apache-2.0