@@ -25,7 +25,7 @@ use numpy::{IntoPyArray, ToPyArray};
2525use pyo3:: exceptions:: PyValueError ;
2626use pyo3:: prelude:: * ;
2727
28- use super :: common:: { DEFAULT_FIDELITY , TraceToFidelity , rx_matrix_nalgebra , rz_matrix_nalgebra } ;
28+ use super :: common:: { DEFAULT_FIDELITY , IPZ , TraceToFidelity , rx_matrix , rz_matrix } ;
2929use super :: gate_sequence:: { TwoQubitGateSequence , TwoQubitSequenceVec } ;
3030use super :: weyl_decomposition:: { __num_basis_gates, _num_basis_gates, TwoQubitWeylDecomposition } ;
3131
@@ -46,7 +46,7 @@ use qiskit_circuit::instruction::{Instruction, Parameters};
4646use qiskit_circuit:: operations:: { Operation , OperationRef , Param , StandardGate } ;
4747use qiskit_circuit:: packed_instruction:: PackedOperation ;
4848use qiskit_circuit:: { NoBlocks , Qubit } ;
49- use qiskit_util:: complex:: { C_M_ONE , C_ONE , C_ZERO , IM , M_IM , c64} ;
49+ use qiskit_util:: complex:: { C_M_ONE , C_ONE , IM , M_IM , c64} ;
5050
5151// Worst case length is 5x 1q gates for each 1q decomposition + 1x 2q gate
5252// We might overallocate a bit if the euler basis is different but
@@ -56,8 +56,6 @@ use qiskit_util::complex::{C_M_ONE, C_ONE, C_ZERO, IM, M_IM, c64};
5656// Python space.
5757const TWO_QUBIT_SEQUENCE_DEFAULT_CAPACITY : usize = 21 ;
5858
59- static IPZ : Matrix2 < Complex64 > = Matrix2 :: new ( IM , C_ZERO , C_ZERO , M_IM ) ;
60-
6159static HGATE : Matrix2 < Complex64 > =
6260 Matrix2 :: new ( H_GATE [ 0 ] [ 0 ] , H_GATE [ 0 ] [ 1 ] , H_GATE [ 1 ] [ 0 ] , H_GATE [ 1 ] [ 1 ] ) ;
6361
@@ -93,11 +91,6 @@ static K22L: Matrix2<Complex64> = Matrix2::new(
9391) ;
9492static K22R : Matrix2 < Complex64 > = Matrix2 :: new ( Complex64 :: ZERO , C_ONE , C_M_ONE , Complex64 :: ZERO ) ;
9593
96- #[ inline]
97- pub fn ndarray_to_matrix2 < T : Copy > ( view : ArrayView2 < T > ) -> Matrix2 < T > {
98- Matrix2 :: new ( view[ [ 0 , 0 ] ] , view[ ( 0 , 1 ) ] , view[ ( 1 , 0 ) ] , view[ ( 1 , 1 ) ] )
99- }
100-
10194#[ derive( Clone , Debug ) ]
10295#[ allow( non_snake_case) ]
10396#[ pyclass(
@@ -152,14 +145,10 @@ impl TwoQubitBasisDecomposer {
152145 ) -> SmallVec < [ Matrix2 < Complex64 > ; 8 ] > {
153146 // FIXME: fix for z!=0 and c!=0 using closest reflection (not always in the Weyl chamber)
154147 smallvec ! [
155- ndarray_to_matrix2( self . basis_decomposer. K2r . view( ) ) . adjoint( )
156- * ndarray_to_matrix2( target. K2r . view( ) ) ,
157- ndarray_to_matrix2( self . basis_decomposer. K2l . view( ) ) . adjoint( )
158- * ndarray_to_matrix2( target. K2l . view( ) ) ,
159- ndarray_to_matrix2( target. K1r . view( ) )
160- * ndarray_to_matrix2( self . basis_decomposer. K1r . view( ) ) . adjoint( ) ,
161- ndarray_to_matrix2( target. K1l . view( ) )
162- * ndarray_to_matrix2( self . basis_decomposer. K1l . view( ) ) . adjoint( ) ,
148+ self . basis_decomposer. K2r . adjoint( ) * target. K2r ,
149+ self . basis_decomposer. K2l . adjoint( ) * target. K2l ,
150+ target. K1r * self . basis_decomposer. K1r . adjoint( ) ,
151+ target. K1l * self . basis_decomposer. K1l . adjoint( ) ,
163152 ]
164153 }
165154
@@ -168,12 +157,12 @@ impl TwoQubitBasisDecomposer {
168157 target : & TwoQubitWeylDecomposition ,
169158 ) -> SmallVec < [ Matrix2 < Complex64 > ; 8 ] > {
170159 smallvec ! [
171- self . q2r * ndarray_to_matrix2 ( target. K2r . view ( ) ) ,
172- self . q2l * ndarray_to_matrix2 ( target. K2l . view ( ) ) ,
173- self . q1ra * rz_matrix_nalgebra ( 2. * target. b) * self . q1rb,
174- self . q1la * rz_matrix_nalgebra ( -2. * target. a) * self . q1lb,
175- ndarray_to_matrix2 ( target. K1r . view ( ) ) * self . q0r,
176- ndarray_to_matrix2 ( target. K1l . view ( ) ) * self . q0l,
160+ self . q2r * target. K2r ,
161+ self . q2l * target. K2l ,
162+ self . q1ra * rz_matrix ( 2. * target. b) * self . q1rb,
163+ self . q1la * rz_matrix ( -2. * target. a) * self . q1lb,
164+ target. K1r * self . q0r,
165+ target. K1l * self . q0l,
177166 ]
178167 }
179168
@@ -182,14 +171,14 @@ impl TwoQubitBasisDecomposer {
182171 target : & TwoQubitWeylDecomposition ,
183172 ) -> SmallVec < [ Matrix2 < Complex64 > ; 8 ] > {
184173 smallvec ! [
185- self . u3r * ndarray_to_matrix2 ( target. K2r . view ( ) ) ,
186- self . u3l * ndarray_to_matrix2 ( target. K2l . view ( ) ) ,
187- self . u2ra * rz_matrix_nalgebra ( 2. * target. b) * self . u2rb,
188- self . u2la * rz_matrix_nalgebra ( -2. * target. a) * self . u2lb,
189- self . u1ra * rz_matrix_nalgebra ( -2. * target. c) * self . u1rb,
174+ self . u3r * target. K2r ,
175+ self . u3l * target. K2l ,
176+ self . u2ra * rz_matrix ( 2. * target. b) * self . u2rb,
177+ self . u2la * rz_matrix ( -2. * target. a) * self . u2lb,
178+ self . u1ra * rz_matrix ( -2. * target. c) * self . u1rb,
190179 self . u1l,
191- ndarray_to_matrix2 ( target. K1r . view ( ) ) * self . u0r,
192- ndarray_to_matrix2 ( target. K1l . view ( ) ) * self . u0l,
180+ target. K1r * self . u0r,
181+ target. K1l * self . u0l,
193182 ]
194183 }
195184
@@ -235,14 +224,11 @@ impl TwoQubitBasisDecomposer {
235224 [ euler_angles[ 2 ] , euler_angles[ 0 ] , euler_angles[ 1 ] ]
236225 } )
237226 . collect ( ) ;
238- let mut euler_matrix_q0 =
239- rx_matrix_nalgebra ( euler_q0[ 0 ] [ 1 ] ) * rz_matrix_nalgebra ( euler_q0[ 0 ] [ 0 ] ) ;
240- euler_matrix_q0 =
241- rz_matrix_nalgebra ( euler_q0[ 0 ] [ 2 ] + euler_q0[ 1 ] [ 0 ] + FRAC_PI_2 ) * euler_matrix_q0;
227+ let mut euler_matrix_q0 = rx_matrix ( euler_q0[ 0 ] [ 1 ] ) * rz_matrix ( euler_q0[ 0 ] [ 0 ] ) ;
228+ euler_matrix_q0 = rz_matrix ( euler_q0[ 0 ] [ 2 ] + euler_q0[ 1 ] [ 0 ] + FRAC_PI_2 ) * euler_matrix_q0;
242229 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix_q0. as_view ( ) , 0 ) ;
243- let mut euler_matrix_q1 =
244- rz_matrix_nalgebra ( euler_q1[ 0 ] [ 1 ] ) * rx_matrix_nalgebra ( euler_q1[ 0 ] [ 0 ] ) ;
245- euler_matrix_q1 = rx_matrix_nalgebra ( euler_q1[ 0 ] [ 2 ] + euler_q1[ 1 ] [ 0 ] ) * euler_matrix_q1;
230+ let mut euler_matrix_q1 = rz_matrix ( euler_q1[ 0 ] [ 1 ] ) * rx_matrix ( euler_q1[ 0 ] [ 0 ] ) ;
231+ euler_matrix_q1 = rx_matrix ( euler_q1[ 0 ] [ 2 ] + euler_q1[ 1 ] [ 0 ] ) * euler_matrix_q1;
246232 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix_q1. as_view ( ) , 1 ) ;
247233 gates. push ( ( StandardGate :: CX . into ( ) , smallvec ! [ ] , smallvec ! [ 0 , 1 ] ) ) ;
248234 if ( euler_q0[ 1 ] [ 1 ] - PI ) . abs ( ) < ANGLE_ZERO_EPSILON {
@@ -268,13 +254,13 @@ impl TwoQubitBasisDecomposer {
268254 ) ) ;
269255 global_phase += FRAC_PI_2 ;
270256 gates. push ( ( StandardGate :: CX . into ( ) , smallvec ! [ ] , smallvec ! [ 0 , 1 ] ) ) ;
271- let mut euler_matrix_q0 = rx_matrix_nalgebra ( euler_q0 [ 2 ] [ 1 ] )
272- * rz_matrix_nalgebra ( euler_q0[ 1 ] [ 2 ] + euler_q0[ 2 ] [ 0 ] + FRAC_PI_2 ) ;
273- euler_matrix_q0 = rz_matrix_nalgebra ( euler_q0[ 2 ] [ 2 ] ) * euler_matrix_q0;
257+ let mut euler_matrix_q0 =
258+ rx_matrix ( euler_q0 [ 2 ] [ 1 ] ) * rz_matrix ( euler_q0[ 1 ] [ 2 ] + euler_q0[ 2 ] [ 0 ] + FRAC_PI_2 ) ;
259+ euler_matrix_q0 = rz_matrix ( euler_q0[ 2 ] [ 2 ] ) * euler_matrix_q0;
274260 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix_q0. as_view ( ) , 0 ) ;
275- let mut euler_matrix_q1 = rz_matrix_nalgebra ( euler_q1 [ 2 ] [ 1 ] )
276- * rx_matrix_nalgebra ( euler_q1[ 1 ] [ 2 ] + euler_q1[ 2 ] [ 0 ] ) ;
277- euler_matrix_q1 = rx_matrix_nalgebra ( euler_q1[ 2 ] [ 2 ] ) * euler_matrix_q1;
261+ let mut euler_matrix_q1 =
262+ rz_matrix ( euler_q1 [ 2 ] [ 1 ] ) * rx_matrix ( euler_q1[ 1 ] [ 2 ] + euler_q1[ 2 ] [ 0 ] ) ;
263+ euler_matrix_q1 = rx_matrix ( euler_q1[ 2 ] [ 2 ] ) * euler_matrix_q1;
278264 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix_q1. as_view ( ) , 1 ) ;
279265 Some ( TwoQubitGateSequence {
280266 gates,
@@ -341,19 +327,18 @@ impl TwoQubitBasisDecomposer {
341327 let x02_add = x12 - euler_q0[ 1 ] [ 0 ] ;
342328 let x12_is_half_pi = abs_diff_eq ! ( x12, FRAC_PI_2 , epsilon = atol) ;
343329
344- let mut euler_matrix_q0 =
345- rx_matrix_nalgebra ( euler_q0[ 0 ] [ 1 ] ) * rz_matrix_nalgebra ( euler_q0[ 0 ] [ 0 ] ) ;
330+ let mut euler_matrix_q0 = rx_matrix ( euler_q0[ 0 ] [ 1 ] ) * rz_matrix ( euler_q0[ 0 ] [ 0 ] ) ;
346331 if x12_is_non_zero && x12_is_pi_mult {
347- euler_matrix_q0 = rz_matrix_nalgebra ( euler_q0[ 0 ] [ 2 ] - x02_add) * euler_matrix_q0;
332+ euler_matrix_q0 = rz_matrix ( euler_q0[ 0 ] [ 2 ] - x02_add) * euler_matrix_q0;
348333 } else {
349- euler_matrix_q0 = rz_matrix_nalgebra ( euler_q0[ 0 ] [ 2 ] + euler_q0[ 1 ] [ 0 ] ) * euler_matrix_q0;
334+ euler_matrix_q0 = rz_matrix ( euler_q0[ 0 ] [ 2 ] + euler_q0[ 1 ] [ 0 ] ) * euler_matrix_q0;
350335 }
351336 euler_matrix_q0 = HGATE * euler_matrix_q0;
352337 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix_q0. as_view ( ) , 0 ) ;
353338
354- let rx_0 = rx_matrix_nalgebra ( euler_q1[ 0 ] [ 0 ] ) ;
355- let rz = rz_matrix_nalgebra ( euler_q1[ 0 ] [ 1 ] ) ;
356- let rx_1 = rx_matrix_nalgebra ( euler_q1[ 0 ] [ 2 ] + euler_q1[ 1 ] [ 0 ] ) ;
339+ let rx_0 = rx_matrix ( euler_q1[ 0 ] [ 0 ] ) ;
340+ let rz = rz_matrix ( euler_q1[ 0 ] [ 1 ] ) ;
341+ let rx_1 = rx_matrix ( euler_q1[ 0 ] [ 2 ] + euler_q1[ 1 ] [ 0 ] ) ;
357342 let mut euler_matrix_q1 = rz * rx_0;
358343 euler_matrix_q1 = rx_1 * euler_matrix_q1;
359344 euler_matrix_q1 = HGATE * euler_matrix_q1;
@@ -386,12 +371,7 @@ impl TwoQubitBasisDecomposer {
386371 global_phase -= FRAC_PI_4 ;
387372 } else if x12_is_non_zero && !x12_is_pi_mult {
388373 if self . pulse_optimize . is_none ( ) {
389- self . append_1q_sequence (
390- & mut gates,
391- & mut global_phase,
392- rx_matrix_nalgebra ( x12) . as_view ( ) ,
393- 0 ,
394- ) ;
374+ self . append_1q_sequence ( & mut gates, & mut global_phase, rx_matrix ( x12) . as_view ( ) , 0 ) ;
395375 } else {
396376 return None ;
397377 }
@@ -403,7 +383,7 @@ impl TwoQubitBasisDecomposer {
403383 self . append_1q_sequence (
404384 & mut gates,
405385 & mut global_phase,
406- rx_matrix_nalgebra ( euler_q1[ 1 ] [ 1 ] ) . as_view ( ) ,
386+ rx_matrix ( euler_q1[ 1 ] [ 1 ] ) . as_view ( ) ,
407387 1 ,
408388 ) ;
409389 } else {
@@ -427,27 +407,27 @@ impl TwoQubitBasisDecomposer {
427407 self . append_1q_sequence (
428408 & mut gates,
429409 & mut global_phase,
430- rx_matrix_nalgebra ( euler_q1[ 2 ] [ 1 ] ) . as_view ( ) ,
410+ rx_matrix ( euler_q1[ 2 ] [ 1 ] ) . as_view ( ) ,
431411 1 ,
432412 ) ;
433413 } else {
434414 return None ;
435415 }
436416 gates. push ( ( StandardGate :: CX . into ( ) , smallvec ! [ ] , smallvec ! [ 1 , 0 ] ) ) ;
437- let mut euler_matrix = rz_matrix_nalgebra ( euler_q0[ 2 ] [ 2 ] + euler_q0[ 3 ] [ 0 ] ) * HGATE ;
438- euler_matrix = rx_matrix_nalgebra ( euler_q0[ 3 ] [ 1 ] ) * euler_matrix;
439- euler_matrix = rz_matrix_nalgebra ( euler_q0[ 3 ] [ 2 ] ) * euler_matrix;
417+ let mut euler_matrix = rz_matrix ( euler_q0[ 2 ] [ 2 ] + euler_q0[ 3 ] [ 0 ] ) * HGATE ;
418+ euler_matrix = rx_matrix ( euler_q0[ 3 ] [ 1 ] ) * euler_matrix;
419+ euler_matrix = rz_matrix ( euler_q0[ 3 ] [ 2 ] ) * euler_matrix;
440420 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix. as_view ( ) , 0 ) ;
441421
442- let mut euler_matrix = rx_matrix_nalgebra ( euler_q1[ 2 ] [ 2 ] + euler_q1[ 3 ] [ 0 ] ) * HGATE ;
443- euler_matrix = rz_matrix_nalgebra ( euler_q1[ 3 ] [ 1 ] ) * euler_matrix;
444- euler_matrix = rx_matrix_nalgebra ( euler_q1[ 3 ] [ 2 ] ) * euler_matrix;
422+ let mut euler_matrix = rx_matrix ( euler_q1[ 2 ] [ 2 ] + euler_q1[ 3 ] [ 0 ] ) * HGATE ;
423+ euler_matrix = rz_matrix ( euler_q1[ 3 ] [ 1 ] ) * euler_matrix;
424+ euler_matrix = rx_matrix ( euler_q1[ 3 ] [ 2 ] ) * euler_matrix;
445425 self . append_1q_sequence ( & mut gates, & mut global_phase, euler_matrix. as_view ( ) , 1 ) ;
446426
447427 let out_unitary = compute_unitary ( & gates, global_phase) ;
448428 // TODO: fix the sign problem to avoid correction here
449429 if abs_diff_eq ! (
450- target_decomposed. unitary_matrix[ [ 0 , 0 ] ] ,
430+ target_decomposed. unitary_matrix[ ( 0 , 0 ) ] ,
451431 -out_unitary[ [ 0 , 0 ] ] ,
452432 epsilon = atol
453433 ) {
@@ -600,10 +580,10 @@ impl TwoQubitBasisDecomposer {
600580 temp * ( M_IM * c64 ( 0. , b) . exp ( ) ) ,
601581 temp * ( M_IM * c64 ( 0. , -b) . exp ( ) ) ,
602582 ) ;
603- let k1ld = ndarray_to_matrix2 ( basis_decomposer. K1l . view ( ) ) . adjoint ( ) ;
604- let k1rd = ndarray_to_matrix2 ( basis_decomposer. K1r . view ( ) ) . adjoint ( ) ;
605- let k2ld = ndarray_to_matrix2 ( basis_decomposer. K2l . view ( ) ) . adjoint ( ) ;
606- let k2rd = ndarray_to_matrix2 ( basis_decomposer. K2r . view ( ) ) . adjoint ( ) ;
583+ let k1ld = basis_decomposer. K1l . adjoint ( ) ;
584+ let k1rd = basis_decomposer. K1r . adjoint ( ) ;
585+ let k2ld = basis_decomposer. K2l . adjoint ( ) ;
586+ let k2rd = basis_decomposer. K2r . adjoint ( ) ;
607587 // Pre-build the fixed parts of the matrices used in 3-part decomposition
608588 let u0l = k31l * k1ld;
609589 let u0r = k31r * k1rd;
@@ -752,10 +732,7 @@ impl TwoQubitBasisDecomposer {
752732}
753733
754734fn decomp0_inner ( target : & TwoQubitWeylDecomposition ) -> SmallVec < [ Matrix2 < Complex64 > ; 8 ] > {
755- smallvec ! [
756- ndarray_to_matrix2( target. K1r . view( ) ) * ndarray_to_matrix2( target. K2r . view( ) ) ,
757- ndarray_to_matrix2( target. K1l . view( ) ) * ndarray_to_matrix2( target. K2l . view( ) ) ,
758- ]
735+ smallvec ! [ target. K1r * target. K2r , target. K1l * target. K2l , ]
759736}
760737
761738type PickleNewArgs < ' a > = ( Py < PyAny > , Py < PyAny > , f64 , & ' a str , Option < bool > ) ;
0 commit comments