Usage examples#
# this cell is hidden in the docs
# it installs the requirements to run this demo
#!python -m pip install qutree[demo]
from urllib.request import urlretrieve
import tempfile
import numpy as np
import matplotlib.pyplot as plt
import pennylane as qml
from scipy.stats import unitary_group
from qutree import BBT
Bell state preparation#
@qml.qnode(qml.device("default.qubit", wires=2))
def bell(t):
qml.Hadamard(wires=[0])
qml.CRY(np.pi*t,wires=[0,1])
return qml.state()
ts = np.linspace(0,1,21)
Ss = np.array([bell(t) for t in ts]).T
bbt = BBT(2)
bbt.add_data(Ss)
bbt.plot_tree()
The top sphere shows the effect of the hadamard gate : an even superposition between the two basis state without phase offset. Then on the bottom sphere we see the effect of the parametrised Control Y rotattion : The left sphere represent the subspace where the first qubit is 0. it is of course untouched by the CY gate. The right sphere represent the subspace where the first qubit is 1. The state is gradually rotated about the Y axis from 0 (blue) to 1 (red). The bell state corresponds to the red point.
Study how an encoding spans the hilbert space#
dev = qml.device('default.qubit', wires=3)
@qml.qnode(dev)
def circuit(t):
state = np.array([1, 2j, 3, t*1j, 5, 6j, 7, 8j])
state = state / np.linalg.norm(state)
qml.MottonenStatePreparation(state_vector=state, wires=range(3))
return qml.state()
print(qml.draw(circuit, expansion_strategy="device", max_length=80)(4))
0: ──RY(2.35)─╭●───────────╭●──────────────╭●────────────────────────╭●
1: ──RY(2.09)─╰X──RY(0.21)─╰X─╭●───────────│────────────╭●───────────│─
2: ──RY(1.88)─────────────────╰X──RY(0.10)─╰X──RY(0.08)─╰X──RY(0.15)─╰X
──╭●────────╭●────╭●────╭●─┤ ╭State
──╰X────────╰X─╭●─│──╭●─│──┤ ├State
───RZ(1.57)────╰X─╰X─╰X─╰X─┤ ╰State
ts = np.linspace(0,8,21)
Ss = np.array([circuit(t) for t in ts]).T
bbt = BBT(3)
bbt.add_data(Ss)
bbt.plot_tree()
quantum states dataset from Machine Learning#
The data is generated using the demo from pennylane about classification that can be found here : https://pennylane.ai/qml/demos/tutorial_variational_classifier.html
# read the file from data folder in github
with tempfile.NamedTemporaryFile() as tmp:
url = 'https://raw.githubusercontent.com/alice4space/qutree/main/docs/source/examples/data/iris_quantum_kernel.npy'
urlretrieve(url, tmp.name)
states_ml = np.load(tmp.name,allow_pickle=True)
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
Cell In[9], line 4
2 with tempfile.NamedTemporaryFile() as tmp:
3 url = 'https://raw.githubusercontent.com/alice4space/qutree/main/docs/source/examples/data/iris_quantum_kernel.npy'
----> 4 urlretrieve(url, tmp.name)
5 states_ml = np.load(tmp.name,allow_pickle=True)
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:241, in urlretrieve(url, filename, reporthook, data)
224 """
225 Retrieve a URL into a temporary location on disk.
226
(...)
237 data file as well as the resulting HTTPMessage object.
238 """
239 url_type, path = _splittype(url)
--> 241 with contextlib.closing(urlopen(url, data)) as fp:
242 headers = fp.info()
244 # Just return the local path and the "headers" for file://
245 # URLs. No sense in performing a copy unless requested.
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:216, in urlopen(url, data, timeout, cafile, capath, cadefault, context)
214 else:
215 opener = _opener
--> 216 return opener.open(url, data, timeout)
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:525, in OpenerDirector.open(self, fullurl, data, timeout)
523 for processor in self.process_response.get(protocol, []):
524 meth = getattr(processor, meth_name)
--> 525 response = meth(req, response)
527 return response
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:634, in HTTPErrorProcessor.http_response(self, request, response)
631 # According to RFC 2616, "2xx" code indicates that the client's
632 # request was successfully received, understood, and accepted.
633 if not (200 <= code < 300):
--> 634 response = self.parent.error(
635 'http', request, response, code, msg, hdrs)
637 return response
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:563, in OpenerDirector.error(self, proto, *args)
561 if http_err:
562 args = (dict, 'default', 'http_error_default') + orig_args
--> 563 return self._call_chain(*args)
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:496, in OpenerDirector._call_chain(self, chain, kind, meth_name, *args)
494 for handler in handlers:
495 func = getattr(handler, meth_name)
--> 496 result = func(*args)
497 if result is not None:
498 return result
File ~/.asdf/installs/python/3.10.13/lib/python3.10/urllib/request.py:643, in HTTPDefaultErrorHandler.http_error_default(self, req, fp, code, msg, hdrs)
642 def http_error_default(self, req, fp, code, msg, hdrs):
--> 643 raise HTTPError(req.full_url, code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
bbt = BBT(4)
lam = 0.3
cs = np.concatenate([np.random.random(50)*lam,np.random.random(50)*lam+1-lam])
bbt.add_data(states_ml.T,colors=cs)
bbt.plot_tree()
hamiltonian simulation#
num_qubits = 4
U = unitary_group.rvs(2**num_qubits,random_state = 0)
D,S = np.linalg.eigh(U)
excite only two eigenstates : a single frequency#
ka = 12
kb = 2
S0 = (S[:,ka]+S[:,kb])/np.sqrt(2)
Sts = []
ts = np.linspace(0,2*np.pi/np.abs(D[ka]-D[kb]),101)
for t in ts:
Sts.append(S @ np.diag(np.exp(1j*D*t)) @ S.T.conj() @ S0)
Sts = np.array(Sts).T
bbt = BBT(4)
bbt.add_data(Sts,cmap='hsv')
bbt.plot_tree()
excite three eigenstates : three frequencies#
ka = 12
kb = 2
kc = 4
S0 = (S[:,ka]+S[:,kb]+S[:,kc])/np.sqrt(3)
Sts = []
ts = np.linspace(0,5,101)
for t in ts:
Sts.append(S @ np.diag(np.exp(1j*D*t)) @ S.T.conj() @ S0)
Sts = np.array(Sts).T
bbt = BBT(4)
bbt.add_data(Sts,cmap='jet')
bbt.plot_tree()