src/linops.rs

branch
dev
changeset 139
f78885441218
parent 133
2b13f8a0c8ba
child 140
26df914dda67
equal deleted inserted replaced
138:593912dc3293 139:f78885441218
301 Self: 'b; 301 Self: 'b;
302 // () means not (pre)adjointable. 302 // () means not (pre)adjointable.
303 303
304 fn adjoint(&self) -> Self::Adjoint<'_> { 304 fn adjoint(&self) -> Self::Adjoint<'_> {
305 SimpleZeroOp 305 SimpleZeroOp
306 }
307 }
308
309 /// A zero operator that can be eitherh dualised or predualised (once).
310 /// This is achieved by storing an oppropriate zero.
311 pub struct ZeroOp<X, Y: AXPY<Field = F>, C, O, F: Float = f64> {
312 codomain_sample: C,
313 other_sample: O,
314 _phantoms: PhantomData<(X, Y, F)>,
315 }
316
317 impl<'b, X, Y, F> ZeroOp<X, Y, &'b Y, &'b X::DualSpace, F>
318 where
319 X: HasDual<F>,
320 Y: HasDual<F>,
321 Y::Owned: Clone,
322 F: Float,
323 {
324 pub fn new_dualisable(x_dual_sample: &'b X::DualSpace, y_sample: &'b Y) -> Self {
325 ZeroOp {
326 codomain_sample: y_sample,
327 other_sample: x_dual_sample,
328 _phantoms: PhantomData,
329 }
330 }
331 }
332
333 impl<'b, X, Y, O, F> Mapping<X> for ZeroOp<X, Y, &'b Y, O, F>
334 where
335 X: Space + Instance<X>,
336 Y: AXPY<Field = F>,
337 F: Float,
338 {
339 type Codomain = Y::Owned;
340
341 fn apply<I: Instance<X>>(&self, _x: I) -> Y::Owned {
342 self.codomain_sample.similar_origin()
343 }
344 }
345
346 impl<'b, X, Y, O, F> Linear<X> for ZeroOp<X, Y, &'b Y, O, F>
347 where
348 X: Space + Instance<X>,
349 Y: AXPY<Field = F>,
350 F: Float,
351 {
352 }
353
354 #[replace_float_literals(F::cast_from(literal))]
355 impl<'b, X, Y, O, F> GEMV<F, X, Y> for ZeroOp<X, Y, &'b Y, O, F>
356 where
357 X: Space + Instance<X>,
358 Y: AXPY<Field = F>,
359 F: Float,
360 {
361 // Computes `y = αAx + βy`, where `A` is `Self`.
362 fn gemv<I: Instance<X>>(&self, y: &mut Y, _α: F, _x: I, β: F) {
363 *y *= β;
364 }
365
366 fn apply_mut<I: Instance<X>>(&self, y: &mut Y, _x: I) {
367 y.set_zero();
368 }
369 }
370
371 impl<'b, X, Y, O, F, E1, E2> BoundedLinear<X, E1, E2, F> for ZeroOp<X, Y, &'b Y, O, F>
372 where
373 X: Space + Instance<X> + Norm<E1, F>,
374 Y: AXPY<Field = F>,
375 Y::Owned: Clone,
376 F: Float,
377 E1: NormExponent,
378 E2: NormExponent,
379 {
380 fn opnorm_bound(&self, _xexp: E1, _codexp: E2) -> DynResult<F> {
381 Ok(F::ZERO)
382 }
383 }
384
385 impl<'b, X, Y, Xprime, Yprime, F> Adjointable<X, Yprime> for ZeroOp<X, Y, &'b Y, &'b Xprime, F>
386 where
387 X: HasDual<F, DualSpace = Xprime>,
388 Y: HasDual<F, DualSpace = Yprime>,
389 F: Float,
390 Xprime: AXPY<Field = F, Owned = Xprime>,
391 Xprime::Owned: AXPY<Field = F>,
392 Yprime: Space + Instance<Yprime>,
393 {
394 type AdjointCodomain = Xprime;
395 type Adjoint<'c>
396 = ZeroOp<Yprime, Xprime, &'b Xprime, (), F>
397 where
398 Self: 'c;
399 // () means not (pre)adjointable.
400
401 fn adjoint(&self) -> Self::Adjoint<'_> {
402 ZeroOp {
403 codomain_sample: self.other_sample,
404 other_sample: (),
405 _phantoms: PhantomData,
406 }
306 } 407 }
307 } 408 }
308 409
309 /* 410 /*
310 /// Trait for forming origins (zeroes) in vector spaces 411 /// Trait for forming origins (zeroes) in vector spaces

mercurial