src/discrete_gradient.rs

Mon, 23 Dec 2024 23:27:45 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 23 Dec 2024 23:27:45 -0500
branch
dev
changeset 80
f802ddbabcfc
parent 67
d7c0f431cbd6
permissions
-rw-r--r--

Basic arithmetric opt-in hack attempt: not allowed by Rust.

67
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Simple disrete gradient operators
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 */
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 use numeric_literals::replace_float_literals;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 use nalgebra::{
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 DVector, Matrix, U1, Storage, StorageMut, Dyn
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 };
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 use crate::types::Float;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 use crate::instance::Instance;
80
f802ddbabcfc Basic arithmetric opt-in hack attempt: not allowed by Rust.
Tuomo Valkonen <tuomov@iki.fi>
parents: 67
diff changeset
10 use crate::mapping::ArithmeticTrue;
67
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 use crate::linops::{Mapping, Linear, BoundedLinear, Adjointable, GEMV};
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 use crate::norms::{Norm, L2};
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 #[derive(Copy, Clone, Debug)]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 /// Forward differences with Neumann boundary conditions
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 pub struct ForwardNeumann;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 #[derive(Copy, Clone, Debug)]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 /// Forward differences with Dirichlet boundary conditions
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 pub struct ForwardDirichlet;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 #[derive(Copy, Clone, Debug)]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 /// Backward differences with Dirichlet boundary conditions
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 pub struct BackwardDirichlet;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 #[derive(Copy, Clone, Debug)]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 /// Backward differences with Neumann boundary conditions
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 pub struct BackwardNeumann;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 /// Finite differences gradient
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 pub struct Grad<
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 const N : usize
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 > {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 dims : [usize; N],
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 h : F, // may be negative to implement adjoints!
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 discretisation : B,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 /// Finite differences divergence
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 pub struct Div<
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 const N : usize
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 > {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 dims : [usize; N],
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 h : F, // may be negative to implement adjoints!
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 discretisation : B,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 /// Internal: classification of a point in a 1D discretisation
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 pub enum DiscretisationOrInterior {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 /// center, forward
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 LeftBoundary(usize, usize),
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 /// center, backward
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 RightBoundary(usize, usize),
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 /// center, (backward, forward)
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 Interior(usize, (usize, usize)),
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 use DiscretisationOrInterior::*;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 /// Trait for different discretisations
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 pub trait Discretisation<F : Float + nalgebra::RealField> : Copy {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 /// Opposite discretisation, appropriate for adjoints with negated cell width.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 type Opposite : Discretisation<F>;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 /// Add to appropiate index of `v` (as determined by `b`) the appropriate difference
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 /// of `x` with cell width `h`.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 fn add_diff_mut<SMut, S>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 &self,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 v : &mut Matrix<F, Dyn, U1, SMut>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 x : &Matrix<F, Dyn, U1, S>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 α : F,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 b : DiscretisationOrInterior,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 ) where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 SMut : StorageMut<F, Dyn, U1>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 S : Storage<F, Dyn, U1>;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 /// Give the opposite discretisation, appropriate for adjoints with negated `h`.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 fn opposite(&self) -> Self::Opposite;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 /// Bound for the corresponding operator norm.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 #[replace_float_literals(F::cast_from(literal))]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 fn opnorm_bound(&self, h : F) -> F {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 // See: Chambolle, “An Algorithm for Total Variation Minimization and Applications”.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 // Ok for forward and backward differences.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 //
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 // Fuck nalgebra for polluting everything with its own shit.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 num_traits::Float::sqrt(8.0) / h
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 impl<F : Float + nalgebra::RealField> Discretisation<F> for ForwardNeumann {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 type Opposite = BackwardDirichlet;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 fn add_diff_mut<SMut, S>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 &self,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 v : &mut Matrix<F, Dyn, U1, SMut>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 x : &Matrix<F, Dyn, U1, S>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 α : F,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 b : DiscretisationOrInterior,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 ) where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 SMut : StorageMut<F, Dyn, U1>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 S : Storage<F, Dyn, U1>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 match b {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 Interior(c, (_, f)) | LeftBoundary(c, f) => { v[c] += (x[f] - x[c]) * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 RightBoundary(_c, _b) => { },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 fn opposite(&self) -> Self::Opposite {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 BackwardDirichlet
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 impl<F : Float + nalgebra::RealField> Discretisation<F> for BackwardNeumann {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 type Opposite = ForwardDirichlet;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 fn add_diff_mut<SMut, S>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 &self,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 v : &mut Matrix<F, Dyn, U1, SMut>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 x : &Matrix<F, Dyn, U1, S>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 α : F,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 b : DiscretisationOrInterior,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 ) where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 SMut : StorageMut<F, Dyn, U1>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 S : Storage<F, Dyn, U1>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 match b {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 Interior(c, (b, _)) | RightBoundary(c, b) => { v[c] += (x[c] - x[b]) * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 LeftBoundary(_c, _f) => { },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 fn opposite(&self) -> Self::Opposite {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 ForwardDirichlet
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 impl<F : Float + nalgebra::RealField> Discretisation<F> for BackwardDirichlet {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 type Opposite = ForwardNeumann;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 fn add_diff_mut<SMut, S>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 &self,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 v : &mut Matrix<F, Dyn, U1, SMut>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 x : &Matrix<F, Dyn, U1, S>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 α : F,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 b : DiscretisationOrInterior,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 ) where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159 SMut : StorageMut<F, Dyn, U1>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 S : Storage<F, Dyn, U1>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 match b {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 Interior(c, (b, _f)) => { v[c] += (x[c] - x[b]) * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 LeftBoundary(c, _f) => { v[c] += x[c] * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 RightBoundary(c, b) => { v[c] -= x[b] * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 fn opposite(&self) -> Self::Opposite {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 ForwardNeumann
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 impl<F : Float + nalgebra::RealField> Discretisation<F> for ForwardDirichlet {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 type Opposite = BackwardNeumann;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 fn add_diff_mut<SMut, S>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 &self,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 v : &mut Matrix<F, Dyn, U1, SMut>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
182 x : &Matrix<F, Dyn, U1, S>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183 α : F,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 b : DiscretisationOrInterior,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 ) where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 SMut : StorageMut<F, Dyn, U1>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187 S : Storage<F, Dyn, U1>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 match b {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 Interior(c, (_b, f)) => { v[c] += (x[f] - x[c]) * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 LeftBoundary(c, f) => { v[c] += x[f] * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 RightBoundary(c, _b) => { v[c] -= x[c] * α },
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
193 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
196 #[inline]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
197 fn opposite(&self) -> Self::Opposite {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
198 BackwardNeumann
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
199 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
202 struct Iter<'a, const N : usize> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
203 /// Dimensions
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
204 dims : &'a [usize; N],
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 /// Dimension along which to calculate differences
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
206 d : usize,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
207 /// Stride along coordinate d
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
208 d_stride : usize,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
209 /// Cartesian indices
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
210 i : [usize; N],
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 /// Linear index
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 k : usize,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 /// Maximal linear index
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214 len : usize
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
217 impl<'a, const N : usize> Iter<'a, N> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 fn new(dims : &'a [usize; N], d : usize) -> Self {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 let d_stride = dims[0..d].iter().product::<usize>();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 let len = dims.iter().product::<usize>();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 Iter{ dims, d, d_stride, i : [0; N], k : 0, len }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
222 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
224
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 impl<'a, const N : usize> Iterator for Iter<'a, N> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
226 type Item = DiscretisationOrInterior;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
227 fn next(&mut self) -> Option<Self::Item> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
228 let res = if self.k >= self.len {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 None
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230 } else {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 let cartesian_idx = self.i[self.d];
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
232 let cartesian_max = self.dims[self.d];
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
233 let k = self.k;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
234
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 if cartesian_idx == 0 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236 Some(LeftBoundary(k, k + self.d_stride))
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237 } else if cartesian_idx + 1 >= cartesian_max {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238 Some(RightBoundary(k, k - self.d_stride))
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 } else {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240 Some(Interior(k, (k - self.d_stride, k + self.d_stride)))
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
241 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242 };
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
243 self.k += 1;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244 for j in 0..N {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
245 if self.i[j] + 1 < self.dims[j] {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
246 self.i[j] += 1;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
247 break
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
248 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
249 self.i[j] = 0
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251 res
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
252 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
253 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
254
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
255 impl<F, B, const N : usize> Mapping<DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
256 for Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
257 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
258 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
259 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
260 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
261 type Codomain = DVector<F>;
80
f802ddbabcfc Basic arithmetric opt-in hack attempt: not allowed by Rust.
Tuomo Valkonen <tuomov@iki.fi>
parents: 67
diff changeset
262 type ArithmeticOptIn = ArithmeticTrue;
f802ddbabcfc Basic arithmetric opt-in hack attempt: not allowed by Rust.
Tuomo Valkonen <tuomov@iki.fi>
parents: 67
diff changeset
263
67
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
264 fn apply<I : Instance<DVector<F>>>(&self, i : I) -> DVector<F> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
265 let mut y = DVector::zeros(N * self.len());
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
266 self.apply_add(&mut y, i);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267 y
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
268 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
269 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
270
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
271 #[replace_float_literals(F::cast_from(literal))]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
272 impl<F, B, const N : usize> GEMV<F, DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
273 for Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
274 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
275 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
276 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
277 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
278 fn gemv<I : Instance<DVector<F>>>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279 &self, y : &mut DVector<F>, α : F, i : I, β : F
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
280 ) {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
281 if β == 0.0 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
282 y.as_mut_slice().iter_mut().for_each(|x| *x = 0.0);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
283 } else if β != 1.0 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
284 //*y *= β;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
285 y.as_mut_slice().iter_mut().for_each(|x| *x *= β);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
286 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
287 let h = self.h;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
288 let m = self.len();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
289 i.eval(|x| {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
290 assert_eq!(x.len(), m);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
291 for d in 0..N {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 let mut v = y.generic_view_mut((d*m, 0), (Dyn(m), U1));
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
293 for b in Iter::new(&self.dims, d) {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 self.discretisation.add_diff_mut(&mut v, x, α/h, b)
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
296 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
297 })
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
298 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
299 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
300
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
301 impl<F, B, const N : usize> Mapping<DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
302 for Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
303 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
304 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
305 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
306 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
307 type Codomain = DVector<F>;
80
f802ddbabcfc Basic arithmetric opt-in hack attempt: not allowed by Rust.
Tuomo Valkonen <tuomov@iki.fi>
parents: 67
diff changeset
308 type ArithmeticOptIn = ArithmeticTrue;
f802ddbabcfc Basic arithmetric opt-in hack attempt: not allowed by Rust.
Tuomo Valkonen <tuomov@iki.fi>
parents: 67
diff changeset
309
67
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310 fn apply<I : Instance<DVector<F>>>(&self, i : I) -> DVector<F> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
311 let mut y = DVector::zeros(self.len());
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 self.apply_add(&mut y, i);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313 y
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
317 #[replace_float_literals(F::cast_from(literal))]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
318 impl<F, B, const N : usize> GEMV<F, DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
319 for Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
324 fn gemv<I : Instance<DVector<F>>>(
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
325 &self, y : &mut DVector<F>, α : F, i : I, β : F
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
326 ) {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
327 if β == 0.0 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
328 y.as_mut_slice().iter_mut().for_each(|x| *x = 0.0);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
329 } else if β != 1.0 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
330 //*y *= β;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
331 y.as_mut_slice().iter_mut().for_each(|x| *x *= β);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
332 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
333 let h = self.h;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
334 let m = self.len();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
335 i.eval(|x| {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
336 assert_eq!(x.len(), N * m);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
337 for d in 0..N {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
338 let v = x.generic_view((d*m, 0), (Dyn(m), U1));
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
339 for b in Iter::new(&self.dims, d) {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
340 self.discretisation.add_diff_mut(y, &v, α/h, b)
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
341 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
342 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
343 })
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
344 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 impl<F, B, const N : usize> Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350 F : Float + nalgebra::RealField
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352 /// Creates a new discrete gradient operator for the vector `u`, verifying dimensions.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 pub fn new_for(u : &DVector<F>, h : F, dims : [usize; N], discretisation : B)
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 -> Option<Self>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356 if u.len() == dims.iter().product::<usize>() {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 Some(Grad { dims, h, discretisation } )
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 } else {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 None
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363 fn len(&self) -> usize {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 self.dims.iter().product::<usize>()
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
366 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
367
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
368
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
369 impl<F, B, const N : usize> Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 F : Float + nalgebra::RealField
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374 /// Creates a new discrete gradient operator for the vector `u`, verifying dimensions.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
375 pub fn new_for(u : &DVector<F>, h : F, dims : [usize; N], discretisation : B)
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 -> Option<Self>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 if u.len() == dims.iter().product::<usize>() * N {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 Some(Div { dims, h, discretisation } )
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
380 } else {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
381 None
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
382 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
384
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
385 fn len(&self) -> usize {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
386 self.dims.iter().product::<usize>()
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
387 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
388 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
389
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
390 impl<F, B, const N : usize> Linear<DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 for Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
396 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
397
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
398 impl<F, B, const N : usize> Linear<DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
399 for Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
400 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
401 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
402 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
404 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
405
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
406 impl<F, B, const N : usize> BoundedLinear<DVector<F>, L2, L2, F>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407 for Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 DVector<F> : Norm<F, L2>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 fn opnorm_bound(&self, _ : L2, _ : L2) -> F {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 // Fuck nalgebra.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415 self.discretisation.opnorm_bound(num_traits::Float::abs(self.h))
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 impl<F, B, const N : usize> BoundedLinear<DVector<F>, L2, L2, F>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 for Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
425 DVector<F> : Norm<F, L2>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
427 fn opnorm_bound(&self, _ : L2, _ : L2) -> F {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
428 // Fuck nalgebra.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 self.discretisation.opnorm_bound(num_traits::Float::abs(self.h))
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
433 impl<F, B, const N : usize>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 Adjointable<DVector<F>, DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 for Grad<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
436 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 type AdjointCodomain = DVector<F>;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
441 type Adjoint<'a> = Div<F, B::Opposite, N> where Self : 'a;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
442
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 /// Form the adjoint operator of `self`.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 fn adjoint(&self) -> Self::Adjoint<'_> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
445 Div {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
446 dims : self.dims,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 h : -self.h,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448 discretisation : self.discretisation.opposite(),
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
449 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
450 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
454 impl<F, B, const N : usize>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
455 Adjointable<DVector<F>, DVector<F>>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
456 for Div<F, B, N>
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
457 where
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
458 B : Discretisation<F>,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
459 F : Float + nalgebra::RealField,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
460 {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
461 type AdjointCodomain = DVector<F>;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
462 type Adjoint<'a> = Grad<F, B::Opposite, N> where Self : 'a;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
463
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
464 /// Form the adjoint operator of `self`.
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
465 fn adjoint(&self) -> Self::Adjoint<'_> {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
466 Grad {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
467 dims : self.dims,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
468 h : -self.h,
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
469 discretisation : self.discretisation.opposite(),
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
470 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
471 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
472 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
473
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
474 #[cfg(test)]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
475 mod tests {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
476 use super::*;
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
477
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
478 #[test]
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
479 fn grad_adjoint() {
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
480 let im = DVector::from( (0..9).map(|t| t as f64).collect::<Vec<_>>());
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
481 let v = DVector::from( (0..18).map(|t| t as f64).collect::<Vec<_>>());
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
482
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
483 let grad = Grad::new_for(&im, 1.0, [3, 3], ForwardNeumann).unwrap();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
484 let a = grad.apply(&im).dot(&v);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
485 let b = grad.adjoint().apply(&v).dot(&im);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
486 assert_eq!(a, b);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
487
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
488 let grad = Grad::new_for(&im, 1.0, [3, 3], ForwardDirichlet).unwrap();
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
489 let a = grad.apply(&im).dot(&v);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
490 let b = grad.adjoint().apply(&v).dot(&im);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
491 assert_eq!(a, b);
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
492
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
493 }
d7c0f431cbd6 Discrete gradients
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
494 }

mercurial