
    z	i6                        S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSK	r
SSKJr  SSKJr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  SSKJr  SSKJr  S r  " S S5      r!g)zG
Driver for a synthesis routine which emits optimal XX-based circuits.
    )annotationsN)
itemgetter)Callable)QuantumCircuit)RXXGateRZXGate)QiskitError)Operator)ONE_QUBIT_EULER_BASIS_GATES)TwoQubitWeylDecomposition   )apply_reflectionapply_shiftcanonical_xx_circuit)EPSILON)
XXPolytopec           
     |   U u  p#nUu  pVnSSSS[         R                  " X%-
  5      S-  [         R                  " X6-
  5      S-  -  [         R                  " XG-
  5      S-  -  [         R                  " X%-
  5      S-  [         R                  " X6-
  5      S-  -  [         R                  " XG-
  5      S-  -  -   -  -   -  -
  $ )zg
Computes the infidelity distance between two points p, q expressed in positive canonical
coordinates.
r   g?         )mathcossin)pqa0b0c0a1b1c1s           l/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/two_qubit/xx_decompose/decomposer.py_average_infidelityr#   $   s     JBBJBBv	
HHRW"TXXbg%6!%;;dhhrw>OST>TThhrw1$txx'8A'==@QUV@VVW
	
      c                      \ rS rSrSr    S       SS jjr\S 5       rS r\S 5       r	SS jr
\SS	 j5       r   S         SS
 jjrSrg)XXDecomposer7   a  
A class for optimal decomposition of 2-qubit unitaries into 2-qubit basis gates of ``XX`` type
(i.e., each locally equivalent to :math:`CAN(\alpha, 0, 0)` for a possibly varying :math:`alpha`).

Args:
    basis_fidelity: available strengths and fidelity of each.
        Can be either (1) a dictionary mapping ``XX`` angle values to fidelity at that angle; or
        (2) a single float ``f``, interpreted as ``{pi: f, pi/2: f/2, pi/3: f/3}``.
    euler_basis: Basis string provided to :class:`.OneQubitEulerDecomposer` for 1Q synthesis.
        Defaults to ``"U"``.
    embodiments: A dictionary mapping interaction strengths alpha to native circuits which
        embody the gate :math:`CAN(\alpha, 0, 0)`. Strengths are taken so that :math:`\pi/2`
        represents the class of a full :class:`.CXGate`.
    backup_optimizer: If supplied, defers synthesis to this callable when :class:`.XXDecomposer`
        has no efficient decomposition of its own. Useful for special cases involving 2 or 3
        applications of :math:`XX(\pi/2)`, in which case standard synthesis methods provide lower
        1Q gate count.

.. note::
    If ``embodiments`` is not passed, or if an entry is missing, it will be populated as needed
    using the method ``_default_embodiment``.

.. automethod:: __call__
Nc                   SSK Jn  U" [        U   5      U l        Ub  UO0 U l        X@l        Xl        [        [        U R                  R                  5       5      [        5       5      nU H/  n[        UR                  5      S:X  d  M  UR                  U l          O#   [        [         R"                  S-  5      U l        U R%                  5         g )Nr   )Optimize1qGatesDecompositionr   )?qiskit.transpiler.passes.optimization.optimize_1q_decompositionr)   r   _decomposer1qembodimentsbackup_optimizerbasis_fidelitynextitervaluesr   lenqubits	operationgater   nppi_check_embodiments)selfr.   euler_basisr,   r-   r)   embodiment_circuitinstructions           r"   __init__XXDecomposer.__init__Q   s    	
 ::UVa:bc*5*A;r 0, "$t'7'7'>'>'@"A>CST-K;%%&!+'11	 .
  	*DI!r$   c                    [        S5      nUR                  S5        UR                  U SS5        UR                  S5        U$ )z
If the user does not provide a custom implementation of XX(strength), then this routine
defines a default implementation using RZX.
r   r   r   )r   hrzx)strength
xx_circuits     r"   _default_embodiment XXDecomposer._default_embodimentl   s<     $A&
 	QxA&Qr$   c                    SSK Jn  U R                  R                  5        HI  u  p#[	        [        U5      5      n[	        U5      nU" XE5      S[        -
  :  d  M9  [        SU SU S35      e   g)z
Checks that `self.embodiments` is populated with legal circuit embodiments: the key-value
pair (angle, circuit) satisfies Operator(circuit) approx RXX(angle).to_matrix().
r   )average_gate_fidelityr   z"RXX embodiment provided for angle z disagrees with RXXGate()N)&qiskit.quantum_info.operators.measuresrG   r,   itemsr
   r   r   r	   )r9   rG   angle
embodimentactual	purporteds         r"   r8   XXDecomposer._check_embodiments|   sp     	Q!%!1!1!7!7!9Egen-F ,I$V7!g+E!8?WX]W^^_` 	 ":r$   c                   / SQS/ pCn/ n[         R                  " US/ 45        [        R                  " U 5      n  [	        U5      S:X  a%  [	        U5      S:X  a  [        S5      e[        S5      e[         R                  " U5      u  pg[        R                  " U Vs/ s H  oS-  PM	     sn6 n	U	R                  U 5      n
U[        X
5      -   nX:  a  XUpCnU	R                  U 5      (       a  OSUR                  5        H<  u  p[	        U5      S:X  d
  XS   ::  d  M  [         R                  " XVU-   X|/-   45        M>     GM  X#US.$ s  snf )	a  
Finds the cheapest sequence of `available_strengths` which supports the best approximation
to `canonical_coordinate`. Returns a dictionary with keys "cost", "point", and "operations".

NOTE: `canonical_coordinate` is a positive canonical coordinate. `strengths` is a dictionary
      mapping the available strengths to their (infidelity) costs, with the strengths
      themselves normalized so that pi/2 represents CX = RZX(pi/2).
r   r   r         ?r   zOAttempting to synthesize entangling gate with no controlled gates in basis set.z>Unable to synthesize a 2q unitary with the supplied basis set.r   )pointcostsequence)heapqheappushr6   arrayr2   r	   heappopr   from_strengthsnearestr#   memberrJ   )canonical_coordinateavailable_strengths
best_point	best_costbest_sequencepriority_queuesequence_costrV   xstrength_polytopecandidate_pointcandidate_costrB   
extra_costs                 r"   _best_decomposition XXDecomposer._best_decomposition   sU    09#r}
~2w/!xx(<=>"a'*+q0%i  ""bcc&+mmN&C#M * 9 98;T8aE8;T U/778LMO*-@$. N )7FX`}
 ''(<==(;(A(A(C$x=A%b\)ANN&)CXPZEZ([ )D- 8 $MRR% <Us   Ec                   U R                  S5      n[        U5      nS Vs/ s H  n[        X45      PM     nnUS   [        * :  a#  [        R
                  S-  US   -
  US   US   * /nU R                  XR5      S   n[        U5      $ s  snf )z
Counts the number of gates that would be emitted during re-synthesis.

.. note::
    This method is used by :class:`.ConsolidateBlocks`.
rR   abcrS   r   r   r   rV   )_strength_to_infidelityr   getattrr   r6   r7   rj   r2   )r9   unitary	strengthsweyl_decompositionre   targetrb   s          r"   num_basis_gatesXXDecomposer.num_basis_gates   s     005	 7w?:IJ/Q',0/J": eeai&)+VAY
CF00CJO=!! Ks   Bc           	        [        U [        5      (       a~  U(       d  Su  p#OSU -
  S-  SU -
  S-  p2[        R                  S-  [        R                  S-  [        R                  S-  4 Vs0 s H  nXBU-  [        R                  S-  -  U-   _M!     sn$ [        U [        5      (       aK  U R                  5        VVs0 s H-  u  pEXA(       a  SU-
  OSSU-  [        R                  S-  -  -   _M/     snn$ [        S5      es  snf s  snnf )	a   
Converts a dictionary mapping XX strengths to fidelities to a dictionary mapping XX
strengths to infidelities. Also supports one of the other formats Qiskit uses: if only a
lone float is supplied, it extends it from CX over CX/2 and CX/3 by linear decay.
)绽|=-q=r   r   r      r{   rz   zUnknown basis_fidelity payload.)
isinstancefloatr6   r7   dictrJ   	TypeError)r.   approximateslopeoffsetrB   fidelitys         r"   rq   $XXDecomposer._strength_to_infidelity   s    ne,, ,v!"^!3q 81~;MQR:Rv "$BEEAIruuqy A AH (*beeai86AA A  -- -;,@,@,B,B(X ;1x<EEHDTXZX]X]`aXaDb<bb,B 
 9::
s   +&C?<4Dc                   U=(       d    U R                   nU R                  X#S9nSSKJn  [	        U5      nS Vs/ s H  n[        Xx5      PM     n	nU	S   [        * :  a#  [        R                  S-  U	S   -
  U	S   U	S   * /n	[        SS	5      " U R                  X5      5      u  pUR                  5        VVs0 s H/  u  pXR                  R                  XR                  U5      5      _M1     nnn[        XU5      nU[        R                  S-  [        R                  S-  [        R                  S-  /[        R                  S-  [        R                  S-  /4;   a7  U R                   b*  SU[        R                  S-     -
  nU R!                  UUUS
9$ UR"                  [        * :  ad  [%        S5      nUR'                  [        R                  S/5        UR)                  USS/SS9  UR'                  [        R                  * S/5        UnO[%        S5      n[+        S/ SQ5      u  nnn[-        S/ SQ5      u  nnnUR)                  UR/                  5       SS9  UR'                  [        R                  S/5        UR)                  USS/SS9  UR'                  [        R                  * S/5        UR)                  UR/                  5       SS9  UR)                  USS9  U=R0                  [        R                  S-  -  sl        Un[%        SUR0                  S9nUR3                  U" UR4                  5      S/5        UR3                  U" UR6                  5      S/5        UR)                  USS/SS9  UR3                  U" UR8                  5      S/5        UR3                  U" UR:                  5      S/5        U R=                  U5      nU(       a  SSKJ n  U" USS9$ U$ s  snf s  snnf )a`  
Fashions a circuit which (perhaps approximately) models the special unitary operation
``unitary``, using the circuit templates supplied at initialization as ``embodiments``.  The
routine uses ``basis_fidelity`` to select the optimal circuit template, including when
performing exact synthesis; the contents of ``basis_fidelity`` is a dictionary mapping
interaction strengths (scaled so that :math:`CX = RZX(\pi/2)` corresponds to :math:`\pi/2`)
to circuit fidelities.

Args:
    unitary (Operator or ndarray): :math:`4 \times 4` unitary to synthesize.
    basis_fidelity (dict or float): Fidelity of basis gates. Can be either (1) a dictionary
        mapping ``XX`` angle values to fidelity at that angle; or (2) a single float ``f``,
        interpreted as ``{pi: f, pi/2: f/2, pi/3: f/3}``.
        If given, overrides the basis_fidelity given at init.
    approximate (bool): Approximates if basis fidelities are less than 1.0 .
    use_dag (bool): If true a :class:`.DAGCircuit` is returned instead of a
        :class:`QuantumCircuit` when this class is called.

Returns:
    QuantumCircuit: Synthesized circuit.
)r   r   )UnitaryGaterm   rS   r   r   rT   rV   )r.   use_dagT)inplacezreflect XX, ZZrQ   zX shift)global_phase)circuit_to_dagF)copy_operations)!r.   rq   qiskit.circuit.libraryr   r   rr   r   r6   r7   r   rj   rJ   r,   getrD   r   r-   rp   r   rzcomposer   r   inverser   appendK2rK2lK1rK1lr+   qiskit.convertersr   )r9   rs   r.   r   r   strength_to_infidelityr   ru   re   rv   r`   rb   kvr,   circuitpi2_fidelitycorrected_circuit_source_reflectionsource_shiftcircr   s                          r"   __call__XXDecomposer.__call__   s   8 (>4+>+>!%!=!= "> "
 	7 7w?:IJ/Q',0/J": eeai&)+VAY
CF %/w
$C$$VD%
!
 /446
6 ##A'?'?'BCC6 	 
 'z+N ruuqy"%%!)RUUQY?"%%!)RUUUVYAWXX%%15beeai@@L((W^(__ G8+ .q 1  ,%%g1vt%D  "%%!-'G !/q 1&67G&S#A !!,Y	!BA|Q%%&7&?&?&A4%P  ,%%g1vt%D  "%%!-%%l&:&:&<d%K%%&7%F**beeai7*'Ga.@.M.MNK 2 6 67!=K 2 6 67!=Wq!fd3K 2 6 67!=K 2 6 67!=!!$'8!$>>w K
s   O"86O')r+   r-   r.   r,   r5   )rR   UNN)r.   zdict | floatr:   strr,   z"dict[float, QuantumCircuit] | Noner-   z$Callable[..., QuantumCircuit] | None)rs   Operator | np.ndarray)F)NTF)
rs   r   r.   zdict | float | Noner   boolr   r   returnr   )__name__
__module____qualname____firstlineno____doc__r=   staticmethodrD   r8   rj   rw   rq   r   __static_attributes__ r$   r"   r&   r&   7   s    6 (+:>AE"$" " 8	"
 ?"6    *S *SX"$ ; ;6 /3 `&` ,` 	`
 ` 
` `r$   r&   )"r   
__future__r   rW   r   operatorr   typingr   numpyr6   qiskit.circuit.quantumcircuitr   %qiskit.circuit.library.standard_gatesr   r   qiskit.exceptionsr	   qiskit.quantum_info.operatorsr
   .qiskit.synthesis.one_qubit.one_qubit_decomposer   .qiskit.synthesis.two_qubit.two_qubit_decomposer   circuitsr   r   r   	utilitiesr   	polytopesr   r#   r&   r   r$   r"   <module>r      sM    #      8 B ) 2 V T I I  !&M Mr$   