1use core::fmt::{Debug, Display};
31use std::error::Error;
32use std::marker::PhantomData;
33use std::vec::Vec;
34
35#[cfg(feature = "serde-serialize")]
36use serde::{Deserialize, Serialize};
37
38use super::{super::state::LatticeState, MonteCarlo};
39
40#[non_exhaustive]
42#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
43#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
44pub enum HybridMethodVecError<Error> {
45 Error(usize, Error),
49 NoMethod,
51}
52
53impl<Error: Display> Display for HybridMethodVecError<Error> {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55 match self {
56 Self::NoMethod => write!(f, "no monte carlo method"),
57 Self::Error(index, error) => {
58 write!(f, "error during integration step {}: {}", index, error)
59 }
60 }
61 }
62}
63
64impl<E: Display + Debug + Error + 'static> Error for HybridMethodVecError<E> {
65 fn source(&self) -> Option<&(dyn Error + 'static)> {
66 match self {
67 Self::NoMethod => None,
68 Self::Error(_, error) => Some(error),
69 }
70 }
71}
72
73#[derive(PartialEq, Eq, Debug)]
75pub struct AdaptorMethodError<'a, MC, State, ErrorBase, Error, const D: usize>
76where
77 MC: MonteCarlo<State, D, Error = ErrorBase> + ?Sized,
78 ErrorBase: Into<Error>,
79 State: LatticeState<D>,
80{
81 data: &'a mut MC,
82 _phantom: PhantomData<(&'a State, &'a ErrorBase, &'a Error)>,
83}
84
85impl<'a, MC, State, ErrorBase, Error, const D: usize>
86 AdaptorMethodError<'a, MC, State, ErrorBase, Error, D>
87where
88 MC: MonteCarlo<State, D, Error = ErrorBase> + ?Sized,
89 ErrorBase: Into<Error>,
90 State: LatticeState<D>,
91{
92 pub fn new(data: &'a mut MC) -> Self {
94 Self {
95 data,
96 _phantom: PhantomData,
97 }
98 }
99
100 pub fn data_mut(&mut self) -> &mut MC {
102 self.data
103 }
104
105 pub const fn data(&self) -> &MC {
107 self.data
108 }
109}
110
111impl<'a, MC, State, ErrorBase, Error, const D: usize> AsMut<MC>
112 for AdaptorMethodError<'a, MC, State, ErrorBase, Error, D>
113where
114 MC: MonteCarlo<State, D, Error = ErrorBase> + ?Sized,
115 ErrorBase: Into<Error>,
116 State: LatticeState<D>,
117{
118 fn as_mut(&mut self) -> &mut MC {
119 self.data_mut()
120 }
121}
122
123impl<'a, MC, State, ErrorBase, Error, const D: usize> AsRef<MC>
124 for AdaptorMethodError<'a, MC, State, ErrorBase, Error, D>
125where
126 MC: MonteCarlo<State, D, Error = ErrorBase> + ?Sized,
127 ErrorBase: Into<Error>,
128 State: LatticeState<D>,
129{
130 fn as_ref(&self) -> &MC {
131 self.data()
132 }
133}
134
135impl<'a, MC, State, ErrorBase, Error, const D: usize> MonteCarlo<State, D>
136 for AdaptorMethodError<'a, MC, State, ErrorBase, Error, D>
137where
138 MC: MonteCarlo<State, D, Error = ErrorBase> + ?Sized,
139 ErrorBase: Into<Error>,
140 State: LatticeState<D>,
141{
142 type Error = Error;
143
144 #[inline]
145 fn next_element(&mut self, state: State) -> Result<State, Self::Error> {
146 self.data.next_element(state).map_err(|err| err.into())
147 }
148}
149
150pub struct HybridMethodVec<'a, State, E, const D: usize>
157where
158 State: LatticeState<D>,
159{
160 methods: Vec<&'a mut dyn MonteCarlo<State, D, Error = E>>,
161}
162
163impl<'a, State, E, const D: usize> HybridMethodVec<'a, State, E, D>
164where
165 State: LatticeState<D>,
166{
167 getter!(
168 pub,
170 methods,
171 Vec<&'a mut dyn MonteCarlo<State, D, Error = E>>
172 );
173
174 pub fn new_empty() -> Self {
176 Self {
177 methods: Vec::new(),
178 }
179 }
180
181 pub fn with_capacity(capacity: usize) -> Self {
183 Self {
184 methods: Vec::with_capacity(capacity),
185 }
186 }
187
188 pub fn new(methods: Vec<&'a mut dyn MonteCarlo<State, D, Error = E>>) -> Self {
190 Self { methods }
191 }
192
193 pub fn methods_mut(&mut self) -> &mut Vec<&'a mut dyn MonteCarlo<State, D, Error = E>> {
195 &mut self.methods
196 }
197
198 pub fn push_method(&mut self, mc_ref: &'a mut dyn MonteCarlo<State, D, Error = E>) {
200 self.methods.push(mc_ref);
201 }
202
203 pub fn pop_method(&mut self) -> Option<&'a mut dyn MonteCarlo<State, D, Error = E>> {
205 self.methods.pop()
206 }
207
208 pub fn len(&self) -> usize {
210 self.methods.len()
211 }
212
213 pub fn is_empty(&self) -> bool {
215 self.methods.is_empty()
216 }
217}
218
219impl<'a, State, E, const D: usize> AsRef<Vec<&'a mut dyn MonteCarlo<State, D, Error = E>>>
220 for HybridMethodVec<'a, State, E, D>
221where
222 State: LatticeState<D>,
223{
224 fn as_ref(&self) -> &Vec<&'a mut dyn MonteCarlo<State, D, Error = E>> {
225 self.methods()
226 }
227}
228
229impl<'a, State, E, const D: usize> AsMut<Vec<&'a mut dyn MonteCarlo<State, D, Error = E>>>
230 for HybridMethodVec<'a, State, E, D>
231where
232 State: LatticeState<D>,
233{
234 fn as_mut(&mut self) -> &mut Vec<&'a mut dyn MonteCarlo<State, D, Error = E>> {
235 self.methods_mut()
236 }
237}
238
239impl<'a, State, E, const D: usize> Default for HybridMethodVec<'a, State, E, D>
240where
241 State: LatticeState<D>,
242{
243 fn default() -> Self {
244 Self::new_empty()
245 }
246}
247
248impl<'a, State, E, const D: usize> MonteCarlo<State, D> for HybridMethodVec<'a, State, E, D>
249where
250 State: LatticeState<D>,
251{
252 type Error = HybridMethodVecError<E>;
253
254 #[inline]
255 fn next_element(&mut self, mut state: State) -> Result<State, Self::Error> {
256 if self.methods.is_empty() {
257 return Err(HybridMethodVecError::NoMethod);
258 }
259 for (index, m) in &mut self.methods.iter_mut().enumerate() {
260 let result = state.monte_carlo_step(*m);
261 match result {
262 Ok(new_state) => state = new_state,
263 Err(error) => return Err(HybridMethodVecError::Error(index, error)),
264 }
265 }
266 Ok(state)
267 }
268}
269
270#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
272#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
273pub enum HybridMethodCoupleError<Error1, Error2> {
274 ErrorFirst(Error1),
276 ErrorSecond(Error2),
278}
279
280impl<Error1: Display, Error2: Display> Display for HybridMethodCoupleError<Error1, Error2> {
281 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
282 match self {
283 Self::ErrorFirst(error) => write!(f, "error during integration step 1: {}", error),
284 Self::ErrorSecond(error) => write!(f, "error during integration step 2: {}", error),
285 }
286 }
287}
288
289impl<Error1: Display + Error + 'static, Error2: Display + Error + 'static> Error
290 for HybridMethodCoupleError<Error1, Error2>
291{
292 fn source(&self) -> Option<&(dyn Error + 'static)> {
293 match self {
294 Self::ErrorFirst(error) => Some(error),
295 Self::ErrorSecond(error) => Some(error),
296 }
297 }
298}
299
300#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
326#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
327pub struct HybridMethodCouple<MC1, Error1, MC2, Error2, State, const D: usize>
328where
329 MC1: MonteCarlo<State, D, Error = Error1>,
330 MC2: MonteCarlo<State, D, Error = Error2>,
331 State: LatticeState<D>,
332{
333 method_1: MC1,
334 method_2: MC2,
335 _phantom: PhantomData<(State, Error1, Error2)>,
336}
337
338impl<MC1, Error1, MC2, Error2, State, const D: usize>
339 HybridMethodCouple<MC1, Error1, MC2, Error2, State, D>
340where
341 MC1: MonteCarlo<State, D, Error = Error1>,
342 MC2: MonteCarlo<State, D, Error = Error2>,
343 State: LatticeState<D>,
344{
345 getter!(
346 pub const,
348 method_1,
349 MC1
350 );
351
352 getter!(
353 pub const,
355 method_2,
356 MC2
357 );
358
359 pub const fn new(method_1: MC1, method_2: MC2) -> Self {
361 Self {
362 method_1,
363 method_2,
364 _phantom: PhantomData,
365 }
366 }
367
368 #[allow(clippy::missing_const_for_fn)] pub fn deconstruct(self) -> (MC1, MC2) {
371 (self.method_1, self.method_2)
372 }
373}
374
375impl<MC1, Error1, MC2, Error2, State, const D: usize> MonteCarlo<State, D>
376 for HybridMethodCouple<MC1, Error1, MC2, Error2, State, D>
377where
378 MC1: MonteCarlo<State, D, Error = Error1>,
379 MC2: MonteCarlo<State, D, Error = Error2>,
380 State: LatticeState<D>,
381{
382 type Error = HybridMethodCoupleError<Error1, Error2>;
383
384 #[inline]
385 fn next_element(&mut self, mut state: State) -> Result<State, Self::Error> {
386 state = state
387 .monte_carlo_step(&mut self.method_1)
388 .map_err(HybridMethodCoupleError::ErrorFirst)?;
389 state
390 .monte_carlo_step(&mut self.method_2)
391 .map_err(HybridMethodCoupleError::ErrorSecond)
392 }
393}
394
395pub type HybridMethodTriple<MC1, Error1, MC2, Error2, MC3, Error3, State, const D: usize> =
397 HybridMethodCouple<
398 HybridMethodCouple<MC1, Error1, MC2, Error2, State, D>,
399 HybridMethodCoupleError<Error1, Error2>,
400 MC3,
401 Error3,
402 State,
403 D,
404 >;
405
406pub type HybridMethodTripleError<Error1, Error2, Error3> =
408 HybridMethodCoupleError<HybridMethodCoupleError<Error1, Error2>, Error3>;
409
410pub type HybridMethodQuadruple<
412 MC1,
413 Error1,
414 MC2,
415 Error2,
416 MC3,
417 Error3,
418 MC4,
419 Error4,
420 State,
421 const D: usize,
422> = HybridMethodCouple<
423 HybridMethodTriple<MC1, Error1, MC2, Error2, MC3, Error3, State, D>,
424 HybridMethodTripleError<Error1, Error2, Error3>,
425 MC4,
426 Error4,
427 State,
428 D,
429>;
430
431pub type HybridMethodQuadrupleError<Error1, Error2, Error3, Error4> =
433 HybridMethodCoupleError<HybridMethodTripleError<Error1, Error2, Error3>, Error4>;
434
435pub type HybridMethodQuintuple<
437 MC1,
438 Error1,
439 MC2,
440 Error2,
441 MC3,
442 Error3,
443 MC4,
444 Error4,
445 MC5,
446 Error5,
447 State,
448 const D: usize,
449> = HybridMethodCouple<
450 HybridMethodQuadruple<MC1, Error1, MC2, Error2, MC3, Error3, MC4, Error4, State, D>,
451 HybridMethodQuadrupleError<Error1, Error2, Error3, Error4>,
452 MC5,
453 Error5,
454 State,
455 D,
456>;
457
458pub type HybridMethodQuintupleError<Error1, Error2, Error3, Error4, Error5> =
460 HybridMethodCoupleError<HybridMethodQuadrupleError<Error1, Error2, Error3, Error4>, Error5>;