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}