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{}