feanor_math/algorithms/linsolve/
mod.rs1use std::alloc::{Allocator, Global};
2
3use crate::divisibility::DivisibilityRing;
4use crate::matrix::{AsPointerToSlice, SubmatrixMut};
5use crate::pid::PrincipalIdealRing;
6use crate::ring::*;
7use crate::rings::extension::extension_impl::FreeAlgebraImplBase;
8use crate::seq::VectorView;
9
10use super::convolution::ConvolutionAlgorithm;
11
12pub mod smith;
17pub mod extension;
21pub mod gauss;
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
37pub enum SolveResult {
38 FoundSomeSolution,
41 FoundUniqueSolution,
43 NoSolution
46}
47
48impl SolveResult {
49
50 pub fn is_solved(&self) -> bool {
54 match self {
55 Self::FoundSomeSolution | Self::FoundUniqueSolution => true,
56 Self::NoSolution => false
57 }
58 }
59
60 pub fn assert_solved(&self) {
64 assert!(self.is_solved());
65 }
66}
67
68pub trait LinSolveRing: DivisibilityRing {
72
73 fn solve_right<V1, V2, V3, A>(&self, lhs: SubmatrixMut<V1, Self::Element>, rhs: SubmatrixMut<V2, Self::Element>, out: SubmatrixMut<V3, Self::Element>, allocator: A) -> SolveResult
85 where V1: AsPointerToSlice<Self::Element>,
86 V2: AsPointerToSlice<Self::Element>,
87 V3: AsPointerToSlice<Self::Element>,
88 A: Allocator;
89}
90
91pub trait LinSolveRingStore: RingStore
95 where Self::Type: LinSolveRing
96{
97 fn solve_right<V1, V2, V3>(&self, lhs: SubmatrixMut<V1, El<Self>>, rhs: SubmatrixMut<V2, El<Self>>, out: SubmatrixMut<V3, El<Self>>) -> SolveResult
103 where V1: AsPointerToSlice<El<Self>>,
104 V2: AsPointerToSlice<El<Self>>,
105 V3: AsPointerToSlice<El<Self>>
106 {
107 self.get_ring().solve_right(lhs, rhs, out, Global)
108 }
109
110 #[stability::unstable(feature = "enable")]
116 fn solve_right_with<V1, V2, V3, A>(&self, lhs: SubmatrixMut<V1, El<Self>>, rhs: SubmatrixMut<V2, El<Self>>, out: SubmatrixMut<V3, El<Self>>, allocator: A) -> SolveResult
117 where V1: AsPointerToSlice<El<Self>>,
118 V2: AsPointerToSlice<El<Self>>,
119 V3: AsPointerToSlice<El<Self>>,
120 A: Allocator
121 {
122 self.get_ring().solve_right(lhs, rhs, out, allocator)
123 }
124}
125
126impl<R> LinSolveRingStore for R
127 where R: RingStore, R::Type: LinSolveRing
128{}
129
130impl<R: ?Sized + PrincipalIdealRing> LinSolveRing for R {
131
132 default fn solve_right<V1, V2, V3, A>(&self, lhs: SubmatrixMut<V1, Self::Element>, rhs: SubmatrixMut<V2, Self::Element>, out: SubmatrixMut<V3, Self::Element>, allocator: A) -> SolveResult
133 where V1: AsPointerToSlice<Self::Element>, V2: AsPointerToSlice<Self::Element>, V3: AsPointerToSlice<Self::Element>,
134 A: Allocator
135 {
136 smith::solve_right_using_pre_smith(RingRef::new(self), lhs, rhs, out, allocator)
137 }
138}
139
140impl<R, V, A_ring, C_ring> LinSolveRing for FreeAlgebraImplBase<R, V, A_ring, C_ring>
141 where R: RingStore,
142 R::Type: LinSolveRing,
143 V: VectorView<El<R>>,
144 A_ring: Allocator + Clone,
145 C_ring: ConvolutionAlgorithm<R::Type>
146{
147 fn solve_right<V1, V2, V3, A>(&self, lhs: SubmatrixMut<V1, Self::Element>, rhs: SubmatrixMut<V2, Self::Element>, out: SubmatrixMut<V3, Self::Element>, allocator: A) -> SolveResult
148 where V1: AsPointerToSlice<Self::Element>,
149 V2: AsPointerToSlice<Self::Element>,
150 V3: AsPointerToSlice<Self::Element>,
151 A: Allocator
152 {
153 extension::solve_right_over_extension(RingRef::new(self), lhs, rhs, out, allocator)
154 }
155}