| 181 type Preadjoint<'a> = IdOp<X> where X : 'a; |
181 type Preadjoint<'a> = IdOp<X> where X : 'a; |
| 182 |
182 |
| 183 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
183 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
| 184 } |
184 } |
| 185 |
185 |
| |
186 |
| |
187 /// The zero operator |
| |
188 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
| |
189 pub struct ZeroOp<'a, X, XD, Y, F> { |
| |
190 zero : &'a Y, // TODO: don't pass this in `new`; maybe not even store. |
| |
191 dual_or_predual_zero : XD, |
| |
192 _phantoms : PhantomData<(X, Y, F)>, |
| |
193 } |
| |
194 |
| |
195 // TODO: Need to make Zero in Instance. |
| |
196 |
| |
197 impl<'a, F : Num, X : Space, XD, Y : Space + Clone> ZeroOp<'a, X, XD, Y, F> { |
| |
198 pub fn new(zero : &'a Y, dual_or_predual_zero : XD) -> Self { |
| |
199 ZeroOp{ zero, dual_or_predual_zero, _phantoms : PhantomData } |
| |
200 } |
| |
201 } |
| |
202 |
| |
203 impl<'a, F : Num, X : Space, XD, Y : AXPY<F> + Clone> Mapping<X> for ZeroOp<'a, X, XD, Y, F> { |
| |
204 type Codomain = Y; |
| |
205 |
| |
206 fn apply<I : Instance<X>>(&self, _x : I) -> Y { |
| |
207 self.zero.clone() |
| |
208 } |
| |
209 } |
| |
210 |
| |
211 impl<'a, F : Num, X : Space, XD, Y : AXPY<F> + Clone> Linear<X> for ZeroOp<'a, X, XD, Y, F> |
| |
212 { } |
| |
213 |
| |
214 #[replace_float_literals(F::cast_from(literal))] |
| |
215 impl<'a, F, X, XD, Y> GEMV<F, X, Y> for ZeroOp<'a, X, XD, Y, F> |
| |
216 where |
| |
217 F : Num, |
| |
218 Y : AXPY<F, Y> + Clone, |
| |
219 X : Space |
| |
220 { |
| |
221 // Computes `y = αAx + βy`, where `A` is `Self`. |
| |
222 fn gemv<I : Instance<X>>(&self, y : &mut Y, _α : F, _x : I, β : F) { |
| |
223 *y *= β; |
| |
224 } |
| |
225 |
| |
226 fn apply_mut<I : Instance<X>>(&self, y : &mut Y, _x : I){ |
| |
227 y.set_zero(); |
| |
228 } |
| |
229 } |
| |
230 |
| |
231 impl<'a, F, X, XD, Y, E1, E2> BoundedLinear<X, E1, E2, F> for ZeroOp<'a, X, XD, Y, F> |
| |
232 where |
| |
233 X : Space + Norm<F, E1>, |
| |
234 Y : AXPY<F> + Clone + Norm<F, E2>, |
| |
235 F : Num, |
| |
236 E1 : NormExponent, |
| |
237 E2 : NormExponent, |
| |
238 { |
| |
239 fn opnorm_bound(&self, _xexp : E1, _codexp : E2) -> F { F::ZERO } |
| |
240 } |
| |
241 |
| |
242 impl<'a, F : Num, X, XD, Y, Yprime : Space> Adjointable<X, Yprime> for ZeroOp<'a, X, XD, Y, F> |
| |
243 where |
| |
244 X : Space, |
| |
245 Y : AXPY<F> + Clone + 'static, |
| |
246 XD : AXPY<F> + Clone + 'static, |
| |
247 { |
| |
248 type AdjointCodomain = XD; |
| |
249 type Adjoint<'b> = ZeroOp<'b, Yprime, (), XD, F> where Self : 'b; |
| |
250 // () means not (pre)adjointable. |
| |
251 |
| |
252 fn adjoint(&self) -> Self::Adjoint<'_> { |
| |
253 ZeroOp::new(&self.dual_or_predual_zero, ()) |
| |
254 } |
| |
255 } |
| |
256 |
| |
257 impl<'a, F, X, XD, Y, Ypre> Preadjointable<X, Ypre> for ZeroOp<'a, X, XD, Y, F> |
| |
258 where |
| |
259 F : Num, |
| |
260 X : Space, |
| |
261 Y : AXPY<F> + Clone, |
| |
262 Ypre : Space, |
| |
263 XD : AXPY<F> + Clone + 'static, |
| |
264 { |
| |
265 type PreadjointCodomain = XD; |
| |
266 type Preadjoint<'b> = ZeroOp<'b, Ypre, (), XD, F> where Self : 'b; |
| |
267 // () means not (pre)adjointable. |
| |
268 |
| |
269 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
| |
270 ZeroOp::new(&self.dual_or_predual_zero, ()) |
| |
271 } |
| |
272 } |
| 186 |
273 |
| 187 impl<S, T, E, X> Linear<X> for Composition<S, T, E> |
274 impl<S, T, E, X> Linear<X> for Composition<S, T, E> |
| 188 where |
275 where |
| 189 X : Space, |
276 X : Space, |
| 190 T : Linear<X>, |
277 T : Linear<X>, |