Skip to content

Commit

Permalink
Fix global phase equality check in DAGCircuit.__eq__
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish committed Aug 7, 2024
1 parent 4a4607d commit ae3ecb8
Showing 1 changed file with 75 additions and 3 deletions.
78 changes: 75 additions & 3 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2608,10 +2608,82 @@ def _format(operand):
// Try to convert to float, but in case of unbound ParameterExpressions
// a TypeError will be raise, fallback to normal equality in those
// cases.
if !self.global_phase.eq(&other.global_phase, py)? {
return Ok(false);
let phase_is_close = |self_phase: f64, other_phase: f64| -> bool {
((self_phase - other_phase + PI).rem_euclid(2. * PI) - PI).abs() <= 1.0e-10
};
match [&self.global_phase, &other.global_phase] {
[Param::Float(self_phase), Param::Float(other_phase)] => {
if !phase_is_close(*self_phase, *other_phase) {
return Ok(false);
}
}
[Param::Float(self_phase), Param::ParameterExpression(other_phase_param)] => {
let other_phase = if let Ok(other_phase) =
other_phase_param.call_method0(py, intern!(py, "numeric"))
{
other_phase.extract::<Param>(py)?
} else {
Param::ParameterExpression(other_phase_param.clone_ref(py))
};
if let Param::Float(other_phase) = other_phase {
if !phase_is_close(*self_phase, other_phase) {
return Ok(false);
}
} else if !self.global_phase.eq(&other.global_phase, py)? {
return Ok(false);
}
}
[Param::ParameterExpression(self_phase_param), Param::ParameterExpression(other_phase_param)] =>
{
let self_phase = if let Ok(self_phase) =
self_phase_param.call_method0(py, intern!(py, "numeric"))
{
self_phase.extract::<Param>(py)?
} else {
Param::ParameterExpression(self_phase_param.clone_ref(py))
};
let other_phase = if let Ok(other_phase) =
other_phase_param.call_method0(py, intern!(py, "numeric"))
{
other_phase.extract::<Param>(py)?
} else {
Param::ParameterExpression(other_phase_param.clone_ref(py))
};
match [self_phase, other_phase] {
[Param::Float(self_phase), Param::Float(other_phase)] => {
if !phase_is_close(self_phase, other_phase) {
return Ok(false);
}
}
_ => {
if !self.global_phase.eq(&other.global_phase, py)? {
return Ok(false);
}
}
}
}
[Param::ParameterExpression(self_phase_param), Param::Float(other_phase)] => {
let self_phase = if let Ok(self_phase) =
self_phase_param.call_method0(py, intern!(py, "numeric"))
{
self_phase.extract::<Param>(py)?
} else {
Param::ParameterExpression(self_phase_param.clone_ref(py))
};
if let Param::Float(self_phase) = self_phase {
if !phase_is_close(self_phase, *other_phase) {
return Ok(false);
}
} else if !self.global_phase.eq(&other.global_phase, py)? {
return Ok(false);
}
}
_ => {
if !self.global_phase.eq(&other.global_phase, py)? {
return Ok(false);
}
}
}

if self.calibrations.len() != other.calibrations.len() {
return Ok(false);
}
Expand Down

0 comments on commit ae3ecb8

Please sign in to comment.