U
    ZÊ¹j€  ã                   @   sì   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„ deƒZG dd„ deƒZdd„ Zdd„ Z dd„ Z!d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                   @   s   e Zd ZdS )ÚOrderFindingExceptionN)Ú__name__Ú
__module__Ú__qualname__© r   r   úY/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/physics/quantum/shor.pyr      s   r   c                   @   sH   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZedd	„ ƒZ	d
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                 C   s   t dƒ‚d S )Nz%The CMod gate has not been completed.)ÚNotImplementedError)ÚclsÚargsr   r   r   Ú
_eval_args(   s    zCMod._eval_argsc                 C   s
   | j d S )z4Size of 1/2 input register.  First 1/2 holds output.r   ©Úlabel©Úselfr   r   r   Út/   s    zCMod.tc                 C   s
   | j d S )z$Base of the controlled mod function.é   r   r   r   r   r   Úa4   s    zCMod.ac                 C   s
   | j d S )z1N is the type of modular arithmetic we are doing.é   r   r   r   r   r   ÚN9   s    zCMod.Nc                 K   s�   d}d}t | jƒD ]"}|||| j|   7 }|d9 }qt| j| | j ƒ}t|jd d| j… ƒ}tt | jƒƒD ]}| ||? d@ ¡ qpt	|Ž 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ÚoutZoutarrayr   r   r   Ú_apply_operator_Qubit>   s    
zCMod._apply_operator_QubitN)r   r   r   Ú__doc__Úclassmethodr   Úpropertyr   r    r"   r.   r   r   r   r   r       s   



r   c                 C   sx   t  | d ¡d }t| |ƒdkr*t| |ƒS t|| ƒ}|d dkrHt| ƒ t||d  d | ƒt||d  d | ƒ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Úanswerr   r   r   r5   X   s    


,r5   c                 C   s   t | |ƒ}t||ƒ}|S )N)Úcontinued_fractionÚratioize)ÚxÚyr"   ZfractionÚtotalr   r   r   Úgetrl   s    

r=   c                 C   s@   | d |krt jS t| ƒdkr&| d S | d t| dd … |ƒ S )Nr   r   )r   ZZeroÚlenr9   )r%   r"   r   r   r   r9   s   s
    r9   c                 C   s†  d}t dt t|dƒ¡ ƒ}dd„ t|ƒD ƒ}dtd| ƒ }d}ttdƒ|dd�D ]}t|ƒ| }|t|Ž  }qT||  	¡ }	t
|| |ƒ|	 }	t|	ƒ}	t|ƒD ]}
t|	|
ƒ}	qžtt||d ƒ ¡ |	 dd	�}	t|ƒD ]}
t|	|
| ƒ}	qÔt|	tƒrø|	}n(t|	tƒ�r|	jd
 }n|	jd
 jd
 }d}d}tt|ƒd ƒD ]"}
||||
|   7 }|d> }�q8|dk�rrtd| ƒ‚t|d| |ƒ}|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                 S   s   g | ]}d ‘qS )r   r   )Ú.0r:   r   r   r   Ú
<listcomp>‡   s     zperiod_find.<locals>.<listcomp>r   r   T)Z
repetition)ZfloatingPointéÿÿÿÿz/Order finder returned 0. Happens with chance %f)r$   ÚmathÚceilr   r#   r   r   r%   r
   Úexpandr   r   r   r   Z	decomposeÚ
isinstancer   r   r>   r   r=   )r    r"   Úepsilonr   ÚstartÚfactorr(   ZarrZ	qbitArrayZcircuitr,   Úregisterr*   r7   Úgr   r   r   r4   {   s@    

ÿr4   )#r/   rB   r2   Zsympy.core.mulr   Zsympy.core.singletonr   Z&sympy.functions.elementary.exponentialr   Z(sympy.functions.elementary.miscellaneousr   Zsympy.core.intfuncr   Zsympy.ntheoryr   r8   Zsympy.utilities.iterablesr   Zsympy.physics.quantum.gater	   Zsympy.physics.quantum.qubitr
   r   Zsympy.physics.quantum.qapplyr   Zsympy.physics.quantum.qftr   Zsympy.physics.quantum.qexprr   r   r   r5   r=   r9   r4   r   r   r   r   Ú<module>   s(   	8