mirror of https://github.com/Qiskit/qiskit.git
fixing headers in tools
This commit is contained in:
parent
de78623e46
commit
d09fdb90d5
|
@ -1,3 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
"""
|
||||
File: fermion_to_qubit_tools.py
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
"""
|
||||
Quantum Optimization tools.
|
||||
|
||||
|
@ -52,10 +68,10 @@ def SPSA_optimization(obj_fun, initial_theta, SPSA_parameters, max_trials, save_
|
|||
theta_minus_save.append(theta_minus)
|
||||
cost_plus_save.append(cost_plus)
|
||||
cost_minus_save.append(cost_minus)
|
||||
|
||||
|
||||
if k>=max_trials-last_avg:
|
||||
theta_best+=theta/last_avg
|
||||
|
||||
|
||||
# final cost update
|
||||
cost_final = obj_fun(theta_best)[0]
|
||||
print('Final objective function is: ' + str(cost_final))
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
"""
|
||||
Tools for working with Pauli Operators.
|
||||
|
||||
|
|
31
tools/qi.py
31
tools/qi.py
|
@ -2,15 +2,18 @@
|
|||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
||||
# Do not distribute.
|
||||
# It is provided without warranty or conditions of any kind, either express or
|
||||
# implied.
|
||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
||||
# https://github.com/IBM/qiskit-sdk-py
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
|
||||
"""
|
||||
A collection of useful quantum information functions.
|
||||
|
||||
|
@ -161,27 +164,27 @@ def devectorize(vec, method='col'):
|
|||
def choi_to_rauli(choi):
|
||||
"""
|
||||
Convert a Choi-matrix to a Pauli-basis superoperator.
|
||||
|
||||
|
||||
Note that this function assumes that the Choi-matrix
|
||||
is defined in the standard column-stacking converntion
|
||||
and is normalized to have trace 1. For a channel E this
|
||||
is defined as: choi = (I \otimes E)(bell_state).
|
||||
|
||||
|
||||
The resulting 'rauli' R acts on input states as
|
||||
|rho_out>_p = R.|rho_in>_p
|
||||
where |rho> = vectorize(rho, method='pauli')
|
||||
|
||||
|
||||
Args:
|
||||
Choi (matrix): the input Choi-matrix.
|
||||
|
||||
|
||||
Returns:
|
||||
A superoperator in the Pauli basis.
|
||||
"""
|
||||
# get number of qubits'
|
||||
n = int(np.log2(np.sqrt(len(choi))))
|
||||
pgp = pauli_group(n)
|
||||
rauli = np.array([ np.trace(np.dot(choi,
|
||||
np.kron(j.to_matrix().T, i.to_matrix())))
|
||||
rauli = np.array([ np.trace(np.dot(choi,
|
||||
np.kron(j.to_matrix().T, i.to_matrix())))
|
||||
for i in pgp for j in pgp])
|
||||
return rauli.reshape(4 ** n, 4 ** n)
|
||||
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
||||
# Do not distribute.
|
||||
# It is provided without warranty or conditions of any kind, either express or
|
||||
# implied.
|
||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
||||
# https://github.com/IBM/qiskit-sdk-py
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
|
||||
"""
|
||||
Functions for performing quantum state and process tomography experiments.
|
||||
|
||||
|
|
|
@ -2,13 +2,17 @@
|
|||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
||||
# Do not distribute.
|
||||
# It is provided without warranty or conditions of any kind, either express or
|
||||
# implied.
|
||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
||||
# https://github.com/IBM/qiskit-sdk-py
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# =============================================================================
|
||||
"""
|
||||
Visualization functions for quantum states.
|
||||
|
|
|
@ -1,451 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||
#
|
||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
||||
# Do not distribute.
|
||||
# It is provided without warranty or conditions of any kind, either express or
|
||||
# implied.
|
||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
||||
# https://github.com/IBM/qiskit-sdk-py
|
||||
# =============================================================================
|
||||
"""
|
||||
Visualization functions for quantum states.
|
||||
|
||||
Author: Jay Gambetta
|
||||
Andrew Cross
|
||||
Christopher J. Wood
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from functools import reduce
|
||||
from scipy import linalg as la
|
||||
from collections import Counter
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d import proj3d
|
||||
from matplotlib.patches import FancyArrowPatch
|
||||
from tools.pauli import pauli_group, pauli_singles
|
||||
|
||||
###############################################################
|
||||
# Plotting historgram
|
||||
###############################################################
|
||||
|
||||
|
||||
def plot_histogram(data, number_to_keep=False):
|
||||
"""Plot a histogram of data.
|
||||
|
||||
data is a dictionary of {'000': 5, '010': 113, ...}
|
||||
number_to_keep is the number of terms to plot and rest is made into a
|
||||
single bar called other values
|
||||
"""
|
||||
if number_to_keep is not False:
|
||||
data_temp = dict(Counter(data).most_common(number_to_keep))
|
||||
data_temp["rest"] = sum(data.values()) - sum(data_temp.values())
|
||||
data = data_temp
|
||||
|
||||
labels = sorted(data)
|
||||
values = np.array([data[key] for key in labels], dtype=float)
|
||||
pvalues = values / sum(values)
|
||||
numelem = len(values)
|
||||
ind = np.arange(numelem) # the x locations for the groups
|
||||
width = 0.35 # the width of the bars
|
||||
fig, ax = plt.subplots()
|
||||
rects = ax.bar(ind, pvalues, width, color='seagreen')
|
||||
# add some text for labels, title, and axes ticks
|
||||
ax.set_ylabel('Probabilities', fontsize=12)
|
||||
ax.set_xticks(ind)
|
||||
ax.set_xticklabels(labels, fontsize=12, rotation=70)
|
||||
ax.set_ylim([0., min([1.2, max([1.2 * val for val in pvalues])])])
|
||||
# attach some text labels
|
||||
for rect in rects:
|
||||
height = rect.get_height()
|
||||
ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
|
||||
'%f' % float(height),
|
||||
ha='center', va='bottom')
|
||||
plt.show()
|
||||
|
||||
|
||||
###############################################################
|
||||
# Plotting states
|
||||
###############################################################
|
||||
|
||||
class Arrow3D(FancyArrowPatch):
|
||||
"""Standard 3D arrow."""
|
||||
|
||||
def __init__(self, xs, ys, zs, *args, **kwargs):
|
||||
"""Create arrow."""
|
||||
FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs)
|
||||
self._verts3d = xs, ys, zs
|
||||
|
||||
def draw(self, renderer):
|
||||
"""Draw the arrow."""
|
||||
xs3d, ys3d, zs3d = self._verts3d
|
||||
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
|
||||
self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
|
||||
FancyArrowPatch.draw(self, renderer)
|
||||
|
||||
|
||||
def plot_bloch_vector(bloch, title=""):
|
||||
"""Plot the Bloch sphere.
|
||||
|
||||
Plot a sphere, axes, the Bloch vector, and its projections onto each axis.
|
||||
|
||||
Args:
|
||||
bloch (list[double]): array of three elements where [<x>, <y>,<z>]
|
||||
title (str): a string that represents the plot title
|
||||
|
||||
Returns:
|
||||
none: plot is shown with matplotlib to the screen
|
||||
|
||||
"""
|
||||
# Set arrow lengths
|
||||
arlen = 1.3
|
||||
|
||||
# Plot semi-transparent sphere
|
||||
u = np.linspace(0, 2 * np.pi, 100)
|
||||
v = np.linspace(0, np.pi, 100)
|
||||
x = np.outer(np.cos(u), np.sin(v))
|
||||
y = np.outer(np.sin(u), np.sin(v))
|
||||
z = np.outer(np.ones(np.size(u)), np.cos(v))
|
||||
|
||||
fig = plt.figure(figsize=(6, 6))
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
ax.set_aspect("equal")
|
||||
ax.plot_surface(x, y, z, color=(.5, .5, .5), alpha=0.1)
|
||||
|
||||
# Plot arrows (axes, Bloch vector, its projections)
|
||||
xa = Arrow3D([0, arlen], [0, 0], [0, 0], mutation_scale=20, lw=1,
|
||||
arrowstyle="-|>", color=(.5, .5, .5))
|
||||
ya = Arrow3D([0, 0], [0, arlen], [0, 0], mutation_scale=20, lw=1,
|
||||
arrowstyle="-|>", color=(.5, .5, .5))
|
||||
za = Arrow3D([0, 0], [0, 0], [0, arlen], mutation_scale=20, lw=1,
|
||||
arrowstyle="-|>", color=(.5, .5, .5))
|
||||
a = Arrow3D([0, bloch[0]], [0, bloch[1]], [0, bloch[2]], mutation_scale=20,
|
||||
lw=2, arrowstyle="simple", color="k")
|
||||
bax = Arrow3D([0, bloch[0]], [0, 0], [0, 0], mutation_scale=20, lw=2,
|
||||
arrowstyle="-", color="r")
|
||||
bay = Arrow3D([0, 0], [0, bloch[1]], [0, 0], mutation_scale=20, lw=2,
|
||||
arrowstyle="-", color="g")
|
||||
baz = Arrow3D([0, 0], [0, 0], [0, bloch[2]], mutation_scale=20, lw=2,
|
||||
arrowstyle="-", color="b")
|
||||
arrowlist = [xa, ya, za, a, bax, bay, baz]
|
||||
for arr in arrowlist:
|
||||
ax.add_artist(arr)
|
||||
|
||||
# Rotate the view
|
||||
ax.view_init(30, 30)
|
||||
|
||||
# Annotate the axes, shifts are ad-hoc for this (30, 30) view
|
||||
xp, yp, _ = proj3d.proj_transform(arlen, 0, 0, ax.get_proj())
|
||||
plt.annotate("x", xy=(xp, yp), xytext=(-3, -8), textcoords='offset points',
|
||||
ha='right', va='bottom')
|
||||
xp, yp, _ = proj3d.proj_transform(0, arlen, 0, ax.get_proj())
|
||||
plt.annotate("y", xy=(xp, yp), xytext=(6, -5), textcoords='offset points',
|
||||
ha='right', va='bottom')
|
||||
xp, yp, _ = proj3d.proj_transform(0, 0, arlen, ax.get_proj())
|
||||
plt.annotate("z", xy=(xp, yp), xytext=(2, 0), textcoords='offset points',
|
||||
ha='right', va='bottom')
|
||||
|
||||
plt.title(title)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_state_city(rho, title=""):
|
||||
"""Plot the cityscape of quantum state.
|
||||
|
||||
Plot two 3d bargraphs (two dimenstional) of the mixed state rho
|
||||
|
||||
Args:
|
||||
rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex
|
||||
numbers
|
||||
title (str): a string that represents the plot title
|
||||
|
||||
Returns:
|
||||
none: plot is shown with matplotlib to the screen
|
||||
|
||||
"""
|
||||
num = int(np.log2(len(rho)))
|
||||
|
||||
# get the real and imag parts of rho
|
||||
datareal = np.real(rho)
|
||||
dataimag = np.imag(rho)
|
||||
|
||||
# get the labels
|
||||
column_names = [bin(i)[2:].zfill(num) for i in range(2**num)]
|
||||
row_names = [bin(i)[2:].zfill(num) for i in range(2**num)]
|
||||
|
||||
lx = len(datareal[0]) # Work out matrix dimensions
|
||||
ly = len(datareal[:, 0])
|
||||
xpos = np.arange(0, lx, 1) # Set up a mesh of positions
|
||||
ypos = np.arange(0, ly, 1)
|
||||
xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25)
|
||||
|
||||
xpos = xpos.flatten()
|
||||
ypos = ypos.flatten()
|
||||
zpos = np.zeros(lx*ly)
|
||||
|
||||
dx = 0.5 * np.ones_like(zpos) # width of bars
|
||||
dy = dx.copy()
|
||||
dzr = datareal.flatten()
|
||||
dzi = dataimag.flatten()
|
||||
|
||||
fig = plt.figure(figsize=(8, 8))
|
||||
ax1 = fig.add_subplot(2, 1, 1, projection='3d')
|
||||
ax1.bar3d(xpos, ypos, zpos, dx, dy, dzr, color="g", alpha=0.5)
|
||||
ax2 = fig.add_subplot(2, 1, 2, projection='3d')
|
||||
ax2.bar3d(xpos, ypos, zpos, dx, dy, dzi, color="g", alpha=0.5)
|
||||
|
||||
ax1.set_xticks(np.arange(0.5, lx+0.5, 1))
|
||||
ax1.set_yticks(np.arange(0.5, ly+0.5, 1))
|
||||
ax1.axes.set_zlim3d(-1.0, 1.0001)
|
||||
ax1.set_zticks(np.arange(-1, 1, 0.5))
|
||||
ax1.w_xaxis.set_ticklabels(row_names, fontsize=12, rotation=45)
|
||||
ax1.w_yaxis.set_ticklabels(column_names, fontsize=12, rotation=-22.5)
|
||||
# ax1.set_xlabel('basis state', fontsize=12)
|
||||
# ax1.set_ylabel('basis state', fontsize=12)
|
||||
ax1.set_zlabel("Real[rho]")
|
||||
|
||||
ax2.set_xticks(np.arange(0.5, lx+0.5, 1))
|
||||
ax2.set_yticks(np.arange(0.5, ly+0.5, 1))
|
||||
ax2.axes.set_zlim3d(-1.0, 1.0001)
|
||||
ax2.set_zticks(np.arange(-1, 1, 0.5))
|
||||
ax2.w_xaxis.set_ticklabels(row_names, fontsize=12, rotation=45)
|
||||
ax2.w_yaxis.set_ticklabels(column_names, fontsize=12, rotation=-22.5)
|
||||
# ax2.set_xlabel('basis state', fontsize=12)
|
||||
# ax2.set_ylabel('basis state', fontsize=12)
|
||||
ax2.set_zlabel("Imag[rho]")
|
||||
plt.title(title)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_state_paulivec(rho, title=""):
|
||||
"""Plot the paulivec representation of a quantum state.
|
||||
|
||||
Plot a bargraph of the mixed state rho over the pauli matricies
|
||||
|
||||
Args:
|
||||
rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex
|
||||
numbers
|
||||
title (str): a string that represents the plot title
|
||||
|
||||
Returns:
|
||||
none: plot is shown with matplotlib to the screen
|
||||
|
||||
"""
|
||||
num = int(np.log2(len(rho)))
|
||||
labels = list(map(lambda x: x.to_label(), pauli_group(num)))
|
||||
values = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
|
||||
pauli_group(num)))
|
||||
numelem = len(values)
|
||||
ind = np.arange(numelem) # the x locations for the groups
|
||||
width = 0.5 # the width of the bars
|
||||
fig, ax = plt.subplots()
|
||||
ax.grid(zorder=0)
|
||||
ax.bar(ind, values, width, color='seagreen')
|
||||
|
||||
# add some text for labels, title, and axes ticks
|
||||
ax.set_ylabel('Expectation value', fontsize=12)
|
||||
ax.set_xticks(ind)
|
||||
ax.set_yticks([-1, -0.5, 0, 0.5, 1])
|
||||
ax.set_xticklabels(labels, fontsize=12, rotation=70)
|
||||
ax.set_xlabel('Pauli', fontsize=12)
|
||||
ax.set_ylim([-1, 1])
|
||||
plt.title(title)
|
||||
plt.show()
|
||||
|
||||
|
||||
def n_choose_k(n, k):
|
||||
"""Return the number of combinations for n choose k.
|
||||
|
||||
Args:
|
||||
n (int): the total number of options .
|
||||
k (int): The number of elements.
|
||||
|
||||
Returns:
|
||||
int: returns the binomial coefficient
|
||||
|
||||
"""
|
||||
if n == 0:
|
||||
return 0
|
||||
else:
|
||||
return reduce(lambda x, y: x * y[0] / y[1],
|
||||
zip(range(n - k + 1, n + 1),
|
||||
range(1, k + 1)), 1)
|
||||
|
||||
|
||||
def lex_index(n, k, lst):
|
||||
"""Return the lex index of a combination..
|
||||
|
||||
Args:
|
||||
n (int): the total number of options .
|
||||
k (int): The number of elements.
|
||||
lst
|
||||
|
||||
Returns:
|
||||
int: returns int index for lex order
|
||||
|
||||
"""
|
||||
assert len(lst) == k, "list should have length k"
|
||||
comb = list(map(lambda x: n - 1 - x, lst))
|
||||
dualm = sum([n_choose_k(comb[k - 1 - i], i + 1) for i in range(k)])
|
||||
return int(dualm)
|
||||
|
||||
|
||||
def bit_string_index(s):
|
||||
"""Return the index of a string of 0s and 1s."""
|
||||
n = len(s)
|
||||
k = s.count("1")
|
||||
assert s.count("0") == n - k, "s must be a string of 0 and 1"
|
||||
ones = [pos for pos, char in enumerate(s) if char == "1"]
|
||||
return lex_index(n, k, ones)
|
||||
|
||||
|
||||
def phase_to_color_wheel(complex_number):
|
||||
"""Map a phase of a complexnumber to a color in (r,g,b).
|
||||
|
||||
complex_number is phase is first mapped to angle in the range
|
||||
[0, 2pi] and then to a color wheel with blue at zero phase.
|
||||
"""
|
||||
angles = np.angle(complex_number)
|
||||
angle_round = int(((angles + 2 * np.pi) % (2 * np.pi))/np.pi*6)
|
||||
# print(angleround)
|
||||
color_map = {0: (0, 0, 1), # blue,
|
||||
1: (0.5, 0, 1), # blue-violet
|
||||
2: (1, 0, 1), # violet
|
||||
3: (1, 0, 0.5), # red-violet,
|
||||
4: (1, 0, 0), # red
|
||||
5: (1, 0.5, 0), # red-oranage,
|
||||
6: (1, 1, 0), # orange
|
||||
7: (0.5, 1, 0), # orange-yellow
|
||||
8: (0, 1, 0), # yellow,
|
||||
9: (0, 1, 0.5), # yellow-green,
|
||||
10: (0, 1, 1), # green,
|
||||
11: (0, 0.5, 1) # green-blue,
|
||||
}
|
||||
return color_map[angle_round]
|
||||
|
||||
|
||||
def plot_state_qsphere(rho):
|
||||
"""Plot the qsphere representation of a quantum state."""
|
||||
num = int(np.log2(len(rho)))
|
||||
# get the eigenvectors and egivenvalues
|
||||
we, stateall = la.eigh(rho)
|
||||
for i in range(2**num):
|
||||
# start with the max
|
||||
probmix = we.max()
|
||||
prob_location = we.argmax()
|
||||
if probmix > 0.001:
|
||||
print("The " + str(i) + "th eigenvalue = " + str(probmix))
|
||||
# get the max eigenvalue
|
||||
state = stateall[:, prob_location]
|
||||
loc = np.absolute(state).argmax()
|
||||
# get the element location closes to lowest bin representation.
|
||||
for j in range(2**num):
|
||||
test = np.absolute(np.absolute(state[j])
|
||||
- np.absolute(state[loc]))
|
||||
if test < 0.001:
|
||||
loc = j
|
||||
break
|
||||
# remove the global phase
|
||||
angles = (np.angle(state[loc]) + 2 * np.pi) % (2 * np.pi)
|
||||
angleset = np.exp(-1j*angles)
|
||||
# print(state)
|
||||
# print(angles)
|
||||
state = angleset*state
|
||||
# print(state)
|
||||
state.flatten()
|
||||
# start the plotting
|
||||
fig = plt.figure(figsize=(10, 10))
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
ax.axes.set_xlim3d(-1.0, 1.0)
|
||||
ax.axes.set_ylim3d(-1.0, 1.0)
|
||||
ax.axes.set_zlim3d(-1.0, 1.0)
|
||||
ax.set_aspect("equal")
|
||||
ax.axes.grid(False)
|
||||
# Plot semi-transparent sphere
|
||||
u = np.linspace(0, 2 * np.pi, 25)
|
||||
v = np.linspace(0, np.pi, 25)
|
||||
x = np.outer(np.cos(u), np.sin(v))
|
||||
y = np.outer(np.sin(u), np.sin(v))
|
||||
z = np.outer(np.ones(np.size(u)), np.cos(v))
|
||||
ax.plot_surface(x, y, z, rstride=1, cstride=1, color='k',
|
||||
alpha=0.05, linewidth=0)
|
||||
# wireframe
|
||||
# Get rid of the panes
|
||||
ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
|
||||
ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
|
||||
ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
|
||||
|
||||
# Get rid of the spines
|
||||
ax.w_xaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
|
||||
ax.w_yaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
|
||||
ax.w_zaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
|
||||
# Get rid of the ticks
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
ax.set_zticks([])
|
||||
|
||||
d = num
|
||||
for i in range(2**num):
|
||||
# get x,y,z points
|
||||
element = bin(i)[2:].zfill(num)
|
||||
weight = element.count("1")
|
||||
zvalue = -2 * weight / d + 1
|
||||
number_of_divisions = n_choose_k(d, weight)
|
||||
weight_order = bit_string_index(element)
|
||||
# if weight_order >= number_of_divisions / 2:
|
||||
# com_key = compliment(element)
|
||||
# weight_order_temp = bit_string_index(com_key)
|
||||
# weight_order = np.floor(
|
||||
# number_of_divisions / 2) + weight_order_temp + 1
|
||||
angle = (weight_order) * 2 * np.pi / number_of_divisions
|
||||
xvalue = np.sqrt(1 - zvalue**2) * np.cos(angle)
|
||||
yvalue = np.sqrt(1 - zvalue**2) * np.sin(angle)
|
||||
ax.plot([xvalue], [yvalue], [zvalue],
|
||||
markerfacecolor=(.5, .5, .5),
|
||||
markeredgecolor=(.5, .5, .5),
|
||||
marker='o', markersize=10, alpha=1)
|
||||
# get prob and angle - prob will be shade and angle color
|
||||
prob = np.real(np.dot(state[i], state[i].conj()))
|
||||
colorstate = phase_to_color_wheel(state[i])
|
||||
a = Arrow3D([0, xvalue], [0, yvalue], [0, zvalue],
|
||||
mutation_scale=20, alpha=prob, arrowstyle="-",
|
||||
color=colorstate, lw=10)
|
||||
ax.add_artist(a)
|
||||
# add weight lines
|
||||
for weight in range(d + 1):
|
||||
theta = np.linspace(-2 * np.pi, 2 * np.pi, 100)
|
||||
z = -2 * weight / d + 1
|
||||
r = np.sqrt(1 - z**2)
|
||||
x = r * np.cos(theta)
|
||||
y = r * np.sin(theta)
|
||||
ax.plot(x, y, z, color=(.5, .5, .5))
|
||||
# add center point
|
||||
ax.plot([0], [0], [0], markerfacecolor=(.5, .5, .5),
|
||||
markeredgecolor=(.5, .5, .5), marker='o', markersize=10,
|
||||
alpha=1)
|
||||
plt.show()
|
||||
we[prob_location] = 0
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
def plot_state(rho, method='city'):
|
||||
"""Plot the quantum state."""
|
||||
num = int(np.log2(len(rho)))
|
||||
# Need updating to check its a matrix
|
||||
if method == 'city':
|
||||
plot_state_city(rho)
|
||||
elif method == "paulivec":
|
||||
plot_state_paulivec(rho)
|
||||
elif method == "qsphere":
|
||||
plot_state_qsphere(rho)
|
||||
elif method == "bloch":
|
||||
for i in range(num):
|
||||
bloch_state = list(map(lambda x: np.real(np.trace(
|
||||
np.dot(x.to_matrix(), rho))),
|
||||
pauli_singles(i, num)))
|
||||
plot_bloch_vector(bloch_state, "qubit " + str(i))
|
||||
else:
|
||||
print("No method given")
|
Loading…
Reference in New Issue