
    z	i0                        S r SSKJrJrJrJrJ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  SS	KJr  SS
KJr  SSKJr  SSKJr      S S\\\4   S\\\      S\S\S\\   S\\\\4   \4   4S jjr S r!     S!S\\\   \RD                  4   S\\\      S\S\S\S\S\\\   \RD                  4   4S jjr#  S"S\S\\\      S\S\\\4   4S jjr$S#S jr%S r&S r'g)$z+Utility functions for working with Results.    )SequenceUnionOptionalDictList)Counter)deepcopyN)QiskitError)Result)Counts)ProbDistribution)QuasiDistribution)_bin_to_hex)resultsresultindicesinplaceformat_marginalmarginalize_memoryreturnc                 0   [        U [        5      (       Ga^  U(       d  [        U 5      n [        U R                  5       GH0  u  pVU R                  U5      n[        Xq5      n0 n	UR                  5        H  u  pX[        U
5      '   M     XR                  l
        UbO  [        U5      UR                  S'   UR                  R                  SS5      nUb  [        X5      UR                  S'   [        UR                  SS5      c  M  Uc  M  USL a  [!        UR                  S5        M  Uc  M  [#        USS9n[$        R&                  " UR                  R(                  USS9UR                  l        GM3     U $ [        X5      nU(       a  Ub  [+        XU5      nU$ )	aD  Marginalize counts from an experiment over some indices of interest.

Args:
    result: result to be marginalized
        (a Result object or a dict(str, int) of counts).
    indices: The bit positions of interest
        to marginalize over. If ``None`` (default), do not marginalize at all.
    inplace: Default: False. Operates on the original Result
        argument if True, leading to loss of original Job Result.
        It has no effect if ``result`` is a dict.
    format_marginal: Default: False. If True, takes the output of
        marginalize and formats it with placeholders between cregs and
        for non-indices.
    marginalize_memory: If True, then also marginalize the memory field (if present).
        If False, remove the memory field from the result.
        If None, leave the memory field as is.

Returns:
    Result or dict(str, int): A Result object or a dictionary with
        the observed counts, marginalized to only account for frequency
        of observations of bits of interest.

Raises:
    QiskitError: in case of invalid indices to marginalize over.
Nmemory_slots
creg_sizesmemoryFTreverse)
return_hex)
isinstancer   r	   	enumerater   
get_counts_marginalizeitemsr   datacountslenheaderget_adjust_creg_sizesgetattrdelattrsorted
results_rsmarginal_memoryr   _format_marginal)r   r   r   r   r   iexperiment_resultr$   
new_countsnew_counts_hexkvcsizesorted_indicesmarg_countss                  M/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/result/utils.pymarginal_countsr9       sx   @ &&!!f%F$-fnn$= A&&q)F%f6JN"((*12{1~. +,:"")";>w<!((8)0044\4H$=OPU=_%,,\:(--x>JwOb%.-22H='/%+&N 5?4N4N)..55~RV5%**1/ %>4 "63w2*6HK    c           	         U  Vs/ s H	  o"S   S/PM     nn[        U5      nU  VVs/ s H  u  pVUPM	     nnn[        S[        U5      S-   5       Vs/ s H  n[        USUS2   5      S-
  PM     snSS nSn	U H;  n
[        U	[        U5      5       H  nXU   ::  d  M  Un	X;   S==   S-  ss'     M9     M=     U Vs/ s H  o"S   S:w  d  M  UPM     nnU$ s  snf s  snnf s  snf s  snf )z,Helper to reduce creg_sizes to match indicesr      N)r+   ranger%   sum)r   r   cregnew_creg_sizesindices_sort_x	creg_numscreg_limitscreg_idxindidxs               r8   r(   r(   e   s    0::ztAwlzN:'?L  **ztqzI*6;As9~PQ?Q6RS6R3y1Q'(1,6RSTUTVWK H3{#34C#&&#A&!+&	 5  (6F~taAd~NF' ;
 +S Gs   CCC"=C'C'r   
int_return
hex_returnavg_dataparallel_thresholdc                 D   U(       a  U(       a  [        S5      e[        U [        R                  5      (       a  U(       a  [        S5      eU(       a  [        S5      eUc  U R	                  5       $ U R
                  S:X  a  [        R                  " X5      $ U R
                  S:X  a3  U(       a  [        R                  " X5      $ [        R                  " X5      $ U R
                  S:X  a  [        R                  " X5      $ [        S5      e[        R                  " U UUUUS9$ )	a?  Marginalize shot memory

This function is multithreaded and will launch a thread pool with threads equal to the number
of CPUs by default. You can tune the number of threads with the ``RAYON_NUM_THREADS``
environment variable. For example, setting ``RAYON_NUM_THREADS=4`` would limit the thread pool
to 4 threads.

Args:
    memory: The input memory list, this is either a list of hexadecimal strings to be marginalized
        representing measure level 2 memory or a numpy array representing level 0 measurement
        memory (single or avg) or level 1 measurement memory (single or avg).
    indices: The bit positions of interest to marginalize over. If
        ``None`` (default), do not marginalize at all.
    int_return: If set to ``True`` the output will be a list of integers.
        By default the return type is a bit string. This and ``hex_return``
        are mutually exclusive and can not be specified at the same time. This option only has an
        effect with memory level 2.
    hex_return: If set to ``True`` the output will be a list of hexadecimal
        strings. By default the return type is a bit string. This and
        ``int_return`` are mutually exclusive and can not be specified
        at the same time. This option only has an effect with memory level 2.
    avg_data: If a 2 dimensional numpy array is passed in for ``memory`` this can be set to
        ``True`` to indicate it's a avg level 0 data instead of level 1
        single data.
    parallel_threshold: The number of elements in ``memory`` to start running in multiple
        threads. If ``len(memory)`` is >= this value, the function will run in multiple
        threads. By default this is set to 1000.

Returns:
    marginal_memory: The list of marginalized memory

Raises:
    ValueError: if both ``int_return`` and ``hex_return`` are set to ``True``
z=Either int_return or hex_return can be specified but not bothz3int_return option only works with memory list inputz3hex_return option only works with memory list inputr<         zInvalid input memory array)
return_intr   rL   )
ValueErrorr   npndarraycopyndimr,   marginal_measure_level_1_avgmarginal_measure_level_0_avgmarginal_measure_level_1marginal_measure_level_0r-   )r   r   rI   rJ   rK   rL   s         r8   r-   r-      s    T jXYY&"**%%RSSRSS?;;= ;;!::6KK;;!!>>vOO!::6KK;;!66vGG566%%- r:   r$   c                 4   [        [        U R                  5       5      R                  SS5      5      nUbI  [        U5      S:X  d(  [	        U5      R                  [        U5      5      (       d  [        SUS-
   S35      e[        U [        5      (       a  [        R                  " X5      nO[        U [        [        45      (       a  [        R                  " X5      nO[        [!        U R#                  5       5      5      n[        U[$        [&        R(                  45      (       a  [        R                  " X5      nOG[        U[*        [&        R,                  45      (       a  [        R                  " X5      nO[        S5      eU(       a  Ub  [/        XU5      $ U$ )a(  Marginalize counts from an experiment over some indices of interest.

Unlike :func:`~.marginal_counts` this function respects the order of
the input ``indices``. If the input ``indices`` list is specified then the order
the bit indices are specified will be the output order of the bitstrings
in the marginalized output.

Args:
    counts: result to be marginalized
    indices: The bit positions of interest
        to marginalize over. If ``None`` (default), do not marginalize at all.
    format_marginal: Default: False. If True, takes the output of
        marginalize and formats it with placeholders between cregs and
        for non-indices.
Returns:
    dict(str, int): A marginalized dictionary
Raises:
    QiskitError: If any value in ``indices`` is invalid or the ``counts`` dict
    is invalid.
  r   indices must be in range [0, r<   ].z(Values of counts must be an int or float)r%   maxkeysreplacesetissubsetr=   r
   r   r   r,   r9   r   r   marginal_distributionnextitervaluesintrR   integerfloatfloatingr.   )r$   r   r   
num_clbitsresfirst_values         r8   rd   rd      s3   2 S'//R89JG 1W9N9NuU_O`9a9a9*q.9ILMM&&!!((9	F-/@A	B	B..v?401kC#455,,V=CeR[[%9::226CCHII7.W55Jr:   c           	         [        [        [        U 5      5      R                  SS5      5      nUb!  [	        [        U5      5      [	        U5      :X  a,  0 nU R                  5        H  u  pE[        U5      nXSU'   M     U$ U(       a1  [	        U5      R                  [	        [        U5      5      5      (       d  [        SUS-
   S35      e[        USS9n[        5       nU R                  5        HC  u  pESR                  U Vs/ s H  n[        U5      U* S-
     PM     sn5      nXh==   U-  ss'   ME     [        U5      $ s  snf )z4Get the marginal counts for the given set of indicesr[   r\   r]   r<   r^   Tr   )r%   re   rf   ra   rb   r=   r"   _remove_space_underscorerc   r
   r+   r   joindict)	r$   r   rl   retkeyvalr1   rH   new_keys	            r8   r!   r!      s    T$v,'//R89J 	Cj 12c'lBHC*3/CH ' 
#g,//E*4E0FGG9*q.9ILMM Wd+G JLLN''gVgs3C8#BgVWs" # 
 Ws    D>
c                    0 n[        [        U 5      5      n[        UR                  SS5      5      n[	        USS9nU H  n[        [        Xg5      5      nSR                  [        U5       V	s/ s H  oU;   a  X   OSPM     sn	5      SSS2   n
[        U5       H  u  pUS:X  d  M  U
SU	 S-   XS -   n
M     X   X:'   M     U$ s  sn	f )zWTake the output of marginalize and add placeholders for
multiple cregs and non-indices.r[   r\   Tr   rB   N)
re   rf   r%   ra   r+   rr   ziprq   r=   r   )r$   r7   r   format_countscounts_template
counts_lenindices_revcount
index_dictindex
count_bitsbits               r8   r.   r.     s     M4<(O_,,S"56J$/K#k12
WWLQR\L]^L]5:"5Z3>L]^

B$
 $O4JEcz'/#5
68JJ
 5 %0$6!   _s   -C
c                 F    U R                  SS5      R                  SS5      $ )z1Removes all spaces and underscores from bitstringr[   r\   rB   )ra   )	bitstrings    r8   rp   rp   $  s"    S"%--c266r:   )NFFT)NFFFi  )NF)N)(__doc__typingr   r   r   r   r   collectionsr   rT   r	   numpyrR   qiskit.exceptionsr
   qiskit.result.resultr   qiskit.result.countsr   'qiskit.result.distributions.probabilityr   !qiskit.result.distributions.quasir   qiskit.result.postprocessr   qiskit._accelerater   r,   rr   rh   boolstrr9   r(   rS   r-   rd   r!   r.   rp    r:   r8   <module>r      s   2 8 8    ) ' ' D ? 1 4
 $(!)-B$,Bd3i B B 	B
 !B 4S>6!"BJ8 $("D$s)RZZ'(Dd3i D D 	D
 D D 49bjj !DR (,!,,hsm$, , 
#s(^	,^6(7r:   