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;
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub enum SolveResult {
33 FoundSomeSolution, FoundUniqueSolution, NoSolution
34}
35
36impl SolveResult {
37
38 pub fn is_solved(&self) -> bool {
39 match self {
40 Self::FoundSomeSolution | Self::FoundUniqueSolution => true,
41 Self::NoSolution => false
42 }
43 }
44
45 pub fn assert_solved(&self) {
46 assert!(self.is_solved());
47 }
48}
49
50pub trait LinSolveRing: DivisibilityRing {
54
55 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
67 where V1: AsPointerToSlice<Self::Element>,
68 V2: AsPointerToSlice<Self::Element>,
69 V3: AsPointerToSlice<Self::Element>,
70 A: Allocator;
71}
72
73pub trait LinSolveRingStore: RingStore
77 where Self::Type: LinSolveRing
78{
79 fn solve_right<V1, V2, V3>(&self, lhs: SubmatrixMut<V1, El<Self>>, rhs: SubmatrixMut<V2, El<Self>>, out: SubmatrixMut<V3, El<Self>>) -> SolveResult
85 where V1: AsPointerToSlice<El<Self>>,
86 V2: AsPointerToSlice<El<Self>>,
87 V3: AsPointerToSlice<El<Self>>
88 {
89 self.get_ring().solve_right(lhs, rhs, out, Global)
90 }
91
92 #[stability::unstable(feature = "enable")]
98 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
99 where V1: AsPointerToSlice<El<Self>>,
100 V2: AsPointerToSlice<El<Self>>,
101 V3: AsPointerToSlice<El<Self>>,
102 A: Allocator
103 {
104 self.get_ring().solve_right(lhs, rhs, out, allocator)
105 }
106}
107
108impl<R> LinSolveRingStore for R
109 where R: RingStore, R::Type: LinSolveRing
110{}
111
112impl<R: ?Sized + PrincipalIdealRing> LinSolveRing for R {
113
114 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
115 where V1: AsPointerToSlice<Self::Element>, V2: AsPointerToSlice<Self::Element>, V3: AsPointerToSlice<Self::Element>,
116 A: Allocator
117 {
118 smith::solve_right_using_pre_smith(RingRef::new(self), lhs, rhs, out, allocator)
119 }
120}
121
122impl<R, V, A_ring, C_ring> LinSolveRing for FreeAlgebraImplBase<R, V, A_ring, C_ring>
123 where R: RingStore,
124 R::Type: LinSolveRing,
125 V: VectorView<El<R>>,
126 A_ring: Allocator + Clone,
127 C_ring: ConvolutionAlgorithm<R::Type>
128{
129 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
130 where V1: AsPointerToSlice<Self::Element>,
131 V2: AsPointerToSlice<Self::Element>,
132 V3: AsPointerToSlice<Self::Element>,
133 A: Allocator
134 {
135 extension::solve_right_over_extension(RingRef::new(self), lhs, rhs, out, allocator)
136 }
137}