
    z	ig-                        S r SSKJr  SSKrSSKrSSKrSSKJr  SSK	J
r
  SSKJrJr  SSKJr  SSKJrJr  \R(                  (       a  SS	KJr   " S
 S5      rSS jrg)z7Synthesize a single qubit gate to a discrete basis set.    )annotationsN)QuantumCircuit)Gate)get_standard_gate_name_mappingIGate)deprecate_func)SolovayKitaevSynthesisGateSequence)
DAGCircuitc                      \ rS rSrSr SSSSS.         SS jjjr\SS j5       r\SS	 j5       r\SS
 j5       r	\
SS j5       rSS jr  S         SS jjrSS jr\" SSSS9SS j5       rSrg) SolovayKitaevDecomposition!   zThe Solovay Kitaev discrete decomposition algorithm.

This class is called recursively by the transpiler pass, which is why it is separated.
See :class:`~qiskit.transpiler.passes.SolovayKitaev` for more information.
N   F)basis_gatesdepthcheck_inputc               \   Uc!  Ub  [        U5      n[        X#SU5      U l        OvUb  [        S5      e[	        U[
        5      (       a&  USS S:w  a  [        R                  " US5      U l        O-U R                  U5      n[        R                  " US5      U l        X0l	        X@l
        X l        g)a  
Args:
    basic_approximations: A specification of the basic SO(3) 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 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.

        Either this parameter, or ``basis_gates`` and ``depth`` can be specified.
    basis_gates: A list of discrete (i.e., non-parameterized) standard gates.
        Defaults to ``["h", "t", "tdg"]``.
    depth: The number of basis gate combinations to consider in the basis set. This
        determines how fast (and if) the algorithm converges and should be chosen
        sufficiently high.
    check_input: If ``True``, perform intermediate steps checking whether the matrices
        are of expected form.
NzNEither basic_approximations or basis_gates + depth can be specified, not both..npyT)normalize_gatesRustSolovayKitaevSynthesis_sk
ValueError
isinstancestrfrom_basic_approximationsload_basic_approximationsfrom_sequences_depth_check_input_basis_gates)selfbasic_approximationsr   r   r   	sequencess         h/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/discrete_basis/solovay_kitaev.py__init__#SolovayKitaevDecomposition.__init__(   s    :  '&-k:1+dKXDH$`  .449Mbc9RV\9\5OO($ !::;OP	5DDYPTU''    c                    U R                   $ )z3The maximum gate depth of the basic approximations.)r   r"   s    r%   r    SolovayKitaevDecomposition.depth]   s     {{r(   c                    U R                   $ )z7Whether to perform runtime checks on the internal data.)r    r*   s    r%   r   &SolovayKitaevDecomposition.check_inputb   s        r(   c                    U R                   $ )zaThe basis gate set of the basic approximations.

If ``None``, defaults to ``["h", "t", "tdg"]``.
)r!   r*   s    r%   r   &SolovayKitaevDecomposition.basis_gatesg   s        r(   c                N   [        U [        5      (       a.  U SS S:w  a%  [        U 5      nUR                  R	                  5       $ [
        R                  " S[        S9  [        U [        5      (       a  U $ [        U [        5      (       a#  [        R                  " U SS9R                  5       n / nU R                  5        Hc  u  p4[        U[        5      (       a  Uu  pVOUSpe[        UR                  5       5      n[         R"                  " XuU5      nUR%                  U5        Me     U$ )	aK  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.
r   Nr   a  It is suggested to pass basic_approximations in the binary format produced by SolovayKitaevDecomposition.save_basic_approximations, which is more performant than other formats. Other formats are pending deprecation and will be deprecated in a future release.)categoryT)allow_pickler   )r   r   r   r   get_gate_sequenceswarningswarnPendingDeprecationWarninglistnploaditemitemstupler   splitr
   from_gates_and_matrixappend)	dataskr$   
gatestringmatrix_and_phasematrixglobal_phasegatessequences	            r%   r   4SolovayKitaevDecomposition.load_basic_approximationso   s   * dC  T"#Y&%8+D1B66,,..: /	
 dD!!K dC  774d388:D 	,0JJL(J*E22'7$'7 $J$4$4$67E#99%VHX& -9 r(   c                b    USS S:X  a  [        S5      eU R                  R                  U5        g)a  Save the basic approximations into a file.

This can then be loaded again via the class initializer (preferred) or
via :meth:`load_basic_approximations`::

    filename = "approximations.bin"
    sk.save_basic_approximations(filename)

    new_sk = SolovayKitaevDecomposition(filename)

Args:
    filename: The filename to store the approximations in.

Raises:
    ValueError: If the filename has a `.npy` extension. The format is not `.npy`,
        and storing as such can cause errors when loading the file again.
r   Nr   zeThe basic approximations are not stored in npy format. Choose a different file extension (e.g. .bin).)r   r   save_basic_approximations)r"   filenames     r%   rJ   4SolovayKitaevDecomposition.save_basic_approximations   s9    * BC=F"A  	**84r(   Tc                ^   U R                   nXE:w  a  X@R                  l        [        U[        5      (       a  U R                  R                  X5      nOU R                  R                  X5      nXE:w  a  XPR                  l        [        R                  " USS9nU(       a  SSK	J
n  U" U5      $ U$ )a  Run the algorithm.

Args:
    gate_matrix: The single-qubit gate to approximate. Can either be a :class:`.Gate`, where
        :meth:`.Gate.to_matrix` returns the matrix, or a :math:`2\times 2` unitary matrix
        representing the gate.
    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.
        Overrides the class attribute with the same name, but only for this function call.

Returns:
    A one-qubit circuit approximating the ``gate_matrix`` in the specified discrete basis.
Tlegacy_qubitsr   )circuit_to_dag)r   r   	do_checksr   r   
synthesizesynthesize_matrixr   _from_circuit_dataqiskit.convertersrP   )	r"   gate_matrixrecursion_degree
return_dagr   self_check_inputr@   circuitrP   s	            r%   runSolovayKitaevDecomposition.run   s    ,  ++*!,HHk4((88&&{ED88--kLD*!1HH 33DM8!'**r(   c                    [        U[        5      (       a  U R                  R                  U5      nOU R                  R	                  U5      n[
        R                  " USS9nU$ )z(Query a basic approximation of a matrix.TrN   )r   r   r   query_basic_approximation query_basic_approximation_matrixr   rT   )r"   gater@   rZ   s       r%   r^   4SolovayKitaevDecomposition.query_basic_approximation   sN    dD!!8855d;D88<<TBD 33DMr(   z2.1zqUse query_basic_approximation instead, which takes a Gate or matrix as input and returns a QuantumCircuit object.)sinceadditional_msgpendingc                8    U R                   R                  U5      $ )zFind ``GateSequence`` in ``self._basic_approximations`` that approximates ``sequence``.

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

Returns:
    ``GateSequence`` in that approximates ``sequence``.
)r   find_basic_approximation)r"   rG   s     r%   rf   3SolovayKitaevDecomposition.find_basic_approximation   s     xx00::r(   )r!   r    r   r   )N)
r#   z7str | dict[str, np.ndarray] | list[GateSequence] | Noner   zlist[str | Gate] | Noner   intr   boolreturnNone)rj   rh   )rj   ri   )rj   zlist[str] | None)r@   zlist | str | dictrj   zlist[GateSequence])rK   r   )FT)
rV   np.ndarray | GaterW   rh   rX   ri   r   ri   rj   zQuantumCircuit | DAGCircuit)r`   rl   rj   r   )rG   r
   rj   r
   )__name__
__module____qualname____firstlineno____doc__r&   propertyr   r   r   staticmethodr   rJ   r[   r^   r   rf   __static_attributes__ r(   r%   r   r   !   s    Y]3( 04!3(U3( -	3(
 3( 3( 
3(j   ! ! ! ! 5 5n5@ ! )&) ) 	)
 ) 
%)V 8		;	;r(   r   c                j   ^ [        5       m[        5       TS'   SU4S jjn[        [        X5      5      $ )z-Normalize a list[Gate | str] into list[Gate].ic                d   > [        U [        5      (       a  U $ U T;   a  TU    $ [        SU  35      e)NzUnsupported gate: )r   r   r   )r`   name_to_gates    r%   	normalize"normalize_gates.<locals>.normalize  s;    dD!!K<%%-dV455r(   )r`   z
Gate | strrj   r   )r   r   r7   map)rF   rz   ry   s     @r%   r   r   
  s0    13L L6 I%&&r(   )rF   zlist[Gate | str]rj   z
list[Gate])rq   
__future__r   typingr4   numpyr8   qiskit.circuit.quantumcircuitr   qiskit.circuit.gater   qiskit.circuit.libraryr   r   qiskit.utils.deprecationr   +qiskit._accelerate.synthesis.discrete_basisr	   r   r
   TYPE_CHECKINGqiskit.dagcircuitr   r   r   ru   r(   r%   <module>r      sG    > "    8 $ H 3
 
,f; f;R'r(   