tensor4all_tcicore/matrixluci/
source.rs1use crate::matrixluci::scalar::Scalar;
8use crate::matrixluci::types::DenseOwnedMatrix;
9use std::marker::PhantomData;
10
11pub trait CandidateMatrixSource<T: Scalar> {
16 fn nrows(&self) -> usize;
18
19 fn ncols(&self) -> usize;
21
22 fn get_block(&self, rows: &[usize], cols: &[usize], out: &mut [T]);
24
25 fn dense_column_major_slice(&self) -> Option<&[T]> {
27 None
28 }
29
30 fn get(&self, row: usize, col: usize) -> T {
32 let mut out = [T::zero(); 1];
33 self.get_block(&[row], &[col], &mut out);
34 out[0]
35 }
36}
37
38pub struct DenseMatrixSource<'a, T: Scalar> {
42 data: &'a [T],
43 nrows: usize,
44 ncols: usize,
45}
46
47pub struct LazyMatrixSource<T: Scalar, F> {
53 nrows: usize,
54 ncols: usize,
55 fill_block: F,
56 _marker: PhantomData<T>,
57}
58
59impl<'a, T: Scalar> DenseMatrixSource<'a, T> {
60 pub fn from_column_major(data: &'a [T], nrows: usize, ncols: usize) -> Self {
62 assert_eq!(data.len(), nrows * ncols);
63 Self { data, nrows, ncols }
64 }
65}
66
67impl<T: Scalar, F> LazyMatrixSource<T, F>
68where
69 F: Fn(&[usize], &[usize], &mut [T]),
70{
71 pub fn new(nrows: usize, ncols: usize, fill_block: F) -> Self {
73 Self {
74 nrows,
75 ncols,
76 fill_block,
77 _marker: PhantomData,
78 }
79 }
80}
81
82impl<T: Scalar> CandidateMatrixSource<T> for DenseMatrixSource<'_, T> {
83 fn nrows(&self) -> usize {
84 self.nrows
85 }
86
87 fn ncols(&self) -> usize {
88 self.ncols
89 }
90
91 fn get_block(&self, rows: &[usize], cols: &[usize], out: &mut [T]) {
92 assert_eq!(out.len(), rows.len() * cols.len());
93 for (j, &col) in cols.iter().enumerate() {
94 for (i, &row) in rows.iter().enumerate() {
95 out[i + rows.len() * j] = self.data[row + self.nrows * col];
96 }
97 }
98 }
99
100 fn dense_column_major_slice(&self) -> Option<&[T]> {
101 Some(self.data)
102 }
103}
104
105impl<T: Scalar, F> CandidateMatrixSource<T> for LazyMatrixSource<T, F>
106where
107 F: Fn(&[usize], &[usize], &mut [T]),
108{
109 fn nrows(&self) -> usize {
110 self.nrows
111 }
112
113 fn ncols(&self) -> usize {
114 self.ncols
115 }
116
117 fn get_block(&self, rows: &[usize], cols: &[usize], out: &mut [T]) {
118 assert_eq!(out.len(), rows.len() * cols.len());
119 (self.fill_block)(rows, cols, out);
120 }
121}
122
123pub(crate) fn materialize_source<T: Scalar, S: CandidateMatrixSource<T>>(
124 source: &S,
125) -> DenseOwnedMatrix<T> {
126 let nrows = source.nrows();
127 let ncols = source.ncols();
128 let rows: Vec<usize> = (0..nrows).collect();
129 let cols: Vec<usize> = (0..ncols).collect();
130 let mut out = vec![T::zero(); nrows * ncols];
131 source.get_block(&rows, &cols, &mut out);
132 DenseOwnedMatrix::from_column_major(out, nrows, ncols)
133}
134
135#[cfg(test)]
136mod tests;