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>, |