Repository URL to install this package:
|
Version:
5.0.3.post1 ▾
|
import pytest
import qutip
import numpy as np
from scipy.special import sph_harm
mpl = pytest.importorskip("matplotlib")
plt = pytest.importorskip("matplotlib.pyplot")
def test_cyclic():
qutip.settings.colorblind_safe = True
rho = qutip.rand_dm(5)
fig, ax = qutip.hinton(rho, color_style='phase')
plt.close()
qutip.settings.colorblind_safe = False
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_diverging():
qutip.settings.colorblind_safe = True
rho = qutip.rand_dm(5)
fig, ax = qutip.hinton(rho)
plt.close()
qutip.settings.colorblind_safe = False
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_sequential():
qutip.settings.colorblind_safe = True
theta = np.linspace(0, np.pi, 90)
phi = np.linspace(0, 2 * np.pi, 60)
phi_mesh, theta_mesh = np.meshgrid(phi, theta)
values = sph_harm(-1, 2, phi_mesh, theta_mesh).T
fig, ax = qutip.sphereplot(values, theta, phi)
plt.close()
qutip.settings.colorblind_safe = False
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
@pytest.mark.parametrize('f, a, projection', [
(True, True, '2d'),
(True, True, '3d'),
(True, False, '2d'),
(True, False, '3d'),
(False, True, '2d'),
(False, True, '3d'),
(False, False, '2d'),
(False, False, '3d'),
])
def test_is_fig_and_ax(f, a, projection):
rho = qutip.rand_dm(5)
fig = plt.figure()
ax = None
if a:
if projection == '2d':
ax = fig.add_subplot(111)
else:
ax = fig.add_subplot(111, projection='3d')
if not f:
fig = None
fig, ax = qutip.plot_wigner(rho, projection=projection,
fig=fig, ax=ax)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_set_ticklabels():
rho = qutip.rand_dm(5)
text = "got 1 ticklabels but needed 5"
with pytest.raises(Exception) as exc_info:
fig, ax = qutip.hinton(rho, x_basis=[1])
assert str(exc_info.value) == text
plt.close()
def test_equal_shape():
rhos = [qutip.rand_dm(5)]*2 + [qutip.rand_dm(4)]
text = "All inputs should have the same shape."
with pytest.raises(Exception) as exc_info:
fig, ax = qutip.hinton(rhos)
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('args', [
({'reflections': True}),
({'cmap': mpl.cm.cividis}),
({'colorbar': False}),
])
def test_plot_wigner_sphere(args):
psi = qutip.rand_ket(5)
wigner = qutip.wigner_transform(psi, 2, False, 50, ["x"])
fig, ax = qutip.plot_wigner_sphere(wigner, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_wigner_sphere_anim():
psi = qutip.rand_ket(5)
wigner = qutip.wigner_transform(psi, 2, False, 50, ["x"])
fig, ani = qutip.plot_wigner_sphere([wigner]*2)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
def to_oper_bra(oper):
return qutip.operator_to_vector(oper).dag()
def to_oper(oper):
return oper
@pytest.mark.parametrize('transform, args', [
(to_oper, {}),
(qutip.operator_to_vector, {}),
(to_oper_bra, {}),
(qutip.spre, {}),
(to_oper, {'x_basis': [0, 1, 2, 3]}),
(to_oper, {'y_basis': [0, 1, 2, 3]}),
(to_oper, {'color_style': 'threshold'}),
(to_oper, {'color_style': 'phase'}),
(to_oper, {'colorbar': False}),
])
def test_hinton(transform, args):
rho = transform(qutip.rand_dm(4))
fig, ax = qutip.hinton(rho, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_hinton1():
fig, ax = qutip.hinton(np.zeros((3, 3)))
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_hinton_anim():
rho = qutip.rand_dm(5)
rhos = [rho]*2
fig, ani = qutip.hinton(rhos)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
def test_hinton_ValueError0():
text = "Input quantum object must be an operator or superoperator."
rho = qutip.basis(2, 0)
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.hinton(rho)
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('transform, args, error_message', [
(to_oper, {'color_style': 'color_style'},
"Unknown color style color_style for Hinton diagrams."),
(qutip.spre, {},
"Hinton plots of superoperators are currently only supported for qubits.")
])
def test_hinton_ValueError1(transform, args, error_message):
rho = transform(qutip.rand_dm(5))
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.hinton(rho, **args)
assert str(exc_info.value) == error_message
plt.close()
@pytest.mark.parametrize('args', [
({'cmap': mpl.cm.cividis}),
({'colorbar': False}),
])
def test_sphereplot(args):
theta = np.linspace(0, np.pi, 90)
phi = np.linspace(0, 2 * np.pi, 60)
phi_mesh, theta_mesh = np.meshgrid(phi, theta)
values = sph_harm(-1, 2, phi_mesh, theta_mesh).T
fig, ax = qutip.sphereplot(values, theta, phi, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_sphereplot_anim():
theta = np.linspace(0, np.pi, 90)
phi = np.linspace(0, 2 * np.pi, 60)
phi_mesh, theta_mesh = np.meshgrid(phi, theta)
values = sph_harm(-1, 2, phi_mesh, theta_mesh).T
fig, ani = qutip.sphereplot([values]*2, theta, phi)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
@pytest.mark.parametrize('response', [
('normal'),
('error')
])
def test_update_yaxis(response):
if response == 'normal':
fig, ax = qutip.matrix_histogram(np.zeros((3, 3)))
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
else:
text = "got 1 ylabels but needed 5"
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
y_basis=[1])
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('response', [
('normal'),
('error')
])
def test_update_xaxis(response):
if response == 'normal':
fig, ax = qutip.matrix_histogram(np.zeros((3, 3)))
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
else:
text = "got 1 xlabels but needed 5"
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
x_basis=[1])
assert str(exc_info.value) == text
plt.close()
def test_get_matrix_components():
text = "got an unexpected argument, error for bar_style"
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
bar_style='error')
assert str(exc_info.value) == text
@pytest.mark.parametrize('args', [
({'options': {'stick': True, 'azim': 45}}),
({'options': {'stick': True, 'azim': 135}}),
({'options': {'stick': True, 'azim': 225}}),
({'options': {'stick': True, 'azim': 315}}),
])
def test_stick_to_planes(args):
rho = qutip.rand_dm(5)
fig, ax = qutip.matrix_histogram(rho, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
@pytest.mark.parametrize('args', [
({}),
({'options': {'zticks': [1]}}),
({'x_basis': [1, 2, 3, 4, 5]}),
({'y_basis': [1, 2, 3, 4, 5]}),
({'limits': [0, 1]}),
({'color_limits': [0, 1]}),
({'color_style': 'phase'}),
({'options': {'threshold': 0.1}}),
({'color_style': 'real', 'colorbar': True}),
({'color_style': 'img', 'colorbar': True}),
({'color_style': 'abs', 'colorbar': True}),
({'color_style': 'phase', 'colorbar': True}),
({'color_limits': [0, 1], 'color_style': 'phase', 'colorbar': True})
])
def test_matrix_histogram(args):
rho = qutip.rand_dm(5)
fig, ax = qutip.matrix_histogram(rho, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_matrix_histogram_zeros():
rho = qutip.Qobj([[0, 0], [0, 0]])
fig, ax = qutip.matrix_histogram(rho)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_matrix_histogram_anim():
rho = qutip.rand_dm(5)
rhos = [rho]*2
fig, ani = qutip.matrix_histogram(rhos)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
@pytest.mark.parametrize('args, expected', [
({'options': 'error'}, ("options must be a dictionary")),
({'options': {'e1': '1', 'e2': '2'}},
("invalid key(s) found in options: e1, e2",
"invalid key(s) found in options: e2, e1")),
])
def test_matrix_histogram_ValueError(args, expected):
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.matrix_histogram(qutip.rand_dm(5),
**args)
assert str(exc_info.value) in expected
plt.close()
@pytest.mark.parametrize('args', [
({'h_labels': ['H0', 'H0+Hint']}),
({'energy_levels': [-2, 0, 2]}),
])
def test_plot_energy_levels(args):
H0 = qutip.tensor(qutip.sigmaz(), qutip.identity(2)) + \
qutip.tensor(qutip.identity(2), qutip.sigmaz())
Hint = 0.1 * qutip.tensor(qutip.sigmax(), qutip.sigmax())
fig, ax = qutip.plot_energy_levels([H0, Hint], **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_energy_levels_ValueError():
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.plot_energy_levels(1)
assert str(exc_info.value) == "H_list must be a list of Qobj instances"
plt.close()
@pytest.mark.parametrize('rho_type, args', [
('oper', {}),
('ket', {}),
('oper', {'fock_numbers': [0, 1, 2, 3]}),
('oper', {'unit_y_range': False}),
])
def test_plot_fock_distribution(rho_type, args):
if rho_type == 'oper':
rho = qutip.rand_dm(4)
else:
rho = qutip.basis(2, 0)
fig, ax = qutip.plot_fock_distribution(rho, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_fock_distribution_anim():
rho = qutip.rand_dm(5)
rhos = [rho]*2
fig, ani = qutip.plot_fock_distribution(rhos)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
@pytest.mark.parametrize('rho_type, args', [
('oper', {}),
('ket', {}),
('oper', {'xvec': np.linspace(-1, 1, 100)}),
('oper', {'yvec': np.linspace(-1, 1, 100)}),
('oper', {'method': 'fft'}),
('oper', {'projection': '3d'}),
('oper', {'colorbar': True})
])
def test_plot_wigner(rho_type, args):
if rho_type == 'oper':
rho = qutip.rand_dm(4)
else:
rho = qutip.basis(2, 0)
fig, ax = qutip.plot_wigner(rho, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_wigner_anim():
rho = qutip.rand_dm(5)
rhos = [rho]*2
fig, ani = qutip.plot_wigner(rhos)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
def test_plot_wigner_ValueError():
text = "Unexpected value of projection keyword argument"
with pytest.raises(ValueError) as exc_info:
rho = qutip.rand_dm(4)
fig, ax = qutip.plot_wigner(rho, projection=1)
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('n_of_results, n_of_e_ops, one_axes, args', [
(1, 3, False, {}),
(1, 3, False, {'ylabels': [1, 2, 3]}),
(1, 1, True, {}),
(2, 3, False, {}),
])
def test_plot_expectation_values(n_of_results, n_of_e_ops, one_axes, args):
H = qutip.sigmaz() + 0.3 * qutip.sigmay()
e_ops = [qutip.sigmax(), qutip.sigmay(), qutip.sigmaz()]
times = np.linspace(0, 10, 100)
psi0 = (qutip.basis(2, 0) + qutip.basis(2, 1)).unit()
result = qutip.mesolve(H, psi0, times, [], e_ops[:n_of_e_ops])
if n_of_results == 1:
results = result
else:
results = [result, result]
if one_axes:
fig = plt.figure()
axes = fig.add_subplot(111)
else:
fig = None
axes = None
fig, axes = qutip.plot_expectation_values(results, **args,
fig=fig, axes=axes)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(axes, np.ndarray)
@pytest.mark.filterwarnings(
"ignore:The input coordinates to pcolor:UserWarning"
)
@pytest.mark.parametrize('color, args', [
('sequential', {}),
('diverging', {}),
('sequential', {'projection': '3d'}),
('sequential', {'colorbar': True})
])
def test_plot_spin_distribution(color, args):
j = 5
psi = qutip.spin_coherent(j, np.random.rand() * np.pi,
np.random.rand() * 2 * np.pi)
theta = np.linspace(0, np.pi, 50)
phi = np.linspace(0, 2 * np.pi, 50)
Q, THETA, PHI = qutip.spin_q_function(psi, theta, phi)
if color == 'diverging':
Q *= -1e12
Q[0, 0] = -1e13
fig, ax = qutip.plot_spin_distribution(Q, THETA, PHI, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
@pytest.mark.filterwarnings(
"ignore:The input coordinates to pcolor:UserWarning"
)
def test_plot_spin_distribution_anim():
j = 5
psi = qutip.spin_coherent(j, np.random.rand() * np.pi,
np.random.rand() * 2 * np.pi)
theta = np.linspace(0, np.pi, 50)
phi = np.linspace(0, 2 * np.pi, 50)
Q, THETA, PHI = qutip.spin_q_function(psi, theta, phi)
fig, ani = qutip.plot_spin_distribution([Q]*2, THETA, PHI)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
def test_plot_spin_distribution_ValueError():
text = "Unexpected value of projection keyword argument"
j = 5
psi = qutip.spin_coherent(j, np.random.rand() * np.pi,
np.random.rand() * 2 * np.pi)
theta = np.linspace(0, np.pi, 50)
phi = np.linspace(0, 2 * np.pi, 50)
Q, THETA, PHI = qutip.spin_q_function(psi, theta, phi)
with pytest.raises(ValueError) as exc_info:
fig, ax = qutip.plot_spin_distribution(Q, THETA, PHI, projection=1)
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('args', [
({}),
({'theme': 'dark'}),
])
def test_complex_array_to_rgb(args):
Y = qutip.complex_array_to_rgb(np.zeros((3, 3)), **args)
plt.close()
assert isinstance(Y, np.ndarray)
@pytest.mark.parametrize('dims, args', [
(2, {}),
(3, {}),
(2, {'how': 'pairs'}),
(2, {'how': 'pairs_skewed'}),
(2, {'how': 'before_after'}),
(2, {'legend_iteration': 'all'}),
(2, {'legend_iteration': 'grid_iteration'}),
(2, {'legend_iteration': 1, 'how': 'before_after'}),
(2, {'legend_iteration': 1, 'how': 'pairs'}),
])
def test_plot_qubism(dims, args):
if dims == 2:
state = qutip.ket("01")
else:
state = qutip.ket("010")
fig, ax = qutip.plot_qubism(state, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_qubism_anim():
state = qutip.ket("01")
fig, ani = qutip.plot_qubism([state]*2)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
@pytest.mark.parametrize('ket, args, expected', [
(False, {}, "Qubism works only for pure states, i.e. kets."),
(True, {'how': 'error'}, "No such 'how'."),
(True, {'legend_iteration': 'error'}, "No such option for " +
"legend_iteration keyword argument. " +
"Use 'all', 'grid_iteration' or an integer."),
])
def test_plot_qubism_Error(ket, args, expected):
if ket:
state = qutip.ket("01")
else:
state = qutip.bra("01")
with pytest.raises(Exception) as exc_info:
fig, ax = qutip.plot_qubism(state, **args)
assert str(exc_info.value) == expected
plt.close()
def test_plot_qubism_dimension():
text = "For 'pairs_skewed' pairs of dimensions need to be the same."
ket = qutip.basis(3) & qutip.basis(2)
with pytest.raises(Exception) as exc_info:
qutip.plot_qubism(ket, how='pairs_skewed')
assert str(exc_info.value) == text
plt.close()
@pytest.mark.parametrize('args', [
({'splitting': None}),
({'labels_iteration': 1}),
])
def test_plot_schmidt(args):
state = qutip.ket("01")
fig, ax = qutip.plot_schmidt(state, **args)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ax, mpl.axes.Axes)
def test_plot_schmidt_anim():
state = qutip.ket("01")
fig, ani = qutip.plot_schmidt([state]*2)
plt.close()
assert isinstance(fig, mpl.figure.Figure)
assert isinstance(ani, mpl.animation.ArtistAnimation)
def test_plot_schmidt_Error():
state = qutip.bra("01")
text = "Schmidt plot works only for pure states, i.e. kets."
with pytest.raises(Exception) as exc_info:
fig, ax = qutip.plot_schmidt(state)
assert str(exc_info.value) == text
plt.close()