ó
¡¼™\c           @  sJ  d  Z  d d l m Z m Z d d l Z d d l Z d d l m Z m Z d d l m	 Z	 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 d e f d „  ƒ  YZ d e f d „  ƒ  YZ  d „  Z! d „  Z" d „  Z# d „  Z$ d S(   sê   Shor's algorithm and helper functions.

Todo:

* Get the CMod gate working again using the new Gate API.
* Fix everything.
* Update docstrings and reformat.
* Remove print statements. We may want to think about a better API for this.
iÿÿÿÿ(   t   print_functiont   divisionN(   t   Mult   S(   t   logt   sqrt(   t   igcd(   t   range(   t   continued_fraction_periodic(   t
   variations(   t   Gate(   t   Qubitt   measure_partial_oneshot(   t   qapply(   t   QFT(   t   QuantumErrort   OrderFindingExceptionc           B  s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyR      s   t   CModc           B  sS   e  Z d  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z	 RS(   sÌ   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(   Ns%   The CMod gate has not been completed.(   t   NotImplementedError(   t   clst   args(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt
   _eval_args)   s    c         C  s   |  j  d S(   s4   Size of 1/2 input register.  First 1/2 holds output.i    (   t   label(   t   self(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   t0   s    c         C  s   |  j  d S(   s$   Base of the controlled mod function.i   (   R   (   R   (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   a5   s    c         C  s   |  j  d S(   s1   N is the type of modular arithmetic we are doing.i   (   R   (   R   (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   N:   s    c         K  s¼   d } d } x: t  |  j ƒ D]) } | | | |  j | } | d } q Wt |  j | |  j ƒ } t | j d |  j  ƒ } x2 t t  |  j ƒ ƒ D] } | j | | ?d @ƒ q“ Wt	 | Œ  S(   sÔ   
            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
        i   i    i   (
   R   R   t   intR   R   t   listR   t   reversedt   appendR   (   R   t   qubitst   optionst   nt   kt   it   outt   outarray(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   _apply_operator_Qubit?   s    (
   R   R   t   __doc__t   classmethodR   t   propertyR   R   R   R(   (    (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyR   !   s   c         C  sÚ   t  j |  d ƒ d } t |  | ƒ d k rC t d ƒ t |  | ƒ St d | ƒ t d |  ƒ t | |  ƒ } t d | ƒ | d d k r  t d ƒ t |  ƒ n  t | | d d |  ƒ t | | d d |  ƒ f } | S(   sâ  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 isn't, 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.
    i   i   s   got lucky with rands   a= s   N= s   r= s   r is not even, begin again(   t   randomt	   randrangeR   t   printt   period_findt   shor(   R   R   t   rt   answer(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyR0   Y   s    


6c         C  s"   t  |  | ƒ } t | | ƒ } | S(   N(   t   continued_fractiont   ratioize(   t   xt   yR   t   fractiont   total(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   getrr   s    c         C  sJ   |  d | k r t  j St |  ƒ d k r1 |  d S|  d t |  d | ƒ S(   Ni    i   (   R   t   Zerot   lenR4   (   R   R   (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyR4   y   s
    c         C  sY  d } t  d t j t | d ƒ ƒ ƒ } g  t | ƒ D] } d ^ q5 } d t d | ƒ } d } x= t t d ƒ | d t ƒD]  } | | }	 | t |	 Œ  } q} W| | j	 ƒ  }
 t
 | |  | ƒ |
 }
 t |
 ƒ }
 t d ƒ x# t | ƒ D] } t |
 | ƒ }
 qê Wt d ƒ t t | | d ƒ j ƒ  |
 d t ƒ}
 t d	 ƒ x' t | ƒ D] } t |
 | | ƒ }
 qMWt |
 ƒ t |
 t ƒ rŒ|
 } n3 t |
 t ƒ r«|
 j d
 } n |
 j d
 j d
 } t | ƒ d } d } x> t t | ƒ d ƒ D]& } | | | | | 7} | d >} qìW| d k r5t d | ƒ ‚ n  t | d | | ƒ } t | ƒ | S(   s/  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      à?i   i    i   t
   repetitions   controlled Mod'ds
   measured 1t   floatingPoints   QFT'diÿÿÿÿs/   Order finder returned 0. Happens with chance %f(   R   t   matht   ceilR   R   R   R	   t   TrueR   t   expandR   R   R.   R   R   t	   decomposet
   isinstanceR   R   R;   R   R9   (   R   R   t   epsilonR   R5   t   startt   factorR!   t   arrt	   qbitArrayt   circuitR%   t   registerR#   R2   t   g(    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyR/      sJ    ""


)

	

(%   R)   t
   __future__R    R   R>   R,   t   sympyR   R   R   R   t   sympy.core.numbersR   t   sympy.core.compatibilityR   t   sympy.ntheoryR   R3   t   sympy.utilities.iterablesR	   t   sympy.physics.quantum.gateR
   t   sympy.physics.quantum.qubitR   R   t   sympy.physics.quantum.qapplyR   t   sympy.physics.quantum.qftR   t   sympy.physics.quantum.qexprR   R   R   R0   R9   R4   R/   (    (    (    s9   lib/python2.7/site-packages/sympy/physics/quantum/shor.pyt   <module>	   s(   8			