use std::collections::HashMap;
#[derive(Clone, Debug)]
pub struct ExprMatrix {
row_names: Vec<String>,
col_names: Vec<String>,
data: Vec<f64>,
row_index: HashMap<String, usize>,
}
impl ExprMatrix {
pub fn new(row_names: Vec<String>, col_names: Vec<String>, data: Vec<f64>) -> Self {
assert_eq!(
data.len(),
row_names.len() * col_names.len(),
"data length must equal nrow * ncol"
);
let mut row_index = HashMap::with_capacity(row_names.len());
for (i, name) in row_names.iter().enumerate() {
row_index.entry(name.clone()).or_insert(i);
}
ExprMatrix {
row_names,
col_names,
data,
row_index,
}
}
pub fn nrow(&self) -> usize {
self.row_names.len()
}
pub fn ncol(&self) -> usize {
self.col_names.len()
}
pub fn row_names(&self) -> &[String] {
&self.row_names
}
pub fn col_names(&self) -> &[String] {
&self.col_names
}
pub fn row_of(&self, name: &str) -> Option<usize> {
self.row_index.get(name).copied()
}
#[inline]
pub fn get(&self, row: usize, col: usize) -> f64 {
self.data[row * self.col_names.len() + col]
}
#[inline]
pub fn row(&self, row: usize) -> &[f64] {
let ncol = self.col_names.len();
&self.data[row * ncol..(row + 1) * ncol]
}
pub fn column(&self, col: usize) -> Vec<f64> {
(0..self.nrow()).map(|r| self.get(r, col)).collect()
}
}