1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::sse::fast_ops::FastOpsTemplate;
use crate::sse::qmc_ising::{IsingManager, QMCIsingGraph};
use crate::sse::*;
use rand::Rng;

/// Enables debugging OpContainers
pub trait DebugOps: OpContainer {
    /// Count the number of diagonal and offdiagonal ops. Sum is self.get_n()
    fn count_diagonal_and_off(&self) -> (usize, usize) {
        let cutoff = self.get_cutoff();
        let mut diag = 0;
        let mut offdiag = 0;
        for p in 0..cutoff {
            let op = self.get_pth(p);
            if let Some(op) = op {
                if op.is_diagonal() {
                    diag += 1;
                } else {
                    offdiag += 1;
                }
            }
        }
        debug_assert_eq!(diag + offdiag, self.get_n());
        (diag, offdiag)
    }

    /// Count the number of constant ops.
    fn count_constant_ops(&self) -> usize {
        let cutoff = self.get_cutoff();
        let mut constant = 0;
        for p in 0..cutoff {
            let op = self.get_pth(p);
            if let Some(op) = op {
                if op.is_constant() {
                    constant += 1;
                }
            }
        }
        constant
    }
}

/// Allows for debugging QMC instances given they have a debuggable OpContainer.
pub trait QMCDebug {
    /// The type of the debuggable manager.
    type M: DebugOps;
    /// The manager which can be debugged.
    fn get_debug_manager(&self) -> &Self::M;

    /// Count the number of diagonal and offdiagonal ops.
    fn count_diagonal_and_off(&self) -> (usize, usize) {
        self.get_debug_manager().count_diagonal_and_off()
    }
    /// Count the number of constant ops.
    fn count_constant_ops(&self) -> usize {
        self.get_debug_manager().count_constant_ops()
    }
}

impl<O: Op> DebugOps for FastOpsTemplate<O> {}

impl<R, M> QMCDebug for QMCIsingGraph<R, M>
where
    R: Rng,
    M: IsingManager + DebugOps,
{
    type M = M;

    fn get_debug_manager(&self) -> &Self::M {
        self.get_manager_ref()
    }
}