lattice_qcd_rs/simulation/monte_carlo/
overrelaxation.rs1#[cfg(feature = "serde-serialize")]
35use serde::{Deserialize, Serialize};
36
37use super::{
38 super::{
39 super::{error::Never, lattice::LatticeLinkCanonical, su3, Complex},
40 state::{LatticeState, LatticeStateDefault},
41 },
42 staple, MonteCarlo,
43};
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
76#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
77pub struct OverrelaxationSweepRotation;
78
79impl OverrelaxationSweepRotation {
80 pub const fn new() -> Self {
82 Self {}
83 }
84
85 #[inline]
86 fn get_modif<const D: usize>(
87 state: &LatticeStateDefault<D>,
88 link: &LatticeLinkCanonical<D>,
89 ) -> na::Matrix3<Complex> {
90 let link_matrix = state
91 .link_matrix()
92 .matrix(&link.into(), state.lattice())
93 .unwrap();
94 let a = staple(state.link_matrix(), state.lattice(), link).adjoint();
95 let svd = na::SVD::<Complex, na::U3, na::U3>::new(a, true, true);
96 let rot = svd.u.unwrap() * svd.v_t.unwrap();
97 rot * link_matrix.adjoint() * rot
98 }
99
100 #[inline]
101 fn next_element_default<const D: usize>(
102 mut state: LatticeStateDefault<D>,
103 ) -> LatticeStateDefault<D> {
104 let lattice = state.lattice().clone();
105 lattice.get_links().for_each(|link| {
106 let potential_modif = Self::get_modif(&state, &link);
107 *state.link_mut(&link).unwrap() = potential_modif;
108 });
109 state
110 }
111}
112
113impl std::fmt::Display for OverrelaxationSweepRotation {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 write!(f, "overrelaxation method by rotation")
116 }
117}
118
119impl Default for OverrelaxationSweepRotation {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124
125impl<const D: usize> MonteCarlo<LatticeStateDefault<D>, D> for OverrelaxationSweepRotation {
126 type Error = Never;
127
128 #[inline]
129 fn next_element(
130 &mut self,
131 state: LatticeStateDefault<D>,
132 ) -> Result<LatticeStateDefault<D>, Self::Error> {
133 Ok(Self::next_element_default(state))
134 }
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
148#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
149pub struct OverrelaxationSweepReverse;
150
151impl OverrelaxationSweepReverse {
152 pub const fn new() -> Self {
154 Self {}
155 }
156
157 #[inline]
158 fn get_modif<const D: usize>(
159 state: &LatticeStateDefault<D>,
160 link: &LatticeLinkCanonical<D>,
161 ) -> na::Matrix3<Complex> {
162 let link_matrix = state
163 .link_matrix()
164 .matrix(&link.into(), state.lattice())
165 .unwrap();
166 let a = staple(state.link_matrix(), state.lattice(), link).adjoint();
167 let svd = na::SVD::<Complex, na::U3, na::U3>::new(a, true, true);
168 svd.u.unwrap()
169 * su3::reverse(svd.u.unwrap().adjoint() * link_matrix * svd.v_t.unwrap().adjoint())
170 * svd.v_t.unwrap()
171 }
172
173 #[inline]
174 fn next_element_default<const D: usize>(
175 mut state: LatticeStateDefault<D>,
176 ) -> LatticeStateDefault<D> {
177 let lattice = state.lattice().clone();
178 lattice.get_links().for_each(|link| {
179 let potential_modif = Self::get_modif(&state, &link);
180 *state.link_mut(&link).unwrap() = potential_modif;
181 });
182 state
183 }
184}
185
186impl Default for OverrelaxationSweepReverse {
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl std::fmt::Display for OverrelaxationSweepReverse {
193 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 write!(f, "overrelaxation method by reverse")
195 }
196}
197
198impl<const D: usize> MonteCarlo<LatticeStateDefault<D>, D> for OverrelaxationSweepReverse {
199 type Error = Never;
200
201 #[inline]
202 fn next_element(
203 &mut self,
204 state: LatticeStateDefault<D>,
205 ) -> Result<LatticeStateDefault<D>, Self::Error> {
206 Ok(Self::next_element_default(state))
207 }
208}
209
210#[cfg(test)]
211mod test {
212 use rand::SeedableRng;
213
214 use super::super::super::state::{LatticeState, LatticeStateDefault};
215 use super::super::MonteCarlo;
216 use super::*;
217
218 const SEED_RNG: u64 = 0x45_78_93_f4_4a_b0_67_f0;
219
220 fn test_same_energy<MC>(mc: &mut MC, rng: &mut impl rand::Rng)
221 where
222 MC: MonteCarlo<LatticeStateDefault<3>, 3>,
223 MC::Error: core::fmt::Debug,
224 {
225 let state = LatticeStateDefault::<3>::new_determinist(1_f64, 1_f64, 4, rng).unwrap();
226 let h = state.hamiltonian_links();
227 let state2 = mc.next_element(state).unwrap();
228 let h2 = state2.hamiltonian_links();
229 println!("h1 {}, h2 {}", h, h2);
230 assert!((h - h2).abs() < f64::EPSILON * 100_f64 * 4_f64.powi(3) * (h + h2) * 0.5_f64);
233 }
234
235 #[test]
237 fn same_energy_reverse() {
238 let mut rng = rand::rngs::StdRng::seed_from_u64(SEED_RNG);
239 let mut overrelax = OverrelaxationSweepReverse::new();
240 for _ in 0_u32..10_u32 {
241 test_same_energy(&mut overrelax, &mut rng);
242 }
243 }
244
245 #[test]
247 fn same_energy_rotation() {
248 let mut rng = rand::rngs::StdRng::seed_from_u64(SEED_RNG);
249 let mut overrelax = OverrelaxationSweepRotation::new();
250 for _ in 0_u32..10_u32 {
251 test_same_energy(&mut overrelax, &mut rng);
252 }
253 }
254}