oat_rust/algebra/matrices/operations/mod.rs
1//! Matrix multiplication, inversion, factorization, etc.
2//!
3//!
4//! - [accessing entries in rows and columns](crate::algebra::matrices::query)
5//! - [matrix and vector multiplication](crate::algebra::matrices::operations::multiply)
6//! - [solving systems of equations](crate::algebra::matrices::operations::solve)
7//! - [matrix factorization](crate::algebra::matrices::operations::umatch)
8//! - [matrix inversion](crate::algebra::matrices::operations::invert)
9//! - [kernels](crate::algebra::matrices::operations::umatch::row_major::Umatch::kernel)
10//! - [images](crate::algebra::matrices::operations::umatch::row_major::Umatch::image)
11//! - [transforming and combining vectors (scale, add, drop zeros, reindex, etc.)](crate::algebra::vectors::operations)
12
13pub mod multiply;
14pub mod invert;
15pub mod vec_of_vec_reduction;
16pub mod solve;
17pub mod transform_entry_wise;
18pub mod transform_vector_wise;
19pub mod umatch;
20// pub mod display;
21pub mod transpose;
22
23
24// =========================================================================
25
26
27use crate::algebra::rings::operator_traits::{Semiring, Ring, DivisionRing};
28use crate::algebra::vectors::entries::{KeyValSet, KeyValGet};
29
30use crate::utilities::order::{OrderOperatorByKeyCutsom, JudgePartialOrder};
31
32use self::{multiply::ProductMatrix, umatch::row_major::Umatch};
33
34use super::query::{ViewRowAscend, IndicesAndCoefficients};
35use super::types::packet::MatrixAlgebraPacket;
36use super::types::transpose::{Transpose, AntiTranspose};
37use super::types::reverse::Reverse;
38
39use std::hash::Hash;
40use std::fmt::Debug;
41
42
43/// Convenient methods for matrix operations
44pub trait MatrixOperations {
45
46
47
48 // fn map_left< Vector, RingOperator, OrderOperator, >(
49 // self,
50 // vector: Vector,
51 // ring_operator: RingOperator,
52 // order_operator: OrderOperator
53 // )
54 // -> LinearCombinationSimplified< MatrixView::IntoIter, MatrixIndex, RingElement, RingOperator >
55
56 // Simplify<
57 // HitMerge<
58 // Scale< MatrixView::IntoIter, MatrixIndex, RingOperator, RingElement >,
59 // OrderOperator,
60 // >,
61 // MatrixIndex,
62 // RingOperator,
63 // RingElement,
64 // >
65 // where
66 // Self: Sized,
67 // Matrix: FnMut( Index ) -> MatrixView,
68 // MatrixView: IntoIterator,
69 // < MatrixView as IntoIterator >::Item: KeyValGet< MatrixIndex, RingElement > + KeyValSet< MatrixIndex, RingElement >,
70 // OrderOperator: JudgePartialOrder< < MatrixView as IntoIterator >::Item >,
71 // MatrixIndex: PartialEq,
72 // RingElement: Clone,
73 // RingOperator: Clone + Semiring< RingElement >,
74 // {
75 // return self.matrix_multiply_unsimplified(matrix, ring_operator.clone(), order_operator).simplify( ring_operator )
76 // }
77
78
79
80 /// Lefthand matrix multiplication
81 ///
82 /// Returns `self * other`
83 fn multiply_left< Othr, RingOperator, OrderOperator >(
84 self,
85 other: Othr,
86 ring_operator: RingOperator,
87 order_operator: OrderOperator
88 )
89 ->
90 ProductMatrix< Self, Othr, RingOperator, OrderOperator >
91
92 where
93 Self: ViewRowAscend + IndicesAndCoefficients + Sized,
94 Othr: ViewRowAscend + IndicesAndCoefficients< Coefficient = Self::Coefficient, RowIndex = Self::ColIndex >,
95 Self::ViewMajorAscend: IntoIterator,
96 Othr::ViewMajorAscend: IntoIterator,
97 Self::EntryMajor: KeyValGet < Self::ColIndex, Self::Coefficient >,
98 Othr::EntryMajor: KeyValGet < Othr::ColIndex, Othr::Coefficient >,
99 Othr::ColIndex: Clone,
100 Othr::Coefficient: Clone,
101 RingOperator: Clone + Semiring< Self::Coefficient >,
102 OrderOperator: Clone + JudgePartialOrder< Othr::EntryMajor >,
103 {
104 ProductMatrix::new( self, other, ring_operator, order_operator)
105 }
106
107 /// Righthand matrix multiplication
108 ///
109 /// Returns `other * self`
110 fn multiply_right< Othr, RingOperator, OrderOperator >(
111 self,
112 other: Othr,
113 ring_operator: RingOperator,
114 order_operator: OrderOperator
115 )
116 ->
117 ProductMatrix< Othr, Self, RingOperator, OrderOperator >
118
119 where
120 Self: ViewRowAscend + IndicesAndCoefficients + Sized,
121 Othr: ViewRowAscend + IndicesAndCoefficients< Coefficient = Self::Coefficient, ColIndex = Self::RowIndex >,
122 Self::ViewMajorAscend: IntoIterator,
123 Othr::ViewMajorAscend: IntoIterator,
124 Self::EntryMajor: KeyValGet < Self::ColIndex, Self::Coefficient >,
125 Othr::EntryMajor: KeyValGet < Othr::ColIndex, Othr::Coefficient >,
126 Self::ColIndex: Clone,
127 Self::Coefficient: Clone,
128 RingOperator: Clone + Semiring< Self::Coefficient >,
129 OrderOperator: Clone + JudgePartialOrder< Self::EntryMajor >,
130 {
131 ProductMatrix::new( other, self, ring_operator, order_operator)
132 }
133
134
135 /// Lefthand matrix multiplication
136 ///
137 /// Returns `self * other`, where `other` is a matrix "packet," containing a matrix, a ring operator, and order operators for row and column entries.
138 ///
139 /// **Note** There is no corresponding function `multiply_right_packet`, because we need an order operator from the packet to combine entries
140 fn multiply_left_packet< Othr, RingOperator, OrderOperatorRowEntries, OrderOperatorColEntries >(
141 self,
142 other: MatrixAlgebraPacket< Othr, RingOperator, OrderOperatorRowEntries, OrderOperatorColEntries >,
143 )
144 ->
145 ProductMatrix< Self, Othr, RingOperator, OrderOperatorRowEntries >
146
147 where
148 Self: ViewRowAscend + IndicesAndCoefficients + Sized,
149 Othr: ViewRowAscend + IndicesAndCoefficients< Coefficient = Self::Coefficient, RowIndex = Self::ColIndex >,
150 Self::ViewMajorAscend: IntoIterator,
151 Othr::ViewMajorAscend: IntoIterator,
152 Self::EntryMajor: KeyValGet < Self::ColIndex, Self::Coefficient >,
153 Othr::EntryMajor: KeyValGet < Othr::ColIndex, Othr::Coefficient >,
154 Othr::ColIndex: Clone,
155 Othr::Coefficient: Clone,
156 RingOperator: Clone + Semiring< Self::Coefficient >,
157 OrderOperatorRowEntries: Clone + JudgePartialOrder< Othr::EntryMajor >,
158 {
159 ProductMatrix::new( self, other.matrix, other.ring, other.row_entry_order )
160 }
161
162
163 /// Returns a U-match factorization
164 ///
165 /// The argument `iter_keymaj` must run over row indices in *strictly descending order*, as determined by `order_operator_RowIndex`.
166 fn umatch< Other, RingOperator, OrderOperatorRowIndex, OrderOperatorColIndex, IterRowIndex >(
167 self,
168 iter_keymaj: IterRowIndex,
169 ring_operator: RingOperator,
170 order_operator_RowIndex: OrderOperatorRowIndex,
171 order_operator_ColIndex: OrderOperatorColIndex,
172 )
173 ->
174 Umatch
175 <
176 Self,
177 RingOperator,
178 OrderOperatorByKeyCutsom< Self::ColIndex, Self::Coefficient, Self::EntryMajor, OrderOperatorColIndex, >, // recall that entries in the major views have minor keys
179 OrderOperatorByKeyCutsom< Self::RowIndex, Self::Coefficient, Self::EntryMinor, OrderOperatorRowIndex, >, // recall that entries in the minor views have major keys
180 >
181 where Self: Sized + ViewRowAscend + IndicesAndCoefficients,
182 IterRowIndex: Iterator < Item = Self::RowIndex >,
183 Self::ColIndex: Clone + Hash + std::cmp::Eq + Debug,
184 Self::RowIndex: Clone + Hash + std::cmp::Eq + Debug, // !!! remove Debug eventually
185 Self::Coefficient: Clone + Debug, // !!! remove Debug eventually
186 RingOperator: Clone + Semiring< Self::Coefficient > + Ring< Self::Coefficient > + DivisionRing< Self::Coefficient >,
187 Self::ViewMajorAscend: Clone, // !!! remove clone
188 Self::ViewMajorAscendIntoIter: Clone,
189 Self::EntryMajor: KeyValSet< Self::ColIndex, Self::Coefficient > + Debug + Clone, // !!!!!!!!!!!!!! REMOVE THE DEBUG REQUIREMENT AFTER DEBUGGING!!!!!
190 OrderOperatorColIndex: Clone + JudgePartialOrder < Self::ColIndex >, // !!! remove clone
191 OrderOperatorRowIndex: Clone + JudgePartialOrder < Self::RowIndex >,
192
193 {
194 Umatch::factor( self, iter_keymaj, ring_operator, order_operator_RowIndex, order_operator_ColIndex )
195 }
196
197 /// Wraps `self` in a [crate::algebra::matrices::types::transpose::Transpose] struct.
198 fn transpose( self ) -> Transpose<Self>
199 where
200 Self: Sized,
201 { Transpose::new( self ) }
202
203 /// Wraps `& self` in a [crate::algebra::matrices::types::transpose::Transpose] struct.
204 fn transpose_ref( &self ) -> Transpose<&Self>
205 where
206 { Transpose::new( & self ) }
207
208 /// Wraps `self` in a [crate::algebra::matrices::types::transpose::Transpose] struct.
209 ///
210 /// # Caution
211 ///
212 /// There are three important differences between [AntiTranspose] and the matrix returned by [antitranspose_deep](crate::algebra::matrices::types::vec_of_vec::sorted::VecOfVec::antitranspose_deep):
213 ///
214 /// - [AntiTranspose] is a lazy object that does not generate new data
215 /// - The set of (key,val) pairs that appear in a major (respectively, minor) view of `AntiTranspose::new(matrix)`
216 /// are the *same* as the entries in a minor (respectively, major) view of `matrix`; only the sequence in which those entries appear is different.
217 /// By contrast, the keys in the (key,val) pairs of [matrix.antitranspose_deep()](crate::algebra::matrices::types::vec_of_vec::sorted::VecOfVec::antitranspose_deep) are different;
218 /// they are obtained by subtracting the original keys from (# rows in the antitransposed matrix - 1).
219 /// - For this reason, [matrix.antitranspose_deep()](crate::algebra::matrices::types::vec_of_vec::sorted::VecOfVec::antitranspose_deep) is only available for
220 /// very specific types of matrices; [AntiTranspose] is available for a much broader class.
221 fn antitranspose( self ) -> AntiTranspose<Self>
222 where
223 Self: Sized,
224 { AntiTranspose::new( self ) }
225
226 /// Wraps `& self` in a [crate::algebra::matrices::types::transpose::AntiTranspose] struct.
227 fn antitranspose_ref( &self ) -> AntiTranspose<&Self>
228 where
229 Self: Sized,
230 { AntiTranspose::new( &self ) }
231
232 /// Wraps `self` in a [crate::algebra::matrices::types::transpose::Transpose] struct.
233 fn reverse( self ) -> Reverse<Self>
234 where
235 Self: Sized,
236 { Reverse::new( self ) }
237
238 /// Wraps `& self` in a [crate::algebra::matrices::types::transpose::Transpose] struct.
239 fn reverse_ref( &self ) -> Reverse<&Self>
240 where
241 { Reverse::new( & self ) }
242}
243
244
245
246// Auto-implement this trait on all types
247// --------------------------------------------------------------
248impl < Matrix >
249
250 MatrixOperations for
251
252 Matrix
253
254{}