src/discrete_gradient.rs

Mon, 08 Dec 2025 15:23:42 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 08 Dec 2025 15:23:42 -0500
branch
dev
changeset 193
dccf609cd020
parent 186
afe04e6b4a5b
permissions
-rw-r--r--

maybe_uninit_slice is stable

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

mercurial