
    sg                         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"y)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                       e Zd Zy)OrderFindingExceptionN)__name__
__module____qualname__     M/var/www/html/venv/lib/python3.12/site-packages/sympy/physics/quantum/shor.pyr   r      s    r   r   c                   V    e Zd ZdZed        Zed        Zed        Zed        Z	d Z
y)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                     t        d      )Nz%The CMod gate has not been completed.)NotImplementedError)clsargss     r   
_eval_argszCMod._eval_args(   s    
 ""IJJr   c                      | j                   d   S )z4Size of 1/2 input register.  First 1/2 holds output.r   labelselfs    r   tzCMod.t/        zz!}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 ]  }|j                  ||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     tvv 	A6$&&1*%%%AFA	
 $&&!)dff$% Aw/0 %-( 	,AOOSAXN+	, hr   N)r   r   r   __doc__classmethodr   propertyr$   r(   r+   r9   r   r   r   r   r       s^     K K       r   r   c                    t        j                  | dz
        dz   }t        | |      dk7  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AqzQAqzAqA1uzQ1qs8a<#T!ac(Q,%:;FMr   c                 6    t        | |      }t        ||      }|S )N)continued_fractionratioize)xyr+   fractiontotals        r   getrrK   l   s    !!Q'HXq!ELr   c                     | d   |kD  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   sF    Aw{vv
4yA~Aw7Xd12h***r   c           	         d}t        dt        j                  t        |d            z        }t	        |      D cg c]  }d }}dt        d|z        z  }d}t        t	        d      |d      D ]  }t        |      |z   }	|t        |	 z   } ||z  j                         }
t        || |      |
z  }
t        |
      }
t	        |      D ]  }t        |
|      }
 t        t        ||dz        j                         |
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 c c}w )
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*   r   r'   T)
repetition)floatingPointz/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$   rG   startfactorr2   arr	qbitArraycircuitr6   registerr4   rC   gs                   r   r@   r@   {   s    GAdiiAq	""#Aa!1Q!E!tAqDz\FF%(A$7 ,I%	%++, f}$$&G 1amG#G WoG1X 6)'156 SAaC[**,W4DIG1X :)'1q59:'5!	GS	!<<#<<#((,	AF3x=?# !HQUO##F {#=GI 	I 	VQT1AHM "s   	G	)#r:   rS   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>rl      sc       " 6 9 # K 0 + F / ) 4	L 	5 4 5 p(+2r   