diff --git a/data/principal_components.npy b/data/principal_components.npy new file mode 100644 index 0000000..6fba20e Binary files /dev/null and b/data/principal_components.npy differ diff --git a/quantum_classifier.qasm b/quantum_classifier.qasm index bad476c..a7dd49f 100644 --- a/quantum_classifier.qasm +++ b/quantum_classifier.qasm @@ -1,4 +1,16 @@ OPENQASM 2.0; include "qelib1.inc"; -qreg q8[3]; -rx(pi) q8[0]; +gate gate_EfficientSU2(param0,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10,param11,param12,param13,param14,param15) q0,q1,q2,q3 { ry(-1.34733884839068) q0; ry(-3.11672195169602) q1; ry(-0.304542042319692) q2; ry(1.67808380799382) q3; rz(-5.86904321551186) q0; rz(-3.03785103262473) q1; rz(0.00911013189400474) q2; rz(0.209435263325009) q3; cx q2,q3; cx q1,q2; cx q0,q1; ry(0.437871284345484) q0; ry(-0.66918976850911) q1; ry(-0.167103421568986) q2; ry(0.73890146588358) q3; rz(-2.53048162240718) q0; rz(-4.52355957377889) q1; rz(-4.60529227190883) q2; rz(-1.55360289533166) q3; } +gate gate_EfficientSU2_239742 q0,q1,q2,q3 { gate_EfficientSU2(-1.34733884839068,-3.11672195169602,-0.304542042319692,1.67808380799382,-5.86904321551186,-3.03785103262473,0.00911013189400474,0.209435263325009,0.437871284345484,-0.66918976850911,-0.167103421568986,0.73890146588358,-2.53048162240718,-4.52355957377889,-4.60529227190883,-1.55360289533166) q0,q1,q2,q3; } +qreg q[4]; +creg meas[4]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +gate_EfficientSU2_239742 q[0],q[1],q[2],q[3]; +barrier q[0],q[1],q[2],q[3]; +measure q[0] -> meas[0]; +measure q[1] -> meas[1]; +measure q[2] -> meas[2]; +measure q[3] -> meas[3]; diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..85a3e3e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,214 @@ +aiofile==3.8.1 +aiohttp==3.8.3 +aiosignal==1.3.1 +alembic @ file:///home/conda/feedstock_root/build_artifacts/alembic_1647367721563/work +anyio @ file:///home/conda/feedstock_root/build_artifacts/anyio_1641898043316/work/dist +argon2-cffi @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi_1640817743617/work +argon2-cffi-bindings @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi-bindings_1640855140139/work +asttokens @ file:///home/conda/feedstock_root/build_artifacts/asttokens_1618968359944/work +async-generator==1.10 +async-timeout==4.0.2 +attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1640799537051/work +awscli==1.27.57 +azure-core==1.26.2 +azure-identity==1.12.0 +azure-quantum @ file:///home/vsts_azpcontainer/conda-bld/qsharp_1670279498240/work/src/drops/wheels/azure_quantum-0.27.244707-py3-none-any.whl +azure-storage-blob==12.14.1 +Babel @ file:///home/conda/feedstock_root/build_artifacts/babel_1619719576210/work +backcall @ file:///home/conda/feedstock_root/build_artifacts/backcall_1592338393461/work +backports.functools-lru-cache @ file:///home/conda/feedstock_root/build_artifacts/backports.functools_lru_cache_1618230623929/work +beautifulsoup4 @ file:///home/conda/feedstock_root/build_artifacts/beautifulsoup4_1631087867185/work +bleach @ file:///home/conda/feedstock_root/build_artifacts/bleach_1629908509068/work +blinker==1.4 +bokeh==3.0.3 +botocore==1.29.57 +brotlipy @ file:///home/conda/feedstock_root/build_artifacts/brotlipy_1636012194889/work +caio==0.9.11 +certifi==2022.12.7 +certipy==0.1.3 +cffi @ file:///home/conda/feedstock_root/build_artifacts/cffi_1636046055389/work +charset-normalizer==3.0.1 +cirq-core==0.14.1 +cirq-ionq==0.14.1 +code-snippets @ file:///tmp/qbraid/wheels/code_snippets-0.1.2-py3-none-any.whl +colorama @ file:///home/conda/feedstock_root/build_artifacts/colorama_1602866480661/work +comm==0.1.2 +conda==4.11.0 +conda-package-handling @ file:///home/conda/feedstock_root/build_artifacts/conda-package-handling_1636021710069/work +configobj==5.0.8 +contourpy==1.0.7 +cryptography @ file:///home/conda/feedstock_root/build_artifacts/cryptography_1639699280527/work +cycler==0.11.0 +Cython==0.29.33 +debugpy @ file:///home/conda/feedstock_root/build_artifacts/debugpy_1636043249011/work +decorator==5.1.1 +defusedxml @ file:///home/conda/feedstock_root/build_artifacts/defusedxml_1615232257335/work +Deprecated==1.2.13 +dill==0.3.5.1 +docs-react-widget @ file:///tmp/qbraid/wheels/docs_react_widget-0.1.0-py3-none-any.whl +docutils==0.16 +duet==0.2.7 +entrypoints @ file:///home/conda/feedstock_root/build_artifacts/entrypoints_1643888246732/work +environment-manager @ file:///tmp/qbraid/wheels/environment_manager-0.1.4-py3-none-any.whl +executing @ file:///home/conda/feedstock_root/build_artifacts/executing_1646044401614/work +fastdtw==0.3.4 +fastjsonschema==2.16.2 +flit_core @ file:///home/conda/feedstock_root/build_artifacts/flit-core_1645629044586/work/source/flit_core +fonttools==4.38.0 +frozenlist==1.3.3 +future==0.18.3 +gitdb==4.0.10 +GitPython==3.1.30 +greenlet @ file:///home/conda/feedstock_root/build_artifacts/greenlet_1635836790477/work +idna==3.4 +importlib-metadata==6.0.0 +importlib-resources @ file:///home/conda/feedstock_root/build_artifacts/importlib_resources_1635615662634/work +ipykernel==6.20.2 +ipyparallel==8.4.1 +ipython==8.8.0 +ipython-genutils==0.2.0 +ipyvue==1.8.0 +ipyvuetify==1.8.4 +ipywidgets==8.0.4 +isodate==0.6.1 +jedi @ file:///home/conda/feedstock_root/build_artifacts/jedi_1637175083648/work +Jinja2 @ file:///home/conda/feedstock_root/build_artifacts/jinja2_1636510082894/work +jmespath==1.0.1 +joblib==1.2.0 +json5 @ file:///home/conda/feedstock_root/build_artifacts/json5_1600692310011/work +jsonschema @ file:///home/conda/feedstock_root/build_artifacts/jsonschema-meta_1642000296051/work +jupyter-bokeh==3.0.5 +jupyter-client @ file:///home/conda/feedstock_root/build_artifacts/jupyter_client_1642858610849/work +jupyter-server==1.23.5 +jupyter-server-mathjax==0.2.6 +jupyter-telemetry @ file:///home/conda/feedstock_root/build_artifacts/jupyter_telemetry_1605173804246/work +jupyter_core==5.1.5 +jupyterhub @ file:///home/conda/feedstock_root/build_artifacts/jupyterhub-feedstock_1647267198467/work +jupyterlab==3.5.3 +jupyterlab-git==0.41.0 +jupyterlab-pygments @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_pygments_1601375948261/work +jupyterlab-server @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_server_1641592475363/work +jupyterlab-widgets==3.0.5 +kiwisolver==1.4.4 +lab-main-menu @ file:///tmp/qbraid/wheels/lab_main_menu-0.1.1-py3-none-any.whl +libmambapy @ file:///home/conda/feedstock_root/build_artifacts/mamba-split_1644831758535/work/libmambapy +Mako @ file:///home/conda/feedstock_root/build_artifacts/mako_1646959760357/work +mamba @ file:///home/conda/feedstock_root/build_artifacts/mamba-split_1644831758535/work/mamba +Markdown==3.4.1 +MarkupSafe @ file:///home/conda/feedstock_root/build_artifacts/markupsafe_1647364298597/work +matplotlib==3.6.3 +matplotlib-inline @ file:///home/conda/feedstock_root/build_artifacts/matplotlib-inline_1631080358261/work +mistune==2.0.4 +mpltools==0.2.0 +mpmath==1.2.1 +msal==1.20.0 +msal-extensions==1.0.0 +msrest==0.7.1 +multidict==6.0.4 +nbclassic==0.4.8 +nbclient==0.7.2 +nbconvert==7.2.9 +nbdime==3.1.1 +nbformat==5.7.3 +nest-asyncio @ file:///home/conda/feedstock_root/build_artifacts/nest-asyncio_1638419302549/work +networkx==2.8.8 +notebook==6.5.2 +notebook-shim @ file:///home/conda/feedstock_root/build_artifacts/notebook-shim_1646330736330/work +ntlm-auth==1.5.0 +numpy==1.24.1 +oauthlib @ file:///home/conda/feedstock_root/build_artifacts/oauthlib_1643507977997/work +packaging==23.0 +pamela==1.0.0 +pandas==1.5.3 +pandocfilters @ file:///home/conda/feedstock_root/build_artifacts/pandocfilters_1631603243851/work +parso @ file:///home/conda/feedstock_root/build_artifacts/parso_1638334955874/work +pbr==5.11.1 +pexpect @ file:///home/conda/feedstock_root/build_artifacts/pexpect_1602535608087/work +pickleshare @ file:///home/conda/feedstock_root/build_artifacts/pickleshare_1602536217715/work +Pillow==9.4.0 +platformdirs==2.6.2 +ply==3.11 +portalocker==2.7.0 +prometheus-client @ file:///home/conda/feedstock_root/build_artifacts/prometheus_client_1643395600215/work +prompt-toolkit @ file:///home/conda/feedstock_root/build_artifacts/prompt-toolkit_1644497866770/work +protobuf==3.20.3 +psutil==5.9.4 +ptyprocess @ file:///home/conda/feedstock_root/build_artifacts/ptyprocess_1609419310487/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl +pure-eval @ file:///home/conda/feedstock_root/build_artifacts/pure_eval_1642875951954/work +py==1.11.0 +pyasn1==0.4.8 +pycosat @ file:///home/conda/feedstock_root/build_artifacts/pycosat_1636020362356/work +pycparser @ file:///home/conda/feedstock_root/build_artifacts/pycparser_1636257122734/work +pycurl==7.45.1 +Pygments @ file:///home/conda/feedstock_root/build_artifacts/pygments_1641580240686/work +PyJWT @ file:///home/conda/feedstock_root/build_artifacts/pyjwt_1638819640841/work +pyOpenSSL @ file:///home/conda/feedstock_root/build_artifacts/pyopenssl_1643496850550/work +pyparsing==3.0.9 +pyqir-generator==0.4.2a1 +pyrsistent @ file:///home/conda/feedstock_root/build_artifacts/pyrsistent_1642534390768/work +PySocks @ file:///home/conda/feedstock_root/build_artifacts/pysocks_1635862404942/work +python-dateutil==2.8.2 +python-json-logger @ file:///home/conda/feedstock_root/build_artifacts/python-json-logger_1602545356084/work +python-markdown-math==0.8 +pytz==2022.7.1 +PyYAML==5.4.1 +pyzmq @ file:///home/conda/feedstock_root/build_artifacts/pyzmq_1635877397296/work +qdk @ file:///home/vsts_azpcontainer/conda-bld/qsharp_1670279498240/work/src/drops/wheels/qdk-0.27.244707-py3-none-any.whl +QInfer==1.0 +qiskit==0.39.5 +qiskit-aer==0.11.2 +qiskit-ibmq-provider==0.19.2 +qiskit-ionq==0.3.10 +qiskit-machine-learning==0.5.0 +qiskit-qir==0.2.0 +qiskit-terra==0.23.0 +qsharp @ file:///home/vsts_azpcontainer/conda-bld/qsharp_1670279498240/work/src/drops/wheels/qsharp-0.27.244707-py3-none-any.whl +qsharp-chemistry @ file:///home/vsts_azpcontainer/conda-bld/qsharp_1670279498240/work/src/drops/wheels/qsharp_chemistry-0.27.244707-py3-none-any.whl +qsharp-core @ file:///home/vsts_azpcontainer/conda-bld/qsharp_1670279498240/work/src/drops/wheels/qsharp_core-0.27.244707-py3-none-any.whl +quantum-jobs @ file:///tmp/qbraid/wheels/quantum_jobs-0.1.1-py3-none-any.whl +qutip==4.7.1 +requests==2.28.2 +requests-ntlm==1.1.0 +requests-oauthlib==1.3.1 +retry==0.9.2 +retworkx==0.12.1 +rsa==4.7.2 +ruamel-yaml-conda @ file:///home/conda/feedstock_root/build_artifacts/ruamel_yaml_1636009144459/work +ruamel.yaml @ file:///home/conda/feedstock_root/build_artifacts/ruamel.yaml_1644759508211/work +ruamel.yaml.clib @ file:///home/conda/feedstock_root/build_artifacts/ruamel.yaml.clib_1636815619750/work +rustworkx==0.12.1 +s3transfer==0.6.0 +scikit-learn==1.2.1 +scipy==1.10.0 +Send2Trash @ file:///home/conda/feedstock_root/build_artifacts/send2trash_1628511208346/work +six==1.16.0 +smmap==5.0.0 +sniffio @ file:///home/conda/feedstock_root/build_artifacts/sniffio_1635844660462/work +sortedcontainers==2.4.0 +soupsieve @ file:///home/conda/feedstock_root/build_artifacts/soupsieve_1638550740809/work +SQLAlchemy @ file:///home/conda/feedstock_root/build_artifacts/sqlalchemy_1646615291967/work +stack-data @ file:///home/conda/feedstock_root/build_artifacts/stack_data_1644872665635/work +stevedore==4.1.1 +symengine==0.9.2 +sympy==1.9 +terminado @ file:///home/conda/feedstock_root/build_artifacts/terminado_1646684455438/work +testpath @ file:///home/conda/feedstock_root/build_artifacts/testpath_1645693042223/work +threadpoolctl==3.1.0 +tinycss2==1.2.1 +tomli==2.0.1 +tornado @ file:///home/conda/feedstock_root/build_artifacts/tornado_1635819584296/work +tqdm==4.64.1 +traitlets==5.8.1 +tweedledum==1.1.1 +typing_extensions==4.4.0 +ui-tweaks @ file:///tmp/qbraid/wheels/ui_tweaks-0.1.1-py3-none-any.whl +urllib3==1.26.14 +wcwidth @ file:///home/conda/feedstock_root/build_artifacts/wcwidth_1600965781394/work +webencodings==0.5.1 +websocket-client @ file:///home/conda/feedstock_root/build_artifacts/websocket-client_1645884408572/work +websockets==10.4 +widgetsnbextension==4.0.5 +wrapt==1.14.1 +xyzservices==2022.9.0 +yarl==1.8.2 +zipp==3.11.0 diff --git a/test_qiskit.py b/test_qiskit.py index ed25cd9..3ce88dc 100644 --- a/test_qiskit.py +++ b/test_qiskit.py @@ -1,5 +1,8 @@ +# team name IonCoffee +# oana.bazavan@physics.ox.ac.uk +# challenge ionq remote import qiskit -from qiskit import quantum_info +from qiskit import quantum_info, QuantumCircuit from qiskit.execute_function import execute from qiskit import BasicAer import numpy as np @@ -14,46 +17,42 @@ if len(sys.argv) > 1: data_path = sys.argv[1] + else: data_path = '.' - -#define utility functions - -def simulate(circuit: qiskit.QuantumCircuit) -> dict: - """Simulate the circuit, give the state vector as the result.""" - backend = BasicAer.get_backend('statevector_simulator') - job = execute(circuit, backend) - result = job.result() - state_vector = result.get_statevector() - - histogram = dict() - for i in range(len(state_vector)): - population = abs(state_vector[i]) ** 2 - if population > 1e-9: - histogram[i] = population - - return histogram - - -def histogram_to_category(histogram): - """This function takes a histogram representation of circuit execution results, and processes into labels as described in - the problem description.""" - assert abs(sum(histogram.values())-1)<1e-8 - positive=0 - for key in histogram.keys(): - digits = bin(int(key))[2:].zfill(20) - if digits[-1]=='0': - positive+=histogram[key] - - return positive +data_path = "data" + + +def simulate(circuit): + backend = backend = BasicAer.get_backend('qasm_simulator') + job = execute(circuit, backend, shots = 10000) + return job.result().get_counts() + + +def histogram_to_category(counts): + # predicts 0 (not a tshirt) or 1 (t-shirt) from histogram of circuit measurements + # majority vote + zeros = 0 + ones = 0 + for count in counts: + for bit in count: + if bit == '0': + zeros += counts[count] + if bit == '1': + ones += counts[count] + if zeros > ones: + prediction = 0 + else: + prediction = 1 + return prediction def count_gates(circuit: qiskit.QuantumCircuit) -> Dict[int, int]: """Returns the number of gate operations with each number of qubits.""" counter = Counter([len(gate[1]) for gate in circuit.data]) #feel free to comment out the following two lines. But make sure you don't have k-qubit gates in your circuit #for k>2 - for i in range(2,20): - assert counter[i]==0 + #for i in range(2,20): + # assert counter[i]==0 return counter @@ -61,12 +60,12 @@ def count_gates(circuit: qiskit.QuantumCircuit) -> Dict[int, int]: def image_mse(image1,image2): # Using sklearns mean squared error: # https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html - return mean_squared_error(255*image1,255*image2) + return mean_squared_error(image1,image2) def test(): #load the actual hackthon data (fashion-mnist) - images=np.load(data_path+'/images.npy') - labels=np.load(data_path+'/labels.npy') + images=np.load('data/images.npy') + labels=np.load('data/labels.npy') #test part 1 @@ -83,7 +82,7 @@ def test(): gatecount+=count_gates(circuit)[2] #calculate mse - mse+=image_mse(image,image_re) + mse+=image_mse(image,image_re) # we didnt normalise the image as per the original problem #fidelity of reconstruction f=1-mse/n @@ -91,7 +90,7 @@ def test(): #score for part1 score_part1=f*(0.999**gatecount) - + #test part 2 score=0 @@ -121,57 +120,90 @@ def test(): # YOUR CODE HERE # ############################ def encode(image): - q = qiskit.QuantumRegister(3) - circuit = qiskit.QuantumCircuit(q) - if image[0][0]==0: - circuit.rx(np.pi,0) - return circuit + n_components = 8 + num_qub = 4 + principal_components = np.load('data/principal_components.npy') + xx = image.flatten() + x_principal_comps = np.zeros([n_components]) + for i in range(n_components): + x_principal_comps[i] = np.dot(xx, principal_components[i]) + + desired_state = np.zeros(2**num_qub) + for i,comp in enumerate(x_principal_comps): + if comp>0: + desired_state[i]= comp + else: + desired_state[i+8] = comp + + desired_state = np.array(desired_state)/np.linalg.norm(desired_state) + + qc_LI = QuantumCircuit(num_qub, num_qub) + qc_LI.initialize(desired_state, [0,1,2,3]) + qc_LI_width = qc_LI.width() + return qc_LI.decompose(reps=10) def decode(histogram): - if 1 in histogram.keys(): - image=[[0,0],[0,0]] - else: - image=[[1,1],[1,1]] - return image + from collections import OrderedDict + od = OrderedDict(sorted(histogram.items())) + Counts = np.zeros(2**num_qub) + total_Counts = 0. + + for key in od.keys(): + Counts[int(key[0:4],2)] = od[key] + total_Counts +=od[key] + + amplitudes = np.sqrt(Counts/total_Counts) + reconst_principle_vals = np.zeros(8) + + for i in range(8): + if (amplitudes[i]>amplitudes[i+8]): + reconst_principle_vals[i] = amplitudes[i] + else: + reconst_principle_vals[i] = -1*amplitudes[i+8] + image_re = np.zeros(28*28) + + for i,a in enumerate(reconst_principle_vals): + image_re += a*principal_components[i,:] + + image_re = image_re.reshape(28,28) + return image_re def run_part1(image): - #encode image into a circuit - circuit=encode(image) - - #simulate circuit - histogram=simulate(circuit) - - #reconstruct the image - image_re=decode(histogram) - - return circuit,image_re + global num_qub + num_qub = 4 #3 for amplitudes 1 for sign + global n_components + n_components = 8 + global principal_components + principal_components = np.load("data/principal_components.npy") + circuit = encode(image) + #circuit.measure_all() + histogram = simulate(circuit) + image_re = decode(histogram) + return circuit, image_re def run_part2(image): # load the quantum classifier circuit classifier=qiskit.QuantumCircuit.from_qasm_file('quantum_classifier.qasm') - + #classifier.measure_all() #encode image into circuit circuit=encode(image) - + circuit.draw() #append with classifier circuit nq1 = circuit.width() + #print(nq1) nq2 = classifier.width() + #print(nq2) nq = max(nq1, nq2) - qc = qiskit.QuantumCircuit(nq) - qc.append(circuit.to_instruction(), list(range(nq1))) - qc.append(classifier.to_instruction(), list(range(nq2))) + qc = qiskit.QuantumCircuit(4) + qc.compose(circuit, inplace = True) + qc.compose(classifier, inplace = True) + #qc.append(circuit.to_instruction(), list(range(4)), list(range(4))) + #qc.append(classifier.to_instruction(), list(range(4)), list(range(4))) #simulate circuit histogram=simulate(qc) - #convert histogram to category label=histogram_to_category(histogram) - - #thresholding the label, any way you want - if label>0.5: - label=1 - else: - label=0 return circuit,label