§
    º³Ùgp"  ã                  óp   — d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ  G d„ d	¦  «        Zd
„ Zd„ ZdS )z7Synthesize a single qubit gate to a discrete basis set.é    )ÚannotationsNé   )ÚGateSequence)Úcommutator_decompose)Úgenerate_basic_approximationsÚ	_1q_gatesÚ_1q_inversesc                  óV   — e Zd ZdZ	 ddd„Zedd„¦   «         Z	 	 dd d„Zd!d"d„Zd#d„Z	dS )$ÚSolovayKitaevDecompositionzãThe Solovay Kitaev discrete decomposition algorithm.

    This class is called recursively by the transpiler pass, which is why it is separeted.
    See :class:`qiskit.transpiler.passes.SolovayKitaev` for more information.
    NÚbasic_approximationsú7str | dict[str, np.ndarray] | list[GateSequence] | NoneÚreturnÚNonec                ód   — |€t          g d¢d¬¦  «        }|                      |¦  «        | _        dS )a  
        Args:
            basic_approximations: A specification of the basic SU(2) approximations in terms
                of discrete gates. At each iteration this algorithm, the remaining error is
                approximated with the closest sequence of gates in this set.
                If a ``str``, this specifies a ``.npy`` filename from which to load the
                approximation. If a ``dict``, then this contains
                ``{gates: effective_SO3_matrix}`` pairs,
                e.g. ``{"h t": np.array([[0, 0.7071, -0.7071], [0, -0.7071, -0.7071], [-1, 0, 0]]}``.
                If a list, this contains the same information as the dict, but already converted to
                :class:`.GateSequence` objects, which contain the SO(3) matrix and gates.
        N)ÚhÚtÚtdgé
   )Úbasis_gatesÚdepth)r   Úload_basic_approximationsr   )Úselfr   s     úd/granary/edev/quantum/lib/python3.11/site-packages/qiskit/synthesis/discrete_basis/solovay_kitaev.pyÚ__init__z#SolovayKitaevDecomposition.__init__   sI   € ð  Ð'å#@Ø-Ð-Ð-°Rð$ñ $ô $Ð ð %)×$BÒ$BÐCWÑ$XÔ$XˆÔ!Ð!Ð!ó    Údataúlist | str | dictúlist[GateSequence]c                ó  — t          | t          ¦  «        r| S t          | t          ¦  «        r(t          j        | d¬¦  «                             ¦   «         } g }|                      ¦   «         D ] \  }}t          |t          ¦  «        r|\  }}n|d}}t          ¦   «         }d„ | 	                    ¦   «         D ¦   «         |_
        d„ |j
        D ¦   «         |_        t          j        |¦  «        |_        ||_        |                     |¦  «         Œ¡|S )a»  Load basic approximations.

        Args:
            data: If a string, specifies the path to the file from where to load the data.
                If a dictionary, directly specifies the decompositions as ``{gates: matrix}``
                or ``{gates: (matrix, global_phase)}``. There, ``gates`` are the names of the gates
                producing the SO(3) matrix ``matrix``, e.g.
                ``{"h t": np.array([[0, 0.7071, -0.7071], [0, -0.7071, -0.7071], [-1, 0, 0]]}``
                and the ``global_phase`` can be given to account for a global phase difference
                between the U(2) matrix of the quantum gates and the stored SO(3) matrix.
                If not given, the ``global_phase`` will be assumed to be 0.

        Returns:
            A list of basic approximations as type ``GateSequence``.

        Raises:
            ValueError: If the number of gate combinations and associated matrices does not match.
        T)Úallow_pickler   c                ó(   — g | ]}t           |         ‘ŒS © )r   )Ú.0Úelements     r   ú
<listcomp>zHSolovayKitaevDecomposition.load_basic_approximations.<locals>.<listcomp>Z   s   € ÐSÐSÐS°W�i¨Ô0ÐSÐSÐSr   c                ó   — g | ]	}|j         ‘Œ
S r"   )Úname)r#   Úgates     r   r%   zHSolovayKitaevDecomposition.load_basic_approximations.<locals>.<listcomp>[   s   € ÐDÐDÐD¨T˜tœyÐDÐDÐDr   )Ú
isinstanceÚlistÚstrÚnpÚloadÚitemÚitemsÚtupler   ÚsplitÚgatesÚlabelsÚasarrayÚproductÚglobal_phaseÚappend)r   Ú	sequencesÚ
gatestringÚmatrix_and_phaseÚmatrixr6   Úsequences          r   r   z4SolovayKitaevDecomposition.load_basic_approximations6   s  € õ* �d�DÑ!Ô!ð 	ØˆKõ �d�CÑ Ô ð 	;Ý”7˜4¨dÐ3Ñ3Ô3×8Ò8Ñ:Ô:ˆDàˆ	Ø,0¯JªJ©L¬Lð 	'ð 	'Ñ(ˆJÐ(ÝÐ*­EÑ2Ô2ð ;Ø'7Ñ$�˜˜à'7¸˜�å#‘~”~ˆHØSÐSÀ
×@PÒ@PÑ@RÔ@RÐSÑSÔSˆHŒNØDÐD°X´^ÐDÑDÔDˆHŒOÝ!œz¨&Ñ1Ô1ˆHÔØ$0ˆHÔ!Ø×Ò˜XÑ&Ô&Ð&Ð&àÐr   FTÚgate_matrixú
np.ndarrayÚrecursion_degreeÚintÚ
return_dagÚboolÚcheck_inputú'QuantumCircuit' | 'DAGCircuit'c                óî  — dt          j        t           j                             |¦  «        ¦  «        z  }t	          j        ||z  ¦  «        }t          j        t          j        |¦  «        t          j        |¦  «        ¦  «        }|  	                    |||¬¦  «        }t          |¦  «         t          |¦  «         |r|                     ¦   «         }	n|                     ¦   «         }	|j        |z
  |	_        |	S )a6  Run the algorithm.

        Args:
            gate_matrix: The 2x2 matrix representing the gate. This matrix has to be SU(2)
                up to global phase.
            recursion_degree: The recursion degree, called :math:`n` in the paper.
            return_dag: If ``True`` return a :class:`.DAGCircuit`, else a :class:`.QuantumCircuit`.
            check_input: If ``True`` check that the input matrix is valid for the decomposition.

        Returns:
            A one-qubit circuit approximating the ``gate_matrix`` in the specified discrete basis.
        r   ©rC   )r,   ÚsqrtÚlinalgÚdetr   Úfrom_matrixÚarctan2ÚimagÚrealÚ_recurseÚ_remove_identitiesÚ_remove_inverse_follows_gateÚto_dagÚ
to_circuitr6   )
r   r=   r?   rA   rC   ÚzÚgate_matrix_su2r6   ÚdecompositionÚouts
             r   ÚrunzSolovayKitaevDecomposition.runb   s×   € ð( •”�œ	Ÿš kÑ2Ô2Ñ3Ô3Ñ3ˆÝ&Ô2°1°{±?ÑCÔCˆÝ”z¥"¤'¨!¡*¤*­b¬g°a©j¬jÑ9Ô9ˆð Ÿš oÐ7GÐU`˜ÑaÔaˆõ 	˜=Ñ)Ô)Ð)Ý$ ]Ñ3Ô3Ð3ð ð 	-Ø×&Ò&Ñ(Ô(ˆCˆCà×*Ò*Ñ,Ô,ˆCà(Ô5¸ÑDˆÔàˆ
r   r<   r   Únc                ó„  — |j         j        dk    rt          d|j        ¦  «        ‚|dk    r|                      |¦  «        S |                      ||dz
  |¬¦  «        }t          |                     |                     ¦   «         ¦  «        j         |¬¦  «        \  }}|                      ||dz
  |¬¦  «        }|                      ||dz
  |¬¦  «        }|                     |¦  «                             |                     ¦   «         ¦  «                             |                     ¦   «         ¦  «                             |¦  «        S )aO  Performs ``n`` iterations of the Solovay-Kitaev algorithm on ``sequence``.

        Args:
            sequence: ``GateSequence`` to which the Solovay-Kitaev algorithm is applied.
            n: The number of iterations that the algorithm needs to run.
            check_input: If ``True`` check that the input matrix represented by ``GateSequence``
                is valid for the decomposition.

        Returns:
            GateSequence that approximates ``sequence``.

        Raises:
            ValueError: If the matrix in ``GateSequence`` does not represent an SO(3)-matrix.
        )é   rZ   z Shape of U must be (3, 3) but isr   r   rF   )r5   ÚshapeÚ
ValueErrorÚfind_basic_approximationrN   r   ÚdotÚadjoint)	r   r<   rX   rC   Úu_n1Úv_nÚw_nÚv_n1Úw_n1s	            r   rN   z#SolovayKitaevDecomposition._recurse‹   s  € ð ÔÔ! VÒ+Ð+ÝÐ?ÀÄÑPÔPÐPà�Š6ˆ6Ø×0Ò0°Ñ:Ô:Ð:à�}Š}˜X q¨1¡u¸+ˆ}ÑFÔFˆå'Ø�LŠL˜Ÿš™œÑ(Ô(Ô0¸kð
ñ 
ô 
‰ˆˆSð �}Š}˜S ! a¡%°[ˆ}ÑAÔAˆØ�}Š}˜S ! a¡%°[ˆ}ÑAÔAˆØ�xŠx˜‰~Œ~×!Ò! $§,¢,¡.¤.Ñ1Ô1×5Ò5°d·l²l±n´nÑEÔE×IÒIÈ$ÑOÔOÐOr   c                ó>   ‡— ˆfd„}t          | j        |¬¦  «        }|S )a%  Find ``GateSequence`` in ``self._basic_approximations`` that approximates ``sequence``.

        Args:
            sequence: ``GateSequence`` to find the approximation to.

        Returns:
            ``GateSequence`` in ``self._basic_approximations`` that approximates ``sequence``.
        c                ó|   •— t           j                             t          j        | j        ‰j        ¦  «        ¦  «        S ©N)r,   rH   ÚnormÚsubtractr5   )Úxr<   s    €r   Úkeyz@SolovayKitaevDecomposition.find_basic_approximation.<locals>.keyµ   s(   ø€ Ý”9—>’>¥"¤+¨a¬i¸Ô9IÑ"JÔ"JÑKÔKÐKr   )rk   )Úminr   )r   r<   rk   Úbests    `  r   r]   z3SolovayKitaevDecomposition.find_basic_approximationª   s=   ø€ ð	Lð 	Lð 	Lð 	Lð 	Lõ �4Ô,°#Ð6Ñ6Ô6ˆØˆr   rg   )r   r   r   r   )r   r   r   r   )FT)
r=   r>   r?   r@   rA   rB   rC   rB   r   rD   )T)r<   r   rX   r@   rC   rB   r   r   )r<   r   r   r   )
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ústaticmethodr   rW   rN   r]   r"   r   r   r   r      s¸   € € € € € ðð ð _cðYð Yð Yð Yð Yð. ð)ð )ð )ñ „\ð)ð^ !Ø ð'ð 'ð 'ð 'ð 'ðRPð Pð Pð Pð Pð>ð ð ð ð ð r   r   c                ó’  — d}|t          | j        ¦  «        dz
  k     r©| j        |         }| j        |dz            }|j        t          v rt          |j                 |j        k    }n|                     ¦   «         |k    }|r&|                      ||dz   g¦  «         |dk    r|dz  }n|dz  }|t          | j        ¦  «        dz
  k     °§d S d S )Nr   r   )Úlenr2   r'   r	   ÚinverseÚremove_cancelling_pair)r<   ÚindexÚ	curr_gateÚ	next_gateÚremoves        r   rP   rP   ¼   sâ   € Ø€EØ
•#�h”nÑ%Ô%¨Ñ)Ò
)Ð
)Ø”N 5Ô)ˆ	Ø”N 5¨1¡9Ô-ˆ	ØŒ>�\Ð)Ð)Ý! )¤.Ô1°Y´^ÒCˆFˆFà×&Ò&Ñ(Ô(¨IÒ5ˆFàð 
	à×+Ò+¨U°E¸A±IÐ,>Ñ?Ô?Ð?ð �qŠyˆyØ˜‘
�øð �Q‰JˆEð% •#�h”nÑ%Ô%¨Ñ)Ò
)Ð
)Ð
)Ð
)Ð
)Ð
)r   c                óÚ   — d}|t          | j        ¦  «        k     rP| j        |         j        dk    r| j                             |¦  «         n|dz  }|t          | j        ¦  «        k     °Nd S d S )Nr   Úidr   )rt   r2   r'   Úpop)r<   rw   s     r   rO   rO   Ó   sv   € Ø€EØ
•#�h”nÑ%Ô%Ò
%Ð
%ØŒ>˜%Ô Ô%¨Ò-Ð-ØŒN×Ò˜uÑ%Ô%Ð%Ð%à�Q‰JˆEð	 •#�h”nÑ%Ô%Ò
%Ð
%Ð
%Ð
%Ð
%Ð
%r   )rq   Ú
__future__r   Únumpyr,   Úgate_sequencer   r   Úgenerate_basis_approximationsr   r   r	   r   rP   rO   r"   r   r   ú<module>r‚      sÆ   ðð >Ð =à "Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð à 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø aÐ aÐ aÐ aÐ aÐ aÐ aÐ aÐ aÐ aðað að að að añ aô að aðHð ð ð.ð ð ð ð r   