
    z	i                        S 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
  SSKJrJrJrJr  SS	KJr  SS
KJr  SSKJr   " S S\
5      rg)z 
Statevector Estimator V2 class
    )annotations)IterableN)SparsePauliOp   )BaseEstimatorV2)DataBinEstimatorPubLikePrimitiveResult	PubResult)EstimatorPub)PrimitiveJob)_statevector_from_circuitc                      \ rS rSrSrSSS.   SS jjr\SS j5       r\SS j5       rSS	.     SS
 jjr	SS jr
SS jrSrg)StatevectorEstimator   a  
Simple implementation of :class:`BaseEstimatorV2` with full state vector simulation.

This class is implemented via :class:`~.Statevector` which turns provided circuits into
pure state vectors. These states are subsequently acted on by :class:`~.SparsePauliOp`,
which implies that, at present, this implementation is only compatible with Pauli-based
observables.

Each tuple of ``(circuit, observables, <optional> parameter values, <optional> precision)``,
called an estimator primitive unified bloc (PUB), produces its own array-based result. The
:meth:`~.EstimatorV2.run` method can be given a sequence of pubs to run in one call.

.. note::
    The result of this class is exact if the circuit contains only unitary operations.
    On the other hand, the result could be stochastic if the circuit contains a non-unitary
    operation such as a reset for a some subsystems.
    The stochastic result can be made reproducible by setting ``seed``, e.g.,
    ``StatevectorEstimator(seed=123)``.

.. plot::
    :alt: Output from the previous code.
    :include-source:

    from qiskit.circuit import Parameter, QuantumCircuit
    from qiskit.primitives import StatevectorEstimator
    from qiskit.quantum_info import Pauli, SparsePauliOp

    import matplotlib.pyplot as plt
    import numpy as np

    # Define a circuit with two parameters.
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(0, 1)
    circuit.h(0)

    # Define a sweep over parameter values, where the second axis is over
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T

    # Define three observables. Many formats are supported here including
    # classes such as qiskit.quantum_info.SparsePauliOp. The inner length-1
    # lists cause this array of observables to have shape (3, 1), rather
    # than shape (3,) if they were omitted.
    observables = [
        [SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
        [Pauli("XX")],
        [Pauli("IY")]
    ]

    # Instantiate a new statevector simulation based estimator object.
    estimator = StatevectorEstimator()

    # Estimate the expectation value for all 300 combinations of
    # observables and parameter values, where the pub result will have
    # shape (3, 100). This shape is due to our array of parameter
    # bindings having shape (100,), combined with our array of observables
    # having shape (3, 1)
    pub = (circuit, observables, params)
    job = estimator.run([pub])

    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]

    # Error-bar information is also available, but the error is 0
    # for this StatevectorEstimator.
    result.data.stds

    # Pull out the array-based expectation value estimate data from the
    # result and plot a trace for each observable.
    for idx, pauli in enumerate(observables):
        plt.plot(result.data.evs[idx], label=pauli)
    plt.legend()
g        N)default_precisionseedc                   Xl         X l        g)z
Args:
    default_precision: The default precision for the estimator if not specified during run.
    seed: The seed or Generator object for random number generation.
        If None, a random seeded default RNG will be used.
N_default_precision_seed)selfr   r   s      a/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/primitives/statevector_estimator.py__init__StatevectorEstimator.__init__q   s     #4
    c                    U R                   $ )zReturn the default precision)r   r   s    r   r   &StatevectorEstimator.default_precision}   s     &&&r   c                    U R                   $ )zAReturn the seed or Generator object for random number generation.)r   r   s    r   r   StatevectorEstimator.seed   s     zzr   )	precisionc                   Uc  U R                   nU Vs/ s H  n[        R                  " X25      PM     nn[        U R                  U5      nUR                  5         U$ s  snf )N)r   r   coercer   _run_submit)r   pubsr"   pubcoerced_pubsjobs         r   runStatevectorEstimator.run   sX     //IGKLt++C;tL499l3
	 Ms    Ac                b    [        U Vs/ s H  o R                  U5      PM     snSS0S9$ s  snf )Nversion   metadata)r
   _run_pub)r   r'   r(   s      r   r%   StatevectorEstimator._run   s-    dCdsc 2dCyZ[n]]Cs   ,c                   [         R                  R                  U R                  5      nUR                  nUR
                  nUR                  nUR                  nUR                  U5      n[         R                  " Xt5      u  p[         R                  " U[         R                  S9n
[         R                  " U[         R                  S9n[         R                  " UR                  6  H  nX   nX   n[        X5      n[        UR!                  5       6 u  nn[#        UU5      n[         R$                  " UR'                  U5      5      nUS:w  a8  [         R(                  " U5      (       d  [+        S5      eUR-                  UU5      nUX'   M     [/        XU
R                  S9n[1        UXaR                  R2                  S.S9$ )N)dtyper   z:Given operator is not Hermitian and noise cannot be added.)evsstdsshape)target_precisioncircuit_metadatar0   )nprandomdefault_rngr   circuitobservablesparameter_valuesr"   bind_allbroadcast_arrays
zeros_likefloat64ndindexr8   r   zipitemsr   real_if_closeexpectation_valueisreal
ValueErrornormalr   r   r1   )r   r(   rngr>   r?   r@   r"   bound_circuitsbc_circuitsbc_obsr6   r7   indexbound_circuit
observablefinal_statepauliscoeffsobsrI   datas                        r   r2   StatevectorEstimator._run_pub   sj   ii##DJJ/++oo//MM	)227; 11.NmmKrzz:}}[

;ZZ!2!23E'.MJ3MGK *"2"2"45NFF/C " 0 01N1Ns1S TA~yy!233$%abb$'JJ/@)$L!*CJ 4 3;	{{OcOcd
 	
r   r   )r   floatr    np.random.Generator | int | None)returnrZ   )r\   r[   )r'   zIterable[EstimatorPubLike]r"   zfloat | Noner\   z(PrimitiveJob[PrimitiveResult[PubResult]])r'   zlist[EstimatorPub]r\   zPrimitiveResult[PubResult])r(   r   r\   r   )__name__
__module____qualname____firstlineno____doc__r   propertyr   r   r+   r%   r2   __static_attributes__ r   r   r   r      s}    Od -0Z^
$)
7W
 ' '  
 NR	.	>J		1	^
r   r   )ra   
__future__r   collections.abcr   numpyr;   qiskit.quantum_infor   baser   
containersr   r	   r
   r   containers.estimator_pubr   primitive_jobr   utilsr   r   rd   r   r   <module>rn      s8    # $  - ! M M 2 ' ,P
? P
r   