Skip to content

strngrthnall/matrix_handler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧮 Matrix Handler

Uma crate Rust para criação e manipulação de matrizes genéricas com foco em performance e ergonomia.

Rust Edition Version License Status


Sobre

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 │
└───┴───┴───┘

Funcionalidades

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

Início Rápido

Adicionando ao seu projeto

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"

Criando uma matriz

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
}

Tratamento de erros

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!");
        }
    }
}

Funciona com qualquer tipo

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();

Soma de matrizes

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);

Subtração de matrizes

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);

Multiplicação de matrizes

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);

Multiplicação Escalar

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);

Divisão Escalar

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);

Exibição formatada (Display)

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 9

Valores 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   3

Arquitetura

matrix_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

Decisões de design

  • 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 de panic!.
  • Indexação via trait Index: permite a sintaxe natural matrix[(i, j)].

Executando os testes

cargo test

Saí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

Gerando a documentação

cargo doc --open

Licença

Este projeto está licenciado sob a Licença MIT.


Feito com 🦀 Rust

About

Uma biblioteca leve e eficiente para manipulação, operações matemáticas e transformação de matrizes em Rust. Focada em performance e simplicidade de interface.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages