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
|
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.
|
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)
|
theta_minus_save.append(theta_minus)
|
||||||
cost_plus_save.append(cost_plus)
|
cost_plus_save.append(cost_plus)
|
||||||
cost_minus_save.append(cost_minus)
|
cost_minus_save.append(cost_minus)
|
||||||
|
|
||||||
if k>=max_trials-last_avg:
|
if k>=max_trials-last_avg:
|
||||||
theta_best+=theta/last_avg
|
theta_best+=theta/last_avg
|
||||||
|
|
||||||
# final cost update
|
# final cost update
|
||||||
cost_final = obj_fun(theta_best)[0]
|
cost_final = obj_fun(theta_best)[0]
|
||||||
print('Final objective function is: ' + str(cost_final))
|
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.
|
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.
|
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# Do not distribute.
|
# you may not use this file except in compliance with the License.
|
||||||
# It is provided without warranty or conditions of any kind, either express or
|
# You may obtain a copy of the License at
|
||||||
# implied.
|
#
|
||||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
#
|
||||||
# https://github.com/IBM/qiskit-sdk-py
|
# 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.
|
A collection of useful quantum information functions.
|
||||||
|
|
||||||
|
@ -161,27 +164,27 @@ def devectorize(vec, method='col'):
|
||||||
def choi_to_rauli(choi):
|
def choi_to_rauli(choi):
|
||||||
"""
|
"""
|
||||||
Convert a Choi-matrix to a Pauli-basis superoperator.
|
Convert a Choi-matrix to a Pauli-basis superoperator.
|
||||||
|
|
||||||
Note that this function assumes that the Choi-matrix
|
Note that this function assumes that the Choi-matrix
|
||||||
is defined in the standard column-stacking converntion
|
is defined in the standard column-stacking converntion
|
||||||
and is normalized to have trace 1. For a channel E this
|
and is normalized to have trace 1. For a channel E this
|
||||||
is defined as: choi = (I \otimes E)(bell_state).
|
is defined as: choi = (I \otimes E)(bell_state).
|
||||||
|
|
||||||
The resulting 'rauli' R acts on input states as
|
The resulting 'rauli' R acts on input states as
|
||||||
|rho_out>_p = R.|rho_in>_p
|
|rho_out>_p = R.|rho_in>_p
|
||||||
where |rho> = vectorize(rho, method='pauli')
|
where |rho> = vectorize(rho, method='pauli')
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
Choi (matrix): the input Choi-matrix.
|
Choi (matrix): the input Choi-matrix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A superoperator in the Pauli basis.
|
A superoperator in the Pauli basis.
|
||||||
"""
|
"""
|
||||||
# get number of qubits'
|
# get number of qubits'
|
||||||
n = int(np.log2(np.sqrt(len(choi))))
|
n = int(np.log2(np.sqrt(len(choi))))
|
||||||
pgp = pauli_group(n)
|
pgp = pauli_group(n)
|
||||||
rauli = np.array([ np.trace(np.dot(choi,
|
rauli = np.array([ np.trace(np.dot(choi,
|
||||||
np.kron(j.to_matrix().T, i.to_matrix())))
|
np.kron(j.to_matrix().T, i.to_matrix())))
|
||||||
for i in pgp for j in pgp])
|
for i in pgp for j in pgp])
|
||||||
return rauli.reshape(4 ** n, 4 ** n)
|
return rauli.reshape(4 ** n, 4 ** n)
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,18 @@
|
||||||
|
|
||||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# Do not distribute.
|
# you may not use this file except in compliance with the License.
|
||||||
# It is provided without warranty or conditions of any kind, either express or
|
# You may obtain a copy of the License at
|
||||||
# implied.
|
#
|
||||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
#
|
||||||
# https://github.com/IBM/qiskit-sdk-py
|
# 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.
|
Functions for performing quantum state and process tomography experiments.
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,17 @@
|
||||||
|
|
||||||
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# This file is intended only for use during the USEQIP Summer School 2017.
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# Do not distribute.
|
# you may not use this file except in compliance with the License.
|
||||||
# It is provided without warranty or conditions of any kind, either express or
|
# You may obtain a copy of the License at
|
||||||
# implied.
|
#
|
||||||
# An open source version of this file will be included in QISKIT-DEV-PY
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
# reposity in the future. Keep an eye on the Github repository for updates!
|
#
|
||||||
# https://github.com/IBM/qiskit-sdk-py
|
# 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.
|
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