| |
1 /*! |
| |
2 Wrappers for implemention [`Euclidean`] operations. |
| |
3 */ |
| |
4 |
| |
5 use crate::euclidean::Euclidean; |
| |
6 use crate::instance::Space; |
| |
7 use crate::types::Float; |
| |
8 |
| |
9 pub trait WrapGuard<'a, F: Float> { |
| |
10 type View<'b>: Euclidean<F> |
| |
11 where |
| |
12 Self: 'b; |
| |
13 fn get_view(&self) -> Self::View<'_>; |
| |
14 } |
| |
15 |
| |
16 pub trait WrapGuardMut<'a, F: Float> { |
| |
17 type ViewMut<'b>: Euclidean<F> |
| |
18 where |
| |
19 Self: 'b; |
| |
20 fn get_view_mut(&mut self) -> Self::ViewMut<'_>; |
| |
21 } |
| |
22 |
| |
23 pub trait Wrapped: Space { |
| |
24 type WrappedField: Float; |
| |
25 type Guard<'a>: WrapGuard<'a, Self::WrappedField> |
| |
26 where |
| |
27 Self: 'a; |
| |
28 type GuardMut<'a>: WrapGuardMut<'a, Self::WrappedField> |
| |
29 where |
| |
30 Self: 'a; |
| |
31 type UnwrappedOutput; |
| |
32 type WrappedOutput; |
| |
33 fn get_guard(&self) -> Self::Guard<'_>; |
| |
34 fn get_guard_mut(&mut self) -> Self::GuardMut<'_>; |
| |
35 fn wrap(output: Self::UnwrappedOutput) -> Self::WrappedOutput; |
| |
36 } |
| |
37 |
| |
38 #[macro_export] |
| |
39 macro_rules! wrap { |
| |
40 // Rust macros are totally fucked up. $trait:path does not work, have to |
| |
41 // manually code paths through $($trait:ident)::+. |
| |
42 (impl_unary $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
43 impl<$($qual)*> $($trait)::+ for $type { |
| |
44 type Output = <Self as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
45 fn $fn(self) -> Self::Output { |
| |
46 let a = self.get_guard(); |
| |
47 Self::wrap(a.get_view().$fn()) |
| |
48 } |
| |
49 } |
| |
50 }; |
| |
51 (impl_binary $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
52 impl<$($qual)*> $($trait)::+<$type> for $type { |
| |
53 type Output = <Self as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
54 fn $fn(self, other: $type) -> Self::Output { |
| |
55 let a = self.get_guard(); |
| |
56 let b = other.get_guard(); |
| |
57 Self::wrap(a.get_view().$fn(b.get_view())) |
| |
58 } |
| |
59 } |
| |
60 |
| |
61 impl<'a, $($qual)*> $($trait)::+<$type> for &'a $type { |
| |
62 type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
63 fn $fn(self, other: $type) -> Self::Output { |
| |
64 let a = self.get_guard(); |
| |
65 let b = other.get_guard(); |
| |
66 <$type>::wrap(a.get_view().$fn(b.get_view())) |
| |
67 } |
| |
68 } |
| |
69 |
| |
70 impl<'a, 'b, $($qual)*> $($trait)::+<&'b $type> for &'a $type { |
| |
71 type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
72 fn $fn(self, other: &'b $type) -> Self::Output { |
| |
73 let a = self.get_guard(); |
| |
74 let b = other.get_guard(); |
| |
75 <$type>::wrap(a.get_view().$fn(b.get_view())) |
| |
76 } |
| |
77 } |
| |
78 |
| |
79 impl<'b, $($qual)*> $($trait)::+<&'b $type> for $type { |
| |
80 type Output = <Self as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
81 fn $fn(self, other: &'b $type) -> Self::Output { |
| |
82 let a = self.get_guard(); |
| |
83 let b = other.get_guard(); |
| |
84 Self::wrap(a.get_view().$fn(b.get_view())) |
| |
85 } |
| |
86 } |
| |
87 }; |
| |
88 (impl_scalar $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
89 impl<$($qual)*> $($trait)::+<$F> for $type |
| |
90 // where |
| |
91 // $type: $crate::euclidean::wrap::Wrapped<WrappedField = F>, |
| |
92 // //$type::Unwrapped: $($trait)::+<F>, |
| |
93 { |
| |
94 type Output = <Self as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
95 fn $fn(self, t: $F) -> Self::Output { |
| |
96 let a = self.get_guard(); |
| |
97 Self::wrap(a.get_view().$fn(t)) |
| |
98 } |
| |
99 } |
| |
100 |
| |
101 impl<'a, $($qual)*> $($trait)::+<$F> for &'a $type |
| |
102 // where |
| |
103 // $type: $crate::euclidean::wrap::Wrapped<WrappedField = F>, |
| |
104 // //$type::Unwrapped: $($trait)::+<F>, |
| |
105 { |
| |
106 type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
107 fn $fn(self, t: $F) -> Self::Output { |
| |
108 let a = self.get_guard(); |
| |
109 <$type>::wrap(a.get_view().$fn(t)) |
| |
110 } |
| |
111 } |
| |
112 |
| |
113 }; |
| |
114 (impl_scalar_lhs $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
115 impl<$($qual)*> $($trait)::+<$type> for $F |
| |
116 // where |
| |
117 // $type: $crate::euclidean::wrap::Wrapped<WrappedField = $F>, |
| |
118 // // where |
| |
119 // // $F: $($trait)::+<$type::Unwrapped>, |
| |
120 { |
| |
121 type Output = <$type as $crate::euclidean::wrap::Wrapped>::WrappedOutput; |
| |
122 fn $fn(self, rhs: $type) -> Self::Output { |
| |
123 let b = rhs.get_guard(); |
| |
124 <$type>::wrap(self.$fn(b.get_view())) |
| |
125 } |
| |
126 } |
| |
127 }; |
| |
128 (impl_binary_mut $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
129 impl<$($qual)*> $($trait)::+<$type> for $type { |
| |
130 fn $fn(&mut self, rhs: $type) { |
| |
131 let mut a = self.get_guard_mut(); |
| |
132 let b = rhs.get_guard(); |
| |
133 a.get_view_mut().$fn(b.get_view()) |
| |
134 } |
| |
135 } |
| |
136 |
| |
137 impl<'b, $($qual)*> $($trait)::+<&'b $type> for $type { |
| |
138 fn $fn(&mut self, rhs: &'b $type) { |
| |
139 let mut a = self.get_guard_mut(); |
| |
140 let b = rhs.get_guard(); |
| |
141 a.get_view_mut().$fn(b.get_view()) |
| |
142 } |
| |
143 } |
| |
144 }; |
| |
145 (impl_scalar_mut $F:ty, $type:ty, $($trait:ident)::+, $fn:ident where $($qual:tt)*) => { |
| |
146 impl<$($qual)*> $($trait)::+<$F> for $type |
| |
147 // where |
| |
148 // $type: $crate::euclidean::wrap::Wrapped<WrappedField = F>, |
| |
149 // // where |
| |
150 // // $type::UnwrappedMut: $($trait)::+<$($trait)::+<F>>, |
| |
151 { |
| |
152 fn $fn(&mut self, t: $F) { |
| |
153 let mut a = self.get_guard_mut(); |
| |
154 a.get_view_mut().$fn(t) |
| |
155 } |
| |
156 } |
| |
157 }; |
| |
158 // ($type:ty) => { |
| |
159 // $crate::wrap!(imp<> do $type); |
| |
160 // }; |
| |
161 ($F:ty; $type:ty where $($qual:tt)*) => { |
| |
162 |
| |
163 $crate::wrap!(impl_unary $type, std::ops::Neg, neg where $($qual)*); |
| |
164 $crate::wrap!(impl_binary $type, std::ops::Add, add where $($qual)*); |
| |
165 $crate::wrap!(impl_binary $type, std::ops::Sub, sub where $($qual)*); |
| |
166 $crate::wrap!(impl_scalar $F, $type, std::ops::Mul, mul where $($qual)*); |
| |
167 $crate::wrap!(impl_scalar $F, $type, std::ops::Div, div where $($qual)*); |
| |
168 $crate::wrap!(impl_scalar_lhs $F, $type, std::ops::Mul, mul where $($qual)*); |
| |
169 $crate::wrap!(impl_binary_mut $type, std::ops::AddAssign, add_assign where $($qual)*); |
| |
170 $crate::wrap!(impl_binary_mut $type, std::ops::SubAssign, sub_assign where $($qual)*); |
| |
171 $crate::wrap!(impl_scalar_mut $F, $type, std::ops::MulAssign, mul_assign where $($qual)*); |
| |
172 $crate::wrap!(impl_scalar_mut $F, $type, std::ops::DivAssign, div_assign where $($qual)*); |
| |
173 |
| |
174 $crate::self_ownable!($type where $($qual)*); |
| |
175 |
| |
176 impl<$($qual)*> $crate::norms::Norm<$crate::norms::L2, $F> for $type |
| |
177 { |
| |
178 fn norm(&self, p : $crate::norms::L2) -> $F { |
| |
179 let a = self.get_guard(); |
| |
180 $crate::norms::Norm::norm(&a.get_view(), p) |
| |
181 } |
| |
182 } |
| |
183 |
| |
184 impl<$($qual)*> $crate::norms::Dist<$crate::norms::L2, $F> for $type |
| |
185 { |
| |
186 fn dist<I: $crate::instance::Instance<Self>>(&self, other : I, p : $crate::norms::L2) -> $F { |
| |
187 other.eval_ref(|other| { |
| |
188 let a = self.get_guard(); |
| |
189 let b = other.get_guard(); |
| |
190 a.get_view().dist(b.get_view(), p) |
| |
191 }) |
| |
192 } |
| |
193 } |
| |
194 |
| |
195 impl<$($qual)*> $crate::norms::Normed<$F> for $type { |
| |
196 type NormExp = $crate::norms::L2; |
| |
197 |
| |
198 fn norm_exponent(&self) -> Self::NormExp { |
| |
199 $crate::norms::L2 |
| |
200 } |
| |
201 } |
| |
202 |
| |
203 impl<$($qual)*> $crate::norms::HasDual<$F> for $type { |
| |
204 type DualSpace = Self; |
| |
205 |
| |
206 fn dual_origin(&self) -> Self { |
| |
207 $crate::linops::VectorSpace::similar_origin(self) |
| |
208 } |
| |
209 } |
| |
210 |
| |
211 impl<$($qual)*> $crate::euclidean::Euclidean<$F> for $type |
| |
212 // where |
| |
213 // Self: $crate::euclidean::wrap::Wrapped<WrappedField = $F> |
| |
214 // + Sized |
| |
215 // + std::ops::Mul<F, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
216 // + std::ops::MulAssign<F> |
| |
217 // + std::ops::Div<F, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
218 // + std::ops::DivAssign<F> |
| |
219 // + std::ops::Add<Self, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
220 // + std::ops::Sub<Self, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
221 // + for<'b> std::ops::Add<&'b Self, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
222 // + for<'b> std::ops::Sub<&'b Self, Output = <Self as $crate::linops::AXPY>::Owned> |
| |
223 // + std::ops::AddAssign<Self> |
| |
224 // + for<'b> std::ops::AddAssign<&'b Self> |
| |
225 // + std::ops::SubAssign<Self> |
| |
226 // + for<'b> std::ops::SubAssign<&'b Self> |
| |
227 // + std::ops::Neg<Output = <Self as $crate::linops::AXPY>::Owned>, |
| |
228 { |
| |
229 type PrincipalE = Self; |
| |
230 |
| |
231 fn dot<I: $crate::instance::Instance<Self>>(&self, other: I) -> $F { |
| |
232 other.eval_decompose(|other| { |
| |
233 let a = self.get_guard(); |
| |
234 let b = other.get_guard(); |
| |
235 a.get_view().dot(&b.get_view()) |
| |
236 }) |
| |
237 } |
| |
238 |
| |
239 fn norm2_squared(&self) -> $F { |
| |
240 let a = self.get_guard(); |
| |
241 a.get_view().norm2_squared() |
| |
242 } |
| |
243 |
| |
244 fn dist2_squared<I: $crate::instance::Instance<Self>>(&self, other: I) -> $F { |
| |
245 other.eval_decompose(|other| { |
| |
246 let a = self.get_guard(); |
| |
247 let b = other.get_guard(); |
| |
248 a.get_view().dist2_squared(b.get_view()) |
| |
249 }) |
| |
250 } |
| |
251 } |
| |
252 |
| |
253 impl<$($qual)*> $crate::linops::VectorSpace for $type |
| |
254 // where |
| |
255 // Self : $crate::euclidean::wrap::Wrapped<WrappedField = $F>, |
| |
256 // Self::Unwrapped : $crate::linops::AXPY<Field = F>, |
| |
257 // Self: std::ops::MulAssign<F> + std::ops::DivAssign<F>, |
| |
258 // Self::Unwrapped: std::ops::MulAssign<F> + std::ops::DivAssign<F>, |
| |
259 { |
| |
260 type Field = $F; |
| |
261 type PrincipalV = Self; |
| |
262 |
| |
263 /// Return a similar zero as `self`. |
| |
264 fn similar_origin(&self) -> Self::PrincipalV { |
| |
265 let a = self.get_guard(); |
| |
266 Self::wrap(a.get_view().similar_origin()) |
| |
267 } |
| |
268 } |
| |
269 |
| |
270 impl<$($qual)*> $crate::linops::AXPY for $type |
| |
271 // where |
| |
272 // Self : $crate::euclidean::wrap::Wrapped<WrappedField = $F>, |
| |
273 // Self::Unwrapped : $crate::linops::AXPY<Field = F>, |
| |
274 // Self: std::ops::MulAssign<F> + std::ops::DivAssign<F>, |
| |
275 // Self::Unwrapped: std::ops::MulAssign<F> + std::ops::DivAssign<F>, |
| |
276 { |
| |
277 fn axpy<I: $crate::instance::Instance<Self>>(&mut self, α: $F, x: I, β: $F) { |
| |
278 x.eval_decompose(|other| { |
| |
279 let mut a = self.get_guard_mut(); |
| |
280 let b = other.get_guard(); |
| |
281 $crate::linops::AXPY::axpy(&mut a.get_view_mut(), α, b.get_view(), β) |
| |
282 }) |
| |
283 } |
| |
284 |
| |
285 fn copy_from<I: $crate::instance::Instance<Self>>(&mut self, x: I) { |
| |
286 x.eval_decompose(|other| { |
| |
287 let mut a = self.get_guard_mut(); |
| |
288 let b = other.get_guard(); |
| |
289 $crate::linops::AXPY::copy_from(&mut a.get_view_mut(), b.get_view()) |
| |
290 }) |
| |
291 } |
| |
292 |
| |
293 fn scale_from<I: $crate::instance::Instance<Self>>(&mut self, α: $F, x: I) { |
| |
294 x.eval_decompose(|other| { |
| |
295 let mut a = self.get_guard_mut(); |
| |
296 let b = other.get_guard(); |
| |
297 $crate::linops::AXPY::scale_from(&mut a.get_view_mut(), α, b.get_view()) |
| |
298 }) |
| |
299 } |
| |
300 |
| |
301 /// Set self to zero. |
| |
302 fn set_zero(&mut self) { |
| |
303 let mut a = self.get_guard_mut(); |
| |
304 a.get_view_mut().set_zero() |
| |
305 } |
| |
306 } |
| |
307 |
| |
308 impl<$($qual)*> $crate::instance::Space for $type { |
| |
309 type Decomp = $crate::instance::BasicDecomposition; |
| |
310 type Principal = Self; |
| |
311 } |
| |
312 }; |
| |
313 } |