qudit_core/
system.rs

1/// A data structure consisting of or operating on a specified number of finite-dimensional qudits.
2///
3/// This trait assumes that each qudit in the system has a well-defined radix, the number of basis
4/// states or dimensions, and these radices are represented collectively by the [crate::Radices]
5/// object. Mixed-radix or heterogeneous quantum systems where different qudits may have differing
6/// dimensions are allowed.
7pub trait QuditSystem {
8    /// Returns the radices of the qudits in the system.
9    ///
10    /// # Returns
11    /// A `[crate::Radices]` instance representing the radices of the qudits.
12    fn radices(&self) -> crate::Radices;
13
14    /// Returns the number of qudits in the system.
15    ///
16    /// # Returns
17    /// A `usize` representing the number of qudits.
18    #[inline(always)]
19    fn num_qudits(&self) -> usize {
20        self.radices().num_qudits()
21    }
22
23    /// Returns the total dimension of the quantum system.
24    ///
25    /// # Returns
26    /// A `usize` representing the product of the radices of all qudits.
27    #[inline(always)]
28    fn dimension(&self) -> usize {
29        self.radices().dimension()
30    }
31
32    /// Checks if the system consists only of qubits (2-level systems).
33    ///
34    /// # Returns
35    /// `true` if all qudits are qubits, otherwise `false`.
36    #[inline(always)]
37    fn is_qubit_only(&self) -> bool {
38        self.radices().is_qubit_only()
39    }
40
41    /// Checks if the system consists only of qutrits (3-level systems).
42    ///
43    /// # Returns
44    /// `true` if all qudits are qutrits, otherwise `false`.
45    #[inline(always)]
46    fn is_qutrit_only(&self) -> bool {
47        self.radices().is_qutrit_only()
48    }
49
50    /// Checks if the system consists only of qudits with a specified radix.
51    ///
52    /// # Parameters
53    /// - `radix`: The radix to check against all qudits in the system.
54    ///
55    /// # Returns
56    /// `true` if all qudits have the specified radix, otherwise `false`.
57    #[inline(always)]
58    fn is_qudit_only<T: Into<crate::Radix>>(&self, radix: T) -> bool {
59        self.radices().is_qudit_only(radix)
60    }
61
62    /// Checks if the system is homogenous, i.e., all qudits have the same radix.
63    ///
64    /// # Returns
65    /// `true` if the system is homogenous, otherwise `false`.
66    #[inline(always)]
67    fn is_homogenous(&self) -> bool {
68        self.radices().is_homogenous()
69    }
70}
71
72/// A data structure consisting of or operating on a specified number of dits.
73pub trait ClassicalSystem {
74    /// Returns the radices of the dits in the system.
75    ///
76    /// # Returns
77    /// A `[Radices]` instance representing the radices of the dits.
78    fn radices(&self) -> crate::Radices;
79
80    /// Returns the number of classical bits in the system.
81    ///
82    /// # Returns
83    /// A `usize` representing the number of classical bits.
84    fn num_dits(&self) -> usize {
85        self.radices().len()
86    }
87
88    /// Returns the total dimension of the classical system.
89    ///
90    /// # Returns
91    /// A `usize` representing the product of the radices of all dits.
92    #[inline(always)]
93    fn dimension(&self) -> usize {
94        self.radices().dimension()
95    }
96
97    /// Checks if the system consists only of bits (2-level systems).
98    ///
99    /// # Returns
100    /// `true` if all dits are bits, otherwise `false`.
101    #[inline(always)]
102    fn is_bit_only(&self) -> bool {
103        self.radices().is_qubit_only() // TODO: seems hacky?
104    }
105
106    /// Checks if the system consists only of trits (3-level systems).
107    ///
108    /// # Returns
109    /// `true` if all dits are trits, otherwise `false`.
110    #[inline(always)]
111    fn is_trit_only(&self) -> bool {
112        self.radices().is_qutrit_only()
113    }
114
115    /// Checks if the system consists only of dits with a specified radix.
116    ///
117    /// # Parameters
118    /// - `radix`: The radix to check against all dits in the system.
119    ///
120    /// # Returns
121    /// `true` if all dits have the specified radix, otherwise `false`.
122    #[inline(always)]
123    fn is_dit_only<T: Into<crate::radix::Radix>>(&self, radix: T) -> bool {
124        self.radices().is_qudit_only(radix)
125    }
126
127    /// Checks if the system is homogenous, i.e., all dits have the same radix.
128    ///
129    /// # Returns
130    /// `true` if the system is homogenous, otherwise `false`.
131    #[inline(always)]
132    fn is_homogenous(&self) -> bool {
133        self.radices().is_homogenous()
134    }
135}
136
137/// A data structure that consists of or operates on a hybrid quantum-classical system.
138pub trait HybridSystem: QuditSystem + ClassicalSystem {
139    /// Returns the radices of the qudits in the system.
140    ///
141    /// # Returns
142    /// A `[QuditRadices]` instance representing the radices of the qudits.
143    #[inline(always)]
144    fn qudit_radices(&self) -> crate::Radices {
145        QuditSystem::radices(self)
146    }
147
148    /// Returns the radices of the dits in the system.
149    ///
150    /// # Returns
151    /// A `[QuditRadices]` instance representing the radices of the dits.
152    fn dit_radices(&self) -> crate::Radices {
153        ClassicalSystem::radices(self)
154    }
155
156    /// Checks if the system is purely quantum with no classical bits.
157    ///
158    /// # Returns
159    /// `true` if there are no classical bits, otherwise `false`.
160    #[inline(always)]
161    fn is_pure_quantum(&self) -> bool {
162        self.num_dits() == 0
163    }
164
165    /// Checks if the system is purely classical with no qudits.
166    ///
167    /// # Returns
168    /// `true` if there are no qudits, otherwise `false`.
169    #[inline(always)]
170    fn is_classical_only(&self) -> bool {
171        self.num_qudits() == 0
172    }
173
174    /// Checks if the system is hybrid with both qudits and classical bits.
175    ///
176    /// # Returns
177    /// `true` if there are both qudits and classical bits, otherwise `false`.
178    #[inline(always)]
179    fn is_hybrid(&self) -> bool {
180        !self.is_pure_quantum() && !self.is_classical_only()
181    }
182}