1
1
use std:: num:: NonZeroUsize ;
2
2
3
3
#[ cfg( feature = "serde-serialize" ) ]
4
- use serde:: Serialize ;
4
+ use serde:: { Deserialize , Serialize } ;
5
5
6
6
use super :: LinkMatrix ;
7
7
use crate :: lattice:: LatticeCyclique ;
8
8
use crate :: CMatrix3 ;
9
9
10
- #[ derive( Debug , PartialEq ) ]
10
+ #[ non_exhaustive]
11
+ #[ derive( Debug , PartialEq , Clone ) ]
11
12
#[ cfg_attr( feature = "serde-serialize" , derive( Serialize ) ) ]
12
- enum LinkMatrixBuilderType < ' a , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > {
13
- Generated ( & ' lat LatticeCyclique < D > , GenType < ' a , Rng > ) ,
13
+ enum LinkMatrixBuilderType < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > {
14
+ /// Generate data procedurally
15
+ Generated ( & ' lat LatticeCyclique < D > , GenType < ' rng , Rng > ) ,
16
+ /// Data already existing
14
17
Data ( Vec < CMatrix3 > ) ,
15
18
}
16
19
20
+ /// Type of generation
21
+ #[ non_exhaustive]
17
22
#[ derive( Debug , PartialEq ) ]
18
- #[ cfg_attr( feature = "serde-serialize" , derive( Serialize ) ) ]
19
- enum GenType < ' a , Rng : rand:: Rng + ?Sized > {
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
20
26
Cold ,
21
- Hot ( & ' a mut Rng ) ,
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)
22
33
HotThreaded ( NonZeroUsize ) ,
23
34
}
24
35
25
- impl < ' a , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > LinkMatrixBuilderType < ' a , ' lat , Rng , D > {
36
+ impl < ' rng , Rng : rand:: Rng + Clone + ?Sized > Clone for GenType < ' rng , Rng > {
37
+ fn clone ( & self ) -> Self {
38
+ match self {
39
+ Self :: Cold => Self :: Cold ,
40
+ Self :: HotDeterministe ( rng_ref) => {
41
+ Self :: HotDeterministeOwned ( Box :: new ( ( * rng_ref) . clone ( ) ) )
42
+ }
43
+ Self :: HotDeterministeOwned ( rng_box) => Self :: HotDeterministeOwned ( rng_box. clone ( ) ) ,
44
+ Self :: HotThreaded ( n) => Self :: HotThreaded ( * n) ,
45
+ }
46
+ }
47
+ }
48
+
49
+ impl < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize >
50
+ LinkMatrixBuilderType < ' rng , ' lat , Rng , D >
51
+ {
26
52
pub fn into_link_matrix ( self ) -> LinkMatrix {
27
53
match self {
28
54
Self :: Data ( data) => LinkMatrix :: new ( data) ,
29
55
Self :: Generated ( l, gen_type) => match gen_type {
30
56
GenType :: Cold => LinkMatrix :: new_cold ( l) ,
31
- GenType :: Hot ( rng) => LinkMatrix :: new_deterministe ( l, rng) ,
57
+ GenType :: HotDeterministe ( rng) => LinkMatrix :: new_deterministe ( l, rng) ,
32
58
// the unwrap is safe because n is non zero
33
59
// there is a possibility to panic in a thread but very unlikly
34
60
// (either something break in this API or in thread_rng())
61
+ GenType :: HotDeterministeOwned ( mut rng_box) => {
62
+ LinkMatrix :: new_deterministe ( l, & mut rng_box)
63
+ }
35
64
GenType :: HotThreaded ( n) => LinkMatrix :: new_random_threaded ( l, n. get ( ) ) . unwrap ( ) ,
36
65
} ,
37
66
}
38
67
}
39
68
}
40
69
41
- #[ derive( Debug , PartialEq ) ]
70
+ #[ derive( Debug , PartialEq , Clone ) ]
42
71
#[ cfg_attr( feature = "serde-serialize" , derive( Serialize ) ) ]
43
- pub struct LinkMatrixBuilder < ' a , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > {
44
- builder_type : LinkMatrixBuilderType < ' a , ' lat , Rng , D > ,
72
+ pub struct LinkMatrixBuilder < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > {
73
+ builder_type : LinkMatrixBuilderType < ' rng , ' lat , Rng , D > ,
45
74
}
46
75
47
- impl < ' a , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > LinkMatrixBuilder < ' a , ' lat , Rng , D > {
76
+ impl < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize > LinkMatrixBuilder < ' rng , ' lat , Rng , D > {
48
77
pub fn new_from_data ( data : Vec < CMatrix3 > ) -> Self {
49
78
Self {
50
79
builder_type : LinkMatrixBuilderType :: Data ( data) ,
@@ -57,7 +86,7 @@ impl<'a, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'a, 'l
57
86
}
58
87
}
59
88
60
- pub fn set_cold ( & mut self ) -> & mut Self {
89
+ pub fn set_cold ( mut self ) -> Self {
61
90
match self . builder_type {
62
91
LinkMatrixBuilderType :: Data ( _) => { }
63
92
LinkMatrixBuilderType :: Generated ( l, _) => {
@@ -67,17 +96,18 @@ impl<'a, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'a, 'l
67
96
self
68
97
}
69
98
70
- pub fn set_hot ( & mut self , rng : & ' a mut Rng ) -> & mut Self {
99
+ pub fn set_hot_deterministe ( mut self , rng : & ' rng mut Rng ) -> Self {
71
100
match self . builder_type {
72
101
LinkMatrixBuilderType :: Data ( _) => { }
73
102
LinkMatrixBuilderType :: Generated ( l, _) => {
74
- self . builder_type = LinkMatrixBuilderType :: Generated ( l, GenType :: Hot ( rng) ) ;
103
+ self . builder_type =
104
+ LinkMatrixBuilderType :: Generated ( l, GenType :: HotDeterministe ( rng) ) ;
75
105
}
76
106
}
77
107
self
78
108
}
79
109
80
- pub fn set_hot_threaded ( & mut self , number_of_threads : NonZeroUsize ) -> & mut Self {
110
+ pub fn set_hot_threaded ( mut self , number_of_threads : NonZeroUsize ) -> Self {
81
111
match self . builder_type {
82
112
LinkMatrixBuilderType :: Data ( _) => { }
83
113
LinkMatrixBuilderType :: Generated ( l, _) => {
@@ -92,3 +122,103 @@ impl<'a, 'lat, Rng: rand::Rng + ?Sized, const D: usize> LinkMatrixBuilder<'a, 'l
92
122
self . builder_type . into_link_matrix ( )
93
123
}
94
124
}
125
+
126
+ #[ doc( hidden) ]
127
+ impl < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize >
128
+ From < LinkMatrixBuilderType < ' rng , ' lat , Rng , D > > for LinkMatrixBuilder < ' rng , ' lat , Rng , D >
129
+ {
130
+ fn from ( builder_type : LinkMatrixBuilderType < ' rng , ' lat , Rng , D > ) -> Self {
131
+ Self { builder_type }
132
+ }
133
+ }
134
+
135
+ impl < ' rng , ' lat , Rng : rand:: Rng + ?Sized , const D : usize >
136
+ From < LinkMatrixBuilder < ' rng , ' lat , Rng , D > > for LinkMatrix
137
+ {
138
+ fn from ( builder : LinkMatrixBuilder < ' rng , ' lat , Rng , D > ) -> Self {
139
+ builder. build ( )
140
+ }
141
+ }
142
+
143
+ #[ cfg( test) ]
144
+ mod test {
145
+ use std:: num:: NonZeroUsize ;
146
+
147
+ use rand:: rngs:: StdRng ;
148
+ use rand:: SeedableRng ;
149
+
150
+ use super :: * ;
151
+ use crate :: error:: LatticeInitializationError ;
152
+
153
+ const SEED_RNG : u64 = 0x45_78_93_f4_4a_b0_67_f0 ;
154
+
155
+ #[ test]
156
+ fn builder ( ) -> Result < ( ) , LatticeInitializationError > {
157
+ let lattice = LatticeCyclique :: < 3 > :: new ( 1_f64 , 10 ) ?;
158
+ let m = LinkMatrixBuilder :: < ' _ , ' _ , rand:: rngs:: ThreadRng , 3 > :: new_generated ( & lattice)
159
+ . set_cold ( )
160
+ . build ( ) ;
161
+ assert_eq ! ( m, LinkMatrix :: new_cold( & lattice) ) ;
162
+
163
+ let mut rng = StdRng :: seed_from_u64 ( SEED_RNG ) ;
164
+ let builder = LinkMatrixBuilder :: < ' _ , ' _ , _ , 3 > :: new_generated ( & lattice)
165
+ . set_hot_deterministe ( & mut rng) ;
166
+ let m = builder. clone ( ) . build ( ) ;
167
+ assert_eq ! ( m, builder. build( ) ) ;
168
+ let _ = LinkMatrixBuilder :: < ' _ , ' _ , rand:: rngs:: ThreadRng , 3 > :: new_generated ( & lattice)
169
+ . set_hot_threaded ( NonZeroUsize :: new ( rayon:: current_num_threads ( ) . min ( 1 ) ) . unwrap ( ) )
170
+ . build ( ) ;
171
+ assert ! ( LinkMatrixBuilder :: <' _, ' _, _, 3 >:: new_from_data( vec![ ] )
172
+ . set_cold( )
173
+ . set_hot_deterministe( & mut rng)
174
+ . set_hot_threaded( NonZeroUsize :: new( 1 ) . unwrap( ) )
175
+ . build( )
176
+ . is_empty( ) ) ;
177
+ assert_eq ! (
178
+ LinkMatrixBuilder :: <' _, ' _, rand:: rngs:: ThreadRng , 3 >:: new_from_data(
179
+ vec![ CMatrix3 :: identity( ) ; 5 ]
180
+ )
181
+ . build( )
182
+ . as_ref( ) ,
183
+ vec![ CMatrix3 :: identity( ) ; 5 ]
184
+ ) ;
185
+ assert_eq ! (
186
+ LinkMatrix :: from(
187
+ LinkMatrixBuilder :: <' _, ' _, rand:: rngs:: ThreadRng , 3 >:: new_from_data(
188
+ vec![ CMatrix3 :: identity( ) ; 100 ]
189
+ )
190
+ )
191
+ . as_ref( ) ,
192
+ vec![ CMatrix3 :: identity( ) ; 100 ]
193
+ ) ;
194
+ Ok ( ( ) )
195
+ }
196
+
197
+ #[ test]
198
+ fn gen_type ( ) {
199
+ let mut rng = StdRng :: seed_from_u64 ( SEED_RNG ) ;
200
+ assert_eq ! (
201
+ GenType :: <' _, StdRng >:: Cold . clone( ) ,
202
+ GenType :: <' _, StdRng >:: Cold
203
+ ) ;
204
+ assert_eq ! (
205
+ GenType :: HotDeterministeOwned ( Box :: new( rng. clone( ) ) ) . clone( ) ,
206
+ GenType :: HotDeterministeOwned ( Box :: new( rng. clone( ) ) )
207
+ ) ;
208
+ assert_eq ! (
209
+ GenType :: <' _, StdRng >:: HotThreaded ( NonZeroUsize :: new( 1 ) . unwrap( ) ) . clone( ) ,
210
+ GenType :: <' _, StdRng >:: HotThreaded ( NonZeroUsize :: new( 1 ) . unwrap( ) )
211
+ ) ;
212
+ let gen_type = GenType :: HotDeterministe ( & mut rng) ;
213
+ assert_ne ! ( gen_type. clone( ) , gen_type) ;
214
+ }
215
+
216
+ #[ test]
217
+ fn trait_misc ( ) {
218
+ let builder_type = LinkMatrixBuilderType :: < ' _ , ' _ , StdRng , 10 > :: Data ( vec ! [ ] ) ;
219
+ assert_eq ! (
220
+ LinkMatrixBuilder :: from( builder_type. clone( ) ) . builder_type,
221
+ builder_type
222
+ ) ;
223
+ }
224
+ }
0 commit comments