U
    	-e                     @   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 )zShor'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   [/var/www/html/Darija-Ai-Train/env/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 )CModzA 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"   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|	|
}	qtt||d  |	 dd	}	t|D ]}
t|	|
| }	qt|	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floatingPointz/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/   rC   r2   Zsympy.core.mulr   Zsympy.core.singletonr   Z&sympy.functions.elementary.exponentialr   Z(sympy.functions.elementary.miscellaneousr   Zsympy.core.numbersr   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