init: repository publish
This commit is contained in:
commit
2120e6fbf5
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
libs/
|
||||
.env
|
||||
__pycache__/
|
43
bench-cirq/deutsch_algorithm.py
Normal file
43
bench-cirq/deutsch_algorithm.py
Normal file
@ -0,0 +1,43 @@
|
||||
from cirq import LineQubit,Circuit,CNOT,X,H,measure
|
||||
from cirq import Simulator
|
||||
|
||||
from qiskit import IBMQ
|
||||
|
||||
from quantum_runner import quantum_simulate,setup_IBM,cirq_qasm
|
||||
|
||||
from random import randint
|
||||
|
||||
q0,q1 = LineQubit.range(2)
|
||||
|
||||
ffunction = [randint(0, 1) for _ in range(2)]
|
||||
|
||||
# создаем вентиль для генерации функции
|
||||
def make_oracle(q0,q1,ffunction):
|
||||
if ffunction[0]:
|
||||
# используем контролируемый вентиль отрицания и матрицу Паули по координате x, sigma_x
|
||||
yield [CNOT(q0,q1), X(q1)]
|
||||
if ffunction[1]:
|
||||
yield CNOT(q0,q1)
|
||||
|
||||
print(f"f(x) = <{', '.join(str(e) for e in ffunction)}>")
|
||||
|
||||
circuit = Circuit()
|
||||
|
||||
# создаем кубиты используя вентиль Адамара и матрицу Паули
|
||||
|
||||
circuit.append([X(q1),H(q1),H(q0)])
|
||||
|
||||
# добавляем функцию
|
||||
circuit.append(make_oracle(q0,q1,ffunction))
|
||||
|
||||
# проведем измерение
|
||||
circuit.append([H(q0),measure(q0)])
|
||||
|
||||
print(circuit)
|
||||
print(Simulator().run(circuit))
|
||||
|
||||
# запуск на квантовом компьютере
|
||||
|
||||
setup_IBM()
|
||||
provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
|
||||
print(quantum_simulate(cirq_qasm(circuit,(q0,q1,)),provider.get_backend('ibm_lagos'),True))
|
61
bench-cirq/grover_algorithm.py
Normal file
61
bench-cirq/grover_algorithm.py
Normal file
@ -0,0 +1,61 @@
|
||||
# https://github.com/quantumlib/Cirq/blob/master/examples/grover.py
|
||||
# https://quantum-ods.github.io/qmlcourse/book/qcalgo/ru/grovers_algorithm.html
|
||||
|
||||
from ctypes import wstring_at
|
||||
from random import randint
|
||||
from cirq import Circuit,X,H,CNOT,TOFFOLI,GridQubit,measure
|
||||
from cirq import Simulator
|
||||
|
||||
from qiskit import IBMQ
|
||||
|
||||
from quantum_runner import quantum_simulate,setup_IBM,cirq_qasm
|
||||
|
||||
def oracle(iqs,oq,bits):
|
||||
yield (X(q) for (q, bit) in zip(iqs,bits) if not bit)
|
||||
yield (TOFFOLI(iqs[0],iqs[1],oq))
|
||||
yield (X(q) for (q,bit) in zip(iqs,bits) if not bit)
|
||||
|
||||
circuit = Circuit()
|
||||
|
||||
qb_count = 2
|
||||
|
||||
iqs = [GridQubit(i,0) for i in range(qb_count)]
|
||||
oq = GridQubit(qb_count,0)
|
||||
bits = [randint(0, 1) for _ in range(qb_count)]
|
||||
|
||||
circuit.append([X(oq),H(oq),H.on_each(iqs)])
|
||||
|
||||
circuit.append(oracle(iqs,oq,bits))
|
||||
|
||||
# Строим оператор Гровера
|
||||
circuit.append(H.on_each(iqs))
|
||||
circuit.append(X.on_each(iqs))
|
||||
circuit.append(H.on(iqs[1]))
|
||||
circuit.append(CNOT.on(iqs[0],iqs[1]))
|
||||
circuit.append(H.on(iqs[1]))
|
||||
circuit.append(X.on_each(iqs))
|
||||
circuit.append(H.on_each(iqs))
|
||||
|
||||
circuit.append(measure(iqs, key="result"))
|
||||
|
||||
print(circuit)
|
||||
|
||||
result = Simulator().run(circuit,repetitions=10)
|
||||
|
||||
def bitstring(bits):
|
||||
return ''.join(str(int(b)) for b in bits)
|
||||
|
||||
frequencies = result.histogram(key='result',fold_func=bitstring)
|
||||
|
||||
print(f"результат",frequencies)
|
||||
print(f"наиболее распространеная битовая строка",frequencies.most_common(1)[0][0])
|
||||
|
||||
setup_IBM()
|
||||
|
||||
provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
|
||||
|
||||
quantum_simulate(
|
||||
cirq_qasm(circuit),
|
||||
provider.get_backend('ibmq_lima'),
|
||||
True
|
||||
)
|
143
bench-cirq/shor_algorithm.py
Normal file
143
bench-cirq/shor_algorithm.py
Normal file
@ -0,0 +1,143 @@
|
||||
# https://github.com/dmitrifried/Shors-Algorithm-in-Cirq/blob/master/Shor's%20Algorithm%20in%20Cirq.ipynb
|
||||
|
||||
from math import gcd,floor,ceil,pow,log2
|
||||
from random import randint
|
||||
from typing import Optional,Sequence,Union,Callable
|
||||
from fractions import Fraction
|
||||
|
||||
from sympy import isprime
|
||||
|
||||
from cirq import ArithmeticGate,Circuit,X,H,qft,measure,LineQubit
|
||||
from cirq import CircuitDiagramInfoArgs,CircuitDiagramInfo,Result
|
||||
from cirq import Simulator
|
||||
|
||||
def classic_order_finder(x: int, n: int) -> Optional[int]:
|
||||
"""
|
||||
Поиск делителя классическим способом
|
||||
"""
|
||||
if x < 2 or n <= x or gcd(x, n) > 1:
|
||||
raise ValueError(f'Invalid x={x} for modulus n={n}.')
|
||||
r, y = 1, x
|
||||
while y != 1:
|
||||
y = (x * y) % n
|
||||
r += 1
|
||||
return r
|
||||
|
||||
class ModularExp(ArithmeticGate):
|
||||
def __init__(self, target: Sequence[int], exponent: Union[int, Sequence[int]], base: int, modulus: int) -> None:
|
||||
if len(target) < modulus.bit_length():
|
||||
raise ValueError(
|
||||
f'Регистр с {len(target)} кубитами маленький для {modulus}'
|
||||
)
|
||||
self.target = target
|
||||
self.exponent = exponent
|
||||
self.base = base
|
||||
self.modulus = modulus
|
||||
|
||||
def registers(self) -> Sequence[Union[int, Sequence[int]]]:
|
||||
return self.target, self.exponent, self.base, self.modulus
|
||||
|
||||
def with_registers(self, *new_registers: Union[int, Sequence[int]]) -> 'ModularExp':
|
||||
if len(new_registers) != 4:
|
||||
raise ValueError(
|
||||
f'Expected 4 registers (target, exponent, base, '
|
||||
f'modulus), but got {len(new_registers)}'
|
||||
)
|
||||
target, exponent, base, modulus = new_registers
|
||||
if not isinstance(target, Sequence):
|
||||
raise ValueError(f'Метка должна быть регистром кубитов {type(target)}')
|
||||
if not isinstance(modulus,int):
|
||||
raise ValueError(f'модуль это классическая константа {type(modulus)}')
|
||||
if not isinstance(base,int):
|
||||
raise ValueError(f'база у числа это классическая константа {type(base)}')
|
||||
return ModularExp(target, exponent, base, modulus)
|
||||
def apply(self, *register_values: int) -> int:
|
||||
assert len(register_values) == 4
|
||||
target, exponent, base, modulus = register_values
|
||||
if target >= modulus:
|
||||
return target
|
||||
return (target * base**exponent) % modulus
|
||||
def _circuit_diagram_info_(self, args: CircuitDiagramInfoArgs) -> CircuitDiagramInfo:
|
||||
assert args.known_qubits is not None
|
||||
wire_symbols = [f't{i}' for i in range(len(self.target))]
|
||||
e_str = str(self.exponent)
|
||||
if isinstance(self.exponent, Sequence):
|
||||
e_str = 'e'
|
||||
wire_symbols += [f'e{i}' for i in range(len(self.exponent))]
|
||||
wire_symbols[0] = f'ModularExp(t*{self.base}**{e_str} % {self.modulus})'
|
||||
return CircuitDiagramInfo(wire_symbols=tuple(wire_symbols))
|
||||
|
||||
def make_order_finding_circuit(x: int, n: int) -> Circuit:
|
||||
L = n.bit_length()
|
||||
target = LineQubit.range(L)
|
||||
exponent = LineQubit.range(L, 3 * L + 3)
|
||||
return Circuit(
|
||||
X(target[L - 1]),
|
||||
H.on_each(*exponent),
|
||||
ModularExp([2] * len(target), [2] * len(exponent), x, n).on(*target + exponent),
|
||||
qft(*exponent, inverse=True),
|
||||
measure(*exponent, key='exponent'),
|
||||
)
|
||||
|
||||
def read_eigenphase(result: Result) -> float:
|
||||
exponent_as_integer = result.data['exponent'][0]
|
||||
exponent_num_bits = result.measurements['exponent'].shape[1]
|
||||
return float(exponent_as_integer / 2**exponent_num_bits)
|
||||
|
||||
def quantum_order_finder(x: int, n: int) -> Optional[int]:
|
||||
if x < 2 or n <= x or gcd(x, n) > 1:
|
||||
raise ValueError(f'Неправильный x={x} для модуля n={n}.')
|
||||
|
||||
circuit = make_order_finding_circuit(x, n)
|
||||
result = Simulator().run(circuit)
|
||||
eigenphase = read_eigenphase(result)
|
||||
f = Fraction.from_float(eigenphase).limit_denominator(n)
|
||||
if f.numerator == 0:
|
||||
return None
|
||||
r = f.denominator
|
||||
if x**r % n != 1:
|
||||
return None
|
||||
print(circuit)
|
||||
return r
|
||||
|
||||
def find_factor_of_prime_power(n: int) -> Optional[int]:
|
||||
for k in range(2, floor(log2(n)) + 1):
|
||||
c = pow(n, 1 / k)
|
||||
c1 =floor(c)
|
||||
if c1**k == n:
|
||||
return c1
|
||||
c2 = ceil(c)
|
||||
if c2**k == n:
|
||||
return c2
|
||||
return None
|
||||
|
||||
def find_factor(
|
||||
n: int, order_finder: Callable[[int, int], Optional[int]], max_attempts: int = 30
|
||||
) -> Optional[int]:
|
||||
if isprime(n):
|
||||
return None
|
||||
if n % 2 == 0:
|
||||
return 2
|
||||
c = find_factor_of_prime_power(n)
|
||||
if c is not None:
|
||||
return c
|
||||
for _ in range(max_attempts):
|
||||
x = randint(2, n - 1)
|
||||
c = gcd(x, n)
|
||||
if 1 < c < n:
|
||||
return c
|
||||
r = order_finder(x, n)
|
||||
if r is None:
|
||||
continue
|
||||
if r % 2 != 0:
|
||||
continue
|
||||
y = x ** (r // 2) % n
|
||||
assert 1 < y < n
|
||||
c = gcd(y - 1, n)
|
||||
if 1 < c < n:
|
||||
return c
|
||||
return None
|
||||
|
||||
n = 33
|
||||
d = find_factor(n, quantum_order_finder)
|
||||
|
85
bench-qiskit/deutsch_alogrithm.py
Normal file
85
bench-qiskit/deutsch_alogrithm.py
Normal file
@ -0,0 +1,85 @@
|
||||
# https://github.com/qiskit-community/qiskit-community-tutorials/blob/master/algorithms/deutsch_jozsa.ipynb
|
||||
# https://github.com/mrtkp9993/QuantumComputingExamples
|
||||
# https://github.com/DavitKhach/quantum-algorithms-tutorials/blob/master/quantum_parallelism_Deutsch_Jozsa.ipynb
|
||||
# https://fullstackquantumcomputation.tech/blog/deutsch-algorithm/
|
||||
# https://www.mlq.ai/quantum-programming-with-qiskit/
|
||||
# https://github.com/przecze/deutschs_algorithm_in_qiskit_vs_cirq/blob/main/common.py
|
||||
from random import randint
|
||||
|
||||
from qiskit import QuantumCircuit,QuantumRegister,ClassicalRegister
|
||||
from qiskit import BasicAer,IBMQ
|
||||
from qiskit.tools.monitor import job_monitor
|
||||
|
||||
from qiskit import transpile
|
||||
|
||||
from quantum_runner import quantum_simulate,setup_IBM
|
||||
|
||||
|
||||
# количество создаваемых битов
|
||||
n = 1
|
||||
|
||||
# создаем функции
|
||||
ff = randint(0, n)
|
||||
|
||||
if ff !=0:
|
||||
randint(1,2**n)
|
||||
|
||||
# создание n-кубитов в системе
|
||||
|
||||
qr = QuantumRegister(n+1)
|
||||
|
||||
# создание n классических битов, для записи измерений
|
||||
|
||||
cr = ClassicalRegister(n)
|
||||
|
||||
circuit = QuantumCircuit(qr,cr)
|
||||
|
||||
# создаем вспомогательные кубиты
|
||||
|
||||
circuit.x(qr[n])
|
||||
|
||||
circuit.h(qr[n])
|
||||
|
||||
# Барьер нужен для группировки отдельных частей цепи
|
||||
circuit.barrier()
|
||||
|
||||
# Первая часть, это подготовка суперпозиции состояний.
|
||||
# Для этого используем вентиль Адамара
|
||||
|
||||
circuit.h(qr[0])
|
||||
circuit.h(qr[1])
|
||||
|
||||
circuit.barrier()
|
||||
|
||||
# Создаем квантовый оракул, используя контроллер
|
||||
circuit.cx(qr[0],qr[1])
|
||||
|
||||
circuit.barrier()
|
||||
|
||||
# Применяем вентиль уже к оракулу
|
||||
|
||||
for i in range(n):
|
||||
circuit.h(qr[i])
|
||||
|
||||
circuit.barrier()
|
||||
|
||||
# Измеряем кубит
|
||||
|
||||
for i in range(n):
|
||||
circuit.measure(qr[i],cr[i])
|
||||
|
||||
# Запустим локально
|
||||
|
||||
backend = BasicAer.get_backend("qasm_simulator")
|
||||
results = quantum_simulate(circuit,backend,True)
|
||||
results = list(results.keys())
|
||||
|
||||
print(circuit)
|
||||
print(f"q({ff})=",results)
|
||||
|
||||
#setup_IBM()
|
||||
#provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
|
||||
#backend = provider.get_backend('ibmq_lima')
|
||||
#job_monitor(quantum_simulate(circuit,backend), interval=2)
|
||||
|
||||
#print(quantum_simulate(circuit,backend,True))
|
49
bench-qiskit/grover_algorithm.py
Normal file
49
bench-qiskit/grover_algorithm.py
Normal file
@ -0,0 +1,49 @@
|
||||
# https://www.qmunity.tech/tutorials/grovers-algorithm-using-2-qubits
|
||||
from qiskit import QuantumCircuit
|
||||
from qiskit import BasicAer,IBMQ
|
||||
|
||||
from quantum_runner import setup_IBM,quantum_simulate
|
||||
|
||||
qb_count = 2
|
||||
|
||||
circuit = QuantumCircuit(qb_count)
|
||||
|
||||
circuit.h(0)
|
||||
circuit.h(1)
|
||||
|
||||
circuit.barrier()
|
||||
|
||||
# создаем оракул для котроллируемого вентиля по z
|
||||
circuit.cz(0,1)
|
||||
circuit.barrier()
|
||||
|
||||
# создаем оператор гровера
|
||||
for k in range(0,qb_count):
|
||||
circuit.h(k)
|
||||
for k in range(0,qb_count):
|
||||
circuit.x(k)
|
||||
|
||||
circuit.h(1)
|
||||
circuit.cx(0,1)
|
||||
|
||||
circuit.x(0)
|
||||
circuit.h(1)
|
||||
circuit.h(0)
|
||||
circuit.x(1)
|
||||
circuit.h(1)
|
||||
|
||||
circuit.barrier()
|
||||
|
||||
circuit.measure_all()
|
||||
|
||||
print(circuit)
|
||||
|
||||
backend = BasicAer.get_backend("qasm_simulator")
|
||||
results = quantum_simulate(circuit,backend,True)
|
||||
|
||||
print(quantum_simulate(circuit,backend,True))
|
||||
|
||||
|
||||
setup_IBM()
|
||||
provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
|
||||
quantum_simulate(circuit,provider.get_backend('ibm_lagos'),True)
|
376
bench-qiskit/shor_algorithm.py
Normal file
376
bench-qiskit/shor_algorithm.py
Normal file
@ -0,0 +1,376 @@
|
||||
# https://qiskit.org/documentation/tutorials/circuits/3_summary_of_quantum_operations.html
|
||||
# https://github.com/olekssy/qiskit-shors/blob/master/shors.py
|
||||
# https://quantumcomputinguk.org/tutorials/shors-algorithm-with-code
|
||||
|
||||
from math import pow,gcd,floor,isinf,ceil,log
|
||||
|
||||
from numpy import zeros,pi
|
||||
|
||||
from fractions import Fraction
|
||||
from array import array
|
||||
|
||||
from qiskit import QuantumRegister,ClassicalRegister,QuantumCircuit
|
||||
from qiskit import IBMQ
|
||||
|
||||
from quantum_runner import setup_IBM,quantum_simulate
|
||||
|
||||
def check_if_power(N):
|
||||
b=2
|
||||
while (2**b) <= N:
|
||||
a = 1
|
||||
c = N
|
||||
while (c-a) >= 2:
|
||||
m = int( (a+c)/2 )
|
||||
|
||||
if (m**b) < (N+1):
|
||||
p = int( (m**b) )
|
||||
else:
|
||||
p = int(N+1)
|
||||
|
||||
if int(p) == int(N):
|
||||
print('N is {0}^{1}'.format(int(m),int(b)) )
|
||||
return True
|
||||
|
||||
if p<N:
|
||||
a = int(m)
|
||||
else:
|
||||
c = int(m)
|
||||
b=b+1
|
||||
|
||||
return False
|
||||
|
||||
def create_QFT(circuit,up_reg,n,with_swaps):
|
||||
i=n-1
|
||||
while i>=0:
|
||||
circuit.h(up_reg[i])
|
||||
j=i-1
|
||||
while j>=0:
|
||||
if (pi)/(pow(2,(i-j))) > 0:
|
||||
circuit.crz( (pi)/(pow(2,(i-j))) , up_reg[i] , up_reg[j] )
|
||||
j=j-1
|
||||
i=i-1
|
||||
|
||||
if with_swaps==1:
|
||||
i=0
|
||||
while i < ((n-1)/2):
|
||||
circuit.swap(up_reg[i], up_reg[n-1-i])
|
||||
i=i+1
|
||||
|
||||
def create_inverse_QFT(circuit,up_reg,n,with_swaps):
|
||||
if with_swaps==1:
|
||||
i=0
|
||||
while i < ((n-1)/2):
|
||||
circuit.swap(up_reg[i], up_reg[n-1-i])
|
||||
i=i+1
|
||||
|
||||
i=0
|
||||
while i<n:
|
||||
circuit.h(up_reg[i])
|
||||
if i != n-1:
|
||||
j=i+1
|
||||
y=i
|
||||
while y>=0:
|
||||
if (pi)/(pow(2,(j-y))) > 0:
|
||||
circuit.crz( - (pi)/(pow(2,(j-y))) , up_reg[j] , up_reg[y] )
|
||||
|
||||
|
||||
def egcd(a, b):
|
||||
if a == 0:
|
||||
return (b, 0, 1)
|
||||
else:
|
||||
g, y, x = egcd(b % a, a)
|
||||
return (g, x - (b // a) * y, y)
|
||||
|
||||
def modinv(a, m):
|
||||
g, x, y = egcd(a, m)
|
||||
if g != 1:
|
||||
raise Exception('modular inverse does not exist')
|
||||
else:
|
||||
return x % m
|
||||
|
||||
def get_factors(x_value,t_upper,N,a):
|
||||
|
||||
if x_value<=0:
|
||||
print('x_value is <= 0, there are no continued fractions\n')
|
||||
return False
|
||||
|
||||
# print('Running continued fractions for this case\n')
|
||||
|
||||
T = pow(2,t_upper)
|
||||
|
||||
x_over_T = x_value/T
|
||||
|
||||
i=0
|
||||
b = array('i')
|
||||
t = array('f')
|
||||
|
||||
b.append(floor(x_over_T))
|
||||
t.append(x_over_T - b[i])
|
||||
|
||||
while i>=0:
|
||||
|
||||
if i>0:
|
||||
b.append( floor( 1 / (t[i-1]) ) )
|
||||
t.append( ( 1 / (t[i-1]) ) - b[i] )
|
||||
|
||||
|
||||
aux = 0
|
||||
j=i
|
||||
while j>0:
|
||||
aux = 1 / ( b[j] + aux )
|
||||
j = j-1
|
||||
|
||||
aux = aux + b[0]
|
||||
|
||||
frac = Fraction(aux).limit_denominator()
|
||||
den=frac.denominator
|
||||
|
||||
print('Approximation number {0} of continued fractions:'.format(i+1))
|
||||
print("Numerator:{0} \t\t Denominator: {1}\n".format(frac.numerator,frac.denominator))
|
||||
|
||||
""" Increment i for next iteration """
|
||||
i=i+1
|
||||
|
||||
if (den%2) == 1:
|
||||
if i>=15:
|
||||
print('Returning because have already done too much tries')
|
||||
return False
|
||||
print('Odd denominator, will try next iteration of continued fractions\n')
|
||||
continue
|
||||
|
||||
""" If denominator even, try to get factors of N """
|
||||
|
||||
""" Get the exponential a^(r/2) """
|
||||
|
||||
exponential = 0
|
||||
|
||||
if den<1000:
|
||||
exponential=pow(a , (den/2))
|
||||
|
||||
""" Check if the value is too big or not """
|
||||
if isinf(exponential)==1 or exponential>1000000000:
|
||||
print('Denominator of continued fraction is too big!\n')
|
||||
aux_out = input('Input number 1 if you want to continue searching, other if you do not: ')
|
||||
if aux_out != '1':
|
||||
return False
|
||||
else:
|
||||
continue
|
||||
|
||||
putting_plus = int(exponential + 1)
|
||||
|
||||
putting_minus = int(exponential - 1)
|
||||
|
||||
one_factor = gcd(putting_plus,N)
|
||||
other_factor = gcd(putting_minus,N)
|
||||
|
||||
""" Check if the factors found are trivial factors or are the desired
|
||||
factors """
|
||||
|
||||
if one_factor==1 or one_factor==N or other_factor==1 or other_factor==N:
|
||||
print('Found just trivial factors, not good enough\n')
|
||||
if t[i-1]==0:
|
||||
print('The continued fractions found exactly x_final/(2^(2n)) , leaving funtion\n')
|
||||
return False
|
||||
else:
|
||||
""" Return if already too much tries and numbers are huge """
|
||||
print('Returning because have already done too many tries\n')
|
||||
return False
|
||||
else:
|
||||
print('The factors of {0} are {1} and {2}\n'.format(N,one_factor,other_factor))
|
||||
print('Found the desired factors!\n')
|
||||
return True
|
||||
|
||||
def getAngles(a,N):
|
||||
s=bin(int(a))[2:].zfill(N)
|
||||
angles=zeros([N])
|
||||
for i in range(0, N):
|
||||
for j in range(i,N):
|
||||
if s[j]=='1':
|
||||
angles[N-i-1]+=pow(2, -(j-i))
|
||||
angles[N-i-1]*=pi
|
||||
return angles
|
||||
|
||||
def ccphase(circuit,angle,ctl1,ctl2,tgt):
|
||||
circuit.crz(angle/2,ctl1,tgt)
|
||||
circuit.cx(ctl2,ctl1)
|
||||
circuit.crz(-angle/2,ctl1,tgt)
|
||||
circuit.cx(ctl2,ctl1)
|
||||
circuit.crz(angle/2,ctl2,tgt)
|
||||
|
||||
def phiADD(circuit,q,a,N,inv):
|
||||
angle=getAngles(a,N)
|
||||
for i in range(0,N):
|
||||
if inv==0:
|
||||
circuit.p(angle[i],q[i])
|
||||
else:
|
||||
circuit.p(-angle[i],q[i])
|
||||
|
||||
def cphiADD(circuit,q,ctl,a,n,inv):
|
||||
angle=getAngles(a,n)
|
||||
for i in range(0,n):
|
||||
if inv==0:
|
||||
circuit.crz(angle[i],ctl,q[i])
|
||||
else:
|
||||
circuit.crz(-angle[i],ctl,q[i])
|
||||
|
||||
def ccphiADD(circuit,q,ctl1,ctl2,a,n,inv):
|
||||
angle=getAngles(a,n)
|
||||
for i in range(0,n):
|
||||
if inv==0:
|
||||
ccphase(circuit,angle[i],ctl1,ctl2,q[i])
|
||||
else:
|
||||
ccphase(circuit,-angle[i],ctl1,ctl2,q[i])
|
||||
|
||||
def ccphiADDmodN(circuit, q, ctl1, ctl2, aux, a, N, n):
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 0)
|
||||
phiADD(circuit, q, N, n, 1)
|
||||
create_inverse_QFT(circuit, q, n, 0)
|
||||
circuit.cx(q[n-1],aux)
|
||||
create_QFT(circuit,q,n,0)
|
||||
cphiADD(circuit, q, aux, N, n, 0)
|
||||
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 1)
|
||||
create_inverse_QFT(circuit, q, n, 0)
|
||||
circuit.x(q[n-1])
|
||||
circuit.cx(q[n-1], aux)
|
||||
circuit.x(q[n-1])
|
||||
create_QFT(circuit,q,n,0)
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 0)
|
||||
|
||||
def ccphiADDmodN_inv(circuit, q, ctl1, ctl2, aux, a, N, n):
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 1)
|
||||
create_inverse_QFT(circuit, q, n, 0)
|
||||
circuit.x(q[n-1])
|
||||
circuit.cx(q[n-1],aux)
|
||||
circuit.x(q[n-1])
|
||||
create_QFT(circuit, q, n, 0)
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 0)
|
||||
cphiADD(circuit, q, aux, N, n, 1)
|
||||
create_inverse_QFT(circuit, q, n, 0)
|
||||
circuit.cx(q[n-1], aux)
|
||||
create_QFT(circuit, q, n, 0)
|
||||
phiADD(circuit, q, N, n, 0)
|
||||
ccphiADD(circuit, q, ctl1, ctl2, a, n, 1)
|
||||
|
||||
def cMULTmodN(circuit, ctl, q, aux, a, N, n):
|
||||
create_QFT(circuit,aux,n+1,0)
|
||||
for i in range(0, n):
|
||||
ccphiADDmodN(circuit, aux, q[i], ctl, aux[n+1], (2**i)*a % N, N, n+1)
|
||||
create_inverse_QFT(circuit, aux, n+1, 0)
|
||||
|
||||
for i in range(0, n):
|
||||
circuit.cswap(ctl,q[i],aux[i])
|
||||
|
||||
a_inv = modinv(a, N)
|
||||
create_QFT(circuit, aux, n+1, 0)
|
||||
i = n-1
|
||||
while i >= 0:
|
||||
ccphiADDmodN_inv(circuit, aux, q[i], ctl, aux[n+1], pow(2,i)*a_inv % N, N, n+1)
|
||||
i -= 1
|
||||
create_inverse_QFT(circuit, aux, n+1, 0)
|
||||
|
||||
def get_value_a(N):
|
||||
a=2
|
||||
while gcd(a,N)!=1:
|
||||
a=a+1
|
||||
return a
|
||||
|
||||
|
||||
|
||||
def factorize_number(N):
|
||||
if N==1 or N==0:
|
||||
print('Please put an N different from 0 and from 1')
|
||||
exit()
|
||||
|
||||
""" Check if N is even """
|
||||
|
||||
if (N%2)==0:
|
||||
print('N is even, so does not make sense!')
|
||||
exit()
|
||||
|
||||
""" Check if N can be put in N=p^q, p>1, q>=2 """
|
||||
|
||||
""" Try all numbers for p: from 2 to sqrt(N) """
|
||||
if check_if_power(N)==True:
|
||||
exit()
|
||||
|
||||
# print('Not an easy case, using the quantum circuit is necessary\n')
|
||||
|
||||
setup_IBM()
|
||||
|
||||
""" Get an integer a that is coprime with N """
|
||||
a = get_value_a(N)
|
||||
|
||||
# """ If user wants to force some values, he can do that here, please make sure to update the print and that N and a are coprime"""
|
||||
# print('Forcing N=15 and a=4 because its the fastest case, please read top of source file for more info')
|
||||
# N=15
|
||||
# a=4
|
||||
|
||||
print("help !!!")
|
||||
""" Get n value used in Shor's algorithm, to know how many qubits are used """
|
||||
n = ceil(log(N,2))
|
||||
|
||||
# print('Total number of qubits used: {0}\n'.format(4*n+2))
|
||||
|
||||
aux = QuantumRegister(n+2)
|
||||
up_reg = QuantumRegister(2*n)
|
||||
down_reg = QuantumRegister(n)
|
||||
up_classic = ClassicalRegister(2*n)
|
||||
circuit = QuantumCircuit(down_reg , up_reg , aux, up_classic)
|
||||
|
||||
circuit.h(up_reg)
|
||||
circuit.x(down_reg[0])
|
||||
|
||||
""" Apply the multiplication gates as showed in the report in order to create the exponentiation """
|
||||
for i in range(0, 2*n):
|
||||
cMULTmodN(circuit, up_reg[i], down_reg, aux, int(pow(a, pow(2, i))), N, n)
|
||||
|
||||
""" Apply inverse QFT """
|
||||
create_inverse_QFT(circuit, up_reg, 2*n ,1)
|
||||
|
||||
""" Measure the top qubits, to get x value"""
|
||||
circuit.measure(up_reg,up_classic)
|
||||
|
||||
""" Simulate the created Quantum Circuit """
|
||||
# print(transpile(circuit,BasicAer.get_backend('qasm_simulator')))
|
||||
#simulation = execute(circuit, backend=BasicAer.get_backend('qasm_simulator'),shots=number_shots)
|
||||
provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
|
||||
simulation = quantum_simulate(circuit,provider.get_backend('ibmq_lima'),True)
|
||||
|
||||
i=0
|
||||
while i < len(simulation):
|
||||
print('Result \"{0}\" happened {1} times out of {2}'.format(list(simulation.keys())[i],list(simulation.values())[i]))
|
||||
i=i+1
|
||||
|
||||
""" An empty print just to have a good display in terminal """
|
||||
print(' ')
|
||||
|
||||
""" Initialize this variable """
|
||||
# prob_success=0
|
||||
|
||||
""" For each simulation result, print proper info to user and try to calculate the factors of N"""
|
||||
# i=0
|
||||
# while i < len(counts_result):
|
||||
|
||||
#""" Get the x_value from the final state qubits """
|
||||
# output_desired = list(sim_result.get_counts().keys())[i]
|
||||
# x_value = int(output_desired, 2)
|
||||
# prob_this_result = 100 * ( int( list(sim_result.get_counts().values())[i] ) ) / (number_shots)
|
||||
|
||||
#print("------> Analysing result {0}. This result happened in {1:.4f} % of all cases\n".format(output_desired,prob_this_result))
|
||||
|
||||
#""" Print the final x_value to user """
|
||||
# print('In decimal, x_final value for this result is: {0}\n'.format(x_value))
|
||||
|
||||
#""" Get the factors using the x value obtained """
|
||||
# success=get_factors(int(x_value),int(2*n),int(N),int(a))
|
||||
|
||||
#if success==True:
|
||||
# prob_success = prob_success + prob_this_result
|
||||
|
||||
#i=i+1
|
||||
|
||||
# print("\nUsing a={0}, found the factors of N={1} in {2:.4f} % of the cases\n".format(a,N,prob_success))
|
||||
|
||||
N = 33
|
||||
factorize_number(N)
|
14
license
Normal file
14
license
Normal file
@ -0,0 +1,14 @@
|
||||
BSD Zero Clause License
|
||||
|
||||
Copyright (c) 2023 Konrad Geletey
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
31
quantum_runner/__init__.py
Normal file
31
quantum_runner/__init__.py
Normal file
@ -0,0 +1,31 @@
|
||||
from qiskit import execute,QuantumCircuit
|
||||
|
||||
def quantum_simulate(circuit,backend,counts=False,shots=1024):
|
||||
exe = execute(circuit,backend=backend,shots=shots)
|
||||
if counts:
|
||||
return exe.result().get_counts()
|
||||
else:
|
||||
return exe
|
||||
|
||||
from dotenv import load_dotenv
|
||||
#from pathlib import Path
|
||||
from os import getenv
|
||||
|
||||
from qiskit import IBMQ
|
||||
|
||||
def setup_IBM():
|
||||
load_dotenv()
|
||||
|
||||
# сохранить аккаунт
|
||||
IBMQ.save_account(getenv('API_KEY'), overwrite=True)
|
||||
IBMQ.load_account()
|
||||
|
||||
from cirq import QasmOutput,Circuit,Qid
|
||||
from typing import Tuple
|
||||
|
||||
def cirq_qasm(circuit: 'Circuit'):
|
||||
qasm_output = circuit.to_qasm()
|
||||
return QuantumCircuit().from_qasm_str(str(qasm_output))
|
||||
|
||||
|
||||
#print(provider.backends())
|
Reference in New Issue
Block a user