
    z	i=                        S r SSKJr  SSKJrJrJr  SSKJrJr	  SSK
JrJr  SSKrSSKJr  SSKJrJr  S	S
KJrJrJr  SS/r\\\4   r \\\\\S4   4   \4   r  " S S\5      rSS jrSS jrSS jrSS jr g)z
Bindings array class
    )annotations)MappingUnionTuple)Iterabler   )chainisliceN)	ArrayLike)	ParameterQuantumCircuit   )ShapedMixin
ShapeInputshape_tupleParameterLikeBindingsArrayLike.c                     ^  \ rS rSrSr  S   SU 4S jjjrSS jrS r\SS j5       r	\SS j5       r
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5       rS rSrU =r$ )BindingsArray6   a  Stores parameter binding value sets for a :class:`qiskit.QuantumCircuit`.

A single parameter binding set provides numeric values to bind to a circuit with free
:class:`qiskit.circuit.Parameter`\s. An instance of this class stores an array-valued collection
of such sets. The simplest example is a 0-d array consisting of a single parameter binding set,
whereas an n-d array of parameter binding sets represents an n-d sweep over values.

The storage format is a dictionary of arrays attached to parameters,
``{params_0: values_0,...}``. A convention is used where the last dimension of each array
indexes (a subset of) circuit parameters. For example, if the last dimension of ``values_0`` is
25, then it represents an array of possible binding values for the 25 distinct parameters
``params_0``, where its leading shape is the array :attr:`~.shape` of its binding array. This
allows flexibility about whether values for different parameters are stored in one big array, or
across several smaller arrays.

.. plot::
   :include-source:
   :nofigs:

    # 0-d array (i.e. only one binding)
    BindingsArray({"a": 4, ("b", "c"): [5, 6]})

    # single array, last index is parameters
    parameters = tuple(f"a{idx}" for idx in range(100))
    BindingsArray({parameters: np.ones((10, 10, 100))})

    # multiple arrays, where each last index is parameters. notice that it's smart enough to
    # figure out that a missing last dimension corresponds to a single parameter.
    BindingsArray(
        {("c", "a"): np.zeros((10, 10, 2)), "b": np.ones((10, 10))}
    )
c           
       > [         TU ]  5         Uc  0 U l        OrUR                  5        VVs0 s HO  u  p4[	        U[
        [        45      (       a  [        U45      O
[        U5      [        R                  " U[        S9_MQ     snnU l        Uc  [        U R                  5      O
[        U5      U l        SU l        U R                  5         gs  snnf )ai  
Initialize a :class:`~.BindingsArray`.

The ``shape`` argument does not need to be provided whenever it can unambiguously
be inferred from the provided arrays. Ambiguity arises whenever the key of an entry of
``data`` contains only one parameter and the corresponding array's shape ends in a one.
In this case, it can't be decided whether that one is an index over parameters, or whether
it should be incorporated in :attr:`~shape`.

Since :class:`~.Parameter` objects are only allowed to represent float values, this
class casts all given values to float. If an incompatible dtype is given, such as complex
numbers, a ``TypeError`` will be raised.

Args:
    data: A mapping from one or more parameters to arrays of values to bind
        them to, where the last axis is over parameters.
    shape: The leading shape of every array in these bindings.

Raises:
    ValueError: If all inputs are ``None``.
    ValueError: If the shape cannot be automatically inferred from the arrays, or if there
        is some inconsistency in the shape of the given arrays.
    TypeError: If some of the vaules can't be cast to a float type.
Ndtype)super__init___dataitems
isinstancer   str_format_keynpasarrayfloat_infer_shaper   _shape_num_parametersvalidate)selfdatashapekeyval	__class__s        e/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/primitives/containers/bindings_array.pyr   BindingsArray.__init__X   s    : 	<DJ !%

	 !-HC ,6cIs;K+L+LK'R]^aRb::c/0 ,	DJ 38-l4::.[QVEW#s   ACc                
   U R                   R                  5        VVs0 s H
  u  p#X#U   _M     nnn [        [        UR	                  5       5      5      R
                  S S n[        XE5      $ s  snnf ! [         a    Sn Nf = f)N )r   r   nextitervaluesr)   StopIterationr   )r'   argsparamsr+   r(   r)   s         r-   __getitem__BindingsArray.__getitem__   s     6:ZZ5E5E5GH5GkfD	!5GH	dkkm,-33CR8E T)) I  	E	s   A-/A3 3BBc                   SU R                    3SU R                   3/nU R                  (       a  [        [        [	        [
        [        R                  " [	        [        U R                  5      5      5      S5      5      n[        U5      U R                  :  a  UR                  S5        UR                  SSR                  U5       S35        [        U 5      R                   SSR                  U5       S	3$ )
Nzshape=znum_parameters=   z...zparameters=[z, ]z(<z>))r)   num_parameterslistr	   mapreprr   from_iterabler   r   lenappendjointype__name__)r'   descriptionsnamess      r-   __repr__BindingsArray.__repr__   s     -ATAT@U/VWD%*=*=c+tzz>Z*[ \^_`aE5zD///U#,tyy/?.@ BCt*%%&b<)@(ADD    c                    U R                   $ )z!The keyword values of this array.)r   r'   s    r-   r(   BindingsArray.data   s     zzrK   c                    U R                   c/  [        S U R                  R                  5        5       5      U l         U R                   $ )zThe total number of parameters.c              3  >   #    U  H  oR                   S    v   M     g7f)r0   Nr)   ).0r+   s     r-   	<genexpr>/BindingsArray.num_parameters.<locals>.<genexpr>   s     &T@Syy}@Ss   )r%   sumr   r4   rM   s    r-   r=   BindingsArray.num_parameters   s<     '#&&T

@Q@Q@S&T#TD ###rK   c           	       ^ Sn[         R                  " [        U R                  U R                  5      5      nUc@  U R
                  R                  5        H   nUR                  S   nXCSX"U-   24'   X%-  nM"     U$ [        U5      n[        U5      U R                  :w  a%  [        SU R                   S[        U5       S35      e[        U5       VVs0 s H  u  pg[        U5      U_M     snnmU R
                  R                  5        H-  u  p U V	s/ s H  n	T[        U	5         U-   PM     n
n	XCSU
4'   M/     U$ s  snnf s  sn	f ! [         a8  n[        U4S j[        [        U5       5       5      n[        S	U S
35      UeSnAff = f)a  Return the contents of this bindings array as a single NumPy array.

The parameters are indexed along the last dimension of the returned array.

Parameters:
    parameters: Optional parameters that determine the order of the output.

Returns:
    This bindings array as a single NumPy array.

Raises:
    ValueError: If ``parameters`` are provided, but do not match those found in ``data``.
r   Nr0   .	Expected z parameters but z
 received.c              3  6   >#    U  H  oT;  d  M
  Uv   M     g 7fNr1   )rR   p
idx_lookups     r-   rS   )BindingsArray.as_array.<locals>.<genexpr>   s     "b.JWaNa11.Js   		z(Could not find placement for parameter 'z'.)r    emptyr   r)   r=   r(   r4   r>   rB   
ValueError	enumerate_param_namer   KeyErrorr2   r?   )r'   
parameterspositionretarrsizeidx	parameter
arr_paramsparamidxsexmissingr\   s                @r-   as_arrayBindingsArray.as_array   s    hh{4::t/B/BCDyy'')yy}7:CtO334  *2 
' j)J:$"5"55  3 344DS_DUU_`  MVV`LabLa.#+i0#5LabJ#'99??#4
eS]^S]%J{5'9:XES]D^ "%CI $5 
 c _ e""bc+z.J"bbG$'OPWyXZ%[\bddes0   D;EE-EE
F3FFc                2   [        U5      U R                  :w  a  [        SU SU R                   S35      eU R                  R                  5        VVVVs0 s H  u  p4[        X4U   5        H  u  pVXV_M	     M!     nnnnnUR                  U5      $ s  snnnnf )a  Return a new circuit bound to the values at the provided index.

Args:
    circuit: The circuit to bind.
    loc: A tuple of indices, on for each dimension of this array.

Returns:
    The bound circuit.

Raises:
    ValueError: If the index doesn't have the right number of values.
rX   z to index all dimensions of .)rB   ndimr_   r)   r   r   zipassign_parameters)r'   circuitlocr7   valsrk   r+   rc   s           r-   bindBindingsArray.bind   s     s8tyy y-I$**UVWXX !%

 0 0 2
 2!&s)4
 J4  2 	 

 ((44
s   &B
c                    [         R                  " U R                  [        S9n[         R                  " U R                  5       H  nU R                  X5      X#'   M     U$ )zReturn an object array of bound circuits with the same shape.

Args:
    circuit: The circuit to bind.

Returns:
    An object array of the same shape containing all bound circuits.
r   )r    r^   r)   objectndindexry   )r'   rv   rf   rh   s       r-   bind_allBindingsArray.bind_all   sD     hhtzz0::djj)Cyy.CH *
rK   c                8    U R                  U R                  5      $ )zReturn a new :class:`~BindingsArray` with one dimension.

The returned bindings array has a :attr:`shape` given by ``(size, )``, where the size is the
:attr:`~size` of this bindings array.

Returns:
    A new bindings array.
)reshaperg   rM   s    r-   ravelBindingsArray.ravel   s     ||DII&&rK   c                  ^ [        U5      n[        S U 5       5      (       aU  [        R                  " U Vs/ s H  o"S:  d  M
  UPM     sn[        S9nU R
                  U-  m[        U4S jU 5       5      n[        R                  " U[        S9U R
                  :w  a  [        S5      eU R                  R                  5        VVs0 s H%  u  pEXER                  XR                  SS -   5      _M'     nnn[        XaS9$ s  snf s  snnf )	a+  Return a new :class:`~BindingsArray` with a different shape.

This results in a new view of the same arrays.

Args:
    shape: The shape of the returned bindings array.

Returns:
    A new bindings array.

Raises:
    ValueError: If the provided shape has a different product than the current size.
c              3  *   #    U  H	  oS :  v   M     g7fr   Nr1   )rR   dims     r-   rS   (BindingsArray.reshape.<locals>.<genexpr>  s     (%3Qw%s   r   r   c              3  6   >#    U  H  oS :  a  UOTv   M     g7fr   r1   )rR   r   missing_dims     r-   rS   r     s     Les#{:es   z5Reshaping cannot change the total number of elements.r0   NrQ   )r   anyr    prodintrg   tupler_   r   r   r   r)   r   )r'   r)   r   positive_sizepsr+   r(   r   s          @r-   r   BindingsArray.reshape  s     E"(%(((GGE$FESAXSE$FcRM))}4KLeLLE775$		1TUUGKzzGWGWGYZGYGBKK		"# 677GYZT// %G [s   	D D ,Dc                    Uc	  U " 5       nU$ [        U[        5      (       a  U " US9nU$ [        U[        5      (       a  U$ [        S[	        U5       S35      e)zCoerce an input that is :class:`~BindingsArrayLike` into a new :class:`~BindingsArray`.

Args:
    bindings_array: An object to be bindings array.

Returns:
    A new bindings array.
)r(   zUnsupported type z
 is given.)r   _Mappingr   	TypeErrorrE   )clsbindings_arrays     r-   coerceBindingsArray.coerce!  sj     ! UN  11 n5N
 	 66!!/^0D/EZPQQrK   c                    U R                   R                  5        HU  u  p[        X R                  5      =o R                   U'   [	        U5      UR
                  S   :w  d  MF  [        SU SU 35      e   g)z+Validate the consistency in bindings_array.r0   z
Length of z% inconsistent with last dimension of N)r   r   _standardize_shaper$   rB   r)   r_   )r'   rc   r+   s      r-   r&   BindingsArray.validate5  si    #zz//1OJ+=c;;+OOC**Z(:#))B-/  ,QRUQVW   2rK   )r   r%   r$   )NN)r(   zBindingsArrayLike | Noner)   zShapeInput | None)returnr   )r   z!dict[tuple[str, ...], np.ndarray])r   r   rZ   )rc   zIterable[ParameterLike] | Noner   
np.ndarray)rv   r   rw   tuple[int, ...]r   r   )rv   r   r   r   )r)   zint | Iterable[int]r   r   )r   r   r   r   )rF   
__module____qualname____firstlineno____doc__r   r8   rI   propertyr(   r=   ro   ry   r~   r   r   classmethodr   r&   __static_attributes____classcell__)r,   s   @r-   r   r   6   s    F *.#',&, !, ,\*E   $ $,\5.	'06  & rK   r   c                    U R                   U:X  a  U S   n U $ U R                  S-
  [        U5      :w  d  U R                   SS U:w  a  [        SU R                    SU 35      eU $ )aQ  Return ``val`` or ``val[..., None]``.

Args:
    val: The array whose shape to standardize.
    shape: The shape to standardize to.

Returns:
    An array with one more dimension than ``len(shape)``, and whose leading dimensions match
    ``shape``.

Raises:
    ValueError: If the leading shape of ``val`` does not match the ``shape``.
).Nr   Nr0   zArray with shape z inconsistent with )r)   rs   rB   r_   )r+   r)   s     r-   r   r   ?  sj     yyE)n J 
AU	#syy"~'>,SYYK7J5'RSSJrK   c                  ^ SmU4S jnU R                  5        Hx  u  p#[        U5      S:w  a  U" UR                  SS 5        M+  UR                  (       a*  UR                  S   S:X  a  U" UR                  SS 5        Mf  U" UR                  5        Mz     Tc  g[        T5      S:X  a  [        [	        T5      5      $ [        T5      S:X  a  [        S5      e[        ST S	35      e)
ax  Return a shape tuple that consistently defines the leading dimensions of all arrays.

Args:
    data: A mapping from tuples to arrays, where the length of each tuple should match the
        last dimension of the corresponding array.

Returns:
    A shape tuple that matches the leading dimension of every array.

Raises:
    ValueError: If this cannot be done unambiguously.
Nc                 F   > Tc  [        U 5      mg TR                  U 5        g rZ   )setintersection_update)possible_shapesonly_possible_shapess    r-   examine_array#_infer_shape.<locals>.examine_arrayc  s"    '#&#7  44_ErK   r   r0   r1   r   z$Could not find any consistent shape.zDCould not unambiguously determine the intended shape, all shapes in z7 are consistent with the input; specify shape manually.)r   rB   r)   r2   r3   r_   )r(   r   rc   r+   r   s       @r-   r#   r#   T  s      F  ::<
z?a#))CR.)YY399R=A- #))CR.) #))$ ( #
 A%D-.//	!	"a	'?@@
N
  W	Y rK   c                4    [        [        [        U 5      5      $ rZ   )r   r?   ra   )r*   s    r-   r   r     s    [#&''rK   c                H    [        U [        5      (       a  U R                  $ U $ rZ   )r   r   name)rk   s    r-   ra   ra     s    #E9555::@5@rK   )r+   r   r)   r   r   r   )r(   z'dict[tuple[Parameter, ...], np.ndarray]r   r   )r*   ztuple[Parameter | str, ...])rk   zParameter | strr   r   )!r   
__future__r   typingr   r   r   collections.abcr   r   	itertoolsr   r	   numpyr    numpy.typingr
   qiskit.circuitr   r   r)   r   r   r   __all__r   r   r   r   r   r#   r   ra   r1   rK   r-   <module>r      s    # ( ( 9 #  " 4 7 7 /
0 in% $E-}c7I1J"JKYVW "FK FR*+\(ArK   