Lattices
We can use Bloqade to simulate the quantum evolution of information stored in neutral atoms. Present-day neutral-atom hardware permits the arrangement of atoms in a regular lattice structure and even in nearly arbitrary geometries in 1D, 2D, and 3D. This makes neutral atom platform a natural playground for quantum simulation of statistical models and quantum matters. With Bloqade, we support several built-in lattice structures and also allow the users to specify atom positions by inputting coordinates. Please refer to the Rydberg Blockade page for recommendations on how to set the lattice constants for different lattices.
Types of Lattices
A crystal lattice is completely determined by a set of Bravais lattice vectors (in unit of μm) plus the locations of atoms within a unit cell. A Bravais lattice is an infinite array of discrete points generated by a set of discrete translation operations described by
\[\mathbf{R} = n_1 \mathbf{a}_1 + n_2 \mathbf{a}_2 + \ldots + n_d \mathbf{a}_d,\]
where $d$ is the dimension of space, $n_1, \ldots, n_d \in Z$ are integers. The unit cell of a Bravais lattice is defined by specifying its lattice vectors $(\mathbf{a}_1, \mathbf{a}_2, \ldots, \mathbf{a}_d)$. To create a simple lattice, we first specify the locations of the atoms within a unit cell and then specify the lattice vectors of the Bravais lattice. For example, for a triangular lattice, we need just one site (atom) at the location (0.0, 0.0)
in the unit cell and then lattice vectors (1.0, 0.0)
and (0.5, 0.5*sqrt(3))
:
julia> using Bloqade
julia> triangular = GeneralLattice([(1.0, 0.0), (0.5, 0.5*sqrt(3))], [(0.0, 0.0)])
GeneralLattice{2, 1, Float64}(((1.0, 0.0), (0.5, 0.8660254037844386)), ((0.0, 0.0),))
For composite lattices, one should provide multiple sites as the second argument to specify their locations in a unit cell. For example, the honeycomb lattice can be defined by:
julia> honeycomb = GeneralLattice([(1.0, 0.0), (0.5, 0.5*sqrt(3))], [(0.0, 0.0), (0.5, 0.5/sqrt(3))])
GeneralLattice{2, 2, Float64}(((1.0, 0.0), (0.5, 0.8660254037844386)), ((0.0, 0.0), (0.5, 0.2886751345948129)))
We provide a few shorthands for several useful lattices, including the ChainLattice
, SquareLattice
, HoneycombLattice
, TriangularLattice
, LiebLattice
, and KagomeLattice
shown below. One can use lattice_vectors
and lattice_sites
to access the lattice vectors and site locations in a unit cell as described in the above section.
ChainLattice
using Bloqade
chain = ChainLattice()
ChainLattice()
# to make the plot look good in both light and dark backgrounds.
BloqadeLattices.DEFAULT_BACKGROUND_COLOR[] = "#FFFFFF"
# to show the lattice vectors (rescaled a bit to shrink the head).
unitvectors(lattice::AbstractLattice{2}) = [((0.0, 0.0), v) for v in lattice_vectors(lattice)]
Bloqade.plot(generate_sites(chain, 10); vectors=[((0.0, 0.0), (0.9, 0.0))], bond_linewidth=0.015)
lattice_vectors(chain)
((1.0,),)
lattice_sites(chain)
((0.0,),)
Once we have defined certain lattice shapes (which have fixed lattice vectors and site positions in the unit cell), we can generate the atom positions by specifying the number of atoms and the scale size of the lattice. This is done by using the function generate_sites
, which will return a AtomList
instance containing the coordinates of each atom, e.g.:
atoms = generate_sites(HoneycombLattice(), 3, 5; scale = 4.5)
where scale
defines the unit distance in the unit μm of the lattice, and 3, 5
specifies the repetitions of unit cells in each lattice vector direction. The default scale
is 1 μm.
Here are some examples of other lattices:
SquareLattice
square = SquareLattice()
Bloqade.plot(generate_sites(square, 10, 10); vectors=unitvectors(square), bond_linewidth=0.015)
Note that the indices showing on the sites are consistent with the indices of the qubits for performing computation. In other words, if we want to do measurement or apply operations on individual sites (qubits), we can refer to the numbering on the atoms for convenience. For more details on how to generate Hamiltonians by using the lattice as an argument, please see the section Hamiltonians.
lattice_vectors(square)
((1.0, 0.0), (0.0, 1.0))
lattice_sites(square)
((0.0, 0.0),)
HoneycombLattice
honeycomb = HoneycombLattice()
Bloqade.plot(generate_sites(honeycomb, 5, 5); vectors=unitvectors(honeycomb), bond_linewidth=0.015)
TriangularLattice
triangular = TriangularLattice()
Bloqade.plot(generate_sites(triangular, 8, 8); vectors=unitvectors(triangular), bond_linewidth=0.015)
LiebLattice
lieb = LiebLattice()
Bloqade.plot(generate_sites(lieb, 5, 5); vectors=unitvectors(lieb), bond_linewidth=0.015)
KagomeLattice
kagome = KagomeLattice()
Bloqade.plot(generate_sites(kagome, 5, 5); vectors=unitvectors(kagome), bond_linewidth=0.015)
Sorting Sites and Other Operations on Lattices
We also support different operations on the generated lattices. For instance, one can apply some predefined filters, e.g. rescale_axes
, clip_axes
, offset_axes
, to manipulate atom locations:
atoms = generate_sites(HoneycombLattice(), 3, 5; scale = 4.5)
rescale_axes(atoms, 0.8)
where the above operation rescales the coordinates of the original sites
by a factor of 0.8
.
The code below restricts the atoms sitting in the window (0.0, 5.0), (0.0, 6.0)
and throw away those outside this area:
clip_axes(atoms, (0.0, 5.0), (0.0, 6.0))
Furthermore, we can shift the origin of the atoms
by some vector (5.0, 5.0)
simply by typing the code:
offset_axes(atoms, 5.0, 5.0)
To sort the atoms by their x-coordinates, one can convert these locations to a MaskedGrid
representation of the atoms:
atoms_in_grid = make_grid(atoms)
Then one can get the sorted atoms by typing:
sorted_atoms = collect_atoms(atoms_in_grid)
Note that the sorting will change the index numbering of the atoms.
You can also delete atoms given their index number:
deleteat!(atoms, 8, 9, 13, 14, 18, 20, 23)
atoms
Note that this permanently changes the contents of atoms
and just like sorting atoms, will change the index numbering albeit to preserve the integer sequence without gaps.
User-Defined Arbitrary Geometries
One can also generate atoms located at arbitrary positions by directly inputting the coordinates of the atoms:
julia> atom_coordinate = AtomList([(0.0, 0.0), (0, 5), (0, 8), (5, 2), (6, 7), (9, 6)])
⠀⠀⠀⠀⠀⠀⠀⠀Approximate Atom Positions⠀⠀⠀⠀⠀⠀⠀⠀ ┌────────────────────────────────────────┐ 8 │⚬⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⚬⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⚬│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⚬⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ μm │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⚬⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 0 │⚬⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ └────────────────────────────────────────┘ ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀9⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀μm⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
Query Neighbors
One can use make_kdtree
to generate a k-d tree data type for the efficient querying of neighborhoods in a low-dimensional space.
tree = make_kdtree(sorted_atoms)
NearestNeighbors.KDTree{StaticArraysCore.SVector{2, Float64}, Distances.Euclidean, Float64, StaticArraysCore.SVector{2, Float64}}
Number of points: 30
Dimensions: 2
Metric: Distances.Euclidean(0.0)
Reordered: true
The return value is a KDTree
instance, which is defined in the package NearestNeigbors
. One can use it to query the neighbors of an atom: e.g. one can find the 20 nearest neighbors of the 5-th site by typing:
neighbors = grouped_nearest(tree, 5, 20)
DistanceGroup([5, 8, 2, 3, 6, 11, 4, 10, 9, 7, 13, 14, 1, 12, 16, 17, 15, 19, 20, 18], [1, 2, 5, 9, 11, 14, 16, 17, 18, 19, 20, 21])
The return value is a DistanceGroup
instance, and the indices of the second nearest neighbors are:
neighbors[2]
4-element Vector{Int64}:
6
11
4
10
One can select and display these atoms with the correct labeling by typing:
Bloqade.plot(sorted_atoms[neighbors[2]]; texts=string.(neighbors[2]))
It shows the correct second nearest neighbors of the site 5. One can check the docstring of Bloqade.plot
to know more about how to customize lattice visualization.
References
BloqadeLattices.AbstractLattice
— TypeAbstractLattice{D}
Supertype for all D
dimensional lattices.
Implementation
lattice_vectors
and lattice_sites
functions must be defined which should both return an indexable iterable containing the Bravais lattice vectors and lattice sites respectively. (e.g.: GeneralLattice
returns a tuple of tuples containing the Bravais lattice vectors and lattice sites).
BloqadeLattices.GeneralLattice
— TypeGeneralLattice{D,K,T} <: AbstractLattice{D}
GeneralLattice(vectors, sites)
The general lattice type for tiling the space. Type parameter D
is the dimension, K
is the number of sites in a unit cell and T
is the data type for coordinates, e.g. Float64
. Input arguments are
vectors
is a vector/tuple of D-tuple. Its length is D, it specifies the Bravais lattice vectors.sites
is a vector/tuple of D-tuple. Its length is K, it specifies the sites inside a Bravais cell.
BloqadeLattices.SquareLattice
— Typestruct SquareLattice <: AbstractLattice{2}
Type representing 2D Square Lattice.
Used as an argument of generate_sites
function to produce tiling in a square pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Square is a 2D Lattice, so there must be two integer arguments as additional inputs.
Example
julia> generate_sites(SquareLattice(), 4, 4)
16-element AtomList{2, Float64}:
(0.0, 0.0)
(1.0, 0.0)
...
(2.0, 3.0)
(3.0, 3.0)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::SquareLattice)
and lattice_sites(::SquareLattice)
.
BloqadeLattices.RectangularLattice
— Typestruct RectangularLattice <: AbstractLattice{2}
Type representing 2D Rectangular Lattice.
Used as an argument of generate_sites
function to produce tiling in a Rectangular pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Rectangular is a 2D Lattice, so there must be two integer arguments as additional inputs. This type also enables the user to modify the length of one of the Bravais lattice vectors, by passing a single integer on construction as the aspect ratio.
Example
julia> generate_sites(RectangularLattice(2.0), 2, 2)
4-element AtomList{2, Float64}:
(0.0, 0.0)
(1.0, 0.0)
(0.0, 2.0)
(1.0, 2.0)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::RectangularLattice)
and lattice_sites(::RectangularLattice)
.
BloqadeLattices.HoneycombLattice
— Typestruct HoneycombLattice <: AbstractLattice{2}
Type representing 2D Honeycomb Lattice.
Used as an argument of generate_sites
function to produce tiling in a honeycomb pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Honeycomb is a 2D Lattice, so there must be two integer arguments as additional inputs.
Example
julia> generate_sites(HoneycombLattice(), 5, 5)
50-element AtomList{2, Float64}:
(0.0, 0.0)
(0.5, 0.2886751345948129)
...
(6.0, 3.4641016151377544)
(6.5, 3.7527767497325675)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::HoneycombLattice)
and lattice_sites(::HoneycombLattice)
.
BloqadeLattices.TriangularLattice
— Typestruct TriangularLattice <: AbstractLattice{2}
Type representing 2D Square Lattice.
Used as an argument of generate_sites
function to produce tiling in a triangle pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Triangle is a 2D Lattice, so there must be two integer arguments as additional inputs.
Example
julia> generate_sites(TriangularLattice(), 3, 3)
9-element AtomList{2, Float64}:
(0.0, 0.0)
(1.0, 0.0)
...
(2.0, 1.7320508075688772)
(3.0, 1.7320508075688772)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::TriangularLattice)
and lattice_sites(::TriangularLattice)
.
BloqadeLattices.ChainLattice
— Typestruct ChainLattice <: AbstractLattice{1}
Type representing 1D Chain Lattice.
Used as an argument of generate_sites
function to produce tiling in a chain pattern, with number of site repetitions being specified by the additional argument of generate_sites
. Chain is a 1D Lattice, so there must be one integer argument as additional inputs.
Example
julia> generate_sites(ChainLattice(), 5)
5-element AtomList{1, Float64}:
(0.0,)
(1.0,)
(2.0,)
(3.0,)
(4.0,)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::ChainLattice)
and lattice_sites(::ChainLattice)
.
BloqadeLattices.LiebLattice
— Typestruct LiebLattice <: AbstractLattice{2}
Type representing 2D Lieb Lattice.
Used as an argument of generate_sites
function to produce tiling in a Lieb (square-depleted) pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Lieb is a 2D Lattice, so there must be two integer arguments as additional inputs.
Example
julia> generate_sites(LiebLattice(), 3, 3)
27-element AtomList{2, Float64}:
(0.0, 0.0)
(0.5, 0.0)
...
(2.5, 2.0)
(2.0, 2.5)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::LiebLattice)
and lattice_sites(::LiebLattice)
.
BloqadeLattices.KagomeLattice
— Typestruct KagomeLattice <: AbstractLattice{2}
Type representing 2D Kagome Lattice.
Used as an argument of generate_sites
function to produce tiling in a Kagome pattern, with number of site repetitions being specified by additional arguments of generate_sites
. Kagome is a 2D Lattice, so there must be two integer arguments as additional inputs.
Example
julia> generate_sites(KagomeLattice(), 3, 3)
27-element AtomList{2, Float64}:
(0.0, 0.0)
(0.25, 0.4330127018922193)
...
(3.25, 2.1650635094610964)
(3.75, 2.1650635094610964)
Overriden functions to return lattice vectors and sites exists as lattice_vectors(::KagomeLattice)
and lattice_sites(::KagomeLattice)
.
BloqadeLattices.lattice_vectors
— Functionlattice_vectors(lattice::AbstractLattice)
Returns Bravais lattice vectors as a D-Tuple of D-Tuple, where D is the space dimension.
lattice_vectors(::HoneycombLattice)
Returns the Bravais lattice vectors for a Honeycomb lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.5, 0.5√3)
lattice_vectors(::SquareLattice)
Returns the Bravais lattice vectors for a Square lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.0, 1.0)
lattice_vectors(::TriangularLattice)
Returns the Bravais lattice vectors for a Triangular lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.5, 0.5√3)
lattice_vectors(::ChainLattice)
Returns the Bravais lattice vectors for a Chain lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0,)
lattice_vectors(::LiebLattice)
Returns the Bravais lattice vectors for a Lieb lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.0, 1.0)
lattice_vectors(::KagomeLattice)
Returns the Bravais lattice vectors for a Kagome lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.5, 0.5√3)
lattice_vectors(r::RectangularLattice)
Returns the Bravais lattice vectors for a Rectangular lattice as a Tuple of Tuples containing floats.
The vectors are defined as:
- 𝐚₁ = (1.0, 0.0)
- 𝐚₂ = (0.0,
r.aspect_ratio
), whereaspect_ratio
is aFloat64
.
lattice_vectors(lattice::BoundedLattice{L,C})
Returns the underlying Bravais lattice vectors of the BoundedLattice
julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice
julia> lattice_vectors(bl) # lattice vectors used in Bravais Lattice definition of underlying SquareLattice
((1.0, 0.0), (0.0, 1.0))
BloqadeLattices.lattice_sites
— Functionlattice_sites(lattice::AbstractLattice)
Returns sites in a Bravais lattice unit cell as a Tuple of D-Tuple, where D is the space dimension.
lattice_sites(::HoneycombLattice)
Returns the Bravais Lattice sites for a Honeycomb lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
- (0.5, 0.5√3)
lattice_sites(::SquareLattice)
Returns the Bravais Lattice sites for a Square lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
lattice_sites(::TriangularLattice)
Returns the Bravais Lattice sites for a Triangular lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
lattice_sites(::ChainLattice)
Returns the Bravais Lattice sites for a Chain lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0,)
lattice_sites(::LiebLattice)
Returns the Bravais Lattice sites for a Lieb lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
- (0.5, 0.0)
- (0.0, 0.5)
lattice_sites(::KagomeLattice)
Returns the Bravais Lattice sites for a Lieb lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
- (0.25, 0.25√3)
- (0.75, 0.25√3)
lattice_sites(::RectangularLattice)
Returns the Bravais Lattice sites for a Rectangular lattice as a Tuple of Tuples containing floats.
The sites are defined as:
- (0.0, 0.0)
lattice_sites(lattice::BoundedLattice{L,C})
Returns the underlying site vectors that define the unit-cell of the BoundedLattice
julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice
julia> lattice_sites(bl) # lattice vectors used in Bravais Lattice definition of underlying SquareLattice
((0.0, 0.0), )
BloqadeLattices.dimension
— Functiondimension(::AbstractLattice{D})
Returns the space dimension of target lattice. e.g. ChainLattice
is a 1D lattice, hence returns 1.
dimension(lattice::BoundedLattice{L,C})
Returns the dimensions of the BoundedLattice
(e.g.: 2
for 2D, 3
for 3D)
julia> bl = parallelepiped_region(ChainLattice(),(4,);pbc=true) # create a 1D BoundedLattice
julia> dimension(bl)
1
julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice
julia> dimension(bl)
2
BloqadeLattices.generate_sites
— Functiongenerate_sites(lattice::AbstractLattice{D}, repeats::Vararg{Int,D}; scale=1.0)
Returns an AtomList
instance by tiling the specified lattice
. The tiling repeat the sites
of the lattice m
times along the first dimension, n
times along the second dimension, and so on. scale
is a real number that re-scales the lattice constant and atom locations.
BloqadeLattices.offset_axes
— Functionoffset_axes(sites::AtomList{D, T}, offsets::Vararg{T,D}) where {D, T}
offset_axes(offsets...)
Offset the sites
by distance specified by offsets
.
julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
(1.0, 2.0)
(10.0, 3.0)
(1.0, 12.0)
(3.0, 5.0)
julia> offset_axes(sites, 1.0, 3.0)
4-element AtomList{2, Float64}:
(2.0, 5.0)
(11.0, 6.0)
(2.0, 15.0)
(4.0, 8.0)
BloqadeLattices.random_dropout
— Functionrandom_dropout(sites::AtomList{D, T}, ratio::Real) where {D, T}
random_dropout(ratio)
Randomly drop out ratio * number of sites
atoms from sites
, where ratio
∈ [0, 1].
BloqadeLattices.rescale_axes
— Functionrescale_axes(sites::AtomList{D, T}, scale::Real) where {D, T}
rescale_axes(scale)
Rescale the sites
by a constant scale
.
julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
(1.0, 2.0)
(10.0, 3.0)
(1.0, 12.0)
(3.0, 5.0)
julia> rescale_axes(sites, 2.0)
4-element AtomList{2, Float64}:
(2.0, 4.0)
(20.0, 6.0)
(2.0, 24.0)
(6.0, 10.0)
BloqadeLattices.clip_axes
— Functionclip_axes(sites::AtomList{D, T}, bounds::Vararg{Tuple{T,T},D}) where {D, T}
clip_axes(bounds...)
Remove sites out of bounds
, where bounds
is specified by D D-tuples.
julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
(1.0, 2.0)
(10.0, 3.0)
(1.0, 12.0)
(3.0, 5.0)
julia> clip_axes(sites, (-5.0, 5.0), (-5.0, 5.0))
2-element AtomList{2, Float64}:
(1.0, 2.0)
(3.0, 5.0)
BloqadeLattices.MaskedGrid
— TypeMaskedGrid{T}
MaskedGrid(xs, ys, mask)
Masked square lattice contains 3 fields, the x-coordinates, y-coordinates and a mask. e.g. MaskedGrid([0.0, 1.0, 3.0], [0.0, 2.0,6.0], Bool[1 0 0; 0 1 1; 0 1 0])
specifies the following lattice:
y₁ y₂ y₃
↓ ↓ ↓
x₁ → ● ⋅ ●
x₂ → ⋅ ● ●
x₃ → ⋅ ● ⋅
BloqadeLattices.AtomList
— TypeAtomList{D, T} <: AbstractVector{NTuple{D, T}}
AtomList(atoms::Vector{<:NTuple})
A list of atoms in D
dimensional space.
BloqadeLattices.make_grid
— Functionmake_grid(sites::AtomList; atol=...)
Create a MaskedGrid
from the sites. It is required by lattice preparation of Rydberg array. Because the grid will sort the sites by rows, we need atol
(default value is 10 time sit data precision) determines up to what level of round off error, two atoms belong to the same row.
BloqadeLattices.collect_atoms
— Functioncollect_atoms(maskedgrid::MaskedGrid)
Returns an list of atoms in the maskedgrid
in order.
BloqadeLattices.img_atoms
— Functionimg_atoms(atoms::Union{AtomList, BoundedLattice};
colors = [DEFAULT_LINE_COLOR[], ...],
texts = ["1", "2", ...],
vectors = [],
format = :svg,
filename = nothing,
kwargs...
)
Plots atoms
or bounded_lattice.site_positions
with colors specified by colors
and texts specified by texts
. You will need a VSCode
, Pluto
notebook or Jupyter
notebook to show the image. If you want to write this image to the disk without displaying it in a frontend, please try
julia> img_atoms(generate_sites(SquareLattice(), 5, 5); filename="test.png")
Keyword Arguments
features
colors
is a vector of colors for nodestexts
is a vector of string displayed on nodesvectors
is a vector of (startloc, endloc) pair to specify a list of arrows.
IO
format
can be:svg
,:pdf
or:png
filename
can be a filename string with suffix.svg
,.png
or.pdf
general
background_color = DEFAULT_BACKGROUND_COLOR[]
scale::Int = 60.0
is the number of pixels per unit lengthxpad::Float64 = 2.5
is the padding space in x axisypad::Float64 = 1.5
is the padding space in y axis
axes
axes_text_color = DEFAULT_TEXT_COLOR[]
axes_text_fontsize::Float64 = 16.0
axes_num_of_xticks = 5
axes_num_of_yticks = 5
axes_x_offset::Float64 = 0.5
axes_y_offset::Float64 = 0.5
axes_unit::String = "μm"
node
node_text_fontsize::Float64 = 16.0
node_text_color = DEFAULT_TEXT_COLOR[]
node_stroke_color = DEFAULT_LINE_COLOR[]
node_stroke_linewidth = 1
node_fill_color = DEFAULT_NODE_COLOR[]
bond
bond_color = DEFAULT_LINE_COLOR[]
bond_linewidth::Float64 = 1.0
blockade
blockade_radius::Float64=0
, atoms withinblockade_radius
will be connected by edges.blockade_style::String = "none"
, can be "none" or "dashed"blockade_stroke_color = DEFAULT_LINE_COLOR[]
blockade_fill_color = "transparent"
blockade_fill_opacity::Float64 = 0.5
blockade_stroke_linewidth = 1.0
# in pt
arrow
arrow_linewidth
arrow_color
arrow_head_length
grid
grid_stroke_color="#AAAAAA"
grid_stroke_width::Float64=1
grid_stroke_style::String="dashed"
BloqadeLattices.img_maskedgrid
— Functionimg_maskedgrid(maskedgrid::MaskedGrid;
colors=[DEFAULT_LINE_COLOR[], ...],
texts=["1", "2", ...],
vectors=[],
format=:svg,
filename=nothing,
kwargs...
)
Draw a maskedgrid
with colors specified by colors
and texts specified by texts
. You will need a VSCode
, Pluto
notebook or Jupyter
notebook to show the image.
Keyword Arguments
features
colors
is a vector of colors for nodestexts
is a vector of string displayed on nodesvectors
is a vector of (startloc, endloc) pair to specify a list of arrows.
IO
format
can be:svg
,:pdf
or:png
filename
can be a filename string with suffix.svg
,.png
or.pdf
general
background_color = DEFAULT_BACKGROUND_COLOR[]
scale::Int = 60.0
is the number of pixels per unit lengthxpad::Float64 = 2.5
is the padding space in x axisypad::Float64 = 1.5
is the padding space in y axis
axes
axes_text_color = DEFAULT_TEXT_COLOR[]
axes_text_fontsize::Float64 = 16.0
axes_num_of_xticks = 5
axes_num_of_yticks = 5
axes_x_offset::Float64 = 0.5
axes_y_offset::Float64 = 0.5
axes_unit::String = "μm"
node
node_text_fontsize::Float64 = 16.0
node_text_color = DEFAULT_TEXT_COLOR[]
node_stroke_color = DEFAULT_LINE_COLOR[]
node_stroke_linewidth = 1
node_fill_color = DEFAULT_NODE_COLOR[]
bond
bond_color = DEFAULT_LINE_COLOR[]
bond_linewidth::Float64 = 1.0
blockade
blockade_radius::Float64=0
, atoms withinblockade_radius
will be connected by edges.blockade_style::String = "none"
, can be "none" or "dashed"blockade_stroke_color = DEFAULT_LINE_COLOR[]
blockade_fill_color = "transparent"
blockade_fill_opacity::Float64 = 0.5
blockade_stroke_linewidth = 1.0
# in pt
arrow
arrow_linewidth
arrow_color
arrow_head_length
grid
grid_stroke_color="#AAAAAA"
grid_stroke_width::Float64=1
grid_stroke_style::String="dashed"
BloqadeLattices.ByDensity
— TypeByDensity(values; colormap="Grays", vmin=minimum(values), vmax=maximum(values))
For specifying the colors for density plots, where values
are densities.
Keyword arguments
colormap
is a string for specifying the color map, check the documentation of [Colors
] package for the detailed description.vmin
andvmax
are the color range.
BloqadeLattices.AbstractRegion
— TypeAbstractRegion{D}
Supertype for all D
dimensional regions used to define bounds on lattices.
Implementation
The following should be overriden:
Base.in
: ReturnsBool
on whether a point exists in the regionBase.mod
: Maps points outside the region back into the regiondistance
: Calculates distance between points with periodic boundary conditions enabled
BloqadeLattices.Parallelepiped
— Typestruct Parallelepiped{D, T} <: AbstractRegion{D}
Region that is a Parallelogram/Parallelepiped
See also Parallelepiped(vecs)
, Parallelepiped(vecs::T) where {T<:Real}
Fields
vecs::Matrix{T}
: Matrix with column vectors defining Parallelogram/Parallelepipedvecs_inv::Matrix{T}
: Inverse ofvecs
.
BloqadeLattices.Parallelepiped
— MethodParallelepiped(vecs)
Parallelepiped(vecs::T) where {T<:Real}
Define a region (either a line segment, parallelogram, or parallelepiped depending on the dimensions of vecs
) using a single value or column vectors in a matrix that can be used to create a BoundedLattice
.
julia> Parallelepiped(2.0) # can bound a 1D lattice
Parallelepiped{1, Float64}([2.0;;], [0.5;;])
julia> bounds = zeros((2,2)); # Create 2x2 matrix to store vectors defining 2D region
julia> bounds[:,1] .= (3,3); bounds[:,2] .= (4,0); # Column Vectors define the Parallelogram
julia> Parallelepiped(bounds)
Parallelepiped{2, Float64}([3.0 4.0; 3.0 0.0], [0.0 0.3333333333333333; 0.25 -0.25])
BloqadeLattices.Parallelepiped
— MethodParallelepiped(vecs)
Parallelepiped(vecs::T) where {T<:Real}
Define a region (either a line segment, parallelogram, or parallelepiped depending on the dimensions of vecs
) using a single value or column vectors in a matrix that can be used to create a BoundedLattice
.
julia> Parallelepiped(2.0) # can bound a 1D lattice
Parallelepiped{1, Float64}([2.0;;], [0.5;;])
julia> bounds = zeros((2,2)); # Create 2x2 matrix to store vectors defining 2D region
julia> bounds[:,1] .= (3,3); bounds[:,2] .= (4,0); # Column Vectors define the Parallelogram
julia> Parallelepiped(bounds)
Parallelepiped{2, Float64}([3.0 4.0; 3.0 0.0], [0.0 0.3333333333333333; 0.25 -0.25])
BloqadeLattices.distance
— Functiondistance(x, y)
distance(region::Parallelepiped{D,T},x,y)
Distance between two points.
If just points x
and y
are provided, the Euclidean distance is calculated.
If a region
is provided, then it is automatically assumed periodic boundary conditions are enabled and the smallest possible distance between the two points is returned.
julia> distance((0.0, 0.0), (1.0, 1.0))
1.4142135623730951
julia> bounds = zeros(2,2); bounds[:,1] .= (3, 0); bounds[:,2] .= (0, 3);
julia> distance(Parallelepiped(bounds), (0.5, 0.5), (2.5, 2.5))
1.4142135623730951
distance(lattice::BoundedLattice,x,y)
Returns the distance between two points in the BoundedLattice
.
Points x
and y
can be any iterable and must have the same dimensions as the BoundedLattice
(ex: (x,y)
for a 2D lattice, (x,y,z)
for a 3D lattice).
If the Periodic Boundary Condition option has been set to true
for the BoundedLattice
, the smallest distance between points (modulo the region) is returned, otherwise the standard Euclidean metric is used.
julia> bl = parallelepiped_region(SquareLattice(), (1,0),(0,1);) # Define 2D BoundedLattice
julia> distance(bl, (0.1, 0.1), (0.5, 1.1)) # distance between two points
1.077032961426901
julia> bl_pbc = parallelepiped_region(SquareLattice(), (1,0),(0,1);pbc=true) # Define 2D BoundedLattice with Periodic Boundary Condition
julia> distance(bl_pbc, (0.1, 0.1), (0.5, 1.1)) # distance with periodic boundary condition enabled
0.4
BloqadeLattices.generate_sites_in_region
— Functiongenerate_sites_in_region(lattice::AbstractLattice{D}, region::AbstractRegion{D})
Generates sites from the lattice
that are present in the region
.
julia> generate_sites_in_region(ChainLattice(), Parallelepiped(4.0))
4-element Vector{Tuple{Float64}}:
(0.0,)
(1.0,)
(2.0,)
(3.0,)
julia> bounds = zeros(2,2)
2×2 Matrix{Float64}:
0.0 0.0
0.0 0.0
julia> bounds[:,1] .= (0.0, 2.0); bounds[:,2] .= (2.0, 0.0);
julia> generate_sites_in_region(SquareLattice(), Parallelepiped(bounds))
4-element Vector{Tuple{Float64, Float64}}:
(0.0, 0.0)
(1.0, 0.0)
(0.0, 1.0)
(1.0, 1.0)
BloqadeLattices.BoundedLattice
— Typestruct BoundedLattice{L<:AbstractLattice, R<:AbstractRegion}
Defines a lattice bounded by a region with the option for periodic boundary conditions.
Fields
lattice <: AbstractLattice
: Lattice to be bounded.region <: AbstractRegion
: Region that bounds the underlyinglattice
.site_positions::AtomList
: Positions of the atoms insideregion
.pbc::Bool
: Enable/Disable behavior for Periodic Boundary Conditions.
BloqadeLattices.parallelepiped_region
— Functionparallelepiped_region(lattice::AbstractLattice{D},M::Vararg{NTuple{D,Int},D};pbc::Bool=false;scale::Real=1)
Create a BoundedLattice
given an existing lattice and tuples defining a parallelogram/paralelepiped /line segment defined by vectors that are integer multiples of the lattice vectors in lattice
.
Periodic Boundary Conditions can be enable/disabled via pbc
. Tuples must be the same length and quantity as the dimensions of the lattice argument.
julia> parallelepiped_region(SquareLattice(),(2,0),(0,2);pbc=true);
julia> parallelepiped_region(KagomeLattice(),(2,2),(-2,2));
BloqadeLattices.two_body_interaction_matrix
— Functiontwo_body_interaction_matrix(f, atoms)
Generates an interaction matrix given a function f
that accepts two atom positions at a time and an indexable iterable atoms
containing atom positions.
See also rydberg_interaction_matrix
julia> atoms = [(0.0,), (1.0,), (2.0,), (3.0,)]; # 1D chain, can also be AtomList
julia> two_body_interaction_matrix(atoms) do x,y return 1/distance(x,y) end
4×4 UpperTriangular{Float64, Matrix{Float64}}:
0.0 1.0 0.5 0.333333
⋅ 0.0 1.0 0.5
⋅ ⋅ 0.0 1.0
⋅ ⋅ ⋅ 0.0
BloqadeLattices.rydberg_interaction_matrix
— Functionrydberg_interaction_matrix(atoms, C::Real)
rydberg_interaction_matrix(lattice::BoundedLattice{L,R},C::Real)
Generate the interaction matrix given an indexable iterable atoms
containg atom positions and the Rydberg interaction constant C
.
A BoundedLattice
can be used in place of atoms
which generates the Rydberg interaction matrix for the lattice, factoring in Periodic Boundary Conditions.
See also two_body_interaction_matrix
julia> atoms = [(0.0,), (1.0,), (2.0,), (3.0,)]; # 1D chain of atoms
julia> rydberg_interaction_matrix(atoms, 2π * 862690) # provide Rydberg constant
4×4 UpperTriangular{Float64, Matrix{Float64}}:
0.0 5.42044e6 84694.4 7435.45
⋅ 0.0 5.42044e6 84694.4
⋅ ⋅ 0.0 5.42044e6
⋅ ⋅ ⋅ 0.0
julia> bl = parallelepiped_region(SquareLattice(),(2,0),(0,2);pbc=true);
julia> rydberg_interaction_matrix(bl, 2π * 862690)
4×4 UpperTriangular{Float64, Matrix{Float64}}:
0.0 5.42044e6 5.42044e6 6.77555e5
⋅ 0.0 6.77555e5 5.42044e6
⋅ ⋅ 0.0 5.42044e6
⋅ ⋅ ⋅ 0.0