Skip to content

Commit

Permalink
Merge pull request #7 (update-versions)
Browse files Browse the repository at this point in the history
Update to Python 3.9 and QuTiP 4.6
  • Loading branch information
goerz committed Mar 18, 2022
2 parents 6859efe + ab8118e commit 2d92759
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 101 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

language: python
python:
- 3.6
- 3.5
- 3.9
install:
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
- bash miniconda.sh -b -p $HOME/miniconda3
Expand Down
94 changes: 44 additions & 50 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,80 +53,74 @@ pep8: ## check style with pep8
pep8 src tests


test: test35 test36 ## run tests on every Python version
test: test39 ## run tests on every Python version

.venv/py34/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py34 python=3.4
.venv/py39/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py39 python=3.9
@# if the conda installation does not work, simply comment out the following line, and let pip handle it
@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py34 $(CONDA_PACKAGES)
@.venv/py34/bin/pip install -e .[dev]
@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py39 $(CONDA_PACKAGES)
@.venv/py39/bin/pip install -e .[dev]

test34: .venv/py34/bin/py.test ## run tests for Python 3.4
test39: .venv/py39/bin/py.test ## run tests for Python 3.9
$(TESTENV) $< -v $(TESTOPTIONS) $(TESTS)

.venv/py35/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py35 python=3.5
@# if the conda installation does not work, simply comment out the following line, and let pip handle it
@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py35 $(CONDA_PACKAGES)
@.venv/py35/bin/pip install -e .[dev]

test35: .venv/py35/bin/py.test ## run tests for Python 3.5
$(TESTENV) $< -v $(TESTOPTIONS) $(TESTS)

.venv/py36/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py36 python=3.6
.venv/py38/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py38 python=3.8
@# if the conda installation does not work, simply comment out the following line, and let pip handle it
@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py36 $(CONDA_PACKAGES)
@.venv/py36/bin/pip install -e .[dev]
#@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py38 $(CONDA_PACKAGES)
@.venv/py38/bin/pip install -e .[dev]

test36: .venv/py36/bin/py.test ## run tests for Python 3.6
test38: .venv/py38/bin/py.test ## run tests for Python 3.8
$(TESTENV) $< -v $(TESTOPTIONS) $(TESTS)


.venv/py37/bin/py.test:
@conda create -y -m --override-channels -c defaults -p .venv/py37 python=3.7
@# if the conda installation does not work, simply comment out the following line, and let pip handle it
#@conda install -y --override-channels -c defaults -c conda-forge -p .venv/py37 $(CONDA_PACKAGES)
@.venv/py37/bin/pip install -e .[dev]

test37: .venv/py37/bin/py.test ## run tests for Python 3.6
test37: .venv/py37/bin/py.test ## run tests for Python 3.7
$(TESTENV) $< -v $(TESTOPTIONS) $(TESTS)

.venv/py36/bin/python: .venv/py36/bin/py.test

.venv/py36/bin/sphinx-build: .venv/py36/bin/py.test
.venv/py39/bin/python: .venv/py39/bin/py.test

.venv/py39/bin/sphinx-build: .venv/py39/bin/py.test

docs: .venv/py36/bin/sphinx-build ## generate Sphinx HTML documentation, including API docs
$(MAKE) -C docs SPHINXBUILD=../.venv/py36/bin/sphinx-build clean
$(MAKE) -C docs SPHINXBUILD=../.venv/py36/bin/sphinx-build html
docs: .venv/py39/bin/sphinx-build ## generate Sphinx HTML documentation, including API docs
$(MAKE) -C docs SPHINXBUILD=../.venv/py39/bin/sphinx-build clean
$(MAKE) -C docs SPHINXBUILD=../.venv/py39/bin/sphinx-build html
@echo "open docs/_build/html/index.html"

spellcheck: .venv/py36/bin/sphinx-build ## check spelling in docs
@.venv/py36/bin/pip install sphinxcontrib-spelling
SPELLCHECK=en_US $(MAKE) -C docs SPHINXBUILD=../.venv/py36/bin/sphinx-build spelling
spellcheck: .venv/py39/bin/sphinx-build ## check spelling in docs
@.venv/py39/bin/pip install sphinxcontrib-spelling
SPELLCHECK=en_US $(MAKE) -C docs SPHINXBUILD=../.venv/py39/bin/sphinx-build spelling

coverage: test36 ## generate coverage report in ./htmlcov
.venv/py36/bin/coverage html
coverage: test39 ## generate coverage report in ./htmlcov
.venv/py39/bin/coverage html
@echo "open htmlcov/index.html"

test-upload: .venv/py36/bin/python clean-build clean-pyc dist ## package and upload a release to test.pypi.org
.venv/py36/bin/twine check dist/*
.venv/py36/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/*
test-upload: .venv/py39/bin/python clean-build clean-pyc dist ## package and upload a release to test.pypi.org
.venv/py39/bin/twine check dist/*
.venv/py39/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/*

upload: .venv/py36/bin/python clean-build clean-pyc dist ## package and upload a release to pypi.org
.venv/py36/bin/twine check dist/*
.venv/py36/bin/twine upload dist/*
upload: .venv/py39/bin/python clean-build clean-pyc dist ## package and upload a release to pypi.org
.venv/py39/bin/twine check dist/*
.venv/py39/bin/twine upload dist/*

release: clean .venv/py36/bin/python ## Create a new version, package and upload it
.venv/py36/bin/python ./scripts/release.py
release: clean .venv/py39/bin/python ## Create a new version, package and upload it
.venv/py39/bin/python ./scripts/release.py


dist: .venv/py36/bin/python clean-build clean-pyc ## builds source and wheel package
dist: .venv/py39/bin/python clean-build clean-pyc ## builds source and wheel package
@$< setup.py sdist
@$< setup.py bdist_wheel
ls -l dist

dist-check: .venv/py36/bin/python ## Check all dist files for correctness
.venv/py36/bin/twine check dist/*
dist-check: .venv/py39/bin/python ## Check all dist files for correctness
.venv/py39/bin/twine check dist/*

install: clean-build clean-pyc ## install the package to the active Python's site-packages
pip install .
Expand All @@ -145,24 +139,24 @@ develop-docs: develop ## generate Sphinx HTML documentation, including API docs
$(MAKE) -C docs html
@echo "open docs/_build/html/index.html"

.venv/py36/bin/jupyter: .venv/py36/bin/py.test
.venv/py39/bin/jupyter: .venv/py39/bin/py.test

# How to execute notebook files
%.ipynb.log: %.ipynb .venv/py36/bin/jupyter
%.ipynb.log: %.ipynb .venv/py39/bin/jupyter
@echo ""
@.venv/py36/bin/jupyter nbconvert --to notebook --execute --inplace --allow-errors --ExecutePreprocessor.kernel_name='python3' --config=/dev/null $< 2>&1 | tee $@
@.venv/py39/bin/jupyter nbconvert --to notebook --execute --inplace --allow-errors --ExecutePreprocessor.kernel_name='python3' --config=/dev/null $< 2>&1 | tee $@

NOTEBOOKFILES = $(shell find docs/ -iname '*.ipynb' -maxdepth 1)
NOTEBOOKLOGS = $(patsubst %.ipynb,%.ipynb.log,$(NOTEBOOKFILES))

notebooks: $(NOTEBOOKLOGS) ## re-evaluate the notebooks
@echo ""
@echo "All notebook are now up to date; the were executed using the python3 kernel"
@.venv/py36/bin/jupyter kernelspec list | grep python3
@.venv/py39/bin/jupyter kernelspec list | grep python3

jupyter-notebook: .venv/py36/bin/jupyter ## run a notebook server for editing the examples
.venv/py36/bin/jupyter notebook --config=/dev/null
jupyter-notebook: .venv/py39/bin/jupyter ## run a notebook server for editing the examples
.venv/py39/bin/jupyter notebook --config=/dev/null

jupyter-lab: .venv/py36/bin/jupyter ## run a jupyterlab server for editing the examples
@.venv/py36/bin/pip install jupyterlab
.venv/py36/bin/jupyter lab --config=/dev/null
jupyter-lab: .venv/py39/bin/jupyter ## run a jupyterlab server for editing the examples
@.venv/py39/bin/pip install jupyterlab
.venv/py39/bin/jupyter lab --config=/dev/null
136 changes: 114 additions & 22 deletions docs/tutorial.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def get_version(filename):
'Intended Audience :: Science/Research',
'License :: OSI Approved :: BSD License',
'Natural Language :: English',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
],
description=(
"Python package for analyzing two-qubit gates in the Weyl chamber"
Expand Down
12 changes: 6 additions & 6 deletions src/weylchamber/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def c1c2c3(U: Gate, ndigits=DEFAULT_WEYL_PRECISSION) -> CTuple:
Algorithm from Childs et al., PRA 68, 052311 (2003).
Example:
>>> print("%.2f %.2f %.2f" % c1c2c3(qutip.gates.cnot()))
>>> print("%.2f %.2f %.2f" % c1c2c3(qutip.qip.operations.cnot()))
0.50 0.00 0.00
"""
U = qutip.Qobj(U, dims=[[2, 2], [2, 2]])
Expand Down Expand Up @@ -65,10 +65,10 @@ def point_in_weyl_chamber(
Examples:
>>> BGATE = qutip.gates.berkeley()
>>> BGATE = qutip.qip.operations.berkeley()
>>> point_in_weyl_chamber(*c1c2c3(BGATE))
True
>>> point_in_weyl_chamber(*c1c2c3(qutip.gates.identity([2, 2])))
>>> point_in_weyl_chamber(*c1c2c3(qutip.identity([2, 2])))
True
The coordinates may also be array-like, in which case a boolean numpy
Expand Down Expand Up @@ -169,10 +169,10 @@ def _point_in_PE(c1, c2, c3, check_weyl=False):
"""Return True if the coordinates c1, c2, c3 are inside the
perfect-entangler polyhedron
>>> BGATE = qutip.gates.berkeley()
>>> BGATE = qutip.qip.operations.berkeley()
>>> _point_in_PE(*c1c2c3(BGATE))
True
>>> _point_in_PE(*c1c2c3(qutip.gates.identity(4)))
>>> _point_in_PE(*c1c2c3(qutip.identity(4)))
False
>>> res = _point_in_PE([0.0, 0.5, 0.8], [1.0, 0.25, 0.0], [1.0, 0.25, 0.0])
Expand Down Expand Up @@ -330,7 +330,7 @@ def canonical_gate(c1: float, c2: float, c3: float) -> qutip.Qobj:
... [0.000000+0.707107j, 0.000000+0.000000j, 0.000000+0.000000j, 0.707107+0.000000j]],
... dims=[[2,2], [2,2]])
>>> U = canonical_gate(0.5,0,0)
>>> assert (U - gate).norm() < 1e-6
>>> assert (U - gate).norm() < 1e-5
>>> assert np.max(np.abs(
... np.array(c1c2c3(U)) - np.array([0.5, 0, 0]))) < 1e-15
"""
Expand Down
6 changes: 3 additions & 3 deletions src/weylchamber/gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ def gate(basis, states):
>>> from qutip import ket
>>> basis = [ket(nums) for nums in [(0, 0), (0, 1), (1, 0), (1, 1)]]
>>> states = mapped_basis(qutip.gates.cnot(), basis)
>>> states = mapped_basis(qutip.qip.operations.cnot(), basis)
>>> U = gate(basis, states)
>>> assert (U - qutip.gates.cnot()).norm() < 1e-15
>>> assert (U - qutip.qip.operations.cnot()).norm() < 1e-15
"""
if not (len(basis) == len(states) == 4):
raise ValueError(
Expand All @@ -135,7 +135,7 @@ def mapped_basis(gate, basis):
>>> from qutip import ket
>>> basis = [ket(nums) for nums in [(0, 0), (0, 1), (1, 0), (1, 1)]]
>>> states = mapped_basis(qutip.gates.cnot(), basis)
>>> states = mapped_basis(qutip.qip.operations.cnot(), basis)
>>> assert (states[0] - ket((0,0))).norm() < 1e-15
>>> assert (states[1] - ket((0,1))).norm() < 1e-15
>>> assert (states[2] - ket((1,1))).norm() < 1e-15 # swap (1, 1) ...
Expand Down
4 changes: 2 additions & 2 deletions src/weylchamber/local_invariants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def g1g2g3(U: Gate, ndigits=DEFAULT_WEYL_PRECISSION) -> GTuple:
values are rounded to the given precision, cf. the `ndigits` parameter of
the built-in :func:`round` function.
>>> print("%.2f %.2f %.2f" % g1g2g3(qutip.gates.cnot()))
>>> print("%.2f %.2f %.2f" % g1g2g3(qutip.qip.operations.cnot()))
0.00 0.00 1.00
"""
# mathematically, the determinant of U and UB is the same, but
Expand Down Expand Up @@ -55,7 +55,7 @@ def g1g2g3_from_c1c2c3(
parameter of the built-in :func:`round` function)
Example:
>>> CNOT = qutip.gates.cnot()
>>> CNOT = qutip.qip.operations.cnot()
>>> print("%.2f %.2f %.2f" % g1g2g3_from_c1c2c3(*c1c2c3(CNOT)))
0.00 0.00 1.00
"""
Expand Down
10 changes: 5 additions & 5 deletions src/weylchamber/perfect_entanglers.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ def concurrence(c1: float, c2: float, c3: float) -> float:
Example:
>>> import qutip
>>> from weylchamber.coordinates import c1c2c3
>>> '%.1f' % concurrence(*c1c2c3(qutip.gates.swap()))
>>> '%.1f' % concurrence(*c1c2c3(qutip.qip.operations.swap()))
'0.0'
>>> '%.1f' % concurrence(*c1c2c3(qutip.gates.cnot()))
>>> '%.1f' % concurrence(*c1c2c3(qutip.qip.operations.cnot()))
'1.0'
>>> '%.1f' % concurrence(*c1c2c3(qutip.gates.identity([2, 2])))
>>> '%.1f' % concurrence(*c1c2c3(qutip.identity([2, 2])))
'0.0'
"""
if ((c1 + c2) >= 0.5) and (c1 - c2 <= 0.5) and ((c2 + c3) <= 0.5):
Expand All @@ -120,9 +120,9 @@ def F_PE(g1: float, g2: float, g3: float) -> float:
Example:
>>> import qutip
>>> from weylchamber.local_invariants import g1g2g3
>>> "%.1f" % F_PE(*g1g2g3(qutip.gates.cnot()))
>>> "%.1f" % F_PE(*g1g2g3(qutip.qip.operations.cnot()))
'0.0'
>>> "%.1f" % F_PE(*g1g2g3(qutip.gates.identity([2, 2])))
>>> "%.1f" % F_PE(*g1g2g3(qutip.identity([2, 2])))
'2.0'
"""
return g3 * np.sqrt(g1 ** 2 + g2 ** 2) - g1 + 0.0
Expand Down
10 changes: 6 additions & 4 deletions src/weylchamber/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,12 @@ def render(self, ax):
ax.set_xlim(0,1)
ax.set_ylim(0,0.5)
ax.set_zlim(0,0.5)
ax.set_xticks([0, 0.25, 0.5, 0.75, 1])
ax.set_xticklabels(['0', '', '$\pi/2$', '', r'$\pi$'])
ax.set_yticklabels(['0', '', '', '', '', r'$\pi/2$'])
ax.set_zticklabels(['0', '', '', '', '', r'$\pi/2$'])
ax.xaxis.set_ticks([0, 0.25, 0.5, 0.75, 1])
ax.xaxis.set_ticklabels(['0', '', r'$\pi/2$', '', r'$\pi$'])
ax.yaxis.set_ticks([0, 0.1, 0.2, 0.3, 0.4, 0.5])
ax.yaxis.set_ticklabels(['0', '', '', '', '', r'$\pi/2$'])
ax.zaxis.set_ticks([0, 0.1, 0.2, 0.3, 0.4, 0.5])
ax.zaxis.set_ticklabels(['0', '', '', '', '', r'$\pi/2$'])
ax.tick_params(axis='x', pad=self.c1_tickspad)
ax.tick_params(axis='y', pad=self.c2_tickspad)
ax.tick_params(axis='z', pad=self.c2_tickspad)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cartan_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_cartan_decomposition_random():
def test_cartan_decomposition_cnot():
warnings.filterwarnings(
'ignore', message='the matrix subclass is not the recommended way')
U = qutip.gates.cnot()
U = qutip.qip.operations.cnot()
phasefactor = np.linalg.det(U.full())**0.25
C = concurrence(*c1c2c3(U))
assert C == 1
Expand Down
8 changes: 4 additions & 4 deletions tests/test_local_invariants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ def test_closest_LI_trivial_powell():
"""Test that a gate exactly at (c1, c2, c3) is in fact closest to itself"""
warnings.filterwarnings(
'ignore', message='the matrix subclass is not the recommended way')
CNOT = qutip.gates.cnot()
CNOT = qutip.qip.operations.cnot()
U = closest_LI(CNOT, *c1c2c3(CNOT), method='Powell')
assert isinstance(U, qutip.Qobj)
assert (CNOT - U).norm() < 1e-15
assert (CNOT - U).norm() < 1e-8


def test_closest_LI_trivial_leastsq():
"""Test that a gate exactly at (c1, c2, c3) is in fact closest to itself"""
warnings.filterwarnings(
'ignore', message='the matrix subclass is not the recommended way')
CNOT = qutip.gates.cnot()
CNOT = qutip.qip.operations.cnot()
U = closest_LI(CNOT, *c1c2c3(CNOT), method='leastsq')
assert isinstance(U, qutip.Qobj)
assert (CNOT - U).norm() < 1e-15
assert (CNOT - U).norm() < 1e-8

0 comments on commit 2d92759

Please sign in to comment.