
    z	i9                        S r SSKJr  SSKrSSKJrJr  SSKJ	r	  SSK
JrJr   " S S	\5      r " S
 S\5      rS rS rg)zHA class implementing a (piecewise-) linear function on qubit amplitudes.    )annotationsN)QuantumCircuitGate)deprecate_func   )PiecewiseLinearPauliRotations!PiecewiseLinearPauliRotationsGatec                  |   ^  \ 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rS	rU =r	$ )LinearAmplitudeFunction   ag  A circuit implementing a (piecewise) linear function on qubit amplitudes.

An amplitude function :math:`F` of a function :math:`f` is a mapping

.. math::

    F|x\rangle|0\rangle = \sqrt{1 - \hat{f}(x)} |x\rangle|0\rangle + \sqrt{\hat{f}(x)}
        |x\rangle|1\rangle.

for a function :math:`\hat{f}: \{ 0, ..., 2^n - 1 \} \rightarrow [0, 1]`, where
:math:`|x\rangle` is a :math:`n` qubit state.

This circuit implements :math:`F` for piecewise linear functions :math:`\hat{f}`.
In this case, the mapping :math:`F` can be approximately implemented using a Taylor expansion
and linearly controlled Pauli-Y rotations, see [1, 2] for more detail. This approximation
uses a ``rescaling_factor`` to determine the accuracy of the Taylor expansion.

In general, the function of interest :math:`f` is defined from some interval :math:`[a,b]`,
the ``domain`` to :math:`[c,d]`, the ``image``, instead of :math:`\{ 1, ..., N \}` to
:math:`[0, 1]`. Using an affine transformation we can rescale :math:`f` to :math:`\hat{f}`:

.. math::

    \hat{f}(x) = \frac{f(\phi(x)) - c}{d - c}

with

.. math::

    \phi(x) = a + \frac{b - a}{2^n - 1} x.

If :math:`f` is a piecewise linear function on :math:`m` intervals
:math:`[p_{i-1}, p_i], i \in \{1, ..., m\}` with slopes :math:`\alpha_i` and
offsets :math:`\beta_i` it can be written as

.. math::

    f(x) = \sum_{i=1}^m 1_{[p_{i-1}, p_i]}(x) (\alpha_i x + \beta_i)

where :math:`1_{[a, b]}` is an indication function that is 1 if the argument is in the interval
:math:`[a, b]` and otherwise 0. The breakpoints :math:`p_i` can be specified by the
``breakpoints`` argument.

References:

[1] Woerner, S., & Egger, D. J. (2018). Quantum Risk Analysis.
`arXiv:1806.06893 <http://arxiv.org/abs/1806.06893>`_

[2] Gacon, J., Zoufal, C., & Woerner, S. (2020). Quantum-Enhanced Simulation-Based Optimization.
`arXiv:2005.10780 <http://arxiv.org/abs/2005.10780>`_
z2.2zIUse the class qiskit.circuit.library.LinearAmplitudeFunctionGate instead.zin Qiskit 3.0)sinceadditional_msgremoval_timelinec	                  > [        US5      (       d  U/n[        US5      (       d  U/nUc  US   /nO+[        R                  " US   US   5      (       d	  US   /U-   n[        X#U5        [	        Xt5        X@l        XPl        X`l        Uu  pUu  p/ n/ n/ n[        U5       H=  u  nnUU	-
  X-
  -  SU-  S-
  -  nUU/-  nXU   X-
  -  SU-  S-
  -  /-  nXU   /-  nM?     [        R                  " [        U5      5      n[        R                  S-  SU-
  -  [        R                  " [        U5      5      -  n[        [        U5      5       HV  n[        R                  U-  UU   -  S-  X-
  -  UU'   UU==   [        R                  U-  UU   U-
  -  S-  X-
  -  -  ss'   MX     [        XSU-  SU-  US9n[        TU ]@  " UR"                  SU06  U R%                  UR'                  5       U R(                  5        g)	a  
Args:
    num_state_qubits: The number of qubits used to encode the variable :math:`x`.
    slope: The slope of the linear function. Can be a list of slopes if it is a piecewise
        linear function.
    offset: The offset of the linear function. Can be a list of offsets if it is a piecewise
        linear function.
    domain: The domain of the function as tuple :math:`(x_\min{}, x_\max{})`.
    image: The image of the function as tuple :math:`(f_\min{}, f_\max{})`.
    rescaling_factor: The rescaling factor to adjust the accuracy in the Taylor
        approximation.
    breakpoints: The breakpoints if the function is piecewise linear. If None, the function
        is not piecewise.
    name: Name of the circuit.
__len__Nr      r      )namer   )hasattrnpisclose_check_sizes_match_check_sorted_and_in_range_domain_image_rescaling_factor	enumeratezeroslenpionesranger   super__init__qregsappendto_gatequbits)selfnum_state_qubitsslopeoffsetdomainimagerescaling_factorbreakpointsr   abcdmapped_breakpointsmapped_slopemapped_offsetipointmapped_breakpointslope_anglesoffset_anglespwl_pauli_rotation	__class__s                         u/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/arithmetic/linear_amplitude_function.pyr$    LinearAmplitudeFunction.__init__O   s3   @ ui((GEvy))XF !!9+K::k!nfQi88%aykK75+6";7!1 !+.HAu!&qu 5<L9Lq9P Q#4"55
 1X/16F3F3JKLLLQi[(M / xxK 01	Q)9%9:RWWSEU=VVs;'(A ee&66aH1LPQPUVLO!(8 8M!<Lq<P QTU UYZY^ __ )
 ;!l2BADU\`
 	,22>>&..0$++>    c                    US-
  [         R                  S-  U R                  -  -   nUS[         R                  -  U R                  -  -  nX R                  S   U R                  S   -
  -  nX R                  S   -  nU$ a  Map the function value of the approximated :math:`\hat{f}` to :math:`f`.

Args:
    scaled_value: A function value from the Taylor expansion of :math:`\hat{f}(x)`.

Returns:
    The ``scaled_value`` mapped back to the domain of :math:`f`, by first inverting
    the transformation used for the Taylor approximation and then mapping back from
    :math:`[0, 1]` to the original domain.
g      ?r   r   r   r   )r   r    r   r   r)   scaled_valuevalues      r?   post_processing'LinearAmplitudeFunction.post_processing   sw     u$ruuqy43I3I'IIRUUT3333 	Q$++a.00QrA   )r   r   r   r   NF)r*   intr+   float | list[float]r,   rL   r-   tuple[float, float]r.   rM   r/   floatr0   list[float] | Noner   strreturnNonerE   rN   rQ   rN   )
__name__
__module____qualname____firstlineno____doc__r   r$   rG   __static_attributes____classcell__r>   s   @r?   r   r      s    2h b( #$*.L?L? #L? $	L?
 $L? #L?  L? (L? L? 
L?
L?\ rA   r   c                  l   ^  \ rS rSrSr   S                 SU 4S jjjrS rS	S jrSrU =r	$ )
LinearAmplitudeFunctionGate   ag  A circuit implementing a (piecewise) linear function on qubit amplitudes.

An amplitude function :math:`F` of a function :math:`f` is a mapping

.. math::

    F|x\rangle|0\rangle = \sqrt{1 - \hat{f}(x)} |x\rangle|0\rangle + \sqrt{\hat{f}(x)}
        |x\rangle|1\rangle.

for a function :math:`\hat{f}: \{ 0, ..., 2^n - 1 \} \rightarrow [0, 1]`, where
:math:`|x\rangle` is a :math:`n` qubit state.

This circuit implements :math:`F` for piecewise linear functions :math:`\hat{f}`.
In this case, the mapping :math:`F` can be approximately implemented using a Taylor expansion
and linearly controlled Pauli-Y rotations, see [1, 2] for more detail. This approximation
uses a ``rescaling_factor`` to determine the accuracy of the Taylor expansion.

In general, the function of interest :math:`f` is defined from some interval :math:`[a,b]`,
the ``domain`` to :math:`[c,d]`, the ``image``, instead of :math:`\{ 1, ..., N \}` to
:math:`[0, 1]`. Using an affine transformation we can rescale :math:`f` to :math:`\hat{f}`:

.. math::

    \hat{f}(x) = \frac{f(\phi(x)) - c}{d - c}

with

.. math::

    \phi(x) = a + \frac{b - a}{2^n - 1} x.

If :math:`f` is a piecewise linear function on :math:`m` intervals
:math:`[p_{i-1}, p_i], i \in \{1, ..., m\}` with slopes :math:`\alpha_i` and
offsets :math:`\beta_i` it can be written as

.. math::

    f(x) = \sum_{i=1}^m 1_{[p_{i-1}, p_i]}(x) (\alpha_i x + \beta_i)

where :math:`1_{[a, b]}` is an indication function that is 1 if the argument is in the interval
:math:`[a, b]` and otherwise 0. The breakpoints :math:`p_i` can be specified by the
``breakpoints`` argument.

References:

[1] Woerner, S., & Egger, D. J. (2018).
Quantum Risk Analysis.
`arXiv:1806.06893 <http://arxiv.org/abs/1806.06893>`_

[2] Gacon, J., Zoufal, C., & Woerner, S. (2020).
Quantum-Enhanced Simulation-Based Optimization.
`arXiv:2005.10780 <http://arxiv.org/abs/2005.10780>`_
c	                  > [        US5      (       d  U/n[        US5      (       d  U/nUc  US   /nO+[        R                  " US   US   5      (       d	  US   /U-   n[        X#U5        [	        Xt5        X l        X0l        X@l        XPl        X`l	        Xpl
        [        [        U5      S:  5      n	[        T
U ]9  SX-   S-   / US9  g)a  
Args:
    num_state_qubits: The number of qubits used to encode the variable :math:`x`.
    slope: The slope of the linear function. Can be a list of slopes if it is a piecewise
        linear function.
    offset: The offset of the linear function. Can be a list of offsets if it is a piecewise
        linear function.
    domain: The domain of the function as tuple :math:`(x_\min{}, x_\max{})`.
    image: The image of the function as tuple :math:`(f_\min{}, f_\max{})`.
    rescaling_factor: The rescaling factor to adjust the accuracy in the Taylor
        approximation.
    breakpoints: The breakpoints if the function is piecewise linear. If None, the function
        is not piecewise.
    label: A label for the gate.
r   Nr   r   LinFunction)label)r   r   r   r   r   r+   r,   r-   r.   r/   r0   rK   r   r#   r$   )r)   r*   r+   r,   r-   r.   r/   r0   ra   num_comparer>   s             r?   r$   $LinearAmplitudeFunctionGate.__init__   s    4 ui((GEvy))XF !!9+K::k!nfQi88%aykK75+6";7

 0&#k*Q./(8(F(JBV[\rA   c                   [        [        U R                  5      S:  5      nU R                  U-
  S-
  nU R                  u  p4U R
                  u  pV/ n/ n/ n	[        U R                  5       HN  u  pX-
  XC-
  -  SU-  S-
  -  nX|/-  nXR                  U
   XC-
  -  SU-  S-
  -  /-  nXR                  U
   /-  n	MP     [        R                  " [        U R                  5      5      n[        R                  S-  SU R                  -
  -  [        R                  " U5      -  n[        [        X5      5       Hh  u  n
u  nn[        R                  U R                  -  U-  S-  Xe-
  -  X'   X==   [        R                  U R                  -  UU-
  -  S-  Xe-
  -  -  ss'   Mj     [        X'SU-  SU-  5      n[!        UR                  5      U l        U R"                  R%                  UU R"                  R&                  5        g )Nr   r   r   )rK   r   r0   
num_qubitsr-   r.   r   r+   r,   r   r   r    r/   	ones_likezipr	   r   
definitionr&   r(   )r)   rb   r*   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   slope_ioffset_ir=   s                     r?   _define#LinearAmplitudeFunctionGate._define"  s   #d../!34??[81< {{zz!$"2"23HA!&qu 5<L9Lq9P Q"55
 ZZ]ae4;K8Ka8OPQQLkk!n--M 4 xxD$4$4 56	Q)>)>%>?",,|B\\&/L0P&Q"A" eed&;&;;gEIQUSLO(=(= =A NQR RVWV[ \\ 'R
 ?!l2BADU
 ));)F)FG14??3I3IJrA   c                    US-
  [         R                  S-  U R                  -  -   nUS[         R                  -  U R                  -  -  nX R                  S   U R                  S   -
  -  nX R                  S   -  nU$ rC   )r   r    r/   r.   rD   s      r?   rG   +LinearAmplitudeFunctionGate.post_processingF  sw     u$ruuqy43H3H'HHRUUT2222 	AA..ArA   )r0   rh   r-   r.   r,   r/   r+   rI   )r*   rK   r+   rL   r,   rL   r-   rM   r.   rM   r/   rN   r0   rO   ra   rP   rQ   rR   rS   )
rT   rU   rV   rW   rX   r$   rk   rG   rY   rZ   r[   s   @r?   r]   r]      s    4z #$*.1]1] #1] $	1]
 $1] #1]  1] (1] 1] 
1] 1]f"KH rA   r]   c                    U c  g [         R                  " [         R                  " U 5      S:  5      (       d  [        S5      eU S   US   :  d  U S   US   :  a  [        S5      eg )Nr   z&Breakpoints must be unique and sorted.r   z'Breakpoints must be included in domain.)r   alldiff
ValueError)r0   r-   s     r?   r   r   \  sg     66"''+&*++ABB1~q	![_vay%@BCC &ArA   c                    [        U 5      n[        U5      U:w  a  [        SU S[        U5       S35      eUb+  [        U5      U:w  a  [        SU S[        U5       S35      eg g )NzSize mismatch of slope (z) and offset (z).z) and breakpoints ()r   rs   )r+   r,   r0   sizes       r?   r   r   h  s{    u:D
6{d3D6F}TVWXX{t#*4&0CCDTCUUWX  $ rA   )rX   
__future__r   numpyr   qiskit.circuitr   r   qiskit.utils.deprecationr    piecewise_linear_pauli_rotationsr   r	   r   r]   r   r    rA   r?   <module>r|      sE    O "  / 3[n [|a$ aH	DrA   