feanor_math/matrix/
owned.rs

1use std::alloc::{Allocator, Global};
2
3use self::submatrix::{AsFirstElement, Submatrix, SubmatrixMut};
4
5use super::*;
6
7///
8/// A matrix that owns its elements.
9/// 
10/// To pass it to algorithms, use the `.data()` and `.data_mut()` functions.
11/// 
12/// # Example
13/// ```
14/// #![feature(allocator_api)]
15/// # use std::alloc::*;
16/// # use feanor_math::ring::*;
17/// # use feanor_math::primitive_int::*;
18/// # use feanor_math::matrix::*;
19/// # use feanor_math::algorithms::linsolve::*;
20/// let mut A = OwnedMatrix::identity(2, 2, StaticRing::<i32>::RING);
21/// let mut B = OwnedMatrix::identity(2, 2, StaticRing::<i32>::RING);
22/// let mut C = OwnedMatrix::identity(2, 2, StaticRing::<i32>::RING);
23/// StaticRing::<i32>::RING.get_ring().solve_right(A.data_mut(), B.data_mut(), C.data_mut(), Global).assert_solved();
24/// ```
25/// 
26pub struct OwnedMatrix<T, A: Allocator = Global> {
27    data: Vec<T, A>,
28    col_count: usize
29}
30
31impl<T> OwnedMatrix<T> {
32
33    pub fn from_fn<F>(row_count: usize, col_count: usize, f: F) -> Self
34        where F: FnMut(usize, usize) -> T
35    {
36        Self::from_fn_in(row_count, col_count, f, Global)
37    }
38    
39    pub fn zero<R: RingStore>(row_count: usize, col_count: usize, ring: R) -> Self
40        where R::Type: RingBase<Element = T>
41    {
42        Self::zero_in(row_count, col_count, ring, Global)
43    }
44
45    pub fn identity<R: RingStore>(row_count: usize, col_count: usize, ring: R) -> Self
46        where R::Type: RingBase<Element = T>
47    {
48        Self::identity_in(row_count, col_count, ring, Global)
49    }
50}
51
52impl<T, A: Allocator> OwnedMatrix<T, A> {
53
54    pub fn new(data: Vec<T, A>, col_count: usize) -> Self {
55        assert!(data.len() % col_count == 0);
56        Self { data, col_count }
57    }
58
59    #[stability::unstable(feature = "enable")]
60    pub fn from_fn_in<F>(row_count: usize, col_count: usize, mut f: F, allocator: A) -> Self
61        where F: FnMut(usize, usize) -> T
62    {
63        let mut data = Vec::with_capacity_in(row_count * col_count, allocator);
64        for i in 0..row_count {
65            for j in 0..col_count {
66                data.push(f(i, j));
67            }
68        }
69        return Self::new(data, col_count);
70    }
71
72    pub fn data<'a>(&'a self) -> Submatrix<'a, AsFirstElement<T>, T> {
73        Submatrix::<AsFirstElement<_>, _>::from_1d(&self.data, self.row_count(), self.col_count())
74    }
75
76    pub fn data_mut<'a>(&'a mut self) -> SubmatrixMut<'a, AsFirstElement<T>, T> {
77        let row_count = self.row_count();
78        let col_count = self.col_count();
79        SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut self.data, row_count, col_count)
80    }
81
82    pub fn at(&self, i: usize, j: usize) -> &T {
83        &self.data[i * self.col_count + j]
84    }
85
86    pub fn at_mut(&mut self, i: usize, j: usize) -> &mut T {
87        &mut self.data[i * self.col_count + j]
88    }
89
90    pub fn row_count(&self) -> usize {
91        self.data.len() / self.col_count()
92    }
93    pub fn col_count(&self) -> usize {
94        self.col_count
95    }
96
97    #[stability::unstable(feature = "enable")]
98    pub fn zero_in<R: RingStore>(row_count: usize, col_count: usize, ring: R, allocator: A) -> Self
99        where R::Type: RingBase<Element = T>
100    {
101        let mut result = Vec::with_capacity_in(row_count * col_count, allocator);
102        for _ in 0..row_count {
103            for _ in 0..col_count {
104                result.push(ring.zero());
105            }
106        }
107        return Self::new(result, col_count);
108    }
109
110    #[stability::unstable(feature = "enable")]
111    pub fn identity_in<R: RingStore>(row_count: usize, col_count: usize, ring: R, allocator: A) -> Self
112        where R::Type: RingBase<Element = T>
113    {
114        let mut result = Vec::with_capacity_in(row_count * col_count, allocator);
115        for i in 0..row_count {
116            for j in 0..col_count {
117                if i != j {
118                    result.push(ring.zero());
119                } else {
120                    result.push(ring.one());
121                }
122            }
123        }
124        return Self::new(result, col_count);
125    }
126
127    #[stability::unstable(feature = "enable")]
128    pub fn clone_matrix<R: RingStore>(&self, ring: R) -> Self
129        where R::Type: RingBase<Element = T>,
130            A: Clone
131    {
132        let mut result = Vec::with_capacity_in(self.row_count() * self.col_count(), self.data.allocator().clone());
133        for i in 0..self.row_count() {
134            for j in 0..self.col_count() {
135                result.push(ring.clone_el(self.at(i, j)));
136            }
137        }
138        return Self::new(result, self.col_count());
139    }
140
141    #[stability::unstable(feature = "enable")]
142    pub fn set_row_count<F>(&mut self, new_count: usize, new_entries: F)
143        where F: FnMut() -> T
144    {
145        self.data.resize_with(new_count * self.col_count(), new_entries);
146    }
147}