use std::iter::Zip;
use std::slice::{ChunksExact, ChunksExactMut, Iter};
pub struct DenseMatrix {
pub(crate) cols: usize,
data: Vec<f32>,
}
impl DenseMatrix {
pub fn new(rows: usize, cols: usize) -> Self {
let data = vec![0.0; rows * cols];
Self { cols, data }
}
pub fn rows(&self) -> ChunksExact<'_, f32> {
self.data.chunks_exact(self.cols)
}
pub fn rows_mut(&mut self) -> ChunksExactMut<'_, f32> {
self.data.chunks_exact_mut(self.cols)
}
pub fn row(&self, i: usize) -> &[f32] {
let idx = i * self.cols;
&self.data[idx..(idx + self.cols)]
}
pub fn row_mut(&mut self, i: usize) -> &mut [f32] {
let idx = i * self.cols;
&mut self.data[idx..(idx + self.cols)]
}
pub fn dot(&self, x: &[f32]) -> Vec<f32> {
self.rows()
.map(|row| row.iter().zip(x).map(|(ri, xi)| ri * xi).sum())
.collect()
}
}
pub struct CooMatrix {
row_indices: Vec<usize>,
col_indices: Vec<usize>,
values: Vec<f32>,
}
impl CooMatrix {
pub fn with_capacity(capacity: usize) -> Self {
Self {
row_indices: Vec::with_capacity(capacity),
col_indices: Vec::with_capacity(capacity),
values: Vec::with_capacity(capacity),
}
}
pub fn push(&mut self, row_index: usize, col_index: usize, value: f32) {
self.row_indices.push(row_index);
self.col_indices.push(col_index);
self.values.push(value);
}
pub fn len(&self) -> usize {
self.row_indices.len()
}
pub fn get(&self, i: usize) -> (usize, usize, f32) {
(self.row_indices[i], self.col_indices[i], self.values[i])
}
}
impl<'a> IntoIterator for &'a CooMatrix {
type Item = ((&'a usize, &'a usize), &'a f32);
type IntoIter = Zip<Zip<Iter<'a, usize>, Iter<'a, usize>>, Iter<'a, f32>>;
fn into_iter(self) -> Self::IntoIter {
self.row_indices
.iter()
.zip(self.col_indices.iter())
.zip(self.values.iter())
}
}
pub struct LilMatrix {
row_list: Vec<Vec<(usize, f32)>>,
}
impl LilMatrix {
pub fn new() -> Self {
Self {
row_list: Vec::new(),
}
}
pub fn push(&mut self, row_index: usize, col_index: usize, value: f32) {
if row_index == self.row_list.len() {
self.row_list.push(Vec::new());
}
self.row_list[row_index].push((col_index, value));
}
}
impl<'a> IntoIterator for &'a LilMatrix {
type Item = &'a Vec<(usize, f32)>;
type IntoIter = Iter<'a, Vec<(usize, f32)>>;
fn into_iter(self) -> Self::IntoIter {
self.row_list.iter()
}
}