Skip to content

Commit 572045f

Browse files
authored
Remove duplicated method on TwoQubitBasisDecomposer (#15835)
This commit removes a duplicated method implementation on the TwoQubitBasisDecomposer. The struct had two methods, call_inner and generate_sequences, which were almost line for line identical. I believe this occured during a rebase when two concurrently developed PRs were touching the same file and the rebase was a bit off after one merged which resulted in the methods being duplicated. This was missed for quite some time and is what prompted #15833 because the original two_qubit_decompose.rs file was so big it was very easy to overlook this duplication. This commit deletes the generate_sequence implementation and just uses the call_inner function.
1 parent 09af631 commit 572045f

1 file changed

Lines changed: 4 additions & 98 deletions

File tree

crates/synthesis/src/two_qubit_decompose/basis_decomposer.rs

Lines changed: 4 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -713,100 +713,6 @@ impl TwoQubitBasisDecomposer {
713713
global_phase,
714714
})
715715
}
716-
/// Decompose a two-qubit ``unitary`` over fixed basis and :math:`SU(2)` using the best
717-
/// approximation given that each basis application has a finite ``basis_fidelity``.
718-
fn generate_sequence(
719-
&self,
720-
unitary: PyReadonlyArray2<Complex64>,
721-
basis_fidelity: Option<f64>,
722-
approximate: bool,
723-
_num_basis_uses: Option<u8>,
724-
) -> PyResult<TwoQubitGateSequence> {
725-
let basis_fidelity = if !approximate {
726-
1.0
727-
} else {
728-
basis_fidelity.unwrap_or(self.basis_fidelity)
729-
};
730-
let target_decomposed =
731-
TwoQubitWeylDecomposition::new(unitary, Some(DEFAULT_FIDELITY), None)?;
732-
let traces = self.traces(&target_decomposed);
733-
let best_nbasis = traces
734-
.into_iter()
735-
.enumerate()
736-
.map(|(idx, trace)| (idx, trace.trace_to_fid() * basis_fidelity.powi(idx as i32)))
737-
.min_by(|(_idx1, fid1), (_idx2, fid2)| fid2.partial_cmp(fid1).unwrap())
738-
.unwrap()
739-
.0;
740-
let best_nbasis = _num_basis_uses.unwrap_or(best_nbasis as u8);
741-
let decomposition = match best_nbasis {
742-
0 => decomp0_inner(&target_decomposed),
743-
1 => self.decomp1_inner(&target_decomposed),
744-
2 => self.decomp2_supercontrolled_inner(&target_decomposed),
745-
3 => self.decomp3_supercontrolled_inner(&target_decomposed),
746-
_ => unreachable!("Invalid basis to use"),
747-
};
748-
let pulse_optimize = self.pulse_optimize.unwrap_or(true);
749-
let sequence = if pulse_optimize {
750-
self.pulse_optimal_chooser(best_nbasis, &decomposition, &target_decomposed)?
751-
} else {
752-
None
753-
};
754-
if let Some(seq) = sequence {
755-
return Ok(seq);
756-
}
757-
let mut target_1q_basis_list = EulerBasisSet::new();
758-
target_1q_basis_list.add_basis(self.euler_basis);
759-
let euler_decompositions: SmallVec<[Option<OneQubitGateSequence>; 8]> = decomposition
760-
.iter()
761-
.map(|decomp| {
762-
unitary_to_gate_sequence_inner(
763-
decomp.view(),
764-
&target_1q_basis_list,
765-
0,
766-
None,
767-
true,
768-
None,
769-
)
770-
})
771-
.collect();
772-
let mut gates = Vec::with_capacity(TWO_QUBIT_SEQUENCE_DEFAULT_CAPACITY);
773-
let mut global_phase = target_decomposed.global_phase;
774-
global_phase -= best_nbasis as f64 * self.basis_decomposer.global_phase;
775-
if best_nbasis == 2 {
776-
global_phase += PI;
777-
}
778-
for i in 0..best_nbasis as usize {
779-
if let Some(euler_decomp) = &euler_decompositions[2 * i] {
780-
for gate in &euler_decomp.gates {
781-
gates.push((gate.0.into(), gate.1.clone(), smallvec![0]));
782-
}
783-
global_phase += euler_decomp.global_phase
784-
}
785-
if let Some(euler_decomp) = &euler_decompositions[2 * i + 1] {
786-
for gate in &euler_decomp.gates {
787-
gates.push((gate.0.into(), gate.1.clone(), smallvec![1]));
788-
}
789-
global_phase += euler_decomp.global_phase
790-
}
791-
gates.push((self.gate.clone(), self.gate_params.clone(), smallvec![0, 1]));
792-
}
793-
if let Some(euler_decomp) = &euler_decompositions[2 * best_nbasis as usize] {
794-
for gate in &euler_decomp.gates {
795-
gates.push((gate.0.into(), gate.1.clone(), smallvec![0]));
796-
}
797-
global_phase += euler_decomp.global_phase
798-
}
799-
if let Some(euler_decomp) = &euler_decompositions[2 * best_nbasis as usize + 1] {
800-
for gate in &euler_decomp.gates {
801-
gates.push((gate.0.into(), gate.1.clone(), smallvec![1]));
802-
}
803-
global_phase += euler_decomp.global_phase
804-
}
805-
Ok(TwoQubitGateSequence {
806-
gates,
807-
global_phase,
808-
})
809-
}
810716
}
811717

812718
static K12R_ARR: GateArray1Q = [
@@ -993,8 +899,8 @@ impl TwoQubitBasisDecomposer {
993899
approximate: bool,
994900
_num_basis_uses: Option<u8>,
995901
) -> PyResult<DAGCircuit> {
996-
let sequence =
997-
self.generate_sequence(unitary, basis_fidelity, approximate, _num_basis_uses)?;
902+
let array = unitary.as_array();
903+
let sequence = self.call_inner(array, basis_fidelity, approximate, _num_basis_uses)?;
998904
let mut dag = DAGCircuit::with_capacity(2, 0, None, Some(sequence.gates.len()), None, None);
999905
dag.set_global_phase_f64(sequence.global_phase);
1000906
dag.add_qubit_unchecked(ShareableQubit::new_anonymous())?;
@@ -1036,8 +942,8 @@ impl TwoQubitBasisDecomposer {
1036942
approximate: bool,
1037943
_num_basis_uses: Option<u8>,
1038944
) -> PyResult<PyCircuitData> {
1039-
let sequence =
1040-
self.generate_sequence(unitary, basis_fidelity, approximate, _num_basis_uses)?;
945+
let array = unitary.as_array();
946+
let sequence = self.call_inner(array, basis_fidelity, approximate, _num_basis_uses)?;
1041947
Ok(CircuitData::from_packed_operations(
1042948
2,
1043949
0,

0 commit comments

Comments
 (0)