src/discrete_gradient.rs

Sun, 19 Jan 2025 16:49:09 +0100

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 19 Jan 2025 16:49:09 +0100
branch
dev
changeset 87
72968cf30033
parent 74
2c76df38d02b
child 86
d5b0e496b72f
permissions
-rw-r--r--

LogarithmicCap verbosity option

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

mercurial