
    z	i8                        S r SSKJr  SSKJrJrJr  SSKrSSKJ	r	  SSK
rSSKJrJrJrJrJr  SSKJr  SS	KJrJr  \\\\R2                  \R4                  \4   r " S
 S\5      r " S S\5      rg)z<A circuit implementing a quadratic form on binary variables.    )annotations)UnionOptionalListN)Sequence)QuantumCircuitQuantumRegisterParameterExpressionGateCircuitError)deprecate_func   )QFTQFTGatec                     ^  \ rS rSrSr\" SSSS9     S
           SU 4S jjj5       r\        SS j5       rS	r	U =r
$ )QuadraticForm     Implements a quadratic form on binary variables encoded in qubit registers.

A quadratic form on binary variables is a quadratic function :math:`Q` acting on a binary
variable of :math:`n` bits, :math:`x = x_0 ... x_{n-1}`. For an integer matrix :math:`A`,
an integer vector :math:`b` and an integer :math:`c` the function can be written as

.. math::

    Q(x) = x^T A x + x^T b + c

If :math:`A`, :math:`b` or :math:`c` contain scalar values, this circuit computes only
an approximation of the quadratic form.

Provided with :math:`m` qubits to encode the value, this circuit computes :math:`Q(x) \mod 2^m`
in [two's complement](https://stackoverflow.com/questions/1049722/what-is-2s-complement)
representation.

.. math::

    |x\rangle_n |0\rangle_m \mapsto |x\rangle_n |(Q(x) + 2^m) \mod 2^m \rangle_m

Since we use two's complement e.g. the value of :math:`Q(x) = 3` requires 2 bits to represent
the value and 1 bit for the sign: `3 = '011'` where the first `0` indicates a positive value.
On the other hand, :math:`Q(x) = -3` would be `-3 = '101'`, where the first `1` indicates
a negative value and `01` is the two's complement of `3`.

If the value of :math:`Q(x)` is too large to be represented with `m` qubits, the resulting
bitstring is :math:`(Q(x) + 2^m) \mod 2^m)`.

The implementation of this circuit is discussed in [1], Fig. 6.

References:

[1] Gilliam et al., Grover Adaptive Search for Constrained Polynomial Binary Optimization.
`arXiv:1912.04088 <https://arxiv.org/pdf/1912.04088.pdf>`_

z2.1z"Use the QuadraticFormGate instead.z
Qiskit 3.0)sinceadditional_msgremoval_timelinec           	       > Ub&  Ub#  [        U5      [        U5      :w  a  [        S5      eUc  / nUc  / nUc  Sn[        R                  " S[        U5      [        U5      /5      nUc`  [	        S U 5       5      (       d,  [	        S U 5       5      (       d  [        U[        5      (       a  [        S5      eU R                  X#U5      n[        U5      n[        U5      n[        XxSS	9n	[        U5      S:X  a  Sn[        U5      S:X  a  Sn[        R                  S
SU-
  -  -  n
U	R                  U5        U(       a  USSS2   nUS:w  a/  [        U5       H   u  pU	R                  U
S
U-  -  U-  U5        M"     [        U5       HT  nUb  X=   OSnXb  X-   U   OS-  nUS:w  d  M"  [        U5       H#  u  pU	R                  U
S
U-  -  U-  X}   U5        M%     MV     Ubu  [        U5       Hf  n[        US-   U5       HP  nX-   U   X/   U   -   nUS:w  d  M  [        U5       H'  u  pU	R!                  U
S
U-  -  U-  X}   X   /U5        M)     MR     Mh     [#        USS9R%                  5       R'                  5       nU	R)                  UUSS SS9  [*        TU ]X  " U	R.                  SS06  U R)                  U	R1                  5       U R2                  SS9  g)aX  
Args:
    num_result_qubits: The number of qubits to encode the result. Called :math:`m` in
        the class documentation.
    quadratic: A matrix containing the quadratic coefficients, :math:`A`.
    linear: An array containing the linear coefficients, :math:`b`.
    offset: A constant offset, :math:`c`.
    little_endian: Encode the result in little endianness.

Raises:
    ValueError: If ``linear`` and ``quadratic`` have mismatching sizes.
    ValueError: If ``num_result_qubits`` is unspecified but cannot be determined because
        some values of the quadratic form are parameterized.
N*Mismatching sizes of quadratic and linear.r      c              3  F   #    U  H  n[        S  U 5       5      v   M     g7f)c              3  B   #    U  H  n[        U[        5      v   M     g 7fN
isinstancer
   ).0q_ijs     j/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/arithmetic/quadratic_form.py	<genexpr>3QuadraticForm.__init__.<locals>.<genexpr>.<genexpr>w   s     N#$
4)<==#   N)any)r    q_is     r"   r#   )QuadraticForm.__init__.<locals>.<genexpr>w   s!     dZcSVCN#NNNZcs   !c              3  B   #    U  H  n[        U[        5      v   M     g 7fr   r   )r    l_is     r"   r#   r(   x   s     Nvz#':;;vr%   zuIf the number of result qubits is not specified, the quadratic form matrices/vectors/offset may not be parameterized.Q(x))namer   F)do_swapsT)qubitsinplacer,   )len
ValueErrornpmaxr&   r   r
   required_result_qubitsr	   r   pih	enumerateprangecpmcpr   inversereverse_bitscomposesuper__init__qregsto_gater/   )selfnum_result_qubits	quadraticlinearoffsetlittle_endiannum_input_qubitsqr_input	qr_resultcircuitscalingir'   jvaluekiqft	__class__s                    r"   rA   QuadraticForm.__init__E   s   <  V%79~V, !MNN I>F>F661c&k3y>"BC $ dZcdddNvNNNf&9:: M  !% ; ;Iv V"#34#$56	 6B y>QIv;!F%%!$5 566 			)!$B$I Q;#I.		'AqD.6137 /
 '(A!'!3FIE(=Y\!_1DEz'	2FAJJwA~5x{CH 3	 )  +,q1u&67A%LOil1o=Ez&/	&:FA#KK!Q$(>hk@Z\_` '; 8 - $u5==?LLNYq\4@'--5f5W__&t{{DI    c                .    [         R                  XU5      $ )7  Get the number of required result qubits.

Args:
    quadratic: A matrix containing the quadratic coefficients.
    linear: An array containing the linear coefficients.
    offset: A constant offset.

Returns:
    The number of qubits needed to represent the value of the quadratic form
    in twos complement.
)QuadraticFormGater5   )rF   rG   rH   s      r"   r5   $QuadraticForm.required_result_qubits   s    " !77	6RRrV    )NNNNT)rE   zOptional[int]rF   zJOptional[Union[np.ndarray, List[List[Union[float, ParameterExpression]]]]]rG   zDOptional[Union[np.ndarray, List[Union[float, ParameterExpression]]]]rH   z+Optional[Union[float, ParameterExpression]]rI   boolreturnNone)rF   z$Union[np.ndarray, List[List[float]]]rG   zUnion[np.ndarray, List[float]]rH   floatr]   int)__name__
__module____qualname____firstlineno____doc__r   rA   staticmethodr5   __static_attributes____classcell__rT   s   @r"   r   r      s    $L ;% ,0 W[>B"fJ(fJ
fJ UfJ <fJ fJ 
fJ
fJP S7S.S S 
	S SrV   r   c                     ^  \ rS rSrSr     S         S	U 4S jjjr\        S
S j5       rU 4S jrS r	Sr
U =r$ )rY      r   c                  > Ub&  Ub#  [        U5      [        U5      :w  a  [        S5      eUc  / nUc  / nUc  Sn[        R                  " S[        U5      [        U5      /5      U l        Uc  U R                  X#U5      nXl        X l        X0l        X@l	        [        U R                  U R                  -   5      n[        TU ]1  SU/ US9  g )Nr   r   r   r   )label)r1   r2   r3   r4   rJ   r5   rE   rF   rG   rH   r`   r@   rA   )rD   rE   rF   rG   rH   rm   
num_qubitsrT   s          r"   rA   QuadraticFormGate.__init__   s      V%79~V, !MNN I>F>F "3v;I'G H $ $ ; ;Iv V!2"..1G1GGH
*bFrV   c                  ^ / nS S 4 HZ  mSnU[        U4S jU  5       5      -  nU[        U4S jU 5       5      -  nUT" U5      (       a  UOS-  nUR                  U5        M\     [        R                  " [        R                  " [        US   * S5      5      5      n[        R                  " [        R                  " US   S-   5      5      nS[        XV5      -   nU$ )rX   c                    U S:  $ Nr   r[   xs    r"   <lambda>:QuadraticFormGate.required_result_qubits.<locals>.<lambda>%  s    AErV   c                    U S:  $ rr   r[   rs   s    r"   ru   rv   %  s    QUrV   g        c              3  N   >#    U  H  n[        U4S  jU 5       5      v   M     g7f)c              3  F   >#    U  H  nT" U5      (       d  M  Uv   M     g 7fr   r[   )r    r!   	conditions     r"   r#   EQuadraticFormGate.required_result_qubits.<locals>.<genexpr>.<genexpr>'  s     EcdYt_TTc   !	!N)sum)r    r'   rz   s     r"   r#   ;QuadraticFormGate.required_result_qubits.<locals>.<genexpr>'  s!     [QZ#EcEEEQZs   "%c              3  F   >#    U  H  nT" U5      (       d  M  Uv   M     g 7fr   r[   )r    r*   rz   s     r"   r#   r~   (  s     A)C.r|   r   r   )r}   appendmathceillog2r4   )	rF   rG   rH   boundsboundnum_qubits_for_minnum_qubits_for_maxrE   rz   s	           @r"   r5   (QuadraticFormGate.required_result_qubits  s    $ )?;IES[QZ[[[ESAAAAEy00Va7EMM%  < "YYtyyfQiZ1C'DE!YYtyyQ'?@$6 KK  rV   c                @  > [        U[        5      (       a  U$ [        U[        R                  [        45      (       aS  [        S U 5       5      (       a  U$ U H2  n[        S U 5       5      (       a  M  [        S[        U5       S35      e   U$ [        TU ]%  U5      $ )Nc              3  B   #    U  H  n[        U[        5      v   M     g 7fr   r   
_ValueTyper    els     r"   r#   7QuadraticFormGate.validate_parameter.<locals>.<genexpr>9  s     B	":b*--	r%   c              3  B   #    U  H  n[        U[        5      v   M     g 7fr   r   r   s     r"   r#   r   <  s     G":b*55r%   zInvalid parameter type z for QuadraticFormGate)
r   r   r3   ndarrayr   allr   typer@   validate_parameter)rD   	parameterparamsrT   s      r"   r   $QuadraticFormGate.validate_parameter4  s    i,,i"**h!788B	BBB  #GGGG&1$y/1BBXY  $ w))44rV   c           	     4   U R                   U R                  U R                  p2n[        U R                  5      n[        U R
                  5      n[        XE5      n[        U5      S:X  a  S n[        U5      S:X  a  S n[        R                  SSU R
                  -
  -  -  n[        U R
                  5      nUR                  X5        US:w  a/  [        U5       H   u  pUR                  USU	-  -  U-  U
5        M"     [        U R                  5       HT  nUb  X+   OSnXb  X   U   OS-  nUS:w  d  M"  [        U5       H#  u  pUR                  USU	-  -  U-  XK   U
5        M%     MV     Ub  [        U R                  5       Hp  n[        US-   U R                  5       HP  nX   U   X   U   -   nUS:w  d  M  [        U5       H'  u  pUR!                  USU	-  -  U-  XK   XM   /U
5        M)     MR     Mr     UR#                  5       nUR                  X5        X`l        g )Nr   r   r   )rF   rG   rH   r	   rJ   rE   r   r1   r3   r6   r   r   r8   r9   r:   r;   r<   r=   
definition)rD   rF   rG   rH   rK   rL   rM   rN   qftrO   r'   rP   rQ   rR   rS   s                  r"   _defineQuadraticFormGate._defineE  s   $(NNDKK6	"4#8#89#D$:$:;	 5 y>QIv;!F%%!D$:$: :;; d,,-s& Q;#I.		'AqD.6137 /
 t,,-A!'!3FIE(=Y\!_1DEz'	2FAJJwA~5x{CH 3	 .  4001q1ud&;&;<A%LOil1o=Ez&/	&:FA#KK!Q$(>hk@Z\_` '; = 2 {{}t'!rV   )r   rG   rJ   rE   rH   rF   )NNNNr+   )
rE   z
int | NonerF    Sequence[Sequence[float]] | NonerG   r   rH   zfloat | Nonerm   str)rF   zSequence[Sequence[float]]rG   zSequence[float]rH   r_   r]   r`   )ra   rb   rc   rd   re   rA   rf   r5   r   r   rg   rh   ri   s   @r"   rY   rY      s    $P )-6:37##G%#G 4#G 1	#G
 #G #G #GJ !,!! ! 
	! !B5"/" /"rV   rY   )re   
__future__r   typingr   r   r   r   collections.abcr   numpyr3   qiskit.circuitr   r	   r
   r   r   qiskit.utils.deprecationr   basis_changer   r   r`   r_   integerfloatingr   r   rY   r[   rV   r"   <module>r      sf    C " ( (  $  c c 3 '3rzz2;;8KKL
eSN eSPn" n"rV   