use crate::core::Error;
#[derive(Debug, Clone, PartialEq)]
pub struct Matrix {
nrows: usize,
ncols: usize,
data: Vec<f64>,
}
impl Matrix {
pub fn from_row_major(nrows: usize, ncols: usize, data: Vec<f64>) -> Result<Self, Error> {
let expected = nrows * ncols;
let got = data.len();
if expected != got {
return Err(Error::InvalidMatrixShape { expected, got });
}
Ok(Self { nrows, ncols, data })
}
pub fn nrows(&self) -> usize {
self.nrows
}
pub fn ncols(&self) -> usize {
self.ncols
}
pub fn data(&self) -> &[f64] {
&self.data
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::Error;
#[test]
fn from_row_major_valid() {
let m = Matrix::from_row_major(2, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).unwrap();
assert_eq!(m.nrows(), 2);
assert_eq!(m.ncols(), 3);
assert_eq!(m.data(), &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
}
#[test]
fn from_row_major_wrong_length() {
let result = Matrix::from_row_major(2, 3, vec![1.0, 2.0]);
assert_eq!(
result.unwrap_err(),
Error::InvalidMatrixShape {
expected: 6,
got: 2
}
);
}
#[test]
fn zero_dimensions() {
let m = Matrix::from_row_major(0, 0, vec![]).unwrap();
assert_eq!(m.nrows(), 0);
assert_eq!(m.ncols(), 0);
assert!(m.data().is_empty());
}
#[test]
fn single_element() {
let m = Matrix::from_row_major(1, 1, vec![42.0]).unwrap();
assert_eq!(m.data(), &[42.0]);
}
#[test]
fn clone_and_eq() {
let m = Matrix::from_row_major(2, 2, vec![1.0, 0.0, 0.0, 1.0]).unwrap();
assert_eq!(m, m.clone());
}
}