§
    ¹³Ùgé  ã                  óš   — d 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mZmZmZ dd	lmZ dd
lmZ ddlmZ  G d„ de
¦  «        ZdS )z 
Statevector Estimator V2 class
é    )Úannotations)ÚIterableN)ÚSparsePauliOpé   )ÚBaseEstimatorV2)ÚDataBinÚEstimatorPubLikeÚPrimitiveResultÚ	PubResult)ÚEstimatorPub)ÚPrimitiveJob)Ú_statevector_from_circuitc                  óp   — e Zd ZdZdddœdd	„Zedd„¦   «         Zedd„¦   «         Zddœdd„Zdd„Z	d d„Z
dS )!ÚStatevectorEstimatora"  
    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Úseedr   Úfloatr   ú np.random.Generator | int | Nonec               ó"   — || _         || _        dS )a  
        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      ú]/granary/edev/quantum/lib/python3.11/site-packages/qiskit/primitives/statevector_estimator.pyÚ__init__zStatevectorEstimator.__init__q   s   € ð #4ˆÔØˆŒ
ˆ
ˆ
ó    Úreturnc                ó   — | j         S )zReturn the default precision)r   ©r   s    r   r   z&StatevectorEstimator.default_precision}   s   € ð Ô&Ð&r   c                ó   — | j         S )zAReturn the seed or Generator object for random number generation.)r   r   s    r   r   zStatevectorEstimator.seed‚   s   € ð ŒzÐr   )Ú	precisionÚpubsúIterable[EstimatorPubLike]r    úfloat | Noneú(PrimitiveJob[PrimitiveResult[PubResult]]c               óˆ   ‡— ‰€| j         Šˆfd„|D ¦   «         }t          | j        |¦  «        }|                     ¦   «          |S )Nc                ó:   •— g | ]}t          j        |‰¦  «        ‘ŒS © )r   Úcoerce)Ú.0Úpubr    s     €r   ú
<listcomp>z,StatevectorEstimator.run.<locals>.<listcomp>Œ   s&   ø€ ÐLÐLÐLÀ�Ô+¨C°Ñ;Ô;ÐLÐLÐLr   )r   r   Ú_runÚ_submit)r   r!   r    Úcoerced_pubsÚjobs     `  r   ÚrunzStatevectorEstimator.run‡   sO   ø€ ð ÐØÔ/ˆIØLÐLÐLÐLÀtÐLÑLÔLˆå˜4œ9 lÑ3Ô3ˆØ�Š‰ŒˆØˆ
r   úlist[EstimatorPub]úPrimitiveResult[PubResult]c                óB   ‡ — t          ˆ fd„|D ¦   «         ddi¬¦  «        S )Nc                ó:   •— g | ]}‰                      |¦  «        ‘ŒS r'   )Ú_run_pub)r)   r*   r   s     €r   r+   z-StatevectorEstimator._run.<locals>.<listcomp>“   s%   ø€ ÐCÐCÐC°s §¢¨cÑ 2Ô 2ÐCÐCÐCr   Úversioné   ©Úmetadata)r
   )r   r!   s   ` r   r,   zStatevectorEstimator._run’   s0   ø€ ÝÐCÐCÐCÐC¸dÐCÑCÔCÈyÐZ[ÈnÐ]Ñ]Ô]Ð]r   r*   r   r   c                ód  — t           j                             | j        ¦  «        }|j        }|j        }|j        }|j        }|                     |¦  «        }t          j	        ||¦  «        \  }}	t          j
        |t           j        ¬¦  «        }
t          j
        |t           j        ¬¦  «        }t          j        |j        Ž D ]»}||         }|	|         }t          ||¦  «        }t          |                     ¦   «         Ž \  }}t#          ||¦  «        }t          j        |                     |¦  «        ¦  «        }|dk    r9t          j        |¦  «        st+          d¦  «        ‚|                     ||¦  «        }||
|<   Œ¼t/          |
||
j        ¬¦  «        }t1          |||j        j        dœ¬¦  «        S )N)Údtyper   z:Given operator is not Hermitian and noise cannot be added.)ÚevsÚstdsÚshape)Útarget_precisionÚcircuit_metadatar8   )ÚnpÚrandomÚdefault_rngr   ÚcircuitÚobservablesÚparameter_valuesr    Úbind_allÚbroadcast_arraysÚ
zeros_likeÚfloat64Úndindexr>   r   ÚzipÚitemsr   Úreal_if_closeÚexpectation_valueÚisrealÚ
ValueErrorÚnormalr   r   r9   )r   r*   ÚrngrD   rE   rF   r    Úbound_circuitsÚbc_circuitsÚbc_obsr<   r=   ÚindexÚbound_circuitÚ
observableÚfinal_stateÚpaulisÚcoeffsÚobsrO   Údatas                        r   r5   zStatevectorEstimator._run_pub•   s›  € ÝŒi×#Ò# D¤JÑ/Ô/ˆØ”+ˆØ”oˆØÔ/ÐØ”Mˆ	Ø)×2Ò2°7Ñ;Ô;ˆÝ Ô1°.À+ÑNÔNÑˆ�VÝŒm˜K­r¬zÐ:Ñ:Ô:ˆÝŒ}˜[µ´
Ð;Ñ;Ô;ˆÝ”Z Ô!2Ð3ð 	+ð 	+ˆEØ'¨Ô.ˆMØ œˆJÝ3°MÀ3ÑGÔGˆKÝ  *×"2Ò"2Ñ"4Ô"4Ð5‰NˆF�FÝ ¨Ñ/Ô/ˆCÝ "Ô 0°×1NÒ1NÈsÑ1SÔ1SÑ TÔ TÐØ˜AŠ~ˆ~Ý”yÐ!2Ñ3Ô3ð cÝ$Ð%aÑbÔbÐbØ$'§J¢JÐ/@À)Ñ$LÔ$LÐ!Ø*ˆC�‰JˆJå˜3 T°´Ð;Ñ;Ô;ˆÝØ°	ÈsÌ{ÔOcÐdÐdð
ñ 
ô 
ð 	
r   )r   r   r   r   )r   r   )r   r   )r!   r"   r    r#   r   r$   )r!   r1   r   r2   )r*   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   r   r0   r,   r5   r'   r   r   r   r      sØ   € € € € € ðOð Oðd -0ÐZ^ð
ð 
ð 
ð 
ð 
ð 
ð ð'ð 'ð 'ñ „Xð'ð ðð ð ñ „Xðð
 NRð	ð 	ð 	ð 	ð 	ð 	ð^ð ^ð ^ð ^ð
ð 
ð 
ð 
ð 
ð 
r   r   )rb   Ú
__future__r   Úcollections.abcr   ÚnumpyrA   Úqiskit.quantum_infor   Úbaser   Ú
containersr   r	   r
   r   Úcontainers.estimator_pubr   Úprimitive_jobr   Úutilsr   r   r'   r   r   ú<module>rm      sý   ððð ð #Ð "Ð "Ð "Ð "Ð "à $Ð $Ð $Ð $Ð $Ð $à Ð Ð Ð à -Ð -Ð -Ð -Ð -Ð -à !Ð !Ð !Ð !Ð !Ð !Ø MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MØ 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,ðP
ð P
ð P
ð P
ð P
˜?ñ P
ô P
ð P
ð P
ð P
r   