o
    GZh                     @   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   I/var/www/auris/lib/python3.10/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)Nz%The CMod gate has not been completed.)NotImplementedError)clsargsr   r   r   
_eval_args(   s   zCMod._eval_argsc                 C   
   | j d S )z4Size of 1/2 input register.  First 1/2 holds output.r   labelselfr   r   r   t/      
zCMod.tc                 C   r   )z$Base of the controlled mod function.   r   r   r   r   r   a4   r    zCMod.ac                 C   r   )z1N is the type of modular arithmetic we are doing.   r   r   r   r   r   N9   r    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@  q8t	| 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$   r0   r   r   r   r   r       s    



r   c                 C   sx   t | d d }t| |dkrt| |S t|| }|d dkr$t|  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   r7   X   s   


,r7   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lenr;   )r'   r$   r   r   r   r;   s   s
   r;   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|  }q*|| 	 }	t
|| ||	 }	t|	}	t|D ]}
t|	|
}	qOtt||d  |	 dd	}	t|D ]	}
t|	|
| }	qjt|	tr||	}nt|	tr|	jd
 }n|	jd
 jd
 }d}d}tt|d D ]}
||||
|   7 }|d> }q|dkrt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   rA   r   r@   )r"   r$   epsilonr   startfactorr*   ZarrZ	qbitArrayZcircuitr.   registerr,   r9   gr   r   r   r6   {   s@   


r6   )#r1   rE   r4   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   r:   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   r7   r@   r;   r6   r   r   r   r   <module>   s*    	8