Skip to content

Commit 10e16bb

Browse files
committed
start working on EField builder
1 parent 716eea2 commit 10e16bb

File tree

5 files changed

+225
-21
lines changed

5 files changed

+225
-21
lines changed

src/builder.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! builder utility
2+
3+
use std::num::NonZeroUsize;
4+
5+
#[cfg(feature = "serde-serialize")]
6+
use serde::{Deserialize, Serialize};
7+
8+
/// Type of generation
9+
#[non_exhaustive]
10+
#[derive(Debug, PartialEq)]
11+
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
12+
pub enum GenType<'rng, Rng: rand::Rng + ?Sized> {
13+
/// Cold generation all ellements are set to the default
14+
Cold,
15+
/// Random deterministe
16+
#[cfg_attr(feature = "serde-serialize", serde(skip_deserializing))]
17+
HotDeterministe(&'rng mut Rng),
18+
/// Random deterministe but own the RNG (for instance the result of `clone`)
19+
HotDeterministeOwned(Box<Rng>),
20+
/// Random threaded (non deterministe)
21+
HotThreaded(NonZeroUsize),
22+
}

src/field.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use super::{
2323

2424
mod link_matrix_builder;
2525
pub use link_matrix_builder::*;
26+
mod e_field_builder;
27+
pub use e_field_builder::*;
2628

2729
/// Adjoint representation of SU(3), it is su(3) (i.e. the lie algebra).
2830
/// See [`su3::GENERATORS`] to view the order of generators.

src/field/e_field_builder.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::borrow::Cow;
2+
use std::fmt::Debug;
3+
use std::num::NonZeroUsize;
4+
5+
use rand::distributions::Distribution;
6+
use rand_distr::Normal;
7+
#[cfg(feature = "serde-serialize")]
8+
use serde::Serialize;
9+
10+
use super::EField;
11+
use crate::builder::GenType;
12+
use crate::lattice::LatticeCyclique;
13+
use crate::{CMatrix3, Real};
14+
15+
#[derive(Debug, Clone)]
16+
enum DistributionForBuilder<'dis, Dis: Distribution<Real> + ?Sized> {
17+
Default(Normal<Real>),
18+
Given(&'dis Dis), // TODO box dyn
19+
}
20+
21+
impl<'d, Dis: Distribution<Real> + ?Sized> Default for DistributionForBuilder<'d, Dis> {
22+
fn default() -> Self {
23+
Self::Default(Normal::new(0_f64, 0.5_f64).unwrap())
24+
}
25+
}
26+
27+
#[derive(Clone, Debug)]
28+
pub struct EFieldProceduralBuilder<
29+
'rng,
30+
'lat,
31+
'dis,
32+
Rng: rand::Rng + ?Sized,
33+
Dis: Distribution<Real> + ToOwned + ?Sized,
34+
const D: usize,
35+
> {
36+
gen_type: GenType<'rng, Rng>,
37+
lattice: Cow<'lat, LatticeCyclique<D>>,
38+
distribution: DistributionForBuilder<'dis, Dis>,
39+
}
40+
41+
/*
42+
impl<'r, 'l, 'd, Rng: rand::Rng + ?Sized, Dis, const D: usize> Debug
43+
for EFieldProceduralBuilder<'r, 'l, 'd, Rng, Dis, D>
44+
where
45+
Dis: Distribution<Real> + ?Sized + ToOwned + Debug,
46+
Rng: Debug,
47+
Dis::Owned: Debug,
48+
{
49+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50+
f.debug_struct("EFieldProceduralBuilder")
51+
.field("gen_type", &self.gen_type)
52+
.field("lattice", &self.lattice)
53+
.field("distribution", &self.distribution)
54+
.finish()
55+
}
56+
}
57+
*/
58+
59+
impl<
60+
'rng,
61+
'lat,
62+
'dis,
63+
Rng: rand::Rng + ?Sized,
64+
Dis: Distribution<Real> + ToOwned + ?Sized,
65+
const D: usize,
66+
> EFieldProceduralBuilder<'rng, 'lat, 'dis, Rng, Dis, D>
67+
{
68+
pub fn new(lattice: impl Into<Cow<'lat, LatticeCyclique<D>>>) -> Self {
69+
Self {
70+
gen_type: GenType::Cold,
71+
lattice: lattice.into(),
72+
distribution: DistributionForBuilder::default(),
73+
}
74+
}
75+
}

src/field/link_matrix_builder.rs

Lines changed: 125 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::num::NonZeroUsize;
22

33
#[cfg(feature = "serde-serialize")]
4-
use serde::{Deserialize, Serialize};
4+
use serde::Serialize;
55

66
use super::LinkMatrix;
7+
use crate::builder::GenType;
78
use crate::lattice::LatticeCyclique;
89
use crate::CMatrix3;
910

@@ -17,22 +18,6 @@ enum LinkMatrixBuilderType<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize>
1718
Data(Vec<CMatrix3>),
1819
}
1920

20-
/// Type of generation
21-
#[non_exhaustive]
22-
#[derive(Debug, PartialEq)]
23-
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
24-
enum GenType<'rng, Rng: rand::Rng + ?Sized> {
25-
/// Cold generation all ellements are set to the default
26-
Cold,
27-
/// Random deterministe
28-
#[cfg_attr(feature = "serde-serialize", serde(skip_deserializing))]
29-
HotDeterministe(&'rng mut Rng),
30-
/// Random deterministe but own the RNG (for instance the result of `clone`)
31-
HotDeterministeOwned(Box<Rng>),
32-
/// Random threaded (non deterministe)
33-
HotThreaded(NonZeroUsize),
34-
}
35-
3621
impl<'rng, Rng: rand::Rng + Clone + ?Sized> Clone for GenType<'rng, Rng> {
3722
fn clone(&self) -> Self {
3823
match self {
@@ -67,25 +52,93 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize>
6752
}
6853
}
6954

55+
/// Consuming [`LinkMatrix`] builder.
56+
/// There is two way to startt the builder, [`LinkMatrixBuilder::new_from_data`]
57+
/// [`LinkMatrixBuilder::new_procedural`].
58+
///
59+
/// The first one juste move the data given in the
60+
/// [`LinkMatrix`] and does not require another configuration.
61+
///
62+
/// The seconde one will build a [`LinkMatrix`] procedurally and accept three configurations.
63+
/// [`LinkMatrixBuilder::set_cold`] that generate a configuration with only indentity matrices.
64+
/// [`LinkMatrixBuilder::set_hot_deterministe`] choose randomly every link matrices with a SU(3)
65+
/// matrix unfiformly distributed in a reproductible way
66+
/// [`LinkMatrixBuilder::set_hot_threaded`] also chooses random matrices as above but does it
67+
/// with multiple thread and is not deterministe.
7068
#[derive(Debug, PartialEq, Clone)]
7169
#[cfg_attr(feature = "serde-serialize", derive(Serialize))]
7270
pub struct LinkMatrixBuilder<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> {
7371
builder_type: LinkMatrixBuilderType<'rng, 'lat, Rng, D>,
7472
}
7573

7674
impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng, 'lat, Rng, D> {
75+
/// This method take an array of data as the base contruction of [`LinkMatrix`].
76+
///
77+
/// Using this methode has no other configuration and can be direcly build.
78+
/// It is equivalent to [`LinkMatrix::new`]
79+
/// # Example
80+
/// ```
81+
/// use lattice_qcd_rs::field::LinkMatrixBuilder;
82+
/// use lattice_qcd_rs::CMatrix3;
83+
/// use rand::rngs::ThreadRng;
84+
///
85+
/// let vec = vec![CMatrix3::identity(); 16];
86+
/// let links = LinkMatrixBuilder::<'_, '_, ThreadRng, 4>::new_from_data(vec.clone()).build();
87+
/// assert_eq!(&vec, links.as_vec());
88+
/// ```
7789
pub fn new_from_data(data: Vec<CMatrix3>) -> Self {
7890
Self {
7991
builder_type: LinkMatrixBuilderType::Data(data),
8092
}
8193
}
8294

83-
pub fn new_generated(l: &'lat LatticeCyclique<D>) -> Self {
95+
/// Initialize the builder to use procedural generation.
96+
///
97+
/// By default the generation type is set to cold.
98+
///
99+
/// # Example
100+
/// ```
101+
/// use lattice_qcd_rs::field::LinkMatrixBuilder;
102+
/// use lattice_qcd_rs::lattice::LatticeCyclique;
103+
/// use lattice_qcd_rs::CMatrix3;
104+
/// use rand::rngs::ThreadRng;
105+
/// # use std::error::Error;
106+
///
107+
/// # fn main() -> Result<(), Box<dyn Error>> {
108+
/// let lat = LatticeCyclique::<3>::new(1_f64, 4)?;
109+
/// let links = LinkMatrixBuilder::<'_, '_, ThreadRng, 3>::new_procedural(&lat).build();
110+
/// assert!(lat.has_compatible_lenght_links(&links));
111+
/// # Ok(())
112+
/// # }
113+
/// ```
114+
pub fn new_procedural(l: &'lat LatticeCyclique<D>) -> Self {
84115
Self {
85116
builder_type: LinkMatrixBuilderType::Generated(l, GenType::Cold),
86117
}
87118
}
88119

120+
/// Change the methode to a cold generation, i.e. all links are set to the identity.
121+
/// Does not affect generactor build with [`LinkMatrixBuilder::new_from_data`].
122+
///
123+
/// # Example
124+
/// ```
125+
/// use lattice_qcd_rs::field::LinkMatrixBuilder;
126+
/// use lattice_qcd_rs::lattice::LatticeCyclique;
127+
/// use lattice_qcd_rs::CMatrix3;
128+
/// use rand::rngs::ThreadRng;
129+
/// # use std::error::Error;
130+
///
131+
/// # fn main() -> Result<(), Box<dyn Error>> {
132+
/// let lat = LatticeCyclique::<3>::new(1_f64, 4)?;
133+
/// let links = LinkMatrixBuilder::<'_, '_, ThreadRng, 3>::new_procedural(&lat)
134+
/// .set_cold()
135+
/// .build();
136+
/// for m in &links {
137+
/// assert_eq!(m, &CMatrix3::identity());
138+
/// }
139+
/// # Ok(())
140+
/// # }
141+
/// ```
89142
pub fn set_cold(mut self) -> Self {
90143
match self.builder_type {
91144
LinkMatrixBuilderType::Data(_) => {}
@@ -96,6 +149,32 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
96149
self
97150
}
98151

152+
/// Change the methode to a hot determinist generation, i.e. all links generated randomly in a single thread.
153+
/// Does not affect generactor build with [`LinkMatrixBuilder::new_from_data`].
154+
///
155+
/// # Example
156+
/// ```
157+
/// use lattice_qcd_rs::field::LinkMatrixBuilder;
158+
/// use lattice_qcd_rs::lattice::LatticeCyclique;
159+
/// use lattice_qcd_rs::CMatrix3;
160+
/// use rand::rngs::StdRng;
161+
/// use rand::SeedableRng;
162+
/// # use std::error::Error;
163+
///
164+
/// # fn main() -> Result<(), Box<dyn Error>> {
165+
/// let mut rng = StdRng::seed_from_u64(0); // change the seed
166+
/// let lat = LatticeCyclique::<3>::new(1_f64, 4)?;
167+
/// let links = LinkMatrixBuilder::<'_, '_, StdRng, 3>::new_procedural(&lat)
168+
/// .set_hot_deterministe(&mut rng)
169+
/// .build();
170+
/// let mut rng_2 = StdRng::seed_from_u64(0); // same seed as before
171+
/// let links_2 = LinkMatrixBuilder::<'_, '_, StdRng, 3>::new_procedural(&lat)
172+
/// .set_hot_deterministe(&mut rng_2)
173+
/// .build();
174+
/// assert_eq!(links, links_2);
175+
/// # Ok(())
176+
/// # }
177+
/// ```
99178
pub fn set_hot_deterministe(mut self, rng: &'rng mut Rng) -> Self {
100179
match self.builder_type {
101180
LinkMatrixBuilderType::Data(_) => {}
@@ -107,6 +186,30 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
107186
self
108187
}
109188

189+
/// Change the methode to a hot determinist generation, i.e. all links generated randomly using multiple threads.
190+
/// Does not affect generactor build with [`LinkMatrixBuilder::new_from_data`].
191+
///
192+
/// # Example
193+
/// ```
194+
/// use std::num::NonZeroUsize;
195+
///
196+
/// use lattice_qcd_rs::error::ImplementationError;
197+
/// use lattice_qcd_rs::field::LinkMatrixBuilder;
198+
/// use lattice_qcd_rs::lattice::LatticeCyclique;
199+
/// use lattice_qcd_rs::CMatrix3;
200+
/// use rand::rngs::ThreadRng;
201+
/// # use std::error::Error;
202+
///
203+
/// # fn main() -> Result<(), Box<dyn Error>> {
204+
/// let lat = LatticeCyclique::<3>::new(1_f64, 4)?;
205+
/// let number_of_threads =
206+
/// NonZeroUsize::new(4).ok_or(ImplementationError::OptionWithUnexpectedNone)?;
207+
/// let links = LinkMatrixBuilder::<'_, '_, ThreadRng, 3>::new_procedural(&lat)
208+
/// .set_hot_threaded(number_of_threads)
209+
/// .build();
210+
/// # Ok(())
211+
/// # }
212+
/// ```
110213
pub fn set_hot_threaded(mut self, number_of_threads: NonZeroUsize) -> Self {
111214
match self.builder_type {
112215
LinkMatrixBuilderType::Data(_) => {}
@@ -118,6 +221,7 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
118221
self
119222
}
120223

224+
/// Therminal methode to build the [`LinkMatrix`]
121225
pub fn build(self) -> LinkMatrix {
122226
self.builder_type.into_link_matrix()
123227
}
@@ -155,17 +259,17 @@ mod test {
155259
#[test]
156260
fn builder() -> Result<(), LatticeInitializationError> {
157261
let lattice = LatticeCyclique::<3>::new(1_f64, 10)?;
158-
let m = LinkMatrixBuilder::<'_, '_, rand::rngs::ThreadRng, 3>::new_generated(&lattice)
262+
let m = LinkMatrixBuilder::<'_, '_, rand::rngs::ThreadRng, 3>::new_procedural(&lattice)
159263
.set_cold()
160264
.build();
161265
assert_eq!(m, LinkMatrix::new_cold(&lattice));
162266

163267
let mut rng = StdRng::seed_from_u64(SEED_RNG);
164-
let builder = LinkMatrixBuilder::<'_, '_, _, 3>::new_generated(&lattice)
268+
let builder = LinkMatrixBuilder::<'_, '_, _, 3>::new_procedural(&lattice)
165269
.set_hot_deterministe(&mut rng);
166270
let m = builder.clone().build();
167271
assert_eq!(m, builder.build());
168-
let _ = LinkMatrixBuilder::<'_, '_, rand::rngs::ThreadRng, 3>::new_generated(&lattice)
272+
let _ = LinkMatrixBuilder::<'_, '_, rand::rngs::ThreadRng, 3>::new_procedural(&lattice)
169273
.set_hot_threaded(NonZeroUsize::new(rayon::current_num_threads().min(1)).unwrap())
170274
.build();
171275
assert!(LinkMatrixBuilder::<'_, '_, _, 3>::new_from_data(vec![])

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub use rand_distr::Distribution;
4848

4949
#[macro_use]
5050
mod macro_def;
51+
pub(crate) mod builder;
5152
pub mod dim;
5253
pub mod error;
5354
pub mod field;

0 commit comments

Comments
 (0)