1use std::alloc::{Allocator, Global};
2use std::fmt::{Debug, Formatter, Result};
3
4use self::submatrix::{AsFirstElement, Submatrix, SubmatrixMut};
5use super::*;
6
7pub struct OwnedMatrix<T, A: Allocator = Global> {
28 data: Vec<T, A>,
29 col_count: usize,
30 row_count: usize,
31}
32
33impl<T> OwnedMatrix<T> {
34 pub fn from_fn<F>(row_count: usize, col_count: usize, f: F) -> Self
37 where
38 F: FnMut(usize, usize) -> T,
39 {
40 Self::from_fn_in(row_count, col_count, f, Global)
41 }
42
43 pub fn zero<R: RingStore>(row_count: usize, col_count: usize, ring: R) -> Self
45 where
46 R::Type: RingBase<Element = T>,
47 {
48 Self::zero_in(row_count, col_count, ring, Global)
49 }
50
51 pub fn identity<R: RingStore>(row_count: usize, col_count: usize, ring: R) -> Self
53 where
54 R::Type: RingBase<Element = T>,
55 {
56 Self::identity_in(row_count, col_count, ring, Global)
57 }
58}
59
60impl<T, A: Allocator> OwnedMatrix<T, A> {
61 pub fn new(data: Vec<T, A>, col_count: usize) -> Self {
68 let row_count = data.len() / col_count;
69 Self::new_with_shape(data, row_count, col_count)
70 }
71
72 pub fn new_with_shape(data: Vec<T, A>, row_count: usize, col_count: usize) -> Self {
83 assert_eq!(row_count * col_count, data.len());
84 Self {
85 data,
86 col_count,
87 row_count,
88 }
89 }
90
91 #[stability::unstable(feature = "enable")]
94 pub fn from_fn_in<F>(row_count: usize, col_count: usize, mut f: F, allocator: A) -> Self
95 where
96 F: FnMut(usize, usize) -> T,
97 {
98 let mut data = Vec::with_capacity_in(row_count * col_count, allocator);
99 for i in 0..row_count {
100 for j in 0..col_count {
101 data.push(f(i, j));
102 }
103 }
104 return Self::new_with_shape(data, row_count, col_count);
105 }
106
107 pub fn data<'a>(&'a self) -> Submatrix<'a, AsFirstElement<T>, T> {
109 Submatrix::<AsFirstElement<_>, _>::from_1d(&self.data, self.row_count(), self.col_count())
110 }
111
112 pub fn data_mut<'a>(&'a mut self) -> SubmatrixMut<'a, AsFirstElement<T>, T> {
114 let row_count = self.row_count();
115 let col_count = self.col_count();
116 SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut self.data, row_count, col_count)
117 }
118
119 pub fn at(&self, i: usize, j: usize) -> &T { &self.data[i * self.col_count + j] }
121
122 pub fn at_mut(&mut self, i: usize, j: usize) -> &mut T { &mut self.data[i * self.col_count + j] }
124
125 pub fn row_count(&self) -> usize { self.row_count }
127
128 pub fn col_count(&self) -> usize { self.col_count }
131
132 #[stability::unstable(feature = "enable")]
134 pub fn zero_in<R: RingStore>(row_count: usize, col_count: usize, ring: R, allocator: A) -> Self
135 where
136 R::Type: RingBase<Element = T>,
137 {
138 let mut result = Vec::with_capacity_in(row_count * col_count, allocator);
139 for _ in 0..row_count {
140 for _ in 0..col_count {
141 result.push(ring.zero());
142 }
143 }
144 return Self::new_with_shape(result, row_count, col_count);
145 }
146
147 #[stability::unstable(feature = "enable")]
149 pub fn identity_in<R: RingStore>(row_count: usize, col_count: usize, ring: R, allocator: A) -> Self
150 where
151 R::Type: RingBase<Element = T>,
152 {
153 let mut result = Vec::with_capacity_in(row_count * col_count, allocator);
154 for i in 0..row_count {
155 for j in 0..col_count {
156 if i != j {
157 result.push(ring.zero());
158 } else {
159 result.push(ring.one());
160 }
161 }
162 }
163 return Self::new_with_shape(result, row_count, col_count);
164 }
165
166 #[stability::unstable(feature = "enable")]
167 pub fn clone_matrix<R: RingStore>(&self, ring: R) -> Self
168 where
169 R::Type: RingBase<Element = T>,
170 A: Clone,
171 {
172 let mut result = Vec::with_capacity_in(self.row_count() * self.col_count(), self.data.allocator().clone());
173 for i in 0..self.row_count() {
174 for j in 0..self.col_count() {
175 result.push(ring.clone_el(self.at(i, j)));
176 }
177 }
178 return Self::new_with_shape(result, self.row_count(), self.col_count());
179 }
180
181 #[stability::unstable(feature = "enable")]
182 pub fn set_row_count<F>(&mut self, new_count: usize, new_entries: F)
183 where
184 F: FnMut() -> T,
185 {
186 self.data.resize_with(new_count * self.col_count(), new_entries);
187 }
188}
189
190impl<T: Debug, A: Allocator> Debug for OwnedMatrix<T, A> {
191 fn fmt(&self, f: &mut Formatter<'_>) -> Result { self.data().fmt(f) }
192}
193
194#[cfg(test)]
195use crate::primitive_int::*;
196
197#[test]
198fn test_zero_col_matrix() {
199 let A: OwnedMatrix<i64> = OwnedMatrix::new_with_shape(Vec::new(), 10, 0);
200 assert_eq!(0, A.col_count());
201 assert_eq!(10, A.row_count());
202
203 let B: OwnedMatrix<i64> = OwnedMatrix::zero(11, 0, StaticRing::<i64>::RING);
204 assert_eq!(0, B.col_count());
205 assert_eq!(11, B.row_count());
206}