From d9534effce0903539fec50695c8600b8b72f36a1 Mon Sep 17 00:00:00 2001 From: markjeveritt Date: Mon, 13 Mar 2017 15:18:14 +0000 Subject: [PATCH 1/2] Adds a simple spin Wigner function calculator example Needs updating following mine and Russell's conversation with Lev to use the jobs interface and to be more general in its construction so that it can become an effective library routine rather than simple calculator. --- WignerFunctionDriver.py | 142 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 WignerFunctionDriver.py diff --git a/WignerFunctionDriver.py b/WignerFunctionDriver.py new file mode 100644 index 000000000000..263f435fcc47 --- /dev/null +++ b/WignerFunctionDriver.py @@ -0,0 +1,142 @@ +"""Wigner function calculator example driver. + +Implements the Wigner function introduced in section +IV. A Wigner Function For Tensor Products of Spins +in reference [1] + +Authors: + * R.P. Rundle [1] + * M.J. Everitt (m.j.everitt@physics.org) [1] + * ... + +Affiliations: + 1. Quantum Systems Engineering Research Group + Loughborough University, Leicestershire LE11 3TU, United Kingdom + +Todo: + * propper documentation + * more examples + * use jobs rather than api + +Refernces: + +[1] Quantum state reconstruction made easy: a direct method for tomography + R.P. Rundle, Todd Tilma, J. H. Samson, M. J. Everitt + https://arxiv.org/abs/1605.08922 + +[2] Wigner Functions for Arbitrary Quantum Systems + T Tilma, MJ Everitt, JH Samson, WJ Munro, K Nemoto + Physical review letters 117 (18), 180401 + https://doi.org/10.1103/PhysRevLett.117.180401 + https://arxiv.org/abs/1601.07772 + +License: +Apache License Version 2.0, January 2004 +http://www.apache.org/licenses/ + +Note: We would normally use GPL but have chosen Apache to fit with the +IBM Quantum Experience qiskit-sdk-py. + +""" + +## +# Functions that will form the library +# + +import math +import numpy as np +import matplotlib.pyplot as plt + +from IBMQuantumExperience import IBMQuantumExperience + +def generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesuremnts(theta,phi,qubits): + returnString="" + for i in range(len(theta)): + returnString = returnString + 'u3('+theta[i]+',0,'+phi[i]+') q[' + qubits[i]+ '];' + for j in range(len(theta)): + returnString = returnString + '\nmeasure q['+ qubits[j]+'] -> c['+str(j)+'];' + returnString = returnString +'\n' + return returnString + +def tensor_product_parity(nQubits): + """Calculates the tensor product parity operator for a given number of qubits""" + P = [0.5+0.5*math.sqrt(3),0.5-0.5*math.sqrt(3)] + par = 1 + for i in range(nQubits): + par = np.kron(par,P) + return par + + +def wigner_function(ibm_setup,theta,phi,qubits): + """Calulates the wigner fucntion at one point in phase space. + + Keyword arguments: + string -- the base string that is the start of the quantum code. + theta -- the theta roations for each qubit + phi -- the phi roations for each qubit + qubits -- array containing a the actual qubits used in the calculations - assumes assnding order + """ + message = "As arguments specify theta, phi and index of each qubit they must be of the same length." + assert len(theta)==len(phi), message + assert len(theta)==len(qubits), message + dimension=2**len(qubits) + # setup and run code on IBM and retive values + runString = ibm_setup['baseString'] + generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesuremnts(theta,phi,qubits) + ibm_setup['api'].run_experiment(runString, ibm_setup['device'], ibm_setup['shots'], timeout=90) + lastCodes =ibm_setup['api'].get_last_codes() + + datas = lastCodes[1]['executions'][0]['result']['data']['p'] + labels = datas['labels'] + results = datas['values'] + + # locally compute the wigner function from IBM output + parity = tensor_product_parity(len(theta)) + x = [0]*dimension + elements = len(results) + norm = 0.0 + for i in range(elements): + y = labels[i] + x[int(y, 2)] = float(results[i]) + norm = norm + float(results[i]) + W = 0.0 + for i in range(dimension): + W = W+(x[i]/norm)*parity[i] + return W + + +## +# Do some setup including commands for state preparation (currently |00>+|11>) +# + +token="PUT A VALID TOKEN HERE" + +api=IBMQuantumExperience(token) +###baseString includes creation of a Bell state + +setup = { "api" : api, + "config" : {'url': 'https://quantumexperience.ng.bluemix.net/api'}, + "device" : 'simulator', + "shots" : 1024, + "baseString": 'OPENQASM 2.0;\n\ninclude "qelib1.inc";\nqreg q[5];\ncreg c[5];\nh q[0];\ncx q[0],q[2];' + } + +## +# Calculate and plot an equatorial section of the equal angle slice of the Wigner function +# + +number_output_points=20 +W=[0]*number_output_points +phis=[0]*number_output_points + +for phiindex in range(0, number_output_points): + phi_string = str(phiindex)+'*2*pi/'+str(number_output_points) + theta = ['pi/2','pi/2'] + phi = [phi_string,phi_string] + qubits = ['0','2'] + print(phi_string) + + W[phiindex] = wigner_function(setup,theta,phi,qubits) + +print(W) +plt.plot(W) +plt.show() From a3b46ae20495f1aa36b481e1db56f3c09308097a Mon Sep 17 00:00:00 2001 From: Mark Everitt Date: Thu, 25 May 2017 09:52:26 +0100 Subject: [PATCH 2/2] Updated for batch processing Creates GHZ states but may not work for two qubits and has problems above five. --- WignerFunctionDriver.py | 214 +++++++++++++++++++++++----------------- 1 file changed, 126 insertions(+), 88 deletions(-) diff --git a/WignerFunctionDriver.py b/WignerFunctionDriver.py index 263f435fcc47..2d78bc069439 100644 --- a/WignerFunctionDriver.py +++ b/WignerFunctionDriver.py @@ -1,44 +1,43 @@ """Wigner function calculator example driver. - -Implements the Wigner function introduced in section -IV. A Wigner Function For Tensor Products of Spins -in reference [1] - -Authors: - * R.P. Rundle [1] - * M.J. Everitt (m.j.everitt@physics.org) [1] - * ... - -Affiliations: - 1. Quantum Systems Engineering Research Group - Loughborough University, Leicestershire LE11 3TU, United Kingdom - -Todo: - * propper documentation - * more examples - * use jobs rather than api - -Refernces: - -[1] Quantum state reconstruction made easy: a direct method for tomography - R.P. Rundle, Todd Tilma, J. H. Samson, M. J. Everitt - https://arxiv.org/abs/1605.08922 - -[2] Wigner Functions for Arbitrary Quantum Systems - T Tilma, MJ Everitt, JH Samson, WJ Munro, K Nemoto - Physical review letters 117 (18), 180401 - https://doi.org/10.1103/PhysRevLett.117.180401 - https://arxiv.org/abs/1601.07772 - -License: -Apache License Version 2.0, January 2004 -http://www.apache.org/licenses/ - -Note: We would normally use GPL but have chosen Apache to fit with the -IBM Quantum Experience qiskit-sdk-py. - -""" - ++ ++Implements the Wigner function introduced in section ++IV. A Wigner Function For Tensor Products of Spins ++in reference [1] ++ ++Authors: ++ * R.P. Rundle [1] ++ * M.J. Everitt (m.j.everitt@physics.org) [1] ++ * ... ++ ++Affiliations: ++ 1. Quantum Systems Engineering Research Group ++ Loughborough University, Leicestershire LE11 3TU, United Kingdom ++ ++Todo: ++ * propper documentation ++ * more examples ++ * use jobs rather than api ++ ++Refernces: ++ ++[1] Quantum state reconstruction made easy: a direct method for tomography ++ R.P. Rundle, Todd Tilma, J. H. Samson, M. J. Everitt ++ https://arxiv.org/abs/1605.08922 ++ ++[2] Wigner Functions for Arbitrary Quantum Systems ++ T Tilma, MJ Everitt, JH Samson, WJ Munro, K Nemoto ++ Physical review letters 117 (18), 180401 ++ https://doi.org/10.1103/PhysRevLett.117.180401 ++ https://arxiv.org/abs/1601.07772 ++ ++License: ++Apache License Version 2.0, January 2004 ++http://www.apache.org/licenses/ ++ ++Note: We would normally use GPL but have chosen Apache to fit with the ++IBM Quantum Experience qiskit-sdk-py. ++ ++""" ## # Functions that will form the library # @@ -46,10 +45,8 @@ import math import numpy as np import matplotlib.pyplot as plt - -from IBMQuantumExperience import IBMQuantumExperience - -def generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesuremnts(theta,phi,qubits): +from IBMQuantumExperience import IBMQuantumExperience +def generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesurements(theta,phi,qubits): returnString="" for i in range(len(theta)): returnString = returnString + 'u3('+theta[i]+',0,'+phi[i]+') q[' + qubits[i]+ '];' @@ -58,6 +55,16 @@ def generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesuremnts(the returnString = returnString +'\n' return returnString +def generate_qasms_for_batch_runs(baseString, qubits, number_output_points, theta): + phi = [0]*len(qubits) + runStrings = [0]*(number_output_points) + for phiindex in range(0,number_output_points): + for i in range(0,len(qubits)): + phi_string = str(phiindex)+'*2*pi/'+str(number_output_points) + phi[i] = phi_string + runStrings[phiindex] = {'qasm': baseString + generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesurements(theta,phi,qubits)} + return runStrings + def tensor_product_parity(nQubits): """Calculates the tensor product parity operator for a given number of qubits""" P = [0.5+0.5*math.sqrt(3),0.5-0.5*math.sqrt(3)] @@ -67,7 +74,7 @@ def tensor_product_parity(nQubits): return par -def wigner_function(ibm_setup,theta,phi,qubits): +def wigner_function(ibm_setup,runStrings,qubits,number_output_points): """Calulates the wigner fucntion at one point in phase space. Keyword arguments: @@ -76,67 +83,98 @@ def wigner_function(ibm_setup,theta,phi,qubits): phi -- the phi roations for each qubit qubits -- array containing a the actual qubits used in the calculations - assumes assnding order """ - message = "As arguments specify theta, phi and index of each qubit they must be of the same length." - assert len(theta)==len(phi), message - assert len(theta)==len(qubits), message - dimension=2**len(qubits) + #message = "As arguments specify theta, phi and index of each qubit they must be of the same length." + #assert len(theta)==len(phi), message + #assert len(theta)==len(qubits), message + number_qubits = len(qubits) + dimension=2**number_qubits # setup and run code on IBM and retive values - runString = ibm_setup['baseString'] + generate_instructions_for_IBM_to_perfom_correct_rotations_and_mesuremnts(theta,phi,qubits) - ibm_setup['api'].run_experiment(runString, ibm_setup['device'], ibm_setup['shots'], timeout=90) - lastCodes =ibm_setup['api'].get_last_codes() - - datas = lastCodes[1]['executions'][0]['result']['data']['p'] - labels = datas['labels'] - results = datas['values'] + + job = ibm_setup['api'].run_job(runStrings, ibm_setup['device'], ibm_setup['shots']) + #lastCodes =ibm_setup['api'].get_last_codes() + #print(lastCodes) + #print(job) + #job_id = job[1] + #print(job_id) + job_id = job['id'] + print('job id' + job_id) + lastCodes = ibm_setup['api'].get_job(job_id) + #print(lastCodes) + datas = [0]*number_output_points + for i in range(0,number_output_points): + datas[i] = lastCodes['qasms'][i]['result']['data']['counts'] + #labels = datas['labels'] + #results = datas['values'] # locally compute the wigner function from IBM output parity = tensor_product_parity(len(theta)) - x = [0]*dimension - elements = len(results) - norm = 0.0 - for i in range(elements): - y = labels[i] - x[int(y, 2)] = float(results[i]) - norm = norm + float(results[i]) - W = 0.0 - for i in range(dimension): - W = W+(x[i]/norm)*parity[i] + W = [0]*number_output_points + for point in range(0,number_output_points): + x = [0]*dimension + norm = 0.0 + for i in range(dimension): + if bin(i)[2:].zfill(number_qubits) in datas[point]: + x[i] = float(datas[point][bin(i)[2:].zfill(number_qubits)]) + norm = norm + float(datas[point][bin(i)[2:].zfill(number_qubits)]) + for i in range(dimension): + W[point] = W[point]+(x[i]/norm)*parity[i] return W ## -# Do some setup including commands for state preparation (currently |00>+|11>) +# Do some setup including commands for state preparation (currently |00>+|11>) # - -token="PUT A VALID TOKEN HERE" - +token = 'token' ### <-- put your token here api=IBMQuantumExperience(token) +number_of_qubits = 3 ###baseString includes creation of a Bell state - +baseString1 = 'OPENQASM 2.0;\n\ninclude "qelib1.inc";\nqreg q['+str(number_of_qubits)+'];\ncreg c['+str(number_of_qubits)+'];' +###assuming qubit 7 is central qubit +centralQubit = 2 +baseString2 = '\nh q[0];' +baseString3 = '\ncx q[0],q['+str(centralQubit)+'];' +baseString4 = '\nh q[0];' +for i in range(1,number_of_qubits): + if i != centralQubit: + baseString2 = baseString2 + '\nh q['+str(i)+'];' + baseString3 = baseString3 + '\ncx q['+str(i)+'],q['+str(centralQubit)+'];' + baseString4 = baseString4 + '\nh q['+str(i)+'];' + else: + baseString2 = baseString2 + '\nx q['+str(i)+'];' + baseString4 = baseString4 + '\nh q['+str(i)+'];' + +baseString = baseString1+baseString2+baseString3+baseString4 setup = { "api" : api, "config" : {'url': 'https://quantumexperience.ng.bluemix.net/api'}, "device" : 'simulator', - "shots" : 1024, - "baseString": 'OPENQASM 2.0;\n\ninclude "qelib1.inc";\nqreg q[5];\ncreg c[5];\nh q[0];\ncx q[0],q[2];' + "shots" : 4000, + "baseString": baseString } -## -# Calculate and plot an equatorial section of the equal angle slice of the Wigner function +### +# Calculate and plot an equatorial section of the equal angle slice of the Wigner function # -number_output_points=20 -W=[0]*number_output_points -phis=[0]*number_output_points +number_output_points=160 -for phiindex in range(0, number_output_points): - phi_string = str(phiindex)+'*2*pi/'+str(number_output_points) - theta = ['pi/2','pi/2'] - phi = [phi_string,phi_string] - qubits = ['0','2'] - print(phi_string) - - W[phiindex] = wigner_function(setup,theta,phi,qubits) +W = [0]*number_output_points +equatorAngle = [0]*number_output_points +theta = [0]*number_of_qubits +qubits = [0]*number_of_qubits + +for i in range(0,number_of_qubits): + theta[i] = 'pi/2' + qubits[i] = str(i) +for i in range(0,number_output_points): + equatorAngle[i] = i*2*math.pi/number_output_points -print(W) -plt.plot(W) +runStrings = generate_qasms_for_batch_runs(baseString, qubits, number_output_points, theta) + +batchSize = 10 + +for i in range(0,(number_output_points/batchSize)): + W[i*batchSize:(i+1)*batchSize] = wigner_function(setup,runStrings[i*batchSize:(i+1)*batchSize], qubits, batchSize) + print(W) + +plt.plot(equatorAngle,W) plt.show()