§
    ¹³Ùgs?  ã                  óÐ   — d Z ddlmZ ddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ dZ G d„ de	¦  «        Zd„ Zd„ Zd„ ZdS )z(
Generic isometries from m to n qubits.
é    )ÚannotationsN)ÚCircuitError)ÚInstruction)ÚQuantumCircuit)ÚQuantumRegister)ÚQiskitError)Úis_isometry)Úisometryé   )ÚDiagonalGate)ÚUCGate)Ú	MCGupDiagg»½×Ùß|Û=c                  ór   ‡ — e Zd ZdZefdˆ fd„Zd„ Zddˆ fd„Zd„ Zd„ Z	d„ Z
d„ Zd„ Zd„ Zd„ Zd„ Zd„ Zˆ xZS )ÚIsometrya¦  Decomposition of arbitrary isometries from :math:`m` to :math:`n` qubits.

    In particular, this allows to decompose unitaries (m=n) and to do state preparation (:math:`m=0`).

    The decomposition is based on [1].

    References:
        1. Iten et al., Quantum circuits for isometries (2016).
           `Phys. Rev. A 93, 032318
           <https://journals.aps.org/pra/abstract/10.1103/PhysRevA.93.032318>`__.

    r
   ú
np.ndarrayÚnum_ancillas_zeroÚintÚnum_ancillas_dirtyÚepsilonÚfloatÚreturnÚNonec                óü  •— t          j        |t          ¬¦  «        }t          |j        ¦  «        dk    r!|                     |j        d         d¦  «        }|| _        || _        || _        d| _	        || _
        t          j        |j        d         ¦  «        }t          j        |j        d         ¦  «        }|                     ¦   «         r|dk     rt          d¦  «        ‚|                     ¦   «         r|dk     rt          d¦  «        ‚||k    rt          d¦  «        ‚t          || j
        ¦  «        st          d¦  «        ‚t!          |¦  «        |z   |z   }t#          ¦   «                              d	|d|g¦  «         dS )
a.  
        Args:
            isometry: An isometry from :math:`m` to :math`n` qubits, i.e., a complex
                ``np.ndarray`` of dimension :math:`2^n \times 2^m` with orthonormal columns (given
                in the computational basis specified by the order of the ancillas
                and the input qubits, where the ancillas are considered to be more
                significant than the input qubits).
            num_ancillas_zero: Number of additional ancillas that start in the state :math:`|0\rangle`
                (the :math:`n-m` ancillas required for providing the output of the isometry are
                not accounted for here).
            num_ancillas_dirty: Number of additional ancillas that start in an arbitrary state.
            epsilon: Error tolerance of calculations.
        )Údtyper   r   NzDThe number of rows of the isometry is not a non negative power of 2.zGThe number of columns of the isometry is not a non negative power of 2.zNThe input matrix has more columns than rows and hence it can't be an isometry.zMThe input matrix has non orthonormal columns and hence it is not an isometry.r
   )ÚnpÚarrayÚcomplexÚlenÚshapeÚreshapeÚiso_datar   r   Ú_inverseÚ_epsilonÚmathÚlog2Ú
is_integerr   r	   r   ÚsuperÚ__init__)	Úselfr
   r   r   r   ÚnÚmÚ
num_qubitsÚ	__class__s	           €úg/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/library/generalized_gates/isometry.pyr(   zIsometry.__init__>   s…  ø€ õ* ”8˜H­GÐ4Ñ4Ô4ˆõ ˆxŒ~ÑÔ !Ò#Ð#Ø×'Ò'¨¬°qÔ(9¸1Ñ=Ô=ˆHà ˆŒà!2ˆÔØ"4ˆÔØˆŒØˆŒõ ŒI�h”n QÔ'Ñ(Ô(ˆÝŒI�h”n QÔ'Ñ(Ô(ˆØ�|Š|‰~Œ~ð 	  Q¢ ÝØVñô ð ð �|Š|‰~Œ~ð 	  Q¢ ÝØYñô ð ð ˆqŠ5ˆ5ÝØ`ñô ð õ ˜8 T¤]Ñ3Ô3ð 	ÝØ_ñô ð õ ˜‘V”VÐ/Ñ/Ð2DÑDˆ
å‰Œ×Ò˜ Z°°X°JÑ?Ô?Ð?Ð?Ð?ó    c                óì   — |                       ¦   «         }|                     ¦   «         }t          | j        d¦  «        }t	          |d¬¦  «        }|                     ||d d …         ¦  «         || _        d S )NÚqr
   ©Úname)Úinv_gateÚinverser   r,   r   ÚappendÚ
definition)r)   Úgater1   Úiso_circuits       r.   Ú_definezIsometry._definex   sj   € ð �}Š}‰ŒˆØ�|Š|‰~Œ~ˆÝ˜DœO¨SÑ1Ô1ˆÝ$ Q¨ZÐ8Ñ8Ô8ˆØ×Ò˜4  1 1 1¤Ñ&Ô&Ð&Ø%ˆŒˆˆr/   FÚ	annotatedÚboolc                ót   •— g | _         t          ¦   «                              |¬¦  «        }| j        g| _         |S )N)r;   )Úparamsr'   r5   r!   )r)   r;   Úinvr-   s      €r.   r5   zIsometry.inverseƒ   s1   ø€ ØˆŒÝ‰gŒg�oŠo¨	ˆoÑ2Ô2ˆØ”}�oˆŒØˆ
r/   c                óª  — t          | j        d¦  «        }t          |d¬¦  «        }|                      |¦  «        \  }}}}| j                             t          ¦  «        }g }t          t          j	        | j        j
        d         ¦  «        ¦  «        }	t          d|	z  ¦  «        D ]I}
|                      |||||
¦  «        \  }}|                     ||
df         ¦  «         |dd…dd…f         }ŒJt          |¦  «        dk    rQt          j        || j        ¦  «        s7t%          t'          j        |¦  «        ¦  «        }|                     ||¦  «         |S )z¼
        Call to create a circuit with gates that take the desired isometry to the first 2^m columns
         of the 2^n*2^n identity matrix (see https://arxiv.org/abs/1501.06911)
        r1   Úisometry_to_uncomputer2   r   é   r   N)r   r,   r   Ú_define_qubit_roler!   Úastyper   r   r$   r%   r   ÚrangeÚ_decompose_columnr6   r   Úisometry_rsÚ#diag_is_identity_up_to_global_phaser#   r   r   Úconj)r)   r1   ÚcircuitÚq_inputÚq_ancillas_for_outputÚq_ancillas_zeroÚq_ancillas_dirtyÚremaining_isometryÚdiagr+   Úcolumn_indexÚdiagonals               r.   Ú_gates_to_uncomputezIsometry._gates_to_uncompute‰   s[  € õ
 ˜DœO¨SÑ1Ô1ˆÝ  Ð)@ÐAÑAÔAˆð ×#Ò# AÑ&Ô&ñ	
ØØ!ØØð "œ]×1Ò1µ'Ñ:Ô:ÐØˆÝ•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆõ
 " ! Q¡$™KœKð 	;ð 	;ˆLØ'+×'=Ò'=Ø˜˜DÐ"4°lñ(ô (Ñ$Ð ð �KŠKÐ*¨<¸¨?Ô;Ñ<Ô<Ð<à!3°A°A°A°q°r°r°EÔ!:ÐÐÝˆt‰9Œ9�qŠ=ˆ=¥Ô!PØ�$”-ñ"
ô "
ˆ=õ $¥B¤G¨D¡M¤MÑ2Ô2ˆHØ�NŠN˜8 WÑ-Ô-Ð-Øˆr/   c           	     óÊ   — t          t          j        | j        j        d         ¦  «        ¦  «        }t          |¦  «        D ]}|                      ||||||¦  «        \  }}Œ ||fS )z@
        Decomposes the column with index column_index.
        r   )r   r$   r%   r!   r   rE   Ú_disentangle)r)   rJ   r1   rP   rO   rQ   r*   Úss           r.   rF   zIsometry._decompose_column®   sr   € õ •”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆÝ�q‘”ð 	ð 	ˆAØ'+×'8Ò'8Ø˜˜DÐ"4°lÀAñ(ô (Ñ$Ð  ð " 4Ð'Ð'r/   c                óÐ  ‡— |}d}|}	t          t          j        | j        j        d         ¦  «        ¦  «        }
dt          j        ||dz   ¦  «        z  d|z  z  t          j        ||dz   ¦  «        z   }dt          j        ||dz   ¦  «        z  dz   d|z  z  t          j        ||dz   ¦  «        z   }|
|z
  dz
  Št          j        ||¦  «        dk    �r+t          j        ||dz   ¦  «        dk    �rt          j
        |	||f         ¦  «        | j        k    rét          j        |	||f         |	||f         gd| j        ¦  «        }ˆfd„t          t          ||
¦  «        ¦  «        D ¦   «         }|                      ||||‰¦  «        }t          j        |	|‰|¦  «        }	t          j        |¦  «                             t&          d¬¦  «        }t          j        |	|‰gz   |¦  «        }	t          j        ||‰gz   ||
¦  «        }|                      |	||¦  «        }t          j        || j        ¦  «        s¶t1          t3          ‰¦  «        ¦  «        }|                      ||||‰¦  «        }t          j        |¦  «                             t&          d¬¦  «        }t          j        ||¦  «        }t          j        |	t;          |¦  «        |¦  «        }	t          j        ||‰gz   ||
¦  «        }|	|fS )z‘
        Disentangle the s-th significant qubit (starting with s = 0) into the zero or the one state
        (dependent on column_index)
        r   rB   r   c                ó2   •— g | ]\  }}|d k    ¯|‰k    ¯|‘ŒS ©r   © )Ú.0ÚiÚxÚtarget_labels      €r.   ú
<listcomp>z)Isometry._disentangle.<locals>.<listcomp>Ô   s:   ø€ ð ð ð á�A�qØ˜’6�6˜a <Ò/Ð/ð à/Ð/Ð/r/   F)Úcopy)r   r$   r%   r!   r   rG   ÚaÚbÚk_sr   Úabsr#   Úreverse_qubit_stateÚ	enumerateÚ_get_binary_rep_as_listÚ_append_mcg_up_to_diagonalÚapply_multi_controlled_gaterI   rD   r   Úapply_diagonal_gateÚapply_diagonal_gate_to_diagÚ_find_squs_for_disentanglingÚ"ucg_is_identity_up_to_global_phaseÚlistrE   Ú_append_ucg_up_to_diagonalÚmerge_ucgate_and_diagÚ	apply_ucgr   )r)   rJ   r1   rP   rO   rQ   rV   ÚkÚk_primeÚvr*   Úindex1Úindex2r8   Úcontrol_labelsÚdiagonal_mcgÚdiag_mcg_inverseÚsingle_qubit_gatesÚdiagonal_ucgÚdiagonal_ucg_inverser^   s                       @r.   rU   zIsometry._disentangle¹   s  ø€ ð ˆð ˆØˆÝ•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆð •[”] 1 a¨!¡eÑ,Ô,Ñ,¨q°!©tÑ3µk´mÀAÀqÈ1ÁuÑ6MÔ6MÑMˆØ•k”m A q¨1¡uÑ-Ô-Ñ-°Ñ1°Q¸±TÑ9½K¼MÈ!ÈQÐQRÉUÑ<SÔ<SÑSˆØ˜1‘u˜q‘yˆõ ŒO˜A˜qÑ!Ô! QÒ&Ñ&Ý”˜a  Q¡Ñ'Ô'¨1Ò,Ñ,Ý”�q˜ ˜Ô)Ñ*Ô*¨T¬]Ò:Ð:õ Ô2Ø�6˜7�?Ô# Q v¨w Ô%7Ð8¸!¸T¼]ñô ˆDðð ð ð å%Õ&=¸aÀÑ&CÔ&CÑDÔDðñ ô ˆNð
  ×:Ò:Ø˜˜D .°,ñô ˆLõ Ô7¸¸>È<ÐY]Ñ^Ô^ˆAå!œw |Ñ4Ô4×;Ò;½GÈ%Ð;ÑPÔPÐÝÔ/Ø�> \ NÑ2Ð4Dñô ˆAõ Ô:Ø�n¨ ~Ñ5Ð7GÈñô ˆDð "×>Ò>¸qÀ!ÀQÑGÔGÐÝÔ=Ð>PÐRVÔR_Ñ`Ô`ð 	Ý!¥%¨Ñ"5Ô"5Ñ6Ô6ˆNØ×:Ò:Ø˜Ð.°Àñô ˆLõ $&¤7¨<Ñ#8Ô#8×#?Ò#?ÅÈeÐ#?Ñ#TÔ#TÐ Ý!,Ô!BØ"Ð$8ñ"ô "Ðõ Ô% a­¨^Ñ)<Ô)<Ð>PÑQÔQˆAåÔ:Ø�n¨ ~Ñ5Ð7KÈQñô ˆDð �$ˆwˆr/   c                ó    — t          j        |||| j        t          t	          j        | j        j        d         ¦  «        ¦  «        ¬¦  «        }|S )Nr   )r*   )rG   Úfind_squs_for_disentanglingr#   r   r$   r%   r!   r   )r)   rt   rr   rV   Úress        r.   rl   z%Isometry._find_squs_for_disentangling  sI   € ÝÔ5Øˆq�!�T”]¥c­$¬)°D´MÔ4GÈÔ4JÑ*KÔ*KÑ&LÔ&Lð
ñ 
ô 
ˆð ˆ
r/   c                óŒ  — |                       |¦  «        \  }}}}	t          t          j        | j        j        d         ¦  «        ¦  «        }
||z   }t          t          |||
¦  «        ¦  «        }t          |g||
¦  «        d         }t          |d¬¦  «        }| 	                    ||g|z   ¦  «         | 
                    ¦   «         S )Nr   T)Úup_to_diagonal)rC   r   r$   r%   r!   r   Ú_reverse_qubit_oderÚ_get_qubits_by_labelr   r6   Ú_get_diagonal)r)   Úcircr1   rz   rw   r^   rK   rL   rM   rN   r*   ÚqubitsÚcontrol_qubitsÚtarget_qubitÚucgs                  r.   ro   z#Isometry._append_ucg_up_to_diagonal
  sÈ   € ð ×#Ò# AÑ&Ô&ñ	
ØØ!ØØå•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆØÐ0Ñ0ˆõ -Õ-AÀ.ÐRXÐZ[Ñ-\Ô-\Ñ]Ô]ˆÝ+¨\¨N¸FÀAÑFÔFÀqÔIˆÝÐ'¸Ð=Ñ=Ô=ˆØ�Š�C˜,˜¨.Ñ8Ñ9Ô9Ð9Ø× Ò Ñ"Ô"Ð"r/   c                óf  ‡‡— |                       |¦  «        \  }}}}	t          t          j        | j        j        d         ¦  «        ¦  «        }
||z   }t          t          ‰||
¦  «        ¦  «        }t          ‰g||
¦  «        d         }ˆˆfd„t          |
¦  «        D ¦   «         }t          t          |||
¦  «        ¦  «        |	z   }t          |t          |¦  «        t          |¦  «        t          |¦  «        ¦  «        }|                     ||g|z   |z   |z   ¦  «         |                     ¦   «         S )Nr   c                ó$   •— g | ]}|‰‰gz   v¯
|‘ŒS rZ   rZ   )r[   r\   rw   r^   s     €€r.   r_   z7Isometry._append_mcg_up_to_diagonal.<locals>.<listcomp>-  s,   ø€ Ð`Ð`Ð` a°qÀÐR^ÐQ_Ñ@_Ð7_Ð7_ Ð7_Ð7_Ð7_r/   )rC   r   r$   r%   r!   r   r‚   rƒ   rE   r   r   r6   r„   )r)   r…   r1   r8   rw   r^   rK   rL   rM   rN   r*   r†   r‡   rˆ   Úancilla_dirty_labelsÚancillas_dirtyÚmcg_up_to_diags       ``           r.   rh   z#Isometry._append_mcg_up_to_diagonal   sJ  øø€ ð ×#Ò# AÑ&Ô&ñ	
ØØ!ØØå•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆØÐ0Ñ0ˆÝ,Õ-AÀ.ÐRXÐZ[Ñ-\Ô-\Ñ]Ô]ˆÝ+¨\¨N¸FÀAÑFÔFÀqÔIˆð  aÐ`Ð`Ð`Ð`­5°©8¬8Ð`Ñ`Ô`ÐåÕ 4Ð5IÈ6ÐSTÑ UÔ UÑVÔVØñð 	õ #Ø•#�nÑ%Ô%¥s¨?Ñ';Ô';½SÀÑ=PÔ=Pñ
ô 
ˆð 	�ŠØ˜\˜N¨^Ñ;¸oÑMÐP^Ñ^ñ	
ô 	
ð 	
ð ×+Ò+Ñ-Ô-Ð-r/   c                óB  — t          t          j        | j        j        d         ¦  «        ¦  «        }t          t          j        | j        j        d         ¦  «        ¦  «        }|d |…         }|||…         }|||| j        z   …         }||| j        z   d …         }||||fS )Nr   r   )r   r$   r%   r!   r   r   )r)   r1   r*   r+   rK   rL   rM   rN   s           r.   rC   zIsometry._define_qubit_role:  s¢   € å•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆÝ•”	˜$œ-Ô-¨aÔ0Ñ1Ô1Ñ2Ô2ˆð �B�Q�B”%ˆØ ! ! A #¤ÐØ˜A  DÔ$:Ñ :Ð:Ô;ˆØ˜Q Ô!7Ñ7Ð9Ð9Ô:ÐØÐ-¨Ð@PÐPÐPr/   c                óÄ   — t          |t          j        ¦  «        r|S t          |t          t          f¦  «        r|S t          dt          |¦  «        › d| j        › �¦  «        ‚)z(Isometry parameter has to be an ndarray.zinvalid param type z
 for gate )Ú
isinstancer   Úndarrayrn   r   r   Útyper3   )r)   Ú	parameters     r.   Úvalidate_parameterzIsometry.validate_parameterF  sb   € å�i¥¤Ñ,Ô,ð 	ØÐÝ�i¥$­ Ñ-Ô-ð 	]ØÐåÐ[µT¸)±_´_Ð[Ð[ÐPTÔPYÐ[Ð[Ñ\Ô\Ð\r/   c                óx   — | j         €-|                      ¦   «         }|                     ¦   «         | _         | j         S )z"Return the adjoint of the unitary.)r"   rS   Úto_instruction)r)   r9   s     r.   r4   zIsometry.inv_gateO  s8   € àŒ=Ð ð ×2Ò2Ñ4Ô4ˆKà'×6Ò6Ñ8Ô8ˆDŒMØŒ}Ðr/   )
r
   r   r   r   r   r   r   r   r   r   )F)r;   r<   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_EPSr(   r:   r5   rS   rF   rU   rl   ro   rh   rC   r•   r4   Ú__classcell__)r-   s   @r.   r   r   )   s  ø€ € € € € ðð ð2 ð8@ð 8@ð 8@ð 8@ð 8@ð 8@ð 8@ðt	&ð 	&ð 	&ðð ð ð ð ð ð ð#ð #ð #ðJ	(ð 	(ð 	(ðEð Eð EðTð ð ð#ð #ð #ð,.ð .ð .ð4
Qð 
Qð 
Qð]ð ]ð ]ðð ð ð ð ð ð r/   r   c                ó$   ‡‡— ˆˆfd„| D ¦   «         S )Nc                ó,   •— g | ]}‰‰|z
  d z
           ‘ŒS rY   rZ   )r[   Úlabelr,   r†   s     €€r.   r_   z(_get_qubits_by_label.<locals>.<listcomp>b  s(   ø€ Ð?Ð?Ð?¨uˆF�: Ñ%¨Ñ)Ô*Ð?Ð?Ð?r/   rZ   )Úlabelsr†   r,   s    ``r.   rƒ   rƒ   a  s!   øø€ Ø?Ð?Ð?Ð?Ð?¸Ð?Ñ?Ô?Ð?r/   c                ó:   — t          t          | ¦  «        ¦  «        S ©N)rn   Úreversed)r†   s    r.   r‚   r‚   e  s   € Ý•˜Ñ Ô Ñ!Ô!Ð!r/   c                óÂ   — t          j        | ¦  «                             |¦  «        }g }|D ])}|D ]$}|                     t	          |¦  «        ¦  «         Œ%Œ*|| d …         S r£   )r   Úbinary_reprÚzfillr6   r   )r*   Ú
num_digitsÚbinary_stringÚbinaryÚlineÚcs         r.   rg   rg   l  ss   € Ý”N 1Ñ%Ô%×+Ò+¨JÑ7Ô7€MØ€FØð "ð "ˆØð 	"ð 	"ˆAØ�MŠM�#˜a™&œ&Ñ!Ô!Ð!Ð!ð	"à�:�+�,�,ÔÐr/   ) r›   Ú
__future__r   r$   Únumpyr   Úqiskit.circuit.exceptionsr   Úqiskit.circuit.instructionr   Úqiskit.circuit.quantumcircuitr   Úqiskit.circuit.quantumregisterr   Úqiskit.exceptionsr   Ú(qiskit.quantum_info.operators.predicatesr	   Úqiskit._accelerater
   rG   rR   r   Úucr   Úmcg_up_to_diagonalr   rœ   r   rƒ   r‚   rg   rZ   r/   r.   ú<module>r¸      s^  ðð$ð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø :Ð :Ð :Ð :Ð :Ð :Ø )Ð )Ð )Ð )Ð )Ð )Ø @Ð @Ð @Ð @Ð @Ð @Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6à "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ø )Ð )Ð )Ð )Ð )Ð )à€ðnð nð nð nð nˆ{ñ nô nð nðp	@ð @ð @ð"ð "ð "ð ð  ð  ð  ð  r/   