Uma crate Rust para criação e manipulação de matrizes genéricas com foco em performance e ergonomia.
Matrix handler é uma biblioteca Rust leve e genérica para trabalhar com matrizes. Os elementos são armazenados em um vetor contíguo na memória (flat array em row-major order), garantindo excelente localidade de cache — muito mais eficiente do que a abordagem clássica de "vetor de vetores".
Matriz 3×3 lógica: Armazenamento interno (Vec<T>):
┌───┬───┬───┐
│ 1 │ 2 │ 3 │ [1, 2, 3, 4, 5, 6, 7, 8, 9]
├───┼───┼───┤ ↑
│ 4 │ 5 │ 6 │ índice = linha × colunas + coluna
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┴───┴───┘
| Funcionalidade | Status |
|---|---|
Criação de matrizes genéricas (Matrix<T>) |
✅ Implementado |
| Validação de dimensões na construção | ✅ Implementado |
Indexação por (linha, coluna) |
✅ Implementado |
Adição de matrizes (Add / AddAssign) |
✅ Implementado |
| Subtração de matrizes | ✅ Implementado |
| Multiplicação matricial | ✅ Implementado |
| Multiplicação / Divisão escalar | ✅ Implementado |
| Transposição | 🔜 Em breve |
| Iteradores (linhas / colunas) | 🔜 Em breve |
Display formatado |
✅ Implementado |
O projeto ainda vai ser carregado ao crates.io, por enquanto para utilizar deve-se baixar e inserir o arquivo ao seu projeto.
[dependencies]
matrix_handler = "0.1.2"use matrix_handler::Matrix;
fn main() {
let matrix = Matrix::new(3, 3, vec![
1, 2, 3,
4, 5, 6,
7, 8, 9,
]).expect("dimensões devem corresponder ao tamanho do vetor");
// Acessa o elemento na linha 1, coluna 2 (indexação começa em 0)
println!("Elemento [1][2] = {}", matrix[(1, 2)]); // → 6
}use matrix_handler::{Matrix, MatrixError};
fn main() {
// Erro: 2×2 exige 4 elementos, mas apenas 3 foram fornecidos
let resultado = Matrix::new(2, 2, vec![1, 2, 3]);
match resultado {
Ok(m) => println!("Matriz criada: {:?}", m),
Err(MatrixError::DimensionMismatch) => {
eprintln!("Erro: dimensões não correspondem ao número de elementos!");
}
}
}use matrix_handler::Matrix;
// Inteiros
let int_matrix = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
// Floats
let float_matrix = Matrix::new(2, 2, vec![1.0, 2.5, 3.7, 4.2]).unwrap();
// Strings
let str_matrix = Matrix::new(1, 3, vec!["a", "b", "c"]).unwrap();use matrix_handler::{Matrix, MatrixMath};
let a = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
let b = Matrix::new(2, 2, vec![10, 20, 30, 40]).unwrap();
// Via operador
let c = &a + &b;
assert_eq!(c[(0, 0)], 11);
// Via método seguro (valida dimensões)
let c = a.try_add(&b).unwrap();
assert_eq!(c[(1, 1)], 44);
// In-place (sem alocação extra)
let mut a = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
a += &b;
assert_eq!(a[(0, 1)], 22);use matrix_handler::{Matrix, MatrixMath};
let a = Matrix::new(2, 2, vec![10, 20, 30, 40]).unwrap();
let b = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
// Via operador
let c = &a - &b;
assert_eq!(c[(0, 0)], 9);
// Via método seguro (valida dimensões)
let c = a.try_sub(&b).unwrap();
assert_eq!(c[(1, 1)], 36);
// In-place (sem alocação extra)
let mut a = Matrix::new(2, 2, vec![10, 20, 30, 40]).unwrap();
a -= &b;
assert_eq!(a[(0, 1)], 18);use matrix_handler::Matrix;
// A (2×3) × B (3×2) = C (2×2)
let a = Matrix::new(2, 3, vec![
1, 2, 3,
4, 5, 6,
]).unwrap();
let b = Matrix::new(3, 2, vec![
7, 8,
9, 10,
11, 12,
]).unwrap();
let c = a * &b;
// Resultado:
// [ 1*7+2*9+3*11, 1*8+2*10+3*12 ] [ 58, 64 ]
// [ 4*7+5*9+6*11, 4*8+5*10+6*12 ] = [ 139, 154 ]
assert_eq!(c[(0, 0)], 58);
assert_eq!(c[(1, 1)], 154);ou
use matrix_handler::Matrix;
// A (2×3) × B (3×2)
let mut a = Matrix::new(2, 3, vec![
1, 2, 3,
4, 5, 6,
]).unwrap();
let b = Matrix::new(3, 2, vec![
7, 8,
9, 10,
11, 12,
]).unwrap();
a *= &b;
// Resultado:
// [ 1*7+2*9+3*11, 1*8+2*10+3*12 ] [ 58, 64 ]
// [ 4*7+5*9+6*11, 4*8+5*10+6*12 ] = [ 139, 154 ]
assert_eq!(c[(0, 0)], 58);
assert_eq!(c[(1, 1)], 154);use matrix_handler::Matrix;
let mut a = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
a = &a * 3;
// Resultado:
// [ 1*3, 2*3 ] [ 3, 6 ]
// [ 3*3, 4*3 ] = [ 9, 12 ]
assert_eq!(c[(0, 0)], 3);
assert_eq!(c[(1, 1)], 12);ou
use matrix_handler::Matrix;
let mut a = Matrix::new(2, 2, vec![1, 2, 3, 4]).unwrap();
&a *= 3;
// Resultado:
// [ 1*3, 2*3 ] [ 3, 6 ]
// [ 3*3, 4*3 ] = [ 9, 12 ]
assert_eq!(c[(0, 0)], 3);
assert_eq!(c[(1, 1)], 12);use matrix_handler::Matrix;
let a = Matrix::new(2, 2, vec![3, 6, 9, 12]).unwrap();
let b = &a / 3;
assert_eq!(b[(0, 0)], 1);
assert_eq!(b[(1, 1)], 4);ou
use matrix_handler::Matrix;
let mut a = Matrix::new(2, 2, vec![3, 6, 9, 12]).unwrap();
a /= 3;
assert_eq!(b[(0, 0)], 1);
assert_eq!(b[(1, 1)], 4);use matrix_handler::Matrix;
let m = Matrix::new(3, 3, vec![
1, 2, 3,
4, 5, 6,
7, 8, 9,
]).unwrap();
println!("{}", m);
// Saída:
// 1 2 3
// 4 5 6
// 7 8 9Valores com larguras diferentes são alinhados automaticamente:
use matrix_handler::Matrix;
let m = Matrix::new(2, 2, vec![1, 100, 20, 3]).unwrap();
println!("{}", m);
// Saída:
// 1 100
// 20 3matrix_handler/
├── Cargo.toml # Metadados e dependências
├── README.md # Este arquivo
├── CONTEXT # Notas de design e decisões arquiteturais
├── src/
│ └── lib.rs # Código principal: Matrix<T>, MatrixError
└── tests/
├── matrix_creation.rs # Testes de criação e validação
├── matrix_math.rs # Testes de soma e subtração
├── matrix_mutability.rs # Testes de indexação mutável
└── matrix_reading.rs # Testes de indexação e leitura
- Flat array vs. Vec<Vec<T>>: armazenamento contíguo em memória para melhor performance de cache.
- Genérica sobre
T: sem restrição de trait na struct — traits são exigidos apenas nos métodos que precisam deles. - Erros explícitos:
Result<Matrix<T>, MatrixError>no construtor em vez depanic!. - Indexação via trait
Index: permite a sintaxe naturalmatrix[(i, j)].
cargo testSaída esperada:
running 3 tests ... ok # matrix_creation
running 4 tests ... ok # matrix_math
running 2 tests ... ok # matrix_mutability
running 4 tests ... ok # matrix_reading
cargo doc --openEste projeto está licenciado sob a Licença MIT.
Feito com 🦀 Rust