
    z	inE                        S r SSKJr  SSKrSSKJ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5      rg)z
Abstract QuantumState class.
    )annotationsN)abstractmethod)BaseOperator)QuantumChannel)OpShape)Operator)Countsc                  *   \ rS rSrSrS*S+S jjrSrS r\S 5       r	\S 5       r
\S	 5       rS*S
 jrS rS*S jr\S,S j5       r\S 5       r\S 5       r\S 5       r\S 5       r\S-S j5       r\S-S j5       rS rS r\S*S.S jj5       r\S*S/S jj5       r\S,S0S jj5       rS,S1S jjrS*S2S jjrS*S3S jjrS*S4S jjr\  S5       S6S jj5       r!\ S7S j5       r"\ S7S j5       r#\  S*       S8S  jj5       r$S! r%S" r&S# r'S$ r(S% r)S& r*S' r+S( r,S)r-g)9QuantumState   z!Abstract quantum state base classNc                    Xl         SU l        g)zInitialize a QuantumState object.

Args:
    op_shape (OpShape): Optional, an OpShape object for state dimensions.

.. note::

    If `op_shape`` is specified it will take precedence over other
    kwargs.
N	_op_shape_rng_generator)selfop_shapes     b/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/quantum_info/states/quantum_state.py__init__QuantumState.__init__!   s     ""       c                |    [        XR                  5      =(       a!    U R                  5       UR                  5       :H  $ N)
isinstance	__class__dimsr   others     r   __eq__QuantumState.__eq__3   s'    %0PTYY[EJJL5PPr   c                4    U R                   R                  S   $ )zReturn total state dimension.r   )r   shaper   s    r   dimQuantumState.dim6   s     ~~##A&&r   c                .    U R                   R                  $ )zAReturn the number of qubits if a N-qubit state or None otherwise.)r   
num_qubitsr#   s    r   r'   QuantumState.num_qubits;   s     ~~(((r   c                p    U R                   c  [        R                  R                  5       $ U R                   $ r   )r   nprandomdefault_rngr#   s    r   _rngQuantumState._rng@   s-    &99((**"""r   c                8    U R                   R                  U5      $ )z9Return tuple of input dimension for specified subsystems.)r   dims_l)r   qargss     r   r   QuantumState.dimsF   s    ~~$$U++r   c                .    [         R                  " U 5      $ )z Make a copy of current operator.)copydeepcopyr#   s    r   r4   QuantumState.copyJ   s    }}T""r   c                    Uc  SU l         g[        U[        R                  R                  5      (       a  Xl         g[        R                  R                  U5      U l         g)z'Set the seed for the quantum state RNG.N)r   r   r*   r+   	Generatorr,   )r   values     r   seedQuantumState.seedN   sC    ="&Dryy2233"'"$))"7"7">Dr   c                    g)z%Return True if a valid quantum state.N )r   atolrtols      r   is_validQuantumState.is_validW        	r   c                    g)z&Convert state to matrix operator classNr=   r#   s    r   to_operatorQuantumState.to_operator\   rB   r   c                    g)z%Return the conjugate of the operator.Nr=   r#   s    r   	conjugateQuantumState.conjugatea   rB   r   c                    g)z:Return the trace of the quantum state as a density matrix.Nr=   r#   s    r   traceQuantumState.tracef   rB   r   c                    g)z'Return the purity of the quantum state.Nr=   r#   s    r   purityQuantumState.purityk   rB   r   c                    g)u   Return the tensor product state self ⊗ other.

Args:
    other (QuantumState): a quantum state object.

Returns:
    QuantumState: the tensor product operator self ⊗ other.

Raises:
    QiskitError: if other is not a quantum state.
Nr=   r   s     r   tensorQuantumState.tensorp        	r   c                    g)u   Return the tensor product state other ⊗ self.

Args:
    other (QuantumState): a quantum state object.

Returns:
    QuantumState: the tensor product state other ⊗ self.

Raises:
    QiskitError: if other is not a quantum state.
Nr=   r   s     r   expandQuantumState.expand   rR   r   c                0    [        [        U 5       S35      e)zReturn the linear combination self + other.

Args:
    other (QuantumState): a state object.

Returns:
    QuantumState: the linear combination self + other.

Raises:
    NotImplementedError: if subclass does not support addition.
z does not support additionNotImplementedErrortyper   s     r   _addQuantumState._add   s     "T$ZL0J"KLLr   c                0    [        [        U 5       S35      e)a  Return the scalar multipled state other * self.

Args:
    other (complex): a complex number.

Returns:
    QuantumState: the scalar multipled state other * self.

Raises:
    NotImplementedError: if subclass does not support scala
                         multiplication.
z' does not support scalar multiplicationrW   r   s     r   	_multiplyQuantumState._multiply   s     "T$ZL0W"XYYr   c                    g)a  Evolve a quantum state by the operator.

Args:
    other (Operator or QuantumChannel): The operator to evolve by.
    qargs (list): a list of QuantumState subsystem positions to apply
                   the operator on.

Returns:
    QuantumState: the output quantum state.

Raises:
    QiskitError: if the operator dimension does not match the
                 specified QuantumState subsystem dimensions.
Nr=   )r   r   r1   s      r   evolveQuantumState.evolve         	r   c                    g)zCompute the expectation value of an operator.

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

Returns:
    complex: the expectation value.
Nr=   )r   operr1   s      r   expectation_valueQuantumState.expectation_value   s     	r   c                    g)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.
Nr=   r   r1   decimalss      r   probabilitiesQuantumState.probabilities   rb   r   c                \    U R                  U R                  XS9U R                  U5      SS9$ )a  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 (ket) form.
)r1   ri   Tstring_labels)_vector_to_dictrj   r   rh   s      r   probabilities_dictQuantumState.probabilities_dict   s<    ( ##U>IIe $ 
 	
r   c                    U R                  U5      nU R                  [        R                  " [	        U5      5      U R                  U5      SS9nU R                  R                  XCUS9$ )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 *samples* measurement outcomes using the measure
    :meth:`probabilities` for the current state and `qargs`. It does
    not actually implement the measurement so the current state is
    not modified.

    The seed for random number generator used for sampling can be
    set to a fixed value by using the stats :meth:`seed` method.
Trm   psize)rj   _index_to_ket_arrayr*   arangelenr   r-   choice)r   shotsr1   probslabelss        r   sample_memoryQuantumState.sample_memory   sd    . ""5) ))IIc%j!499U#34 * 
 yye<<r   c                v    U R                  XS9n[        R                  " USS9u  pE[        [	        XE5      5      $ )a  Sample a dict 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:
    Counts: sampled counts dictionary.

Additional Information:

    This function *samples* measurement outcomes using the measure
    :meth:`probabilities` for the current state and `qargs`. It does
    not actually implement the measurement so the current state is
    not modified.

    The seed for random number generator used for sampling can be
    set to a fixed value by using the stats :meth:`seed` method.
r1   T)return_counts)r}   r*   uniquer	   zip)r   rz   r1   samplesindscountss         r   sample_countsQuantumState.sample_counts  s;    . $$U$8 yy=c$'((r   c                   U R                  U5      nU R                  U5      nU R                  R                  [	        U5      USS9nU R                  X@R                  U5      SS9S   n[        R                  " [	        U5      [        S9nS[        R                  " X4   5      -  Xd'   U R                  [        [        R                  " U5      X"S9US9nXW4$ )	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 state for the corresponding
           outcome.
   rs   Trm   r   dtype)
input_dimsoutput_dimsr   )r   rj   r-   ry   rx   rv   r*   zeroscomplexsqrtr`   r   diag)r   r1   r   r{   sampleoutcomeprojrets           r   measureQuantumState.measure2  s    & yy""5)!!#e*A!> **699U3CSW*XYZ[ xxE
'22775=11
 kk(2774=TT\akb|r   c                   S/nUSS  H  nUR                  US   U-  5        M     [        R                  " [        X5       VVs/ s H  u  pEX-  U-  PM     snn5      nU(       a  [	        U5      n[        R
                  " U[        R                  S9nUS   n	USS  HH  n
US:  a   [        R                  R                  SU	5      n	[        R                  R                  X5      n	MJ     U	R                  $ UR                  $ s  snnf )a  Convert an index array into a ket array.

Args:
    inds (np.array): an integer index array.
    dims (tuple): a list of subsystem dimensions.
    string_labels (bool): return ket as string if True, otherwise
                          return as index array (Default: False).

Returns:
    np.array: an array of ket strings if string_label=True, otherwise
              an array of ket lists.
r   Nr   r   
   ,)
appendr*   arrayr   maxasarraystr_charaddT)r   r   rn   shiftsr$   shiftketsmax_dim	char_ketsstr_ketsrows              r   rv    QuantumState._index_to_ket_arrayW  s      9CMM&*s*+ xxTARSAR:3$-3.ARST$iG

4rww7I |H }R<!ww{{39H77;;s5 % ::vv Ts   D
c                   Uc  U OU R                  US9nUR                  5       u  n[        R                  XQUS9nU(       a  [	        [        X`U   5      5      $ [        XdU   5       VVs0 s H  u  px[        U5      U_M     snn$ s  snnf )a6  Convert a vector to a ket dictionary.

This representation will not show zero values in the output dict.

Args:
    vec (array): a Numpy vector array.
    dims (tuple): subsystem dimensions.
    decimals (None or int): number of decimal places to round to.
                            (See Numpy.round), if None no rounding
                            is done (Default: None).
    string_labels (bool): return ket as string if True, otherwise
                          return as index array (Default: False).

Returns:
    dict: the vector in dictionary `ket` form.
ri   rm   )roundnonzeror   rv   dictr   tuple)	vecr   ri   rn   valsr   r   ketvals	            r   ro   QuantumState._vector_to_dictx  s    & &sCIIxI,H,,. //-/X Dd),--03Dt*0EF0EHCc
C0EFFFs   *Bc           	        Uc  U OU R                  US9nUR                  5       u  nn[        R                  XQUS9n[        R                  XaUS9nU(       a-  [	        XXEU4   5       V	V
Vs0 s H  u  po SU
 3U_M     snn
n	$ [	        XXEU4   5       V	V
Vs0 s H  u  pn[        U	5      [        U
5      4U_M     snn
n	$ s  snn
n	f s  snn
n	f )a6  Convert a matrix to a ket dictionary.

This representation will not show zero values in the output dict.

Args:
    mat (array): a Numpy matrix array.
    dims (tuple): subsystem dimensions.
    decimals (None or int): number of decimal places to round to.
                            (See Numpy.round), if None no rounding
                            is done (Default: None).
    string_labels (bool): return ket as string if True, otherwise
                          return as index array (Default: False).

Returns:
    dict: the matrix in dictionary `ket` form.
r   rm   |)r   r   r   rv   r   r   )matr   ri   rn   r   inds_rowinds_colbrasr   r   brar   s               r   _matrix_to_dictQuantumState._matrix_to_dict  s    & &sCIIxI,H LLN	
 //m/\//m/\ 9<TX`N`Ia9b9b#%q#9b  "%T6H1I!J
!J# 3Zs$c)!J
 	
	
s   +C$Cc                  ^ Uc  U $ [         R                  " U [        [        U5      5      5      nUR                  n[        U5       Vs/ s H
  oTS-
  U-
  PM     snm[        U4S j[        U5       5       5      nU(       a>  [         R                  " X6S9n[         R                  " [         R                  " T5      5      m[         R                  " UTS9n[         R                  " X3R                  45      nU$ s  snf )a  Marginalize a probability vector according to subsystems.

Args:
    probs (np.array): a probability vector Numpy array.
    dims (tuple): subsystem dimensions.
    qargs (None or list): a list of subsystems to return
        marginalized probabilities for. If None return all
        probabilities (Default: None).

Returns:
    np.array: the marginalized probability vector flattened
              for the specified qargs.
r   c              3  6   >#    U  H  oT;  d  M
  Uv   M     g 7fr   r=   ).0i
qargs_axess     r   	<genexpr>8QuantumState._subsystem_probabilities.<locals>.<genexpr>  s     GKqJ3FKs   		)axis)axes)r*   reshapelistreversedndimr   rangesumargsort	transposeru   )	r{   r   r1   
probs_tensr   r   sum_axis	new_probsr   s	           @r   _subsystem_probabilities%QuantumState._subsystem_probabilities  s    " =LZZtHTN';<
,4UO<OqQhlO<
GE$KGG
:JBJJz$:;J\\*:>
JJzOO+=>	 =s   	C8c                $    U R                  U5      $ r   )r`   r   s     r   __and__QuantumState.__and__      {{5!!r   c                $    U R                  U5      $ r   )rP   r   s     r   __xor__QuantumState.__xor__  r   r   c                $    U R                  U5      $ r   r]   r   s     r   __mul__QuantumState.__mul__  s    ~~e$$r   c                *    U R                  SU-  5      $ )Nr   r   r   s     r   __truediv__QuantumState.__truediv__  s    ~~a%i((r   c                $    U R                  U5      $ r   )r   r   s     r   __rmul__QuantumState.__rmul__  s    ||E""r   c                $    U R                  U5      $ r   rZ   r   s     r   __add__QuantumState.__add__  s    yyr   c                &    U R                  U* 5      $ r   r   r   s     r   __sub__QuantumState.__sub__  s    yy%  r   c                $    U R                  S5      $ )Nr   r   r#   s    r   __neg__QuantumState.__neg__  s    ~~b!!r   r   r   )r   zOpShape | None)NN)r   r   returnr   )r   zOperator | QuantumChannelr1   list | Noner   r   )rd   r   r1   None | listr   r   )r1   r   ri   
None | intr   
np.ndarray)r1   r   ri   r   r   r   )rz   intr1   r   r   r   )rz   r   r1   r   r   r	   )r1   r   r   r   )F)r   r   r   r   rn   boolr   r   )NF)r{   r   r   r   r1   r   r   r   ).__name__
__module____qualname____firstlineno____doc__r   __array_priority__r   propertyr$   r'   r-   r   r4   r:   r   r@   rD   rG   rJ   rM   rP   rT   rZ   r]   r`   re   rj   rp   r}   r   r   staticmethodrv   ro   r   r   r   r   r   r   r   r   r   r   __static_attributes__r=   r   r   r   r      s   +#  Q ' ' ) ) # #
,#?              MZ  " 
 
  "
4=>):#J =B %6:	 @ G G< %
 %
N =A!&/:	 B""%)# !"r   r   )r   
__future__r   r4   abcr   numpyr*   +qiskit.quantum_info.operators.base_operatorr   5qiskit.quantum_info.operators.channel.quantum_channelr   &qiskit.quantum_info.operators.op_shaper   &qiskit.quantum_info.operators.operatorr   qiskit.result.countsr	   r   r=   r   r   <module>r
     s3    #    D P : ; 'Y" Y"r   