§
    OŠtj€  ã                   óþ   — d 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mZ ddlmZ ddlmZ ddlmZ  G d„ de¦  «        Z G d„ de¦  «        Zd„ Zd„ Z d„ Z!d„ Z"dS )z�Shor's algorithm and helper functions.

Todo:

* Get the CMod gate working again using the new Gate API.
* Fix everything.
* Update docstrings and reformat.
é    N)ÚMul)ÚS)Úlog)Úsqrt)Úigcd)Úcontinued_fraction_periodic)Ú
variations)ÚGate)ÚQubitÚmeasure_partial_oneshot)Úqapply)ÚQFT)ÚQuantumErrorc                   ó   — e Zd ZdS )ÚOrderFindingExceptionN)Ú__name__Ú
__module__Ú__qualname__© ó    úX/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/physics/quantum/shor.pyr   r      s   € € € € € Ø€Dr   r   c                   óp   — e Zd ZdZed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Z	d„ Z
dS )ÚCModzÍA controlled mod gate.

    This is black box controlled Mod function for use by shor's algorithm.
    TODO: implement a decompose property that returns how to do this in terms
    of elementary gates
    c                 ó    — t          d¦  «        ‚)Nz%The CMod gate has not been completed.)ÚNotImplementedError)ÚclsÚargss     r   Ú
_eval_argszCMod._eval_args(   s   € õ
 "Ð"IÑJÔJÐJr   c                 ó   — | j         d         S )z4Size of 1/2 input register.  First 1/2 holds output.r   ©Úlabel©Úselfs    r   ÚtzCMod.t/   ó   € ð Œz˜!Œ}Ðr   c                 ó   — | j         d         S )z$Base of the controlled mod function.é   r    r"   s    r   ÚazCMod.a4   r%   r   c                 ó   — | j         d         S )z1N is the type of modular arithmetic we are doing.é   r    r"   s    r   ÚNzCMod.N9   r%   r   c                 óŠ  — d}d}t          | j        ¦  «        D ]}|||| j        |z            z  z  }|dz  }Œt          | j        |z  | j        z  ¦  «        }t          |j        d         d| j        …         ¦  «        }t          t          | j        ¦  «        ¦  «        D ]}|                     ||z	  dz  ¦  «         Œt          |Ž S )zÔ
            This directly calculates the controlled mod of the second half of
            the register and puts it in the second
            This will look pretty when we get Tensor Symbolically working
        r'   r   r*   N)
Úranger$   Úintr(   r+   Úlistr   ÚreversedÚappendr   )r#   ÚqubitsÚoptionsÚnÚkÚiÚoutÚoutarrays           r   Ú_apply_operator_QubitzCMod._apply_operator_Qubit>   sÏ   € ð ˆØˆå�t”v‘”ð 	ð 	ˆAØ��6˜$œ& 1™*Ô%Ñ%Ñ%ˆAØ�‰FˆAˆAõ �$”&˜!‘)˜dœfÑ$Ñ%Ô%ˆõ ˜œ Aœ w¨¬ wÔ/Ñ0Ô0ˆõ �% ¤™-œ-Ñ(Ô(ð 	,ð 	,ˆAØ�OŠO˜S A™X¨™NÑ+Ô+Ð+Ð+å�hÐÐr   N)r   r   r   Ú__doc__Úclassmethodr   Úpropertyr$   r(   r+   r9   r   r   r   r   r       sœ   € € € € € ðð ð ðKð Kñ „[ðKð ðð ñ „Xðð ðð ñ „Xðð ðð ñ „Xðð ð  ð  ð  ð  r   r   c                 ó6  — t          j        | dz
  ¦  «        dz   }t          | |¦  «        dk    rt          | |¦  «        S t          || ¦  «        }|dz  dk    rt	          | ¦  «         t          ||dz  z  dz
  | ¦  «        t          ||dz  z  dz   | ¦  «        f}|S )aã  This function implements Shor's factoring algorithm on the Integer N

    The algorithm starts by picking a random number (a) and seeing if it is
    coprime with N. If it is not, then the gcd of the two numbers is a factor
    and we are done. Otherwise, it begins the period_finding subroutine which
    finds the period of a in modulo N arithmetic. This period, if even, can
    be used to calculate factors by taking a**(r/2)-1 and a**(r/2)+1.
    These values are returned.
    r*   r'   )ÚrandomÚ	randranger   Úperiod_findÚshor)r+   r(   ÚrÚanswers       r   rA   rA   X   sž   € õ 	Ô˜˜Q™ÑÔ !Ñ#€AÝˆAˆq�z„z�Q‚€Ý�A�q‰zŒzÐÝ�A�qÑÔ€AØˆ1�u�‚z€zÝˆQ‰ŒˆÝ�1�q˜‘s‘8˜a‘< Ñ#Ô#¥T¨!¨a°©c©(°Q©,¸Ñ%:Ô%:Ð;€FØ€Mr   c                 óF   — t          | |¦  «        }t          ||¦  «        }|S )N)Úcontinued_fractionÚratioize)ÚxÚyr+   ÚfractionÚtotals        r   ÚgetrrK   l   s%   € Ý! ! QÑ'Ô'€Hå�X˜qÑ!Ô!€EØ€Lr   c                 óª   — | d         |k    rt           j        S t          | ¦  «        dk    r| d         S | d         t          | dd …         |¦  «        z   S )Nr   r'   )r   ÚZeroÚlenrF   )r/   r+   s     r   rF   rF   s   sO   € ØˆA„w�‚{€{ÝŒvˆÝ
ˆ4�y„y�A‚~€~Ø�AŒwˆØ�Œ7•X˜d 1 2 2œh¨Ñ*Ô*Ñ*Ð*r   c           	      ó4  — d}t          dt          j        t          |d¦  «        ¦  «        z  ¦  «        }d„ t	          |¦  «        D ¦   «         }dt          d|z  ¦  «        z  }d}t          t	          d¦  «        |d¬¦  «        D ] }t          |¦  «        |z   }|t          |Ž z   }Œ!||z   	                    ¦   «         }	t          || |¦  «        |	z  }	t          |	¦  «        }	t	          |¦  «        D ]}
t          |	|
¦  «        }	Œt          t          ||dz  ¦  «                             ¦   «         |	z  d¬¦  «        }	t	          |¦  «        D ]}
t          |	|
|z   ¦  «        }	Œt          |	t          ¦  «        r|	}n;t          |	t           ¦  «        r|	j        d	         }n|	j        d	         j        d	         }d}d}t	          t%          |¦  «        dz  ¦  «        D ]}
||||
|z            z  z  }|dz  }Œ|dk    rt'          d
|z  ¦  «        ‚t)          |d|z  |¦  «        }|S )a0  Finds the period of a in modulo N arithmetic

    This is quantum part of Shor's algorithm. It takes two registers,
    puts first in superposition of states with Hadamards so: ``|k>|0>``
    with k being all possible choices. It then does a controlled mod and
    a QFT to determine the order of a.
    g      à?r*   c                 ó   — g | ]}d ‘ŒS )r   r   )Ú.0rG   s     r   ú
<listcomp>zperiod_find.<locals>.<listcomp>‡   s   € Ð!Ð!Ð!�1ˆQÐ!Ð!Ð!r   r'   r   T)Ú
repetition)ÚfloatingPointéÿÿÿÿz/Order finder returned 0. Happens with chance %f)r.   ÚmathÚceilr   r-   r   r	   r/   r   Úexpandr   r   r   r   Ú	decomposeÚ
isinstancer   r   rN   r   rK   )r(   r+   Úepsilonr$   ÚstartÚfactorr2   ÚarrÚ	qbitArrayÚcircuitr6   Úregisterr4   rC   Úgs                  r   r@   r@   {   s8  € ð €GåˆA�dŒi�˜A˜q™	œ	Ñ"Ô"Ñ"Ñ#Ô#€Aà!Ð!�˜a™œÐ!Ñ!Ô!€Eà�t�A�q‘D‰zŒz‰\€FØ€FÝ�% ™(œ( A°$Ð7Ñ7Ô7ð ,ð ,ˆÝ˜‘I”I Ñ%ˆ	Ø�% Ð+Ñ+ˆˆØ�f‰}×$Ò$Ñ&Ô&€Gõ �1�a˜‰mŒm˜GÑ#€Gõ �W‰oŒo€GÝ�1‰XŒXð 6ð 6ˆÝ)¨'°1Ñ5Ô5ˆˆõ •S˜˜A˜a™C‘[”[×*Ò*Ñ,Ô,¨WÑ4ÀDÐIÑIÔI€GÝ�1‰XŒXð :ð :ˆÝ)¨'°1°q±5Ñ9Ô9ˆˆÝ�'�5Ñ!Ô!ð -ØˆˆÝ	�G�SÑ	!Ô	!ð -Ø”< Ô#ˆˆà”< Ô#Ô(¨Ô,ˆà	€AØ€FÝ•3�x‘=”= ‘?Ñ#Ô#ð ð ˆØ�!�H˜Q ™U”OÑ#Ñ#ˆØ�‰FˆˆØ�‚{€{Ý#Ø=ÀÑGñIô Ið 	Iõ 	ˆV�Q˜‘T˜1ÑÔ€AØ€Hr   )#r:   rV   r>   Úsympy.core.mulr   Úsympy.core.singletonr   Ú&sympy.functions.elementary.exponentialr   Ú(sympy.functions.elementary.miscellaneousr   Úsympy.core.intfuncr   Úsympy.ntheoryr   rE   Úsympy.utilities.iterablesr	   Úsympy.physics.quantum.gater
   Úsympy.physics.quantum.qubitr   r   Úsympy.physics.quantum.qapplyr   Úsympy.physics.quantum.qftr   Úsympy.physics.quantum.qexprr   r   r   rA   rK   rF   r@   r   r   r   ú<module>ro      sœ  ððð ð €€€Ø €€€à Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø #Ð #Ð #Ð #Ð #Ð #Ø KÐ KÐ KÐ KÐ KÐ KØ 0Ð 0Ð 0Ð 0Ð 0Ð 0à +Ð +Ð +Ð +Ð +Ð +Ø FÐ FÐ FÐ FÐ FÐ FÐ FÐ FØ /Ð /Ð /Ð /Ð /Ð /Ø )Ð )Ð )Ð )Ð )Ð )Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4ð	ð 	ð 	ð 	ð 	˜Lñ 	ô 	ð 	ð5 ð 5 ð 5 ð 5 ð 5 ˆ4ñ 5 ô 5 ð 5 ðpð ð ð(ð ð ð+ð +ð +ð2ð 2ð 2ð 2ð 2r   