
    z	i6@                        S r SSKJr  SSKrSSKJrJr  SSKrSSK	J
r
JrJrJr  SSKJr   " S S	\5      r " S
 S\5      rg)z)Compute the weighted sum of qubit states.    )annotationsN)ListOptional)QuantumRegisterAncillaRegisterQuantumCircuitGate   )BlueprintCircuitc                    ^  \ rS rSrSr   S       SU 4S jjjr\SS j5       r\SS j5       r\R                  SS j5       r\SS j5       r
\
R                  SS j5       r
S	 r\SS
 j5       r\SS j5       rSS jrU 4S jrSrU =r$ )WeightedAdder   u  A circuit to compute the weighted sum of qubit registers.

Given :math:`n` qubit basis states :math:`q_0, \ldots, q_{n-1} \in \{0, 1\}` and non-negative
integer weights :math:`\lambda_0, \ldots, \lambda_{n-1}`, this circuit performs the operation

.. math::

    |q_0 \ldots q_{n-1}\rangle |0\rangle_s
    \mapsto |q_0 \ldots q_{n-1}\rangle |\sum_{j=0}^{n-1} \lambda_j q_j\rangle_s

where :math:`s` is the number of sum qubits required.
This can be computed as

.. math::

    s = 1 + \left\lfloor \log_2\left( \sum_{j=0}^{n-1} \lambda_j \right) \right\rfloor

or :math:`s = 1` if the sum of the weights is 0 (then the expression in the logarithm is
invalid).

For qubits in a circuit diagram, the first weight applies to the upper-most qubit.
For an example where the state of 4 qubits is added into a sum register, the circuit can
be schematically drawn as

.. code-block:: text

               ┌────────┐
      state_0: ┤0       ├ | state_0 * weights[0]
               │        │ |
      state_1: ┤1       ├ | + state_1 * weights[1]
               │        │ |
      state_2: ┤2       ├ | + state_2 * weights[2]
               │        │ |
      state_3: ┤3       ├ | + state_3 * weights[3]
               │        │
        sum_0: ┤4       ├ |
               │  Adder │ |
        sum_1: ┤5       ├ | = sum_0 * 2^0 + sum_1 * 2^1 + sum_2 * 2^2
               │        │ |
        sum_2: ┤6       ├ |
               │        │
      carry_0: ┤7       ├
               │        │
      carry_1: ┤8       ├
               │        │
    control_0: ┤9       ├
               └────────┘
c                T   > [         TU ]  US9  SU l        SU l        X l        Xl        g)z
Args:
    num_state_qubits: The number of state qubits.
    weights: List of weights, one for each state qubit. If none are provided they
        default to 1 for every qubit.
    name: The name of the circuit.
nameN)super__init___weights_num_state_qubitsweightsnum_state_qubits)selfr   r   r   	__class__s       j/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/arithmetic/weighted_adder.pyr   WeightedAdder.__init__L   s/     	d#!% 0    c           	         [        U R                  5      S:  aI  [        [        R                  " [        R
                  " [        U R                  5      5      5      S-   5      $ g)zThe number of sum qubits in the circuit.

Returns:
    The number of qubits needed to represent the weighted sum of the qubits.
r      )sumr   intnpfloorlog2r   s    r   num_sum_qubitsWeightedAdder.num_sum_qubitsa   sC     t||q rxxDLL(9 :;a?@@r   c                    U R                   (       a  U R                   $ U R                  (       a  S/U R                  -  $ g)zQThe weights for the qubit states.

Returns:
    The weight for the qubit states.
r   N)r   r   r$   s    r   r   WeightedAdder.weightsl   s4     ====   3....r   c                ,   U(       ag  [        U5       HX  u  p#[        R                  " U[        R                  " U5      5      (       d  [	        S5      e[        R                  " U5      X'   MZ     U R                  5         Xl        U R                  5         g)zSet the weights for summing the qubit states.

Args:
    weights: The new weights.

Raises:
    ValueError: If not all weights are close to an integer.
z&Non-integer weights are not supported!N)	enumerater!   iscloseround
ValueError_invalidater   _reset_registers)r   r   iweights       r   r   r(   y   sm     &w/	zz&"((6*:;;$%MNNXXf-
 0
 	r   c                    U R                   $ )zMThe number of qubits to be summed.

Returns:
    The number of state qubits.
)r   r$   s    r   r   WeightedAdder.num_state_qubits   s     %%%r   c                    U R                   b  XR                   :w  a'  U R                  5         Xl         U R                  5         gg)z]Set the number of state qubits.

Args:
    num_state_qubits: The new number of state qubits.
N)r   r.   r/   )r   r   s     r   r   r3      s@     !!)-=AWAW-W%5"!!# .Xr   c                l   / U l         U R                  (       a  [        U R                  SS9n[        U R                  SS9nX/U l         U R                  S:  a%  [        U R                  SS9nU R                  U5        U R                  S:  a&  [        U R                  SS9nU R                  U5        ggg)zReset the registers.stater   r   r   carrycontrolN)qregsr   r   r%   num_carry_qubitsr   add_registernum_control_qubits)r   qr_stateqr_sumqr_carry
qr_controls        r   r/   WeightedAdder._reset_registers   s    
  &t'<'<7KH$T%8%8uEF"+DJ$$q(*4+@+@wO!!(+&&*,T-D-D9U
!!*- + !r   c                     U R                   S-
  $ )zThe number of carry qubits required to compute the sum.

Note that this is not necessarily equal to the number of ancilla qubits, these can
be queried using ``num_ancilla_qubits``.

Returns:
    The number of carry qubits required to compute the sum.
r   )r%   r$   s    r   r:   WeightedAdder.num_carry_qubits   s     ""Q&&r   c                2    [        U R                  S:  5      $ )zThe number of additional control qubits required.

Note that the total number of ancilla qubits can be obtained by calling the
method ``num_ancilla_qubits``.

Returns:
    The number of additional control qubits required (0 or 1).
r
   )r    r%   r$   s    r   r<    WeightedAdder.num_control_qubits   s     4&&*++r   c                    SnU R                   c  SnU(       a  [        S5      eU R                   [        U R                  5      :w  a  SnU(       a  [	        S5      eU$ )z,Check if the current configuration is valid.TFz,The number of state qubits has not been set.z/Mismatching number of state qubits and weights.)r   AttributeErrorlenr   r-   )r   raise_on_failurevalids      r   _check_configuration"WeightedAdder._check_configuration   sW    !!)E$%STT!!S%66E !RSSr   c           
       > U R                   (       a  g[        TU ]	  5         U R                  U R                  -   n[        U R                  6 nUR                  SU R                   nUR                  U R                  U nUR                  XU R                  -    nUR                  XR                  -   S n[        U R                  5       GH  u  px[        R                  " US5      (       a  M$  X7   n	[        U5      S R                  U R                  S5      SSS2   n
[        U
5       GHP  u  pUS:X  Ga  U R                  S:X  a  UR                  XU   5        M3  US:X  a-  UR!                  XU   X[   5        UR                  XU   5        Mf  XR                  S-
  :X  a0  UR                  XU   5        UR!                  XUS-
     XK   5        M  UR#                  XK   5        UR#                  X[S-
     5        [$        R&                  " 5          [$        R(                  " S[*        S	S
9  UR-                  XU   X[S-
     /X[   USS9  SSS5        UR                  XU   5        UR#                  XK   5        UR#                  X[S-
     5        UR                  XU   5        UR!                  XUS-
     XK   5        GM  U R                  S:X  a  GM  US:X  a  GM  XR                  S-
  :X  a  UR!                  XUS-
     XK   5        GM  [$        R&                  " 5          [$        R(                  " S[*        S	S
9  UR-                  XU   X[S-
     /X[   USS9  SSS5        UR!                  XUS-
     XK   5        GMS     [/        [1        [3        U
5      5      5       GH  nX   nUS:X  Ga  U R                  S:X  a  M!  US:X  a?  UR#                  XK   5        UR!                  XU   X[   5        UR#                  XK   5        Mf  XR                  S-
  :X  a  Mz  UR#                  X[S-
     5        [$        R&                  " 5          [$        R(                  " S[*        S	S
9  UR-                  XU   X[S-
     /X[   USS9  SSS5        UR                  XU   5        UR#                  X[S-
     5        GM  U R                  S:X  a  GM&  US:X  a  GM/  XR                  S-
  :X  a  GMD  UR#                  XK   5        [$        R&                  " 5          [$        R(                  " S[*        S	S
9  UR-                  XU   X[S-
     /X[   USS9  SSS5        UR#                  XK   5        GM     GM     U R5                  UR7                  5       U R                  5        g! , (       d  f       GNO= f! , (       d  f       GNR= f! , (       d  f       GNB= f! , (       d  f       N= f)z(If not already built, build the circuit.Nr   b01r   ignoreqiskit)categorymodulezv-chain)mode)	_is_builtr   _buildr   r%   r   r9   qubitsr:   r*   r   r!   r+   r    rjustcxccxxwarningscatch_warningsfilterwarningsDeprecationWarningmcxreversedrangerH   appendto_gate)r   num_result_qubitscircuitr=   r>   r?   r@   r0   r1   q_stateweight_binaryjbitr   s                r   rX   WeightedAdder._build   s)   >> 11D4G4GG $**->>"9D$9$9: 5 58IJ>>"3$J_J_6_`^^$58M8M$M$OP
 #4<<0IAzz&!$$ kG  #6{1o44T5H5H#NtQStTM $M2#:**a/

71I6a  GAYD

71I611A55  

71I6Ga!e_fiH  		&),		(q5/2%446$33 (3Eh $KK!()X!e_ E ( *%.	 ( 	 7  

7QK8		&),		(q5/2

71I6Ga!e_fiH**a/a11A55  Ga!e_fiH &446$33 (3Eh $KK!()X!e_ E ( *%.	 ( 	 7  Ga!e_fiHy 3~ eC$678#&#:**a/a		&),GAYD		&),11A55		(q5/2%446$33 (3Eh $KK!()X!e_ E ( *%.	 ( 	 7  

7QK8		(q5/2**a/a11A55  		&),%446$33 (3Eh $KK!()X!e_ E ( *%.	 ( 	 7  		&),] 9W 1v 	GOO%t{{3u 76: 764 76. 76s0   9V9V#9V59W
V #
V25
W
W)r   r   r   r9   r   )NNadder)r   zOptional[int]r   zOptional[List[int]]r   strreturnNone)rp   r    )rp   	List[int])r   rr   rp   rq   )r   r    rp   rq   )T)__name__
__module____qualname____firstlineno____doc__r   propertyr%   r   setterr   r/   r:   r<   rK   rX   __static_attributes____classcell__r   s   @r   r   r      s    /f +/'+	1'1 %1 	1
 
1 1*   
 
 ^^   & & & 	$ 	$." 	' 	' 	, 	,K4 K4r   r   c                  F   ^  \ rS rSrSr  S       SU 4S jjjrSrU =r$ )WeightedSumGateih  uY  A gate to compute the weighted sum of qubit registers.

Given :math:`n` qubit basis states :math:`q_0, \ldots, q_{n-1} \in \{0, 1\}` and non-negative
integer weights :math:`\lambda_0, \ldots, \lambda_{n-1}`, this implements the operation

.. math::

    |q_0 \ldots q_{n-1}\rangle |0\rangle_s
    \mapsto |q_0 \ldots q_{n-1}\rangle |\sum_{j=0}^{n-1} \lambda_j q_j\rangle_s

where :math:`s` is the number of sum qubits required.
This can be computed as

.. math::

    s = 1 + \left\lfloor \log_2\left( \sum_{j=0}^{n-1} \lambda_j \right) \right\rfloor

or :math:`s = 1` if the sum of the weights is 0 (then the expression in the logarithm is
invalid).

For qubits in a circuit diagram, the first weight applies to the upper-most qubit.
For an example where the state of 4 qubits is added into a sum register, the circuit can
be schematically drawn as

.. code-block:: text

               ┌──────────────┐
      state_0: ┤0             ├ | state_0 * weights[0]
               │              │ |
      state_1: ┤1             ├ | + state_1 * weights[1]
               │              │ |
      state_2: ┤2             ├ | + state_2 * weights[2]
               │              │ |
      state_3: ┤3 WeightedSum ├ | + state_3 * weights[3]
               │              │
        sum_0: ┤4             ├ |
               │              │ |
        sum_1: ┤5             ├ | = sum_0 * 2^0 + sum_1 * 2^1 + sum_2 * 2^2
               │              │ |
        sum_2: ┤6             ├ |
               └──────────────┘
c           	     *  > Uc  S/U-  nXl         [        U5      S:  aE  [        [        R                  " [        R
                  " [        U5      5      5      S-   5      U l        OSU l        [        TU ]!  SU R                   U R                  -   X#5        g)z
Args:
    num_state_qubits: The number of state qubits.
    weights: List of weights, one for each state qubit. If none are provided they
        default to 1 for every qubit.
    label: The name of the circuit.
Nr   r   WeightedSum)	r   r   r    r!   r"   r#   r%   r   r   )r   r   r   labelr   s       r   r   WeightedSumGate.__init__  s|     ?c,,G 0w<!"%bhhrwws7|/D&E&I"JD"#D(=(=@S@S(SU\dr   )r   r%   )NN)r   r    r   zlist[int] | Noner   z
str | Nonerp   rq   )rs   rt   ru   rv   rw   r   rz   r{   r|   s   @r   r~   r~   h  sG    )\ %) 	ee "e 	e
 
e er   r~   )rw   
__future__r   r^   typingr   r   numpyr!   qiskit.circuitr   r   r   r	   blueprintcircuitr   r   r~    r   r   <module>r      s?    0 "  !  Q Q /K4$ K4\
Ced Cer   