§
    º³Ùgås  ã                  óÂ   — d Z ddlmZ ddlm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 dd	lmZmZmZ dd
lmZ ddlmZ ddlmZmZ erddlmZ  G d„ de¦  «        ZdS )z
Stabilizer state class.
é    )Úannotations)Ú
Collection)ÚTYPE_CHECKINGN©ÚQiskitError)ÚOpShape)ÚOperator)ÚCliffordÚPauliÚ	PauliList)Ú	_append_x)ÚQuantumState)ÚQuantumCircuitÚInstruction)Úcircuitc                  ó„  ‡ — e Zd ZdZ	 dFdGˆ fd„Ze	 	 dHdId„¦   «         Zd„ Zd„ Ze	d„ ¦   «         Z
dJd„Zd„ Zd„ ZdKd„ZdKd„ZdLd„Zd„ ZdMd„ZdMd„Z	 dNdOd"„ZdNdPd'„ZdQd(„ZdJdRd,„Z	 	 dJdSd0„Z	 dJdTd1„ZdNdUd2„ZdNdVd4„ZdNdWd7„Zd8„ Zed9„ ¦   «         Zed:„ ¦   «         Z ed;„ ¦   «         Z!ed<„ ¦   «         Z"	 dNdXdC„Z#	 	 	 dYdZdE„Z$ˆ xZ%S )[ÚStabilizerStatea�  StabilizerState class.
    Stabilizer simulator using the convention from reference [1].
    Based on the internal class :class:`~qiskit.quantum_info.Clifford`.

    .. code-block::

        from qiskit import QuantumCircuit
        from qiskit.quantum_info import StabilizerState, Pauli

        # Bell state generation circuit
        qc = QuantumCircuit(2)
        qc.h(0)
        qc.cx(0, 1)
        stab = StabilizerState(qc)

        # Print the StabilizerState
        print(stab)

        # Calculate the StabilizerState measurement probabilities dictionary
        print (stab.probabilities_dict())

        # Calculate expectation value of the StabilizerState
        print (stab.expectation_value(Pauli('ZZ')))

    .. code-block:: text

        StabilizerState(StabilizerTable: ['+XX', '+ZZ'])
        {'00': 0.5, '11': 0.5}
        1

    Given a list of stabilizers, :meth:`qiskit.quantum_info.StabilizerState.from_stabilizer_list`
    returns a state stabilized by the list

    .. code-block:: python

        from qiskit.quantum_info import StabilizerState

        stabilizer_list = ["ZXX", "-XYX", "+ZYY"]
        stab = StabilizerState.from_stabilizer_list(stabilizer_list)


    References:
        1. S. Aaronson, D. Gottesman, *Improved Simulation of Stabilizer Circuits*,
           Phys. Rev. A 70, 052328 (2004).
           `arXiv:quant-ph/0406196 <https://arxiv.org/abs/quant-ph/0406196>`_
    TÚdataúUStabilizerState | Clifford | Pauli | QuantumCircuit | circuit.instruction.InstructionÚvalidateÚboolc                ón  •— t          |t          ¦  «        r|j        | _        nQt          |t          ¦  «        r't	          |                     ¦   «         ¦  «        | _        nt	          ||¦  «        | _        t          ¦   «                              t          j	        | j        j
        d¬¦  «        ¬¦  «         dS )zÚInitialize a StabilizerState object.

        Args:
            data: Data from which the stabilizer state can be constructed.
            validate: validate that the stabilizer state data is a valid Clifford.
        r   )Únum_qubits_rÚnum_qubits_l)Úop_shapeN)Ú
isinstancer   Ú_datar   r
   Úto_instructionÚsuperÚ__init__r   ÚautoÚ
num_qubits)Úselfr   r   Ú	__class__s      €ú`/granary/edev/quantum/lib/python3.11/site-packages/qiskit/quantum_info/states/stabilizerstate.pyr    zStabilizerState.__init__T   sœ   ø€ õ �d�OÑ,Ô,ð 	2ØœˆDŒJˆJå˜�eÑ$Ô$ð 	2Ý! $×"5Ò"5Ñ"7Ô"7Ñ8Ô8ˆDŒJˆJõ " $¨Ñ1Ô1ˆDŒJõ 	‰Œ×Ò¥'¤,¸D¼JÔ<QÐ`aÐ"bÑ"bÔ"bÐÑcÔcÐcÐcÐcó    FÚstabilizersúCollection[str]Úallow_redundantÚallow_underconstrainedÚreturnc                ó@   — ddl m}  ||||¬¦  «        } | |¦  «        S )a  Create a stabilizer state from the collection of stabilizers.

        Args:
            stabilizers (Collection[str]): list of stabilizer strings
            allow_redundant (bool): allow redundant stabilizers (i.e., some stabilizers
                can be products of the others)
            allow_underconstrained (bool): allow underconstrained set of stabilizers (i.e.,
                the stabilizers do not specify a unique state)

        Return:
            StabilizerState: a state stabilized by stabilizers.
        r   )Úsynth_circuit_from_stabilizers)r)   r*   )Úqiskit.synthesis.stabilizerr-   )Úclsr'   r)   r*   r-   r   s         r%   Úfrom_stabilizer_listz$StabilizerState.from_stabilizer_listm   sG   € ð* 	OÐNÐNÐNÐNÐNà0Ð0ØØ+Ø#9ð
ñ 
ô 
ˆð
 ˆs�7‰|Œ|Ðr&   c                óZ   — | j         j        |j         j        k                         ¦   «         S ©N)r   ÚstabÚall©r#   Úothers     r%   Ú__eq__zStabilizerState.__eq__‹   s"   € Ø”
” 5¤;Ô#3Ò3×8Ò8Ñ:Ô:Ð:r&   c                ó@   — d| j                              d¬¦  «        › d�S )NzStabilizerState(ÚS)Úmodeú))r   Ú	to_labels©r#   s    r%   Ú__repr__zStabilizerState.__repr__Ž   s&   € ØC $¤*×"6Ò"6¸CÐ"6Ñ"@Ô"@ÐCÐCÐCÐCr&   c                ó   — | j         S )z$Return StabilizerState Clifford data)r   r=   s    r%   ÚcliffordzStabilizerState.clifford‘   s   € ð ŒzÐr&   Nc                ó4   — | j                              ¦   «         S )z'Return True if a valid StabilizerState.)r   Ú
is_unitary)r#   ÚatolÚrtols      r%   Úis_validzStabilizerState.is_valid–   s   € àŒz×$Ò$Ñ&Ô&Ð&r&   c                ó@   — t          t          | ¦  «        › d�¦  «        ‚)Nz does not support addition©ÚNotImplementedErrorÚtyper5   s     r%   Ú_addzStabilizerState._addš   s   € Ý!¥T¨$¡Z¤ZÐ"KÐ"KÐ"KÑLÔLÐLr&   c                ó@   — t          t          | ¦  «        › d�¦  «        ‚)Nz' does not support scalar multiplicationrG   r5   s     r%   Ú	_multiplyzStabilizerState._multiply�   s   € Ý!¥T¨$¡Z¤ZÐ"XÐ"XÐ"XÑYÔYÐYr&   Úfloatc                óL   — |                       ¦   «         st          d¦  «        ‚dS )a  Return the trace of the stabilizer state as a density matrix,
        which equals to 1, since it is always a pure state.

        Returns:
            float: the trace (should equal 1).

        Raises:
            QiskitError: if input is not a StabilizerState.
        ú-StabilizerState is not a valid quantum state.ç      ð?©rE   r   r=   s    r%   ÚtracezStabilizerState.trace    ó)   € ð �}Š}‰Œð 	OÝÐMÑNÔNÐNØˆsr&   c                óL   — |                       ¦   «         st          d¦  «        ‚dS )zûReturn the purity of the quantum state,
        which equals to 1, since it is always a pure state.

        Returns:
            float: the purity (should equal 1).

        Raises:
            QiskitError: if input is not a StabilizerState.
        rO   rP   rQ   r=   s    r%   ÚpurityzStabilizerState.purity®   rS   r&   r	   c                óN   — t          | j        ¦  «                             ¦   «         S )z&Convert state to matrix operator class)r
   r@   Úto_operatorr=   s    r%   rW   zStabilizerState.to_operator¼   s   € å˜œÑ&Ô&×2Ò2Ñ4Ô4Ð4r&   c                ój   — |                       ¦   «         }|j                             ¦   «         |_        |S )z%Return the conjugate of the operator.)Úcopyr   Ú	conjugate)r#   Úrets     r%   rZ   zStabilizerState.conjugateÀ   s)   € à�iŠi‰kŒkˆØ”I×'Ò'Ñ)Ô)ˆŒ	Øˆ
r&   r6   c                ó¾   — t          |t          ¦  «        st          |¦  «        }|                      ¦   «         }| j                             |j        ¦  «        |_        |S )u:  Return the tensor product stabilizer state self âŠ— other.

        Args:
            other (StabilizerState): a stabilizer state object.

        Returns:
            StabilizerState: the tensor product operator self âŠ— other.

        Raises:
            QiskitError: if other is not a StabilizerState.
        )r   r   rY   r@   Útensorr   ©r#   r6   r[   s      r%   r]   zStabilizerState.tensorÆ   óN   € õ ˜%¥Ñ1Ô1ð 	+Ý# EÑ*Ô*ˆEØ�iŠi‰kŒkˆØ”M×(Ò(¨¬Ñ8Ô8ˆŒ	Øˆ
r&   c                ó¾   — t          |t          ¦  «        st          |¦  «        }|                      ¦   «         }| j                             |j        ¦  «        |_        |S )u:  Return the tensor product stabilizer state other âŠ— self.

        Args:
            other (StabilizerState): a stabilizer state object.

        Returns:
            StabilizerState: the tensor product operator other âŠ— self.

        Raises:
            QiskitError: if other is not a StabilizerState.
        )r   r   rY   r@   Úexpandr   r^   s      r%   ra   zStabilizerState.expandØ   r_   r&   ú'Clifford | QuantumCircuit | InstructionÚqargsúlist | Nonec                óÂ   — t          |t          ¦  «        st          |¦  «        }|                      ¦   «         }| j                             |j        |¬¦  «        |_        |S )aP  Evolve a stabilizer state by a Clifford operator.

        Args:
            other (Clifford or QuantumCircuit or qiskit.circuit.Instruction):
                The Clifford operator to evolve by.
            qargs (list): a list of stabilizer subsystem positions to apply the operator on.

        Returns:
            StabilizerState: the output stabilizer state.

        Raises:
            QiskitError: if other is not a StabilizerState.
            QiskitError: if the operator dimension does not match the
                         specified StabilizerState subsystem dimensions.
        )rc   )r   r   rY   r@   Úcomposer   )r#   r6   rc   r[   s       r%   ÚevolvezStabilizerState.evolveê   sS   € õ$ ˜%¥Ñ1Ô1ð 	+Ý# EÑ*Ô*ˆEØ�iŠi‰kŒkˆØ”M×)Ò)¨%¬.ÀÐ)ÑFÔFˆŒ	Øˆ
r&   Úoperr   úNone | listÚcomplexc                ó   — t          |t          ¦  «        st          d¦  «        ‚| j        j        }|€t          |¦  «        }n|}t          |dz  ¦  «        }d}|j        r
d|j        z  nd}t          |¦  «        D ]M\  }}	|j        |         |j        |	<   |j	        |         |j	        |	<   ||j        |	         |j	        |	         z  z  }ŒNt          |¦  «        D ]n}
d}|t          j        |j	        | j        j        |
         z  ¦  «        z  }|t          j        |j        | j        j        |
         z  ¦  «        z  }|dz  dk    r dS Œo|j	                             ¦   «         }t          |¦  «        D �]}
d}|t          j        |j	        | j        j        |
         z  ¦  «        z  }|t          j        |j        | j        j        |
         z  ¦  «        z  }|dz  dk    rŒm|d| j        j        |
         z  z  }|t          j        | j        j        |
         | j        j        |
         z  ¦  «        z  }|dt          j        || j        j        |
         z  ¦  «        z  z  }|| j        j        |
         z  }�Œ|dz  dk    r| S |S )	ax  Compute the expectation value of a Pauli operator.

        Args:
            oper (Pauli): a Pauli operator to evaluate expval.
            qargs (None or list): subsystems to apply the operator on.

        Returns:
            complex: the expectation value (only 0 or 1 or -1 or i or -i).

        Raises:
            QiskitError: if oper is not a Pauli operator.
        z7Operator for expectation value is not a Pauli operator.NÚIr   y       €      ð¿é   é   é   )r   r   r   r@   r"   ÚrangeÚphaseÚ	enumerateÚxÚzÚnpÚcount_nonzeroÚstab_xÚstab_zrY   Údestab_xÚdestab_zÚ
stab_phase)r#   rh   rc   r"   ÚqubitsÚpaulirq   Úpauli_phaseÚposÚqubitÚpÚnum_antiÚpauli_zs                r%   Úexpectation_valuez!StabilizerState.expectation_value  sŒ  € õ ˜$¥Ñ&Ô&ð 	YÝÐWÑXÔXÐXà”]Ô-ˆ
Øˆ=Ý˜:Ñ&Ô&ˆFˆFàˆFõ �j 3Ñ&Ñ'Ô'ˆØˆØ-1¬ZÐ>�s˜tœzÑ)Ð)¸Qˆå# FÑ+Ô+ð 	5ð 	5‰JˆC�Ø!œV Cœ[ˆEŒG�E‰NØ!œV Cœ[ˆEŒG�E‰NØ�U”W˜U”^ e¤g¨e¤nÑ4Ñ4ˆEˆEõ �zÑ"Ô"ð 	ð 	ˆAØˆHØ�Ô(¨¬°4´=Ô3GÈÔ3JÑ)JÑKÔKÑKˆHØ�Ô(¨¬°4´=Ô3GÈÔ3JÑ)JÑKÔKÑKˆHØ˜!‰|˜qÒ Ð Ø�q�qð !ð ”7—.’.Ñ"Ô"ˆÝ�zÑ"Ô"ð 	8ñ 	8ˆAàˆHØ�Ô(¨¬°4´=Ô3IÈ!Ô3LÑ)LÑMÔMÑMˆHØ�Ô(¨¬°4´=Ô3IÈ!Ô3LÑ)LÑMÔMÑMˆHØ˜!‰|˜qÒ Ð Øð �Q˜œÔ1°!Ô4Ñ4Ñ4ˆEØ•RÔ% d¤mÔ&:¸1Ô&=ÀÄÔ@TÐUVÔ@WÑ&WÑXÔXÑXˆEØ�Q�Ô)¨'°D´MÔ4HÈÔ4KÑ*KÑLÔLÑLÑLˆEØ ¤Ô 4°QÔ 7Ñ7ˆG‰Gð �1‰9˜Š>ˆ>Ø�<ÐàÐr&   c                ó*  ‡— t          |t          ¦  «        s"	 t          |¦  «        }n# t          $ r Y dS w xY w| j        }|j        |k    rdS t	          j        | j        j        | j        j        d| j        j	        z  ¦  «        }t	          j        |j        j        |j        j        d|j        j	        z  ¦  «        Št          j        ˆfd„|D ¦   «         ¦  «        sdS t          |¦  «        D ]&}|                      ‰|         ¦  «        }|dk    r dS Œ'dS )a  Return True if the two generating sets generate the same stabilizer group.

        Args:
            other (StabilizerState): another StabilizerState.

        Returns:
            bool: True if other has a generating set that generates the same StabilizerState.
        Frn   c                ó:   •— g | ]}|                      ‰¦  «        ‘ŒS © )Úcommutes)Ú.0r}   Úpauli_others     €r%   ú
<listcomp>z)StabilizerState.equiv.<locals>.<listcomp>_  s%   ø€ ÐKÐKÐK°u�u—~’~ kÑ2Ô2ÐKÐKÐKr&   rm   T)r   r   r   r"   r   Úfrom_symplecticr   rx   rw   r{   ru   r4   rp   r„   )r#   r6   r"   Ú
pauli_origÚiÚexp_valrŠ   s         @r%   ÚequivzStabilizerState.equivC  s?  ø€ õ ˜%¥Ñ1Ô1ð 	ðÝ'¨Ñ.Ô.��øÝð ð ð Ø�u�uðøøøð ”_ˆ
ØÔ˜zÒ)Ð)Ø�5åÔ.ØŒJÔ˜tœzÔ0°!°d´jÔ6KÑ2Kñ
ô 
ˆ
õ  Ô/ØŒKÔ ¤Ô 2°A¸¼Ô8NÑ4Nñ
ô 
ˆõ ŒvÐKÐKÐKÐKÀ
ÐKÑKÔKÑLÔLð 	Ø�5õ
 �zÑ"Ô"ð 	ð 	ˆAØ×,Ò,¨[¸¬^Ñ<Ô<ˆGØ˜!Š|ˆ|Ø�u�uð ð ˆts   ˜( ¨
6µ6Údecimalsú
None | intú
np.ndarrayc                ó  — |                       ||¦  «        }|€t          | j        j        ¦  «        }t	          j        dt          |¦  «        z  ¦  «        }|                     ¦   «         D ]\  }}t          |d¦  «        }|||<   Œ|S )a)  Return the subsystem measurement probability vector.

        Measurement probabilities are with respect to measurement in the
        computation (diagonal) basis.

        Args:
            qargs (None or list): subsystems to return probabilities for,
                if None return for all subsystems (Default: None).
            decimals (None or int): the number of decimal places to round
                values. If None no rounding is done (Default: None).

        Returns:
            np.array: The Numpy vector array of probabilities.
        Nrn   )	Úprobabilities_dictrp   r@   r"   ru   ÚzerosÚlenÚitemsÚint)r#   rc   r‘   Ú
probs_dictÚprobsÚkeyÚvalueÚplaces           r%   ÚprobabilitieszStabilizerState.probabilitiesl  s…   € ð ×,Ò,¨U°HÑ=Ô=ˆ
Øˆ=Ý˜$œ-Ô2Ñ3Ô3ˆEÝ”˜�c %™jœj™Ñ)Ô)ˆà$×*Ò*Ñ,Ô,ð 	!ð 	!‰JˆC�Ý˜˜Q‘K”KˆEØ ˆE�%‰LˆLàˆr&   Úoutcome_bitstringÚstrúdict[str, float]c                ó2   — |                       |||¬¦  «        S )aX  Return the subsystem measurement probability dictionary utilizing
        a targeted outcome_bitstring to perform the measurement for. This
        will calculate a probability for only a single targeted
        outcome_bitstring value, giving a performance boost over calculating
        all possible outcomes.

        Measurement probabilities are with respect to measurement in the
        computation (diagonal) basis.

        This dictionary representation uses a Ket-like notation where the
        dictionary keys are qudit strings for the subsystem basis vectors.
        If any subsystem has a dimension greater than 10 comma delimiters are
        inserted between integers so that subsystems can be distinguished.

        Args:
            outcome_bitstring (None or str): targeted outcome bitstring
                to perform a measurement calculation for, this will significantly
                reduce the number of calculation performed (Default: None)
            qargs (None or list): subsystems to return probabilities for,
                    if None return for all subsystems (Default: None).
            decimals (None or int): the number of decimal places to round
                    values. If None no rounding is done (Default: None)

        Returns:
            dict[str, float]: The measurement probabilities in dict (ket) form.
        ©r    rc   r‘   ©Ú_get_probabilities_dict)r#   r    rc   r‘   s       r%   Ú!probabilities_dict_from_bitstringz1StabilizerState.probabilities_dict_from_bitstring†  s)   € ð@ ×+Ò+Ø/°uÀxð ,ñ 
ô 
ð 	
r&   c                ó2   — |                       d||¬¦  «        S )aa  Return the subsystem measurement probability dictionary.

        Measurement probabilities are with respect to measurement in the
        computation (diagonal) basis.

        This dictionary representation uses a Ket-like notation where the
        dictionary keys are qudit strings for the subsystem basis vectors.
        If any subsystem has a dimension greater than 10 comma delimiters are
        inserted between integers so that subsystems can be distinguished.

        Args:
            qargs (None or list): subsystems to return probabilities for,
                if None return for all subsystems (Default: None).
            decimals (None or int): the number of decimal places to round
                values. If None no rounding is done (Default: None).

        Returns:
            dict: The measurement probabilities in dict (key) form.
        Nr¤   r¥   )r#   rc   r‘   s      r%   r•   z"StabilizerState.probabilities_dictª  s    € ð, ×+Ò+¸dÈ%ÐZbÐ+ÑcÔcÐcr&   c                ó’  — |€;t          t          t          j        d| j        j        z  ¦  «        ¦  «        ¦  «        S | j                             dt          |¦  «        ¬¦  «        }|  	                    ¦   «         }t          |¦  «        D ]<\  }}|                     |||         ¦  «        }|dk    rt          |j        |¦  «         Œ=|S )a	  Reset state or subsystems to the 0-state.

        Args:
            qargs (list or None): subsystems to reset, if None all
                                  subsystems will be reset to their 0-state
                                  (Default: None).

        Returns:
            StabilizerState: the reset state.

        Additional Information:
            If all subsystems are reset this will return the ground state
            on all subsystems. If only some subsystems are reset this
            function will perform a measurement on those subsystems and
            evolve the subsystems so that the collapsed post-measurement
            states are rotated to the 0-state. The RNG seed for this
            sampling can be set using the :meth:`seed` method.
        Nrn   ©Úsizerm   )r   r
   ru   Úeyer@   r"   Ú_rngÚintegersr—   rY   rr   Ú_measure_and_updater   )r#   rc   Úrandbitsr[   Úbitr€   Úoutcomes          r%   ÚresetzStabilizerState.resetÂ  s·   € ð( ˆ=Ý"¥8­B¬F°1°t´}Ô7OÑ3OÑ,PÔ,PÑ#QÔ#QÑRÔRÐRà”9×%Ò% a­c°%©j¬jÐ%Ñ9Ô9ˆØ�iŠi‰kŒkˆå# EÑ*Ô*ð 	/ð 	/‰JˆC�à×-Ò-¨e°X¸c´]ÑCÔCˆGð ˜!Š|ˆ|Ý˜#œ,¨Ñ.Ô.Ð.øàˆ
r&   Útuplec                ó@  — |€t          | j        j        ¦  «        }| j                             dt          |¦  «        ¬¦  «        }|                      ¦   «         }d}t          |¦  «        D ]1\  }}t          | 	                    |||         ¦  «        ¦  «        |z   }Œ2||fS )aý  Measure subsystems and return outcome and post-measure state.

        Note that this function uses the QuantumStates internal random
        number generator for sampling the measurement outcome. The RNG
        seed can be set using the :meth:`seed` method.

        Args:
            qargs (list or None): subsystems to sample measurements for,
                                  if None sample measurement of all
                                  subsystems (Default: None).

        Returns:
            tuple: the pair ``(outcome, state)`` where ``outcome`` is the
                   measurement outcome string label, and ``state`` is the
                   collapsed post-measurement stabilizer state for the
                   corresponding outcome.
        Nrn   rª   Ú )
rp   r@   r"   r­   r®   r—   rY   rr   r¡   r¯   )r#   rc   r°   r[   r²   r±   r€   s          r%   ÚmeasurezStabilizerState.measureç  sœ   € ð$ ˆ=Ý˜$œ-Ô2Ñ3Ô3ˆEà”9×%Ò% a­c°%©j¬jÐ%Ñ9Ô9ˆØ�iŠi‰kŒkˆàˆÝ# EÑ*Ô*ð 	Sð 	S‰JˆC�Ý˜#×1Ò1°%¸À#¼ÑGÔGÑHÔHÈ7ÑRˆGˆGà˜ˆ|Ðr&   Úshotsr™   c                ó²   — g }t          |¦  «        D ]D}|                      ¦   «         }|                     |                     |¦  «        d         ¦  «         ŒE|S )a¶  Sample a list of qubit measurement outcomes in the computational basis.

        Args:
            shots (int): number of samples to generate.
            qargs (None or list): subsystems to sample measurements for,
                                if None sample measurement of all
                                subsystems (Default: None).

        Returns:
            np.array: list of sampled counts if the order sampled.

        Additional Information:

            This function implements the measurement :meth:`measure` method.

            The seed for random number generator used for sampling can be
            set to a fixed value by using the stats :meth:`seed` method.
        r   )rp   rY   Úappendr·   )r#   r¸   rc   ÚmemoryÚ_r3   s         r%   Úsample_memoryzStabilizerState.sample_memory  sV   € ð& ˆÝ�u‘”ð 	2ð 	2ˆAà—9’9‘;”;ˆDØ�MŠM˜$Ÿ,š, uÑ-Ô-¨aÔ0Ñ1Ô1Ð1Ð1Øˆr&   c                óH  — | j         j        }| j         }| j         j        }t          j        |dd…|f         ¦  «        }|dk    rZt          |dz  ¦  «        }t          |¦  «        D ]/}|j        |         |         r|                      ||||z   ¦  «        }Œ0|j	        }	|	S |}	t          j
        t          j        |dd…|f         ¦  «        ¦  «        }
|
|z  }
t          d|z  ¦  «        D ];}|j        |         |         r&||
k    r ||
|z
  k    r|                      |||
¦  «         Œ<|j        |
|z
                                ¦   «         |j        |
|z
  <   t          j        |¦  «        |j        |
<   t          j        |¦  «        |j        |
<   d|j        |
         |<   |	|j	        |
<   |	S )aà  Measure a single qubit and return outcome and post-measure state.

        Note that this function uses the QuantumStates internal random
        number generator for sampling the measurement outcome. The RNG
        seed can be set using the :meth:`seed` method.

        Note that stabilizer state measurements only have three probabilities:
        (p0, p1) = (0.5, 0.5), (1, 0), or (0, 1)
        The random case happens if there is a row anti-commuting with Z[qubit]
        Nr   rl   rn   T)r@   r"   rw   ru   Úanyr   rp   rs   Ú_rowsum_deterministicrq   ÚminÚnonzeroÚ_rowsum_nondeterministicr3   rY   Údestabr–   rt   )r#   r€   Úrandbitr"   r@   rw   Úz_anticommutingÚ	aux_paulirŽ   r²   Úp_qubits              r%   r¯   z#StabilizerState._measure_and_update"  sÄ  € ð ”]Ô-ˆ
Ø”=ˆØ”Ô%ˆõ œ& ¨¨¨¨5¨Ô!1Ñ2Ô2ˆà˜aÒÐå˜j¨3Ñ.Ñ/Ô/ˆIÝ˜:Ñ&Ô&ð `ð `�Ø”:˜a”= Ô'ð `Ø $× :Ò :¸8ÀYÐPQÐT^ÑP^Ñ _Ô _�IøØ”oˆGØˆNð ˆGÝ”f�RœZ¨¨q¨q¨q°%¨xÔ(8Ñ9Ô9Ñ:Ô:ˆGØ�zÑ!ˆGõ ˜1˜z™>Ñ*Ô*ð Hð H�à”J˜q”M %Ô(ð H¨q°Gª|¨|À!ÈÐR\ÑH\ÒB]ÐB]Ø×1Ò1°(¸A¸wÑGÔGÐGøà4<´MÀ'ÈJÑBVÔ4W×4\Ò4\Ñ4^Ô4^ˆHŒO˜G jÑ0Ñ1Ý"$¤(¨:Ñ"6Ô"6ˆHŒJ�wÑÝ"$¤(¨:Ñ"6Ô"6ˆHŒJ�wÑØ)-ˆHŒJ�wÔ Ñ&Ø&-ˆHŒN˜7Ñ#ØˆNr&   c                óž   — ||z  dd|z  z   d| z  z   z  | |z  dd|z  z   d|z  z   z  z
  dz  }|dk     r|dz  }|dk    rt          d¦  «        ‚|S )zNExponent g of i such that Pauli(x1,z1) * Pauli(x2,z2) = i^g Pauli(x1+x2,z1+z2)rm   rn   ro   r   z9Invalid rowsum phase exponent in measurement calculation.r   )Úx1Úz1Úx2Úz2rq   s        r%   Ú_phase_exponentzStabilizerState._phase_exponentR  sw   € ð
 �b‘˜A  B¡™J¨¨R©Ñ/Ñ0°2¸±7¸aÀ!ÀbÁ&¹jÈ1ÈrÉ6Ñ>QÑ3RÑRÐVWÑWˆØ�1Š9ˆ9Ø�Q‰JˆEà�AŠ:ˆ:ÝÐYÑZÔZÐZØˆr&   c           	     ó¢  — d|z  d|z  z   }t          |j        ¦  «        D ]N}|t                               |j        |         |j        |         | j        |         | j        |         ¦  «        z  }ŒO|dz  }|dk    |dk    z  rt          d¦  «        ‚t          |dk    ¦  «        }| xj        |j        z  c_        | xj        |j        z  c_        | |fS )z)Aaronson-Gottesman rowsum helper functionrn   ro   r   z*Invalid rowsum in measurement calculation.)rp   r"   r   rÎ   rs   rt   r   r™   )Úaccum_pauliÚaccum_phaseÚ	row_pauliÚ	row_phaseÚnewrr€   s         r%   Ú_rowsumzStabilizerState._rowsum_  sâ   € ð �9‰}˜q ;™Ñ.ˆå˜9Ô/Ñ0Ô0ð 	ð 	ˆEØ•O×3Ò3Ø”˜EÔ" I¤K°Ô$6¸¼ÀeÔ8LÈkÌmÐ\aÔNbñô ñ ˆDˆDð 	�‰	ˆØ�AŠI˜$ !š)Ñ$ð 	LÝÐJÑKÔKÐKå˜$ !š)‘n”nˆØˆŒ˜œÑ$ˆŒØˆŒ˜œÑ$ˆŒØ˜KÐ'Ð'r&   c                óF  — | j         |         }| j         |         }| j        }| j        }t          ||         ||         f¦  «        }t          ||         ||         f¦  «        }t                               ||||¦  «        \  }}|| j         |<   |j        ||<   |j        ||<   dS )z–Updating StabilizerState Clifford in the
        non-deterministic rowsum calculation.
        row and accum are rows in the StabilizerState Clifford.N)rq   rt   rs   r   r   rÕ   )	r@   ÚaccumÚrowrÓ   rÑ   rt   rs   rÒ   rÐ   s	            r%   rÃ   z(StabilizerState._rowsum_nondeterministicr  s©   € ð ”N 3Ô'ˆ	Ø”n UÔ+ˆàŒJˆØŒJˆÝ˜1˜Sœ6 1 S¤6Ð*Ñ+Ô+ˆ	Ý˜Q˜uœX q¨¤xÐ0Ñ1Ô1ˆå#2×#:Ò#:Ø˜ i°ñ$
ô $
Ñ ˆ�[ð !,ˆŒ�uÑØ”=ˆˆ%‰Ø”=ˆˆ%‰ˆˆr&   c                óÒ   — | j         |         }|j         }|}t          | j        |         | j        |         f¦  «        }t                               ||||¦  «        \  }}|}||_         |S )z‰Updating an auxiliary Pauli aux_pauli in the
        deterministic rowsum calculation.
        The StabilizerState itself is not updated.)rq   r   rt   rs   r   rÕ   )r@   rÇ   rØ   rÓ   rÑ   rÐ   rÒ   s          r%   rÀ   z%StabilizerState._rowsum_deterministicˆ  sq   € ð ”N 3Ô'ˆ	Ø”oˆàˆÝ˜8œ: cœ?¨H¬J°s¬OÐ<Ñ=Ô=ˆ	å#2×#:Ò#:Ø˜ i°ñ$
ô $
Ñ ˆ�[ð  ˆ	Ø%ˆ	ŒØÐr&   r|   rp   r²   ú	list[str]Úoutcome_probr›   c                ój  — d}|                       ¦   «         }t          t          |¦  «        ¦  «        D ]­}||         dk    rŸ|t          |¦  «        |z
  dz
           }	t          |j        j        dd…|	f         ¦  «        s_|                     |	d¦  «        }
|�t          ||         ¦  «        |
k    rt          |
¦  «        ||<   Œ�t          ||         ¦  «        ||<   d}Œ«|}Œ®|dk    rd 	                    |¦  «        }|||<   dS |€t          dd¦  «        nt          ||         ¦  «        gD ]‡}
|                      ¦   «         }t          |
¦  «        ||<   |                      ¦   «         }|                     |t          |¦  «        |z
  dz
           |
¦  «         | 
                    ||d|z  ||¦  «         ŒˆdS )	aÕ  Recursive helper function for calculating the probabilities

        Args:
            qubits (range): range of qubits
            outcome (list[str]): outcome being built
            outcome_prob (float): probability of the outcome
            probs (dict[str, float]): holds the outcomes and probability results
            outcome_bitstring (str): target outcome to measure which reduces measurements, None
                if not targeting a specific target
        éÿÿÿÿÚXrm   Nr   r¶   rn   g      à?)rY   rp   r—   r¿   r@   rw   r¯   r™   r¡   ÚjoinÚ_get_probabilities)r#   r|   r²   rÛ   r›   r    Úqubit_for_branchingr[   rŽ   r€   Úsingle_qubit_outcomeÚstr_outcomeÚnew_outcomeÚstab_cpys                 r%   rà   z"StabilizerState._get_probabilitiesŸ  sö  € ð$ $&Ðà#Ÿyšy™{œ{ˆõ •s˜6‘{”{Ñ#Ô#ð 	,ð 	,ˆAØ�qŒz˜SÒ Ð à¥ F¡¤¨a¡°!Ñ 3Ô5�å˜3œ<Ô.¨q¨q¨q°%¨xÔ8Ñ9Ô9ð ,Ø58×5LÒ5LÈUÐTUÑ5VÔ5VÐ(Ø(Ð0ÝÐ-¨aÔ0Ñ1Ô1Ð5IÒIÐIõ
 &)Ð)=Ñ%>Ô%>˜ ™
˜
õ &)Ð):¸1Ô)=Ñ%>Ô%>˜ ™
Ø'(˜˜à*+Ð'øà "Ò$Ð$ØŸ'š' 'Ñ*Ô*ˆKØ!-ˆE�+ÑØˆFð "Ð)õ �!�Q‰KŒKˆKåÐ'Ð(;Ô<Ñ=Ô=Ð>ð	ð 	Ð ð
 "Ÿ,š,™.œ.ˆKÝ/2Ð3GÑ/HÔ/HˆKÐ+Ñ,à—x’x‘z”zˆHØ×(Ò(Ø�˜F™œÐ&9Ñ9¸AÑ=Ô?ÐAUñô ð ð ×'Ò'Ø˜ c¨LÑ&8¸5ÐBSñô ð ð ð	ð 	r&   ú
None | strc                ó   — |€t          | j        j        ¦  «        }n|}dgt          |¦  «        z  }d}i }|                      |||||¦  «         |�-|                     ¦   «         D ]\  }}	t          |	|¦  «        ||<   Œ|S )aI  Helper Function for calculating the subsystem measurement probability dictionary.
        When the targeted outcome_bitstring value is set, then only the single outcome_bitstring
        probability will be calculated.

        Args:
            outcome_bitstring (None or str): targeted outcome bitstring
                to perform a measurement calculation for, this will significantly
                reduce the number of calculation performed (Default: None)
            qargs (None or list): subsystems to return probabilities for,
                if None return for all subsystems (Default: None).
            decimals (None or int): the number of decimal places to round
                values. If None no rounding is done (Default: None).

        Returns:
            dict: The measurement probabilities in dict (key) form.
        NrÞ   rP   )rp   r@   r"   r—   rà   r˜   Úround)
r#   r    rc   r‘   r|   r²   rÛ   r›   rœ   r�   s
             r%   r¦   z'StabilizerState._get_probabilities_dictá  s–   € ð, ˆ=Ý˜4œ=Ô3Ñ4Ô4ˆFˆFàˆFà�%�#˜f™+œ+Ñ%ˆØˆØ"$ˆà×Ò ¨°¸uÐFWÑXÔXÐXàÐØ#Ÿkšk™mœmð 4ð 4‘
��UÝ" 5¨(Ñ3Ô3��c‘
�
àˆr&   )T)r   r   r   r   )FF)r'   r(   r)   r   r*   r   r+   r   )NN)r+   rM   )r+   r	   )r6   r   r+   r   r2   )r6   rb   rc   rd   r+   r   )rh   r   rc   ri   r+   rj   )r6   r   r+   r   )rc   ri   r‘   r’   r+   r“   )r    r¡   rc   ri   r‘   r’   r+   r¢   )rc   ri   r‘   r’   r+   r¢   )rc   rd   r+   r   )rc   rd   r+   r´   )r¸   r™   rc   ri   r+   r“   )
r|   rp   r²   rÚ   rÛ   rM   r›   r¢   r    r¡   )NNN)r    ræ   rc   ri   r‘   r’   r+   r¢   )&Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    Úclassmethodr0   r7   r>   Úpropertyr@   rE   rJ   rL   rR   rU   rW   rZ   r]   ra   rg   r„   r�   rŸ   r§   r•   r³   r·   r½   r¯   ÚstaticmethodrÎ   rÕ   rÃ   rÀ   rà   r¦   Ú__classcell__)r$   s   @r%   r   r   $   s,  ø€ € € € € ð-ð -ðd ðdð dð dð dð dð dð dð2 ð !&Ø',ð	ð ð ð ñ „[ðð:;ð ;ð ;ðDð Dð Dð ðð ñ „Xðð'ð 'ð 'ð 'ðMð Mð MðZð Zð Zðð ð ð ðð ð ð ð5ð 5ð 5ð 5ðð ð ðð ð ð ð$ð ð ð ð& TXðð ð ð ð ð0?ð ?ð ?ð ?ð ?ðB'ð 'ð 'ð 'ðRð ð ð ð ð: "Ø#ð	"
ð "
ð "
ð "
ð "
ðJ AEðdð dð dð dð dð0#ð #ð #ð #ð #ðJð ð ð ð ð<ð ð ð ð ð:.ð .ð .ð` ð
ð 
ñ „\ð
ð ð(ð (ñ „\ð(ð$ ð!ð !ñ „\ð!ð* ðð ñ „\ðð8 "&ð@ð @ð @ð @ð @ðH )-Ø!Ø#ð	%ð %ð %ð %ð %ð %ð %ð %ð %r&   r   )rì   Ú
__future__r   Úcollections.abcr   Útypingr   Únumpyru   Úqiskit.exceptionsr   Ú&qiskit.quantum_info.operators.op_shaper   Ú&qiskit.quantum_info.operators.operatorr	   Ú(qiskit.quantum_info.operators.symplecticr
   r   r   Ú:qiskit.quantum_info.operators.symplectic.clifford_circuitsr   Ú(qiskit.quantum_info.states.quantum_stater   Úqiskit.circuitr   r   Úqiskitr   r   r‡   r&   r%   ú<module>rý      s;  ððð ð #Ð "Ð "Ð "Ð "Ð "à &Ð &Ð &Ð &Ð &Ð &Ø  Ð  Ð  Ð  Ð  Ð  à Ð Ð Ð à )Ð )Ð )Ð )Ð )Ð )Ø :Ð :Ð :Ð :Ð :Ð :Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OØ PÐ PÐ PÐ PÐ PÐ PØ AÐ AÐ AÐ AÐ AÐ AØ 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6àð ØÐÐÐÐÐðbð bð bð bð b�lñ bô bð bð bð br&   