src/discrete_gradient.rs

Mon, 06 Jan 2025 20:29:25 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 06 Jan 2025 20:29:25 -0500
branch
dev
changeset 86
d5b0e496b72f
parent 74
2c76df38d02b
permissions
-rw-r--r--

More Serialize / Deserialize / Debug derives

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

mercurial