
    z	i^&                        S r SSKrSSKrSSKJr  SSKJr  SSKJr  SSK	J
r
  SSK	Jr  SSKJrJrJrJrJrJrJrJrJrJrJr  SS	KJr  SS
KJr  SSKJr  \R<                  " \5      r \\\\\\\\\\\S.r! " S S\5      r"S r#g)z?Optimize chains of single-qubit gates using Euler 1q decomposer    N)TransformationPass)control_flow)one_qubit_decompose)euler_one_qubit_decomposer)optimize_1q_gates_decomposition)UGate	PhaseGateU3GateU2GateU1GateRXGateRYGateRZGateRGateSXGateXGate)Qubit)CircuitInstruction)
DAGCircuit)uu1u2u3prxryrzrsxxc                      ^  \ rS rSrSrSU 4S jjrS rSS jrSS jrS r	SS jr
\R                  S	 5       rS
 rSrU =r$ )Optimize1qGatesDecomposition=   a  Optimize chains of single-qubit gates by combining them into a single gate.

The decision to replace the original chain with a new re-synthesis depends on:
 - whether the original chain was out of basis: replace
 - whether the original chain was in basis but re-synthesis is lower error: replace
 - whether the original chain amounts to identity: replace with null

 Error is computed as a multiplication of the errors of individual gates on that qubit.
c                   > [         TU ]  5         U(       a   [        U5      S:  a  [        U5      U l        OSU l        Ub  [        UR
                  5      S:  a  UOSU l        SU l        0 U l        U R                  (       a  [        [        U5      5      U l        O3Ub  [        UR
                  5      S:X  a  [        S5      U l        SU l        U R                  5       U l        g)a  Optimize1qGatesDecomposition initializer.

Args:
    basis (list[str]): Basis gates to consider, e.g. `['u3', 'cx']`. For the effects
        of this pass, the basis is the set intersection between the `basis` parameter
        and the Euler basis. Ignored if ``target`` is also specified.
    target (Optional[Target]): The :class:`~.Target` object corresponding to the compilation
        target. When specified, any argument specified for ``basis_gates`` is ignored.
r   N)super__init__lenset_basis_gatesoperation_names_target_global_decomposers_local_decomposers_cache_possible_decomposers_build_error_map	error_map)selfbasistarget	__class__s      y/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/optimization/optimize_1q_decomposition.pyr&   %Optimize1qGatesDecomposition.__init__H   s     	SZ!^ #E
D $D "(!3F<R<R8SVW8Wv]a#' (*%'<SZ'HD$^s6#9#9:a?'<T'BD$ $D..0    c                    U R                   b  U R                   R                  b  [        R                  " U R                   R                  5      n[	        U R                   R                  5       Hs  n0 nU R                   R                  5        H?  u  pEUc  M
  UR                  U4S 5      nUc  M"  UR                  c  M1  UR                  X4'   MA     UR                  U5        Mu     U$ g N)	r+   
num_qubitsr   OneQubitGateErrorMaprangeitemsgeterror	add_qubit)r1   r0   qubit
gate_errorgate
gate_propspropss          r5   r/   -Optimize1qGatesDecomposition._build_error_mapf   s    <<#(?(?(K2GGH_H_`It||667
(,(:(:(<$D!- *x > ,1H/4{{J,	 )=
 ##J/ 8 r7   c                 b   U R                   b  U R                   R                  b~  [        U R                   R                  5      S:  a[  Ub  U4nOS nX R                  ;   a  U R                  U   nU$ [        U R                   R                  U5      5      n[        U5      n U$ U R                  nU$ )Nr   )	r+   r:   r'   r*   r-   r(   operation_names_for_qargsr.   r,   )r1   rA   qubits_tupledecomposersavailable_1q_basiss        r5   _get_decomposer,Optimize1qGatesDecomposition._get_decomposerv   s     LL$''3DLL001A5  %x#<<<";;LI 	 &))O)OP\)]%^"34FG  22Kr7   c                 n    U R                  U5      n[        R                  " UUUU R                  5      nU$ )a:  
Re-synthesizes one 2x2 `matrix`, typically extracted via `dag.collect_1q_runs`.

Returns the newly synthesized circuit in the indicated basis, or None
if no synthesis routine applied.

When multiple synthesis options are available, it prefers the one with the lowest
error when the circuit is applied to `qubit`.
)rL   r   unitary_to_gate_sequencer0   )r1   matrixrA   rJ   best_synth_circuits        r5   _resynthesize_run.Optimize1qGatesDecomposition._resynthesize_run   s=     **517PPNN	
 "!r7   c                     [        5       4n[        5       nUR                  U5        UR                  Ul        U H7  u  pE[        R
                  " XBU5      nUR                  UR                  USS9  M9     U$ )NF)check)r   r   
add_qubitsglobal_phaser   from_standardapply_operation_back	operation)r1   rQ   qubitsout_dag	gate_nameanglesops          r5   _gate_sequence_to_dag2Optimize1qGatesDecomposition._gate_sequence_to_dag   sm    ',6"1>>!3I#11)VLB((vU(K "4 r7   c                 R  ^ Uc  gTb  [        U4S jU 5       5      nOSnU(       d)  Uc  U R                  X$5      nUc  U R                  X5      nOSnSnU=(       dK    Xe:  =(       d@    [        R                  " US   S5      =(       a    [        R                  " US   S5      (       + $ )zZ
Returns `True` when it is recommended to replace `old_run` with `new_circ` over `basis`.
Fc              3   @   >#    U  H  oR                   T;  v   M     g 7fr9   )name).0gr2   s     r5   	<genexpr>DOptimize1qGatesDecomposition._substitution_checks.<locals>.<genexpr>   s     C7affE17s   g        r   )any_errormathisclose)r1   old_runnew_circr2   rA   	old_error	new_errornot_basis_ps      `    r5   _substitution_checks1Optimize1qGatesDecomposition._substitution_checks   s      C7CCK  K
   KK8	  KK7	II  U".UYq\1-Sdll9Q<QR6S2S	
r7   c                 p    [         R                   " UU R                  U R                  U R                  S9  U$ )zRun the Optimize1qGatesDecomposition pass on `dag`.

Args:
    dag (DAGCircuit): the DAG to be optimized.

Returns:
    DAGCircuit: the optimized DAG.
)r3   global_decomposersbasis_gates)r   r+   r,   r)   )r1   dags     r5   run Optimize1qGatesDecomposition.run   s5     	(GG<<#77))		
 
r7   c                 D    [         R                  " XU R                  5      $ )z
Calculate a rough error for a `circuit` that runs on a specific
`qubit` of `target` (`circuit` is a list of DAGOPNodes).

Use basis errors from target if available, otherwise use length
of circuit as a weak proxy for error.
)r   compute_error_listr0   )r1   circuitrA   s      r5   rj   #Optimize1qGatesDecomposition._error   s     *<<WT^^\\r7   )r)   r,   r-   r+   r0   )NNr9   )__name__
__module____qualname____firstlineno____doc__r&   r/   rL   rR   r`   rr   r   trivial_recurserx   rj   __static_attributes____classcell__)r4   s   @r5   r"   r"   =   sM    1< ("(	
@ !! ""] ]r7   r"   c                 p   / nU c  [        [        R                  5      nU$ [        R                  nUR                  5        H7  u  p4[	        U5      R                  U 5      (       d  M&  UR                  U5        M9     SU;   a  SU;   a  UR                  S5        SU;   a  SU;   a  UR                  S5        U$ )NU3U321ZSXZSXX)listr   ONE_QUBIT_EULER_BASIS_GATESr=   r(   issubsetappendremove)	basis_setrJ   euler_basis_gateseuler_basis_namegatess        r5   r.   r.      s    K.JJK$ ! 0KK'8'>'>'@#5z""9--""#34 (A ;6[#8t$ KFk$9u%r7   )$r   loggingrk   qiskit.transpiler.basepassesr   qiskit.transpiler.passes.utilsr   qiskit.synthesis.one_qubitr   qiskit._accelerater   r   %qiskit.circuit.library.standard_gatesr   r	   r
   r   r   r   r   r   r   r   r   qiskit.circuitr   !qiskit.circuit.quantumcircuitdatar   qiskit.dagcircuit.dagcircuitr   	getLoggerr~   loggerNAME_MAPr"   r.    r7   r5   <module>r      s    F   ; 7 : 9 >    ! @ 3 
		8	$ 



	


	
	f]#5 f]Rr7   