# -*- coding: utf-8 -*- """ Created on Sep 14 17:42:42 2024 @author: tuema """ print('HSK qiskit Exercises') #--------------------------------------------------------------------------- #Comment #Reminder BUG!!! #Extract results #job_result = job.result() #counts = job_result[0].data.cx.get_counts() #oder #counts = job_result[0].data.meas.get_counts() #Es ist nicht klar welcher Ansatz zur Lösung führt #Es können auch beide Ansätze falsch sein #Problem ist wie sich bei Verwendung von Sampler #die counts als dictionary aus dem result extrahieren lassen!!!!! #--------------------------------------------------------------------------- #imports from qiskit import QuantumCircuit, transpile from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit import QuantumCircuit,QuantumRegister,ClassicalRegister from qiskit.visualization import plot_histogram,plot_bloch_multivector #math import numpy as np from fractions import Fraction #ploting-printing import matplotlib.pyplot as plt import pandas as pd #---------------------------------------------------------------------------- #definitions # # Specify variables n=15 nx=4 ny=4 a=7 rx=QuantumRegister(nx) ry=QuantumRegister(ny) ra=QuantumRegister(1) cx=ClassicalRegister(nx) cy=ClassicalRegister(ny) qc=QuantumCircuit(rx,ra,ry,cx,cy) #-------------------- #IBM real Hardware prerequ # Save an IBM Quantum account and set it as your default account. QiskitRuntimeService.save_account( channel="ibm_quantum", token="!!!!!Hier euren Token aus qiskit eingeben!!!!!!", set_as_default=True, # Use `overwrite=True` if you're updating your token. overwrite=True, ) # Load saved credentials service = QiskitRuntimeService() #---------------------------------------------------------------------------- #functions # f(x)= a^x mod n def c_amod15(a, power): """Controlled multiplication by a mod 15""" if a not in [2,4,7,8,11,13]: raise ValueError("'a' must be 2,4,7,8,11 or 13") U = QuantumCircuit(4) for _iteration in range(power): if a in [2,13]: U.swap(2,3) U.swap(1,2) U.swap(0,1) if a in [7,8]: U.swap(0,1) U.swap(1,2) U.swap(2,3) if a in [4, 11]: U.swap(1,3) U.swap(0,2) if a in [7,11,13]: for q in range(4): U.x(q) U = U.to_gate() U.name = f"{a}^{power} mod 15" c_U = U.control() return c_U #Functions for the QFT def swap_registers(circuit, n): for qubit in range(n//2): circuit.swap(qubit, n-qubit-1) return circuit def qft_rotations(circuit, n): """Performs qft on the first n qubits in circuit (without swaps)""" if n == 0: return circuit n -= 1 circuit.h(n) for qubit in range(n): circuit.cp(np.pi/2**(n-qubit), qubit, n) # At the end of our function, we call the same function again on # the next qubits (we reduced n by one earlier in the function) qft_rotations(circuit, n) def qft(circuit, n): """QFT on the first n qubits in circuit""" qft_rotations(circuit, n) swap_registers(circuit, n) return circuit #calculate ggT def euklid_rek(wert_1,wert_2): if wert_2 == 0: return wert_1 else: return euklid_rek(wert_2,(wert_1 % wert_2)) #--------------------------------------------------------------------------- #main print("Shor Algorithm implementation") # Example usage print('Initialize the register x and y to zero') for i in range(nx): qc.initialize(0,rx[i]) for i in range(ny): qc.initialize(0,ry[i]) qc.barrier() print('Apply Hadamard Operator to register x') for i in range(nx): qc.h(rx[i]) print('Initialize Ancilla to |1>') qc.initialize(1,ra[0]) qc.barrier() # Do controlled-U operations print('U Operations') for k in range(nx): qc.append(c_amod15(a, 2**k),[k] + [i+nx for i in range(4)]) qc.barrier() # Do QFT print('QFT') qft(qc,nx) qc.barrier() #Do the measurement print('Measure') for i in range(nx): qc.measure(rx[i],cx[i]) #--------------------------------------------------------------------------- #draw qc.draw("mpl",fold=-1) plt.show() #--------------------------------------------------------------------------- #execute print('Exexute on Hardware') backend = service.least_busy(operational=True, simulator=False) #Set Preset Pass Manager prepaman = generate_preset_pass_manager(backend=backend, optimization_level=1) #Set up Circuit qc_trans = prepaman.run(qc) # Define Sampler sampler = Sampler(mode=backend) #Define number of shots sampler.options.default_shots = 10_000 # Run calculation job = sampler.run([qc_trans]) #Extract results job_result = job.result() counts = job_result[0].data.cx.get_counts() print("Basic simulator : ") print(counts) #--------------------------------------------------------------------------- #plot legend = ['gen execution'] plot_histogram([counts], legend=legend, color=['midnightblue'], title="HSK Base Circuit ZufGen gen multi") plt.show() print('Do Post Processing') print('Calculate Phases of result') rows, measured_phases = [], [] for output in counts: split=output.split( ) decimal = int(split[1],2) # Convert (base 2) string to decimal phase = decimal/(2**nx) # Find corresponding eigenvalue measured_phases.append(phase) # Add these values to the rows in our table: rows.append([f"{output}(bin) = {decimal:>3}(dec)", f"{decimal}/{2**nx} = {phase:.2f}"]) # Print the rows in a table headers=["Register Output", "Phase"] df = pd.DataFrame(rows, columns=headers) print(df) print('continued fraction algorithm') rows = [] for phase in measured_phases: frac = Fraction(phase).limit_denominator(15) rows.append([phase, f"{frac.numerator}/{frac.denominator}", frac.denominator]) # Print as a table headers=["Phase", "Fraction", "Guess for r"] df = pd.DataFrame(rows, columns=headers) print(df) print('calculate the guesses') for entry in rows: guess_per=int(entry[2]) if (guess_per%2)==0: print('Potentieller FaktorI',euklid_rek((a**(guess_per/2)-1) ,n)) print('Potentieller FaktorII',euklid_rek((a**(guess_per/2)+1) ,n)) print('end') #--------------------------------------------------------------------------- #draw #qc.draw("mpl") #---------------------------------------------------------------------------