1
1
use std:: num:: NonZeroUsize ;
2
2
3
3
#[ cfg( feature = "serde-serialize" ) ]
4
- use serde:: { Deserialize , Serialize } ;
4
+ use serde:: Serialize ;
5
5
6
6
use super :: LinkMatrix ;
7
+ use crate :: builder:: GenType ;
7
8
use crate :: lattice:: LatticeCyclique ;
8
9
use crate :: CMatrix3 ;
9
10
@@ -17,22 +18,6 @@ enum LinkMatrixBuilderType<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize>
17
18
Data ( Vec < CMatrix3 > ) ,
18
19
}
19
20
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
-
36
21
impl < ' rng , Rng : rand:: Rng + Clone + ?Sized > Clone for GenType < ' rng , Rng > {
37
22
fn clone ( & self ) -> Self {
38
23
match self {
@@ -67,25 +52,93 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize>
67
52
}
68
53
}
69
54
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.
70
68
#[ derive( Debug , PartialEq , Clone ) ]
71
69
#[ cfg_attr( feature = "serde-serialize" , derive( Serialize ) ) ]
72
70
pub struct LinkMatrixBuilder < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > {
73
71
builder_type : LinkMatrixBuilderType < ' rng , ' lat , Rng , D > ,
74
72
}
75
73
76
74
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
+ /// ```
77
89
pub fn new_from_data ( data : Vec < CMatrix3 > ) -> Self {
78
90
Self {
79
91
builder_type : LinkMatrixBuilderType :: Data ( data) ,
80
92
}
81
93
}
82
94
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 {
84
115
Self {
85
116
builder_type : LinkMatrixBuilderType :: Generated ( l, GenType :: Cold ) ,
86
117
}
87
118
}
88
119
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
+ /// ```
89
142
pub fn set_cold ( mut self ) -> Self {
90
143
match self . builder_type {
91
144
LinkMatrixBuilderType :: Data ( _) => { }
@@ -96,6 +149,32 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
96
149
self
97
150
}
98
151
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
+ /// ```
99
178
pub fn set_hot_deterministe ( mut self , rng : & ' rng mut Rng ) -> Self {
100
179
match self . builder_type {
101
180
LinkMatrixBuilderType :: Data ( _) => { }
@@ -107,6 +186,30 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
107
186
self
108
187
}
109
188
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
+ /// ```
110
213
pub fn set_hot_threaded ( mut self , number_of_threads : NonZeroUsize ) -> Self {
111
214
match self . builder_type {
112
215
LinkMatrixBuilderType :: Data ( _) => { }
@@ -118,6 +221,7 @@ impl<'rng, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'rng
118
221
self
119
222
}
120
223
224
+ /// Therminal methode to build the [`LinkMatrix`]
121
225
pub fn build ( self ) -> LinkMatrix {
122
226
self . builder_type . into_link_matrix ( )
123
227
}
@@ -155,17 +259,17 @@ mod test {
155
259
#[ test]
156
260
fn builder ( ) -> Result < ( ) , LatticeInitializationError > {
157
261
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)
159
263
. set_cold ( )
160
264
. build ( ) ;
161
265
assert_eq ! ( m, LinkMatrix :: new_cold( & lattice) ) ;
162
266
163
267
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)
165
269
. set_hot_deterministe ( & mut rng) ;
166
270
let m = builder. clone ( ) . build ( ) ;
167
271
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)
169
273
. set_hot_threaded ( NonZeroUsize :: new ( rayon:: current_num_threads ( ) . min ( 1 ) ) . unwrap ( ) )
170
274
. build ( ) ;
171
275
assert ! ( LinkMatrixBuilder :: <' _, ' _, _, 3 >:: new_from_data( vec![ ] )
0 commit comments