
    z	iS                       S 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
rSSKJrJrJr  SSKJr  SS	KJr  SS
KJrJr  SSKJrJr  SSKJrJ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!S jjr,S"S jr-S#S jr.S$S jr/S%S jr0\	 " S S5      5       r1\	 " S S5      5       r2 " S S\ 5      r3S&S jr4g)'z<Estimator V2 implementation for an arbitrary Backend object.    )annotationsN)defaultdict)Iterable)	dataclass)ClassicalRegisterQuantumCircuitQuantumRegister)QiskitError)	BackendV2)Pauli	PauliList)CountsResult)PassManagerPassManagerConfig)Optimize1qGatesDecomposition   )BaseEstimatorV2)DataBinEstimatorPubLikePrimitiveResult	PubResult)BindingsArray)EstimatorPub)PrimitiveJobc           	        [        U [        5      (       a  U /n / nU  H.  nUR                  UR                  5        U(       d  M'  0 Ul        M0     [        U[        5      (       a  UR
                  nO[        S5      eU(       a]  [        S[        U 5      U5       Vs/ s H  nUR                  " XXv-    40 UD6PM     nnU V	s/ s H  oR                  5       PM     n
n	X4$ UR                  " U 40 UD6R                  5       /n
X4$ s  snf s  sn	f )a+  Remove metadata of circuits and run the circuits on a backend.
Args:
    circuits: The circuits
    backend: The backend
    clear_metadata: Clear circuit metadata before passing to backend.run if
        True.
    **run_options: run_options
Returns:
    The result and the metadata of the circuits
zBackend version not supportedr   )
isinstancer   appendmetadatar   max_circuitsRuntimeErrorrangelenrunresult)circuitsbackendclear_metadatarun_optionsr   circr    posjobsxr%   s              `/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/primitives/backend_estimator_v2.py_run_circuitsr/   '   s
     (N++:H&>DM  '9%%++:;; QH|<
< KKs'9:JkJ< 	 
 '++d((*d+  ++h6+6==?@
 ,s   !DD
c                    / nU  H<  nUR                  5       n[        U[        5      (       d  U/nUR                  U5        M>     U$ N)
get_countsr   listextend)resultscountsrescounts       r.   _prepare_countsr9   M   sD    F %&&GEe	 
 M    c                t   [        U5      n[        U5      n[        R                  " U[        S9nSnU R                  5        He  u  pgSU;   a  UR                  SS5      S   OUn[        US5      n	XW-  n[        U5       H$  n
S[        X:   U	-  5      -  nXJ==   X{-  -  ss'   M&     Mg     XE-  nSUS-  -
  nXL4$ )zReturn array of expval and variance pairs for input Paulis.
Note: All non-identity Pauli's are treated as Z-paulis, assuming
that basis rotations have been applied to convert them to the
diagonal basis.
dtyper    r      )
r#   _paulis2indsnpzerosfloatitemssplitintr"   _parity)r6   paulissize	diag_indsexpvalsdenombin_outcomefreqsplit_outcomeoutcomekcoeff	variancess                r.   _pauli_expval_with_variancerU   W   s     v;DV$Ihht5)GE#\\^8;{8J))#q1!4P[mQ'tAGIL7$:;;EJ$,&J 	 , G GQJIr:   c                    U R                   U R                  -  n[        R                  " USSS9nSS[        R                  " UR
                  S   [        S9-  -  nX#-  nUR                  5       $ )zConvert PauliList to diagonal integers.
These are integer representations of the binary string with a
1 where there are Paulis, and 0 where there are identities.
r   little)axisbitorder   r<   )zr-   rB   packbitsarangeshapeobjecttolist)rI   nonidpacked_valspower_uint8indss        r.   rA   rA   s   sc     HHvxxE ++e!h?KBIIk&7&7&:&IIJK$D;;=r:   c                <    [        U 5      R                  S5      S-  $ )zReturn the parity of an integer1r?   )binr8   )integers    r.   rH   rH      s    w<c"Q&&r:   c                  H    \ rS rSr% SrSrS\S'    SrS\S'    S	rS
\S'   Sr	g	)Options   z*Options for :class:`~.BackendEstimatorV2`.g      ?rD   default_precisionTboolabelian_groupingNz
int | Noneseed_simulator )
__name__
__module____qualname____firstlineno____doc__rl   __annotations__rn   ro   __static_attributes__rp   r:   r.   rj   rj      s8    4'u' "d! "&NJ%r:   rj   c                  <    \ rS rSr% SrS\S'    S\S'    S\S'   Srg	)
_PreprocessedData   zKInternal data structure to store the results of the preprocessing of a pub.list[QuantumCircuit]r&   z
np.ndarrayparameter_indicesobservablesrp   N)rq   rr   rs   rt   ru   rv   rw   rp   r:   r.   ry   ry      s     U""T!!TGr:   ry   c                     \ rS rSrSr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S jrSS jr          SS jr        SS jr      SS jr        SS jrSrg)BackendEstimatorV2   a	  Evaluates expectation values for provided quantum circuit and observable combinations.

The :class:`~.BackendEstimatorV2` class is a generic implementation of the
:class:`~.BaseEstimatorV2` interface that is used to wrap a :class:`~.BackendV2`
object in the :class:`~.BaseEstimatorV2` API. It
facilitates using backends that do not provide a native
:class:`~.BaseEstimatorV2` implementation in places that work with
:class:`~.BaseEstimatorV2`. However,
if you're using a provider that has a native implementation of
:class:`~.BaseEstimatorV2`, it is a better choice to leverage that native
implementation as it will likely include additional optimizations and be
a more efficient implementation. The generic nature of this class
precludes doing any provider- or backend-specific optimizations.

This class does not perform any measurement or gate mitigation, and, presently, is only
compatible with Pauli-based observables. More formally, given an observable of the type
:math:`O=\sum_{i=1}^Na_iP_i`, where :math:`a_i` is a complex number and :math:`P_i` is a
Pauli operator, the estimator calculates the expectation :math:`\mathbb{E}(P_i)` of each
:math:`P_i` and finally calculates the expectation value of :math:`O` as
:math:`\mathbb{E}(O)=\sum_{i=1}^Na_i\mathbb{E}(P_i)`. The reported ``std`` is calculated
as

.. math::

    \frac{\sum_{i=1}^{n}|a_i|\sqrt{\textrm{Var}\big(P_i\big)}}{\sqrt{N}}\:,

where :math:`\textrm{Var}(P_i)` is the variance of :math:`P_i`, :math:`N=O(\epsilon^{-2})` is
the number of shots, and :math:`\epsilon` is the target precision [1].

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:`~.BackendEstimatorV2.run` method can be given a sequence of pubs to run in one call.

The options for :class:`~.BackendEstimatorV2` consist of the following items.

* ``default_precision``: The default precision to use if none are specified in :meth:`~run`.
  Default: 0.015625 (1 / sqrt(4096)).

* ``abelian_grouping``: Whether the observables should be grouped into sets of qubit-wise
  commuting observables.
  Default: True.

* ``seed_simulator``: The seed to use in the simulator. If None, a random seed will be used.
  Default: None.

**Reference:**

[1] O. Crawford, B. van Straaten, D. Wang, T. Parks, E. Campbell, St. Brierley,
Efficient quantum measurement of Pauli operators in the presence of finite sampling error.
`Quantum 5, 385 <https://doi.org/10.22331/q-2021-01-20-385>`_
N)optionsc                  Xl         U(       a  [        S0 UD6O	[        5       U l        [        R                  " U5      R
                  n[        U[        5      (       a  [        X1R                  S9nO	[        US9n[        U/5      U l        g)a  
Args:
    backend: The backend to run the primitive on.
    options: The options to control the default precision (``default_precision``),
        the operator grouping (``abelian_grouping``), and
        the random seed for the simulator (``seed_simulator``).
)basistarget)r   Nrp   )_backendrj   _optionsr   from_backendbasis_gatesr   r   r   r   r   _passmanager)selfr'   r   r   opt1qs        r.   __init__BackendEstimatorV2.__init__   sh      .5*'*79!..w7CCgy))0u^^TE0u=E'0r:   c                    U R                   $ )zReturn the options)r   r   s    r.   r   BackendEstimatorV2.options        }}r:   c                    U R                   $ )z7Returns the backend which this sampler object based on.)r   r   s    r.   r'   BackendEstimatorV2.backend   r   r:   )	precisionc                   Uc  U R                   R                  nU Vs/ s H  n[        R                  " X25      PM     nnU R	                  U5        [        U R                  U5      nUR                  5         U$ s  snf r1   )r   rl   r   coerce_validate_pubsr   _run_submit)r   pubsr   pubcoerced_pubsjobs         r.   r$   BackendEstimatorV2.run   sj     77IGKLt++C;tLL)499l3
	 Ms    A9c                    [        U5       H2  u  p#UR                  S::  d  M  [        SU SUR                   S3S5      e   g )Ng        zThe z/-th pub has precision less than or equal to 0 (z). z&But precision should be larger than 0.)	enumerater   
ValueError)r   r   ir   s       r.   r   !BackendEstimatorV2._validate_pubs  sF    oFA}}# 1#LS]]O[^_<  &r:   c                   [        [        5      n[        U5       HG  u  p4[        [        R
                  " SUR                  S-  -  5      5      nX%   R                  U5        MI     S /[        U5      -  nUR                  5        HB  u  pWU R                  U Vs/ s H  o1U   PM	     snU5      n[        Xx5       H	  u  p9XU'   M     MD     [        USS0S9$ s  snf )Ng      ?r?   versionr   )r   r3   r   rG   mathceilr   r   r#   rE   	_run_pubszipr   )
r   r   pub_dictr   r   shotsr5   lstpub_results
pub_results
             r.   r   BackendEstimatorV2._run  s    t$oFA		#q(8"89:EO""1% & &3t9$"..*JE..3)?3aq'3)?GK!$S!6'
 "7	 + w)Q@@	 *@s   C
c           	        / n/ nU H@  nU R                  U5      nUR                  U5        UR                  UR                  5        MB     [	        X@R
                  X R                  R                  S9u  px[        U5      n	/ n
Sn[        X5       HV  u  pVU[        UR                  5      -   nU R                  XU XU 5      nUnU
R                  U R                  X]Xb5      5        MX     U
$ )zFCompute results for pubs that all require the same value of ``shots``.)r   ro   r   )_preprocess_pubr   r4   r&   r/   r   r   ro   r9   r   r#   _calc_expval_map_postprocess_pub)r   r   r   preprocessed_dataflat_circuitsr   data
run_resultr   r6   r5   startend
expval_maps                 r.   r   BackendEstimatorV2._run_pubs#  s    C'',D$$T*  / 
  -==mmFbFb 

 !,T5IC#dmm,,C..vC/@(QTBUVJENN400$NO	 6
 r:   c                   UR                   nUR                  nUR                  nUR                  n[        R
                  " [        R                  " U5      [        S9R                  U5      n[        R                  " Xc5      u  px[        [        5      n	[        R                  " UR                  6  H  n
Xz   nX   R                  X   5        M     U R                  X$U	5      n[        XU5      $ )a  Converts a pub into a list of bound circuits necessary to estimate all its observables.

The circuits contain metadata explaining which bindings array index they are with respect to,
and which measurement basis they are measuring.

Args:
    pub: The pub to preprocess.

Returns:
    The values ``(circuits, bc_param_ind, bc_obs)`` where ``circuits`` are the circuits to
    execute on the backend, ``bc_param_ind`` are indices of the pub's bindings array and
    ``bc_obs`` is the observables array, both broadcast to the shape of the pub.
r<   )circuitr}   parameter_valuesr^   rB   fromiterndindexr_   reshapebroadcast_arraysr   setupdate_bind_and_add_measurementsry   )r   r   r   r}   r   param_shapeparam_indicesbc_param_indbc_obsparam_obs_mapindexparam_indexbound_circuitss                r.   r   "BackendEstimatorV2._preprocess_pub:  s     ++oo// ',,BJJ{$;6JRRS^_!22=N#C(ZZ!3!34E&-K&--fm< 5 88Tab vFFr:   c                F   UR                   nUR                  n[        R                  " U[        S9n[        R                  " U[        S9n[        R
                  " UR                  6  H^  n	XY   n
Xi   R                  5        HA  u  pX*U4   u  pXy==   X-  -  ss'   X==   [        R                  " U5      US-  -  -  ss'   MC     M`     U[        R                  " U5      -  n[        XUR                  S9n[        UUR                  UUR                  R                  S.S9$ )a0  Computes expectation values (evs) and standard errors (stds).

The values are stored in arrays broadcast to the shape of the pub.

Args:
    pub: The pub to postprocess.
    expval_map: The map
    data: The result data of the preprocessing.
    shots: The number of shots.

Returns:
    The pub result.
r<   g      ?)evsstdsr^   )target_precisionr   circuit_metadatar   )r|   r}   rB   
zeros_likerD   r   r^   rE   abssqrtr   r   r   r   r   )r   r   r   r   r   r   r   r   rT   r   r   paulirS   expvalvariancer   data_bins                    r.   r   #BackendEstimatorV2._postprocess_pubY  s      --!!mmL6MM,e<	ZZ!3!34E&-K & 3 3 5#-5.@#A 
fn,
 BFF5MHcM$AA  !6 5 2775>)sSYY?$'MM$'KK$8$8
 	
r:   c                    / nUR                  5        HM  u  pVUR                  X5      n[        [        U5      5      nU R	                  XxU5      n	UR                  U	5        MO     U$ )a  Bind the given circuit against each parameter value set, and add necessary measurements
to each.

Args:
    circuit: The (possibly parametric) circuit of interest.
    parameter_values: An array of parameter value sets that can be applied to the circuit.
    param_obs_map: A mapping from locations in ``parameter_values`` to a sets of
        Pauli terms whose expectation values are required in those locations.

Returns:
    A flat list of circuits sufficient to measure all Pauli terms in the ``param_obs_map``
    values at the corresponding ``parameter_values`` location, where requisite
    book-keeping is stored as circuit metadata.
)rE   bindr   sorted_create_measurement_circuitsr4   )
r   r   r   r   r&   r   pauli_stringsbound_circuitmeas_paulisnew_circuitss
             r.   r   -BackendEstimatorV2._bind_and_add_measurements~  si    ( *7*=*=*?&K,11'GM#F=$9:K<<KL OOL) +@ r:   c                    0 n[        X5       HL  u  pEUS   nUS   nUS   n[        XG5      u  p[        XiU
5       H  u  pnX4X8UR                  5       4'   M     MN     U$ )a  Computes the map of expectation values.

Args:
    counts: The counts data.
    metadata: The metadata.

Returns:
    The map of expectation values takes a pair of an index of the bindings array and
    a pauli string as a key and returns the expectation value of the pauli string
    with the the pub's circuit bound against the parameter value set in the index of
    the bindings array.
orig_paulisr   r   )r   rU   to_label)r   r6   r   r   r8   metar   r   r   rL   rT   r   r   r   s                 r.   r   #BackendEstimatorV2._calc_expval_map  s}    " NP
v0KE}-K}-K}-K!<U!PG+.{Y+O'x=C<N
(889 ,P 1 r:   c                   / nU R                   R                  (       a  UR                  SS9 H  n[        [        R
                  R                  UR                  5      [        R
                  R                  UR                  5      45      n[        UR                  U5      u  px[        R                  " UR                  SS2U4   UR                  SS2U4   UR                  5      n	UU	US.Ul        UR                  U5        M     OU H  n[        UR                  U5      u  px[        U5      n[        R                  " UR                  SS2U4   UR                  SS2U4   UR                  5      n	UU	US.Ul        UR                  U5        M     U R                   R#                  U5      n/ n
U H  nUR%                  5       nUR&                  S   nUR&                   H,  nUR(                  UR(                  :X  d  M  [+        SU S35      e   UR-                  U5        UR/                  X|SS9  UR                  Ul        U
R                  U5        M     U
$ )	a   Generate a list of circuits sufficient to estimate each of the given Paulis.

Paulis are divided into qubitwise-commuting subsets to reduce the total circuit count.
Metadata is attached to circuits in order to remember what each one measures, and
where it belongs in the output.

Args:
    circuit: The circuit of interest.
    observable: Which Pauli terms we would like to observe.
    param_index: Where to put the data we estimate (only passed to metadata).

Returns:
    A list of circuits sufficient to estimate each of the given Paulis.
T)
qubit_wiseN)r   r   r   r   zNClassical register for measurements conflict with those of the input circuit: z9. Recommended to avoid register names starting with '__'.)clbitsinplace)r   rn   group_commutingr   rB   
logical_orreducer[   r-   _measurement_circuit
num_qubitsr   from_symplecticphaser   r   r   r$   copycregsnamer
   add_registercompose)r   r   
observabler   meas_circuitsobsr   meas_circuitindicesrI   preprocessed_circuitscircuit_copyr   cregs                 r.   r   /BackendEstimatorV2._create_measurement_circuits  s2   " /1==))!11T1Br}}33CEE:BMM<P<PQTQVQV<WXY(<W=O=OQV(W%"22EE!W*%EE!W*%II $'#)#.)%
 $$\2 C $(<W=O=OQV(W%&"22EE!W*%EE!W*%II $'#)#.)%
 $$\2 $  ))--m< !#)L"<<>L "''*F$**;;$))+%$$*8 ,RR  + %%f-  d K$0$9$9L!!((6 *  %$r:   )r   r   r   )r'   r   r   zdict | None)returnrj   )r  r   )r   zIterable[EstimatorPubLike]r   zfloat | Noner  z(PrimitiveJob[PrimitiveResult[PubResult]])r   list[EstimatorPub])r   r  r  zPrimitiveResult[PubResult])r   r  r   rG   r  zlist[PubResult])r   r   r  ry   )
r   r   r   dictr   ry   r   rG   r  r   )r   r   r   r   r   zdict[tuple[int, ...], set[str]]r  r{   )r6   zlist[Counts]r   r  r  z6dict[tuple[tuple[int, ...], str], tuple[float, float]])r   r   r   r   r   ztuple[int, ...]r  r{   )rq   rr   rs   rt   ru   r   propertyr   r'   r$   r   r   r   r   r   r   r   r   rw   rp   r:   r.   r   r      s-   2p  $	1 1 	1.    
 NR	.	>J		1	A .G>#
#
-1#
9J#
SV#
	#
J ( 7	
 
>  
@	6F%%F%3<F%KZF%	F%r:   r   c                   [         R                  " UR                  5      UR                  UR                  -     n[         R
                  " U5      (       d  S/n[        [        U S5      [        [        U5      SU 35      5      n[        U5       H`  u  pEUR                  U   (       a6  UR                  U   (       a  UR                  U5        UR                  U5        UR                  XT5        Mb     X24$ )Nr   q__c_)rB   r]   r   r[   r-   anyr   r	   r   r#   r   sdghmeasure)r   r   qubit_indicesr   clbitr   s         r.   r   r     s    
 IIe../%''0ABM66-  !
C(*;C<NRVW\V]P^*_L m,771:wwqz  #NN1Q& - &&r:   )T)r&   z%QuantumCircuit | list[QuantumCircuit]r'   r   r(   rm   r  ztuple[list[Result], list[dict]])r5   zlist[Result])r6   r   rI   r   r  ztuple[np.ndarray, np.ndarray])rI   r   r  z	list[int])rh   rG   r  rG   )r   rG   r   r   )5ru   
__future__r   r   collectionsr   collections.abcr   dataclassesr   numpyrB   qiskit.circuitr   r   r	   qiskit.exceptionsr
   qiskit.providersr   qiskit.quantum_infor   r   qiskit.resultr   r   qiskit.transpilerr   r   qiskit.transpiler.passesr   baser   
containersr   r   r   r   containers.bindings_arrayr   containers.estimator_pubr   primitive_jobr   r/   r9   rU   rA   rH   rj   ry   r   r   rp   r:   r.   <module>r"     s    C "  # $ !  M M ) & 0 ( < A ! M M 4 2 '  #3## #
 %#L8 '
   & 
H 
H 
HT% T%n
'r:   