Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion qse/lattices/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""
r"""
A collection of convenience functions for creating common lattices.
Qbits class is very flexible to generate arbitrary structures. For
convenience, helper functions to generate several common types of
Expand All @@ -13,7 +13,33 @@
repeats_x=4, repeats_y=4)
qsqr.draw(radius=2)

Generic Definition
------------------

Any arbitrary periodic structure is defined in terms of two
objects, :math:`(i)` a set of points that are chosen, called
basis; and :math:`(ii)` a set of linearly independent vectors,
called primitive lattice vectors, or just **lattice vectors**,
through which we translate the points.

For example, for 2D square lattice, one has just one point at
origin :math:`(0, 0)`, and two lattice vectors :math:`{\bf A_1} = (a, 0)`
and :math:`{\bf A_2} = (0, a)` with :math:`a` being the lattice spacing.

Then one translate the points at origin to all passible integer
linear combinations :math:`n_1 {\bf A_1} + n_2 {\bf A_2}`.

Mathematically a lattice is usually infinite, however we usually
work with finite repititions, so :math:`n_1, n_2` are bounded
by the extent or size of the pattern, which in the above example
is 4.

In 2D one needs 2 lattice vectors, and in 3D one need 3 lattice
vectors. A number of lattices can be generated by just one point,
and suitably choosing the lattice vectors.

More complex structure require multiple points to translate to,
in order to generate the desired structure.
"""

__all__ = [
Expand Down
157 changes: 150 additions & 7 deletions qse/lattices/lattices.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def _check_repeats(repeats, param_name):

def chain(lattice_spacing: float, repeats: int) -> qse.Qbits:
"""
Generate a Qbits object in linear chain geometry.
Generate a Qbits object in linear chain geometry. This is
the simplest lattice in one dimension, with equally separated
qubits along a line.

Parameters
----------
Expand All @@ -28,6 +30,22 @@ def chain(lattice_spacing: float, repeats: int) -> qse.Qbits:
-------
Qbits
The Qbits lattice.

Examples
----
.. jupyter-execute::

import qse
q1d = qse.lattices.chain(
lattice_spacing=2.0,
repeats=6)
q1d.draw()

Note
----
For a one dimensional lattice, there isn't really a 'lattice vector'
as the positions are represented as numbers. The lattice separation
:math:`a` can be thought of as 1D lattice vector.
"""
_check_repeats(repeats, "repeats")
qbits = qse.Qbits(positions=np.zeros((1, 1)), cell=np.array([[lattice_spacing]]))
Expand All @@ -37,7 +55,7 @@ def chain(lattice_spacing: float, repeats: int) -> qse.Qbits:


def square(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
"""
r"""
Generate a Qbits object in square lattice geometry.

Parameters
Expand All @@ -55,6 +73,26 @@ def square(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
-------
Qbits
The Qbits lattice.


Examples
----
.. jupyter-execute::

import qse
qbit = qse.lattices.square(
lattice_spacing=2.0,
repeats_x=3, repeats_y=3)
qbit.draw(radius=4)

Note
----
For the square lattice the unit vectors are

.. math::
A_1 = (a, 0) \quad A_2 = (0, a)

with the single basis point at origin :math:`(0, 0)`.
"""
_check_repeats(repeats_x, "repeats_x")
_check_repeats(repeats_y, "repeats_y")
Expand All @@ -68,7 +106,7 @@ def square(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:


def triangular(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
"""
r"""
Generate a Qbits object in triangular lattice geometry.

Parameters
Expand All @@ -86,6 +124,25 @@ def triangular(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qb
-------
Qbits
The Qbits lattice.

Examples
----
.. jupyter-execute::

import qse
qbit = qse.lattices.triangular(
lattice_spacing=2.0,
repeats_x=3, repeats_y=3)
qbit.draw(radius=3)

Note
-----
For the triangular lattice the unit vectors are

.. math::
A_1 = (a, 0) \quad A_2 = (\frac 12 a,\frac{\sqrt{3}}{2} a)

with the single basis point at origin :math:`(0, 0)`.
"""
_check_repeats(repeats_x, "repeats_x")
_check_repeats(repeats_y, "repeats_y")
Expand All @@ -97,7 +154,7 @@ def triangular(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qb


def hexagonal(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
"""
r"""
Generate a Qbits object in hexagonal lattice geometry.

Parameters
Expand All @@ -115,6 +172,26 @@ def hexagonal(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbi
-------
Qbits
The Qbits lattice.

Examples
----
.. jupyter-execute::

import qse
qbit = qse.lattices.hexagonal(
lattice_spacing=2.0,
repeats_x=3, repeats_y=3)
qbit.draw(radius=3)

Note
-----
For the hexagonal lattice the unit vectors are

.. math::
A_1 = (\frac 32 a, \frac{\sqrt{3}}{2} a)\quad
A_2 = (\frac 32 a, -\frac{\sqrt{3}}{2} a)

with two basis points at :math:`(0, 0)` and :math:`(a, 0)`.
"""
_check_repeats(repeats_x, "repeats_x")
_check_repeats(repeats_y, "repeats_y")
Expand All @@ -128,7 +205,7 @@ def hexagonal(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbi


def kagome(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
"""
r"""
Generate a Qbits object in kagome lattice geometry.

Parameters
Expand All @@ -146,6 +223,29 @@ def kagome(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:
-------
Qbits
The Qbits lattice.

Examples
----
.. jupyter-execute::

import qse
qbit = qse.lattices.kagome(
lattice_spacing=2.0,
repeats_x=3, repeats_y=3)
qbit.draw(radius=3)

Note
-----
For the kagome lattice the unit vectors are

.. math::
A_1 = (2a, 0)\quad
A_2 = (a, \sqrt{3}a)

with three basis points at

.. math::
(0, 0)\quad (a, 0) \quad (\frac 12 a, \frac{\sqrt{3}}{2}a)
"""
_check_repeats(repeats_x, "repeats_x")
_check_repeats(repeats_y, "repeats_y")
Expand All @@ -166,12 +266,12 @@ def kagome(lattice_spacing: float, repeats_x: int, repeats_y: int) -> qse.Qbits:


def ring(spacing: float, nqbits: int) -> qse.Qbits:
"""
r"""
Generate a Qbits object in a ring geometry.

Parameters
----------
radius : float
spacing : float
The spacing between the qubits.
nqbits : int
Number of qubits on the ring.
Expand All @@ -180,6 +280,33 @@ def ring(spacing: float, nqbits: int) -> qse.Qbits:
-------
Qbits
The Qbits object.

Examples
--------
.. jupyter-execute::

import qse
qbit = qse.lattices.ring(
spacing=1.0,
nqbits=9)
qbit.draw(radius=3)

Note
----
This can be thought of as 1D chain where you connect
the end point and place them on a circular shape.

:math:`n` points placed on a circle of radius :math:`r`
have coordinates :math:`X_l = (r\cos\theta_l, r\sin\theta_l)`,
where :math:`l` ranges from 0 to :math:`n-1` and
:math:`\theta_l = \frac{2\pi l}{n}`.

If the qubit spacing supplied is :math:`a`, then we compute the
appropriate radius by solving :math:`a = |X_{l+1} - X_l|`, which
gives us the radius :math:`r` as

.. math::
r = \frac{a} {\sqrt{2 (1 - \cos{\frac{2\pi}{n}})}}
"""
# Using cosine rule
# spacing^2 = 2radius^2 [ 1 - cos(2pi/nqubits) ]
Expand Down Expand Up @@ -211,6 +338,22 @@ def torus(
-------
Qbits
The Qbits object.

Examples
--------
.. jupyter-execute::

import qse
qbit = qse.lattices.torus(
n_outer=12, n_inner=12,
inner_radius=5.0,
outer_radius=6.0)
qbit.draw()

Note
----
Though its not a commonly explored geometry, it represents
the 2D version of a ring, with periodic connection built in.
"""
theta = (2.0 * np.pi / n_outer) * np.arange(n_outer)
phi = (2.0 * np.pi / n_inner) * np.arange(n_inner)
Expand Down
Loading