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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use super::*;
use crate::operation::OperationSet;
use crate::param::{Parameter, ParameterVector};
/// Properties
impl QuditCircuit {
/// Returns the number of cycles in the circuit.
///
/// # Performance
///
/// This method is O(1).
pub fn num_cycles(&self) -> usize {
self.cycles.len()
}
/// Returns the number of parameters in the circuit.
///
/// # Performance
///
/// This method is O(1).
pub fn num_params(&self) -> usize {
self.params.len()
}
/// Returns the number of unassigned (variable) parameters in the circuit.
///
/// # Performance
///
/// This method is O(p) where
/// - `p` is the total number of parameters in the circuit.
pub fn num_unassigned_params(&self) -> usize {
self.params
.iter()
.filter(|&p| matches!(p, Parameter::Unassigned))
.count()
}
/// Returns the number of operations in the circuit.
///
/// # Performance
///
/// This method is O(|t|) where
/// - `t` is the number of distinct instruction types in the circuit.
pub fn num_operations(&self) -> usize {
self.operations.num_operations()
}
/// Returns a vector of active qudit indices.
///
/// An active qudit is one that participates in at least one operation.
///
/// # Returns
///
/// A vector containing the indices of qudits that are active.
///
/// # Performance
///
/// This method is O(w) where
/// - `w` is the number of wires in the circuit.
pub fn active_qudits(&self) -> Vec<usize> {
self.front
.keys()
.filter_map(|wire| wire.is_quantum().then_some(wire.index()))
.collect()
}
/// Returns a vector of active classical dit indices.
///
/// An active classical dit is one that participates in at least one operation.
///
/// # Returns
///
/// A vector containing the indices of classical dits that are active.
///
/// # Performance
///
/// This method is O(w) where
/// - `w` is the number of wires in the circuit.
pub fn active_dits(&self) -> Vec<usize> {
self.front
.keys()
.filter_map(|wire| wire.is_classical().then_some(wire.index()))
.collect()
}
/// A reference to the parameters of the circuit.
pub fn params(&self) -> &ParameterVector {
&self.params
}
/// A reference to the operation set of the circuit.
pub fn operations(&self) -> &OperationSet {
&self.operations
}
/// Checks if the circuit is empty.
///
/// # Returns
///
/// `true` if the circuit contains no cycles, `false` otherwise.
///
/// # Examples
///
/// ```
/// # use qudit_circuit::QuditCircuit;
/// let circuit = QuditCircuit::pure([2, 2]);
/// assert!(circuit.is_empty());
/// ```
///
/// # Performance
///
/// This method is O(1).
pub fn is_empty(&self) -> bool {
self.cycles.is_empty()
}
}