Skip to content

Index

start module-attribute

start = ListOfLocations()

A Program starting point, alias of empty [ListOfLocations][bloqade.ir.location.list.ListOfLocations].

  • Next possible steps to build your program are:
  • Specify which level coupling to address with:
    • start.rydberg: for Rydberg Level coupling
    • start.hyperfine: for Hyperfine Level coupling
    • LOCKOUT: You cannot add atoms to your geometry after specifying level coupling.
  • continue/start building your geometry with:
    • start.add_position(): to add atom(s) to current register. It will accept:
      • A single coordinate, represented as a tuple (e.g. (5,6)) with a value that can either be:
        • integers: (5,6)
        • floats: (5.1, 2.5)
        • strings (for later variable assignment): ("x", "y")
        • Scalar objects: (2*cast("x"), 5+cast("y"))
      • A list of coordinates, represented as a list of types mentioned previously.
      • A numpy array with shape (n, 2) where n is the total number of atoms

AlignedWaveform

Bases: Waveform

<padded waveform> ::= <waveform> | <waveform> <alignment> <value>

<alignment> ::= 'left aligned' | 'right aligned'
<value> ::= 'left value' | 'right value' | <scalar expr>

AnalogCircuit

AnalogCircuit is a dummy type that bundle register and sequence together.

register property

register

Get the register of the program.

Returns:

Type Description

register (Union["AtomArrangement", "ParallelRegister"])

Note

If the program is built with [parallelize()][bloqade.builder.emit.Emit.parallelize], The the register will be a [ParallelRegister][bloqade.ir.location.base.ParallelRegister]. Otherwise it will be a [AtomArrangement][bloqade.ir.location.base.AtomArrangement].

show

show(**assignments)

Interactive visualization of the program

Parameters:

Name Type Description Default
**assignments

assigning the instance value (literal) to the existing variables in the program

{}
Source code in src/bloqade/ir/analog_circuit.py
def show(self, **assignments):
    """Interactive visualization of the program

    Args:
        **assignments: assigning the instance value (literal) to the
            existing variables in the program

    """
    display_ir(self, assignments)

AtomArrangement

AtomArrangement(parent=None)

Bases: ProgramStart

Source code in src/bloqade/builder/base.py
def __init__(
    self,
    parent: Optional["Builder"] = None,
) -> None:
    self.__parent__ = parent

n_atoms property

n_atoms

number of atoms (filled sites) in the register.

n_dims property

n_dims

number of dimensions in the register.

n_sites property

n_sites

number of sites in the register.

n_vacant property

n_vacant

number of vacant sites in the register.

add_position

add_position(position, filling=None)

Add a position or multiple positions to a pre-existing geometry.

add_position is capable of accepting: - A single tuple for one atom coordinate: (1.0, 2.5) - A list of tuples: `[(0.0, 1.0), (2.0,1.5), etc.] - A numpy array of shape (N, 2) where N is the number of atoms

You may also intersperse variables anywhere a value may be present.

You can also pass in an optional argument which determines the atom "filling" (whether or not at a specified coordinate an atom should be present).

Usage Example:
# single coordinate
>>> reg = start.add_position((0,0))
# you may chain add_position calls
>>> reg_plus_two = reg.add_position([(2,2),(5.0, 2.1)])
# you can add variables anywhere a value may be present
>>> reg_with_var = reg_plus_two.add_position(("x", "y"))
# and specify your atom fillings
>>> reg_with_filling = reg_with_var.add_position([(3.1, 0.0), (4.1, 2.2)],
[True, False])
# alternatively you could use one boolean to specify
# all coordinates should be empty/filled
>>> reg_with_more_filling = reg_with_filling.add_positions([(3.1, 2.9),
(5.2, 2.2)], False)
  • Next possible steps are:
  • Continuing to build your geometry via:
    • ...add_position(positions).add_position(positions): to add more positions
    • ...add_position(positions).apply_defect_count(n_defects): to randomly drop out n_atoms
    • ...add_position(positions).apply_defect_density(defect_probability): to drop out atoms with a certain probability
    • ...add_position(positions).scale(scale): to scale the geometry
  • Targeting a level coupling once you're done with the atom geometry:
    • ...add_position(positions).rydberg: to specify Rydberg coupling
    • ...add_position(positions).hyperfine: to specify Hyperfine coupling
  • Visualizing your atom geometry:
    • ...add_position(positions).show(): shows your geometry in your web browser
Source code in src/bloqade/ir/location/location.py
def add_position(
    self,
    position: Union[
        PositionArray,
        List[Tuple[ScalarType, ScalarType]],
        Tuple[ScalarType, ScalarType],
    ],
    filling: Optional[Union[BoolArray, List[bool], bool]] = None,
) -> "ListOfLocations":
    """
    Add a position or multiple positions to a pre-existing geometry.

    `add_position` is capable of accepting:
    - A single tuple for one atom coordinate: `(1.0, 2.5)`
    - A list of tuples: `[(0.0, 1.0), (2.0,1.5), etc.]
    - A numpy array of shape (N, 2) where N is the number of atoms

    You may also intersperse variables anywhere a value may be present.

    You can also pass in an optional argument which determines the atom "filling"
    (whether or not at a specified coordinate an atom should be present).

    ### Usage Example:
    ```
    # single coordinate
    >>> reg = start.add_position((0,0))
    # you may chain add_position calls
    >>> reg_plus_two = reg.add_position([(2,2),(5.0, 2.1)])
    # you can add variables anywhere a value may be present
    >>> reg_with_var = reg_plus_two.add_position(("x", "y"))
    # and specify your atom fillings
    >>> reg_with_filling = reg_with_var.add_position([(3.1, 0.0), (4.1, 2.2)],
    [True, False])
    # alternatively you could use one boolean to specify
    # all coordinates should be empty/filled
    >>> reg_with_more_filling = reg_with_filling.add_positions([(3.1, 2.9),
    (5.2, 2.2)], False)
    ```

    - Next possible steps are:
    - Continuing to build your geometry via:
        - `...add_position(positions).add_position(positions)`:
            to add more positions
        - `...add_position(positions).apply_defect_count(n_defects)`:
        to randomly drop out n_atoms
        - `...add_position(positions).apply_defect_density(defect_probability)`:
        to drop out atoms with a certain probability
        - `...add_position(positions).scale(scale)`: to scale the geometry
    - Targeting a level coupling once you're done with the atom geometry:
        - `...add_position(positions).rydberg`: to specify Rydberg coupling
        - `...add_position(positions).hyperfine`: to specify Hyperfine coupling
    - Visualizing your atom geometry:
        - `...add_position(positions).show()`:
        shows your geometry in your web browser

    """

    if is_bearable(position, PositionArray) and is_bearable(
        filling, Optional[BoolArray]
    ):
        return self.add_position_ndarray(position, filling)
    elif is_bearable(position, List[Tuple[ScalarType, ScalarType]]) and is_bearable(
        filling, Optional[List[bool]]
    ):
        return self.add_position_list_tuples(position, filling)
    elif is_bearable(position, Tuple[ScalarType, ScalarType]) and is_bearable(
        filling, Optional[bool]
    ):
        return self.add_position_single_tupe(position, filling)
    else:
        raise TypeError("Invalid input types for add_position provided!")

apply_defect_count

apply_defect_count(n_defects, rng=np.random.default_rng())

Drop n_defects atoms from the geometry randomly. Internally this occurs by setting certain sites to have a SiteFilling set to false indicating no atom is present at the coordinate.

A default numpy-based Random Number Generator is used but you can explicitly override this by passing in your own.

Usage Example:
>>> from bloqade.atom_arrangement import Chain
>>> import numpy as np
# set a custom seed for a numpy-based RNG
>>> custom_rng = np.random.default_rng(888)
# randomly remove two atoms from the geometry
>>> reg = Chain(11).apply_defect_count(2, custom_rng)
# you may also chain apply_defect_count calls
>>> reg.apply_defect_count(2, custom_rng)
# you can also use apply_defect_count on custom geometries
>>> from bloqade import start
>>> start.add_position([(0,0), (1,1)]).apply_defect_count(1, custom_rng)
  • Next possible steps are:
  • Continuing to build your geometry via:
    • ...apply_defect_count(defect_counts).add_position(positions): to add more positions
    • ...apply_defect_count(defect_counts) .apply_defect_count(n_defects): to randomly drop out n_atoms
    • ...apply_defect_count(defect_counts) .apply_defect_density(defect_probability): to drop out atoms with a certain probability
    • ...apply_defect_count(defect_counts).scale(scale): to scale the geometry
  • Targeting a level coupling once you're done with the atom geometry:
    • ...apply_defect_count(defect_counts).rydberg: to specify Rydberg coupling
    • ...apply_defect_count(defect_counts).hyperfine: to specify Hyperfine coupling
  • Visualizing your atom geometry:
    • ...apply_defect_count(defect_counts).show(): shows your geometry in your web browser
Source code in src/bloqade/ir/location/location.py
@beartype
def apply_defect_count(
    self, n_defects: int, rng: np.random.Generator = np.random.default_rng()
):
    """
    Drop `n_defects` atoms from the geometry randomly. Internally this occurs
    by setting certain sites to have a SiteFilling set to false indicating
    no atom is present at the coordinate.

    A default numpy-based Random Number Generator is used but you can
    explicitly override this by passing in your own.

    ### Usage Example:

    ```
    >>> from bloqade.atom_arrangement import Chain
    >>> import numpy as np
    # set a custom seed for a numpy-based RNG
    >>> custom_rng = np.random.default_rng(888)
    # randomly remove two atoms from the geometry
    >>> reg = Chain(11).apply_defect_count(2, custom_rng)
    # you may also chain apply_defect_count calls
    >>> reg.apply_defect_count(2, custom_rng)
    # you can also use apply_defect_count on custom geometries
    >>> from bloqade import start
    >>> start.add_position([(0,0), (1,1)]).apply_defect_count(1, custom_rng)
    ```

    - Next possible steps are:
    - Continuing to build your geometry via:
        - `...apply_defect_count(defect_counts).add_position(positions)`:
            to add more positions
        - `...apply_defect_count(defect_counts)
            .apply_defect_count(n_defects)`: to randomly drop out n_atoms
        - `...apply_defect_count(defect_counts)
            .apply_defect_density(defect_probability)`:
            to drop out atoms with a certain probability
        - `...apply_defect_count(defect_counts).scale(scale)`:
            to scale the geometry
    - Targeting a level coupling once you're done with the atom geometry:
        - `...apply_defect_count(defect_counts).rydberg`: to specify
            Rydberg coupling
        - `...apply_defect_count(defect_counts).hyperfine`:
            to specify Hyperfine coupling
    - Visualizing your atom geometry:
        - `...apply_defect_count(defect_counts).show()`:
            shows your geometry in your web browser
    """

    location_list = []
    for location_info in self.enumerate():
        location_list.append(location_info)

    filled_sites = []

    for index, location_info in enumerate(location_list):
        if location_info.filling is SiteFilling.filled:
            filled_sites.append(index)

    if n_defects >= len(filled_sites):
        raise ValueError(
            f"n_defects {n_defects} must be less than the number of filled sites "
            f"({len(filled_sites)})"
        )

    for _ in range(n_defects):
        index = rng.choice(filled_sites)
        location_list[index] = LocationInfo.create(
            location_list[index].position,
            (False if location_list[index].filling is SiteFilling.filled else True),
        )
        filled_sites.remove(index)

    return ListOfLocations(location_list)

apply_defect_density

apply_defect_density(
    defect_probability, rng=np.random.default_rng()
)

Drop atoms randomly with defect_probability probability (range of 0 to 1). Internally this occurs by setting certain sites to have a SiteFilling set to false indicating no atom is present at the coordinate.

A default numpy-based Random Number Generator is used but you can explicitly override this by passing in your own.

Usage Example:
>>> from bloqade.atom_arrangement import Chain
>>> import numpy as np
# set a custom seed for a numpy-based RNG
>>> custom_rng = np.random.default_rng(888)
# randomly remove two atoms from the geometry
>>> reg = Chain(11).apply_defect_density(0.2, custom_rng)
# you may also chain apply_defect_density calls
>>> reg.apply_defect_count(0.1, custom_rng)
# you can also use apply_defect_density on custom geometries
>>> from bloqade import start
>>> start.add_position([(0,0), (1,1)])
.apply_defect_density(0.5, custom_rng)
  • Next possible steps are:
  • Continuing to build your geometry via:
    • ...apply_defect_count(defect_counts).add_position(positions): to add more positions
    • ...apply_defect_count(defect_counts).apply_defect_count(n_defects): to randomly drop out n_atoms
    • ...apply_defect_count(defect_counts) .apply_defect_density(defect_probability): to drop out atoms with a certain probability
    • ...apply_defect_count(defect_counts).scale(scale): to scale the geometry
  • Targeting a level coupling once you're done with the atom geometry:
    • ...apply_defect_count(defect_counts).rydberg: to specify Rydberg coupling
    • ...apply_defect_count(defect_counts).hyperfine: to specify Hyperfine coupling
  • Visualizing your atom geometry:
    • ...apply_defect_count(defect_counts).show(): shows your geometry in your web browser
Source code in src/bloqade/ir/location/location.py
@beartype
def apply_defect_density(
    self,
    defect_probability: float,
    rng: np.random.Generator = np.random.default_rng(),
):
    """
    Drop atoms randomly with `defect_probability` probability (range of 0 to 1).
    Internally this occurs by setting certain sites to have a SiteFilling
    set to false indicating no atom is present at the coordinate.

    A default numpy-based Random Number Generator is used but you can
    explicitly override this by passing in your own.

    ### Usage Example:

    ```
    >>> from bloqade.atom_arrangement import Chain
    >>> import numpy as np
    # set a custom seed for a numpy-based RNG
    >>> custom_rng = np.random.default_rng(888)
    # randomly remove two atoms from the geometry
    >>> reg = Chain(11).apply_defect_density(0.2, custom_rng)
    # you may also chain apply_defect_density calls
    >>> reg.apply_defect_count(0.1, custom_rng)
    # you can also use apply_defect_density on custom geometries
    >>> from bloqade import start
    >>> start.add_position([(0,0), (1,1)])
    .apply_defect_density(0.5, custom_rng)
    ```

    - Next possible steps are:
    - Continuing to build your geometry via:
        - `...apply_defect_count(defect_counts).add_position(positions)`:
        to add more positions
        - `...apply_defect_count(defect_counts).apply_defect_count(n_defects)`:
        to randomly drop out n_atoms
        - `...apply_defect_count(defect_counts)
        .apply_defect_density(defect_probability)`:
        to drop out atoms with a certain probability
        - `...apply_defect_count(defect_counts).scale(scale)`:
        to scale the geometry
    - Targeting a level coupling once you're done with the atom geometry:
        - `...apply_defect_count(defect_counts).rydberg`:
        to specify Rydberg coupling
        - `...apply_defect_count(defect_counts).hyperfine`:
        to specify Hyperfine coupling
    - Visualizing your atom geometry:
        - `...apply_defect_count(defect_counts).show()`:
        shows your geometry in your web browser
    """

    p = min(1, max(0, defect_probability))
    location_list = []

    for location_info in self.enumerate():
        if rng.random() < p:
            location_list.append(
                LocationInfo.create(
                    location_info.position,
                    (
                        False
                        if location_info.filling is SiteFilling.filled
                        else True
                    ),
                )
            )
        else:
            location_list.append(location_info)

    return ListOfLocations(location_list=location_list)

enumerate

enumerate()

enumerate all locations in the register.

Source code in src/bloqade/ir/location/location.py
def enumerate(self) -> Generator[LocationInfo, None, None]:
    """enumerate all locations in the register."""
    raise NotImplementedError

figure

figure(fig_kwargs=None, **assignments)

obtain a figure object from the atom arrangement.

Source code in src/bloqade/ir/location/location.py
def figure(self, fig_kwargs=None, **assignments):
    """obtain a figure object from the atom arrangement."""
    return get_atom_arrangement_figure(self, fig_kwargs=fig_kwargs, **assignments)

rydberg_interaction

rydberg_interaction(**assignments)

calculate the Rydberg interaction matrix.

Parameters:

Name Type Description Default
**assignments

the values to assign to the variables in the register.

{}

Returns:

Name Type Description
NDArray NDArray

the Rydberg interaction matrix in the lower triangular form.

Source code in src/bloqade/ir/location/location.py
def rydberg_interaction(self, **assignments) -> NDArray:
    """calculate the Rydberg interaction matrix.

    Args:
        **assignments: the values to assign to the variables in the register.

    Returns:
        NDArray: the Rydberg interaction matrix in the lower triangular form.

    """

    from bloqade.constants import RB_C6

    # calculate the Interaction matrix
    V_ij = np.zeros((self.n_sites, self.n_sites))
    for i, site_i in enumerate(self.enumerate()):
        pos_i = np.array([float(ele(**assignments)) for ele in site_i.position])

        for j, site_j in enumerate(self.enumerate()):
            if j >= i:
                break  # enforce lower triangular form

            pos_j = np.array([float(ele(**assignments)) for ele in site_j.position])
            r_ij = np.linalg.norm(pos_i - pos_j)

            V_ij[i, j] = RB_C6 / r_ij**6

    return V_ij

scale

scale(scale)

Scale the geometry of your atoms.

Usage Example:
>>> reg = start.add_position([(0,0), (1,1)])
# atom positions are now (0,0), (2,2)
>>> new_reg = reg.scale(2)
# you may also use scale on pre-defined geometries
>>> from bloqade.atom_arrangement import Chain
# atoms in the chain will now be 2 um apart versus
# the default 1 um
>>> Chain(11).scale(2)
  • Next possible steps are:
  • Continuing to build your geometry via:
    • ...add_position(positions).add_position(positions): to add more positions
    • ...add_position(positions).apply_defect_count(n_defects): to randomly drop out n_atoms
    • ...add_position(positions).apply_defect_density(defect_probability): to drop out atoms with a certain probability
    • ...add_position(positions).scale(scale): to scale the geometry
  • Targeting a level coupling once you're done with the atom geometry:
    • ...add_position(positions).rydberg: to specify Rydberg coupling
    • ...add_position(positions).hyperfine: to specify Hyperfine coupling
  • Visualizing your atom geometry:
    • ...add_position(positions).show(): shows your geometry in your web browser
Source code in src/bloqade/ir/location/location.py
@beartype
def scale(self, scale: ScalarType):
    """
    Scale the geometry of your atoms.

    ### Usage Example:
    ```
    >>> reg = start.add_position([(0,0), (1,1)])
    # atom positions are now (0,0), (2,2)
    >>> new_reg = reg.scale(2)
    # you may also use scale on pre-defined geometries
    >>> from bloqade.atom_arrangement import Chain
    # atoms in the chain will now be 2 um apart versus
    # the default 1 um
    >>> Chain(11).scale(2)
    ```

    - Next possible steps are:
    - Continuing to build your geometry via:
        - `...add_position(positions).add_position(positions)`:
            to add more positions
        - `...add_position(positions).apply_defect_count(n_defects)`:
        to randomly drop out n_atoms
        - `...add_position(positions).apply_defect_density(defect_probability)`:
        to drop out atoms with a certain probability
        - `...add_position(positions).scale(scale)`: to scale the geometry
    - Targeting a level coupling once you're done with the atom geometry:
        - `...add_position(positions).rydberg`:
        to specify Rydberg coupling
        - `...add_position(positions).hyperfine`:
        to specify Hyperfine coupling
    - Visualizing your atom geometry:
        - `...add_position(positions).show()`:
        shows your geometry in your web browser

    """

    scale = cast(scale)
    location_list = []
    for location_info in self.enumerate():
        x, y = location_info.position
        new_position = (scale * x, scale * y)
        location_list.append(
            LocationInfo.create(new_position, bool(location_info.filling.value))
        )

    return ListOfLocations(location_list)

BoundedBravais

BoundedBravais(parent=None)

Bases: AtomArrangement

Source code in src/bloqade/builder/base.py
def __init__(
    self,
    parent: Optional["Builder"] = None,
) -> None:
    self.__parent__ = parent

__match_args__ class-attribute instance-attribute

__match_args__ = ('shape', 'lattice_spacing')

Base classe for Bravais lattices [AtomArrangement][bloqade.ir.location.base.AtomArrangement].

n_dims property

n_dims

dimension of the lattice

Returns:

Name Type Description
int

dimension of the lattice

coordinates

coordinates(index)

calculate the coordinates of a cell in the lattice given the cell index.

Source code in src/bloqade/ir/location/bravais.py
@beartype
def coordinates(self, index: List[int]) -> NDArray:
    """calculate the coordinates of a cell in the lattice
    given the cell index.
    """
    # damn! this is like stone age broadcasting
    vectors = np.array(self.cell_vectors())
    index = np.array(index)
    pos = np.sum(vectors.T * index, axis=1)
    return pos + np.array(self.cell_atoms())

scale

scale(factor)

Scale the current location with a factor.

(x,y) -> factor*(x,y)

Parameters:

Name Type Description Default
factor str | Real | Decimal | Scalar

scale factor

required

Returns:

Name Type Description
BoundedBravais BoundedBravais

The lattice with the scaled locations

Source code in src/bloqade/ir/location/bravais.py
@beartype
def scale(self, factor: ScalarType) -> "BoundedBravais":
    """Scale the current location with a factor.

    (x,y) -> factor*(x,y)

    Args:
        factor (str | Real | Decimal | Scalar): scale factor

    Returns:
        BoundedBravais: The lattice with the scaled locations
    """
    factor = cast(factor)
    obj = self.__new__(type(self))
    for f in fields(self):
        if f.name == "lattice_spacing":
            obj.lattice_spacing = factor * self.lattice_spacing
        else:
            setattr(obj, f.name, getattr(self, f.name))
    return obj

Chain

Chain(L, *, lattice_spacing=1.0, vertical_chain=False)

Bases: BoundedBravais

Chain lattice.

  • 1D lattice
  • primitive (cell) vector(s)
    • a1 = (1,0).
  • unit cell (1 atom(s))
    • loc (0,0)

Parameters:

Name Type Description Default
L int

number of sites in the chain

required
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L: int, *, lattice_spacing: ScalarType = 1.0, vertical_chain: bool = False
):
    self.L = L
    self.lattice_spacing = cast(lattice_spacing)
    self.vertical_chain = vertical_chain
    super().__init__()

Constant

Constant(value, duration)

Bases: Instruction

<constant> ::= 'constant' <scalar expr>

f(t=0:duration) = value

Parameters:

Name Type Description Default
value Scalar

the constant value

required
duration Scalar

the time span of the constant waveform.

required
Source code in src/bloqade/ir/control/waveform.py
@beartype
def __init__(self, value: ScalarType, duration: ScalarType):
    object.__setattr__(self, "value", cast(value))
    object.__setattr__(self, "duration", cast(duration))

Field

Bases: FieldExpr

Field node in the IR. Which contains collection(s) of Waveform

<field> ::= ('field' <spatial modulation>  <padded waveform>)*

show

show(**assignments)

Interactive visualization of the Field

Parameters:

Name Type Description Default
**assignments

assigning the instance value (literal) to the existing variables in the Field

{}
Source code in src/bloqade/ir/control/field.py
def show(self, **assignments):
    """
    Interactive visualization of the Field

    Args:
        **assignments: assigning the instance value (literal) to the
            existing variables in the Field

    """
    display_ir(self, assignments)

Honeycomb

Honeycomb(L1, L2=None, *, lattice_spacing=1.0)

Bases: BoundedBravais

Honeycomb lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1, 0)
    • a2 = (½, sqrt(3)/2)
  • unit cell (2 atom(s))
    • loc1 (0, 0)
    • loc2 (½, 1/(2*sqrt(3))

Parameters:

Name Type Description Default
L1 int

number of unit cells in linear direction. n_atoms = L1 * L1 * 2.

required
L2 Optional[int]

number of unit cells in direction a2. n_atoms = L1 * L2 * 2, default is L1.

None
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L1: int, L2: Optional[int] = None, *, lattice_spacing: ScalarType = 1.0
):
    if L2 is None:
        L2 = L1

    self.L1 = L1
    self.L2 = L2
    self.lattice_spacing = cast(lattice_spacing)

    super().__init__()

Kagome

Kagome(L1, L2=None, *, lattice_spacing=1.0)

Bases: BoundedBravais

Kagome lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1, 0)
    • a2 = (½, sqrt(3)/2)
  • unit cell (3 atom(s))
    • loc1 (0, 0)
    • loc2 (0.5, 0)
    • loc3 (0.25 ,0.25sqrt(3))

Parameters:

Name Type Description Default
L1 int

number of sites in linear direction. n_atoms = 3 * L1 * L1.

required
L2 Optional[int]

number of unit cells along a2 direction, n_atoms = 3 * L1 * L2, default is L1.

None
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L1: int, L2: Optional[int] = None, *, lattice_spacing: ScalarType = 1.0
):
    if L2 is None:
        L2 = L1

    self.L1 = L1
    self.L2 = L2
    self.lattice_spacing = cast(lattice_spacing)
    super().__init__()

Lieb

Lieb(L1, L2=None, *, lattice_spacing=1.0)

Bases: BoundedBravais

Lieb lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1, 0)
    • a2 = (0, 1)
  • unit cell (3 atom(s))
    • loc1 (0, 0)
    • loc2 (0.5, 0)
    • loc3 (0 ,0.5)

Parameters:

Name Type Description Default
L1 int

number of unit cells in linear direction. n_atoms = 3* L1 * L1.

required
L2 Optional[int]

number of unit cells along a2 direction, n_atoms = 3 * L1 * L2, default is L1.

None
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L1: int, L2: Optional[int] = None, *, lattice_spacing: ScalarType = 1.0
):
    if L2 is None:
        L2 = L1
    self.L1 = L1
    self.L2 = L2
    self.lattice_spacing = cast(lattice_spacing)

Linear

Linear(start, stop, duration)

Bases: Instruction

<linear> ::= 'linear' <scalar expr> <scalar expr>

f(t=0:duration) = start + (stop-start)/duration * t

Parameters:

Name Type Description Default
start Scalar

start value

required
stop Scalar

stop value

required
duration Scalar

the time span of the linear waveform.

required
Source code in src/bloqade/ir/control/waveform.py
@beartype
def __init__(self, start: ScalarType, stop: ScalarType, duration: ScalarType):
    object.__setattr__(self, "start", cast(start))
    object.__setattr__(self, "stop", cast(stop))
    object.__setattr__(self, "duration", cast(duration))

Literal

Bases: Real

value instance-attribute

value

Scalar Literal, which stores a decimaal value instance.

Parameters:

Name Type Description Default
value Decimal

decimal value instance

required

Poly

Poly(coeffs, duration)

Bases: Instruction

<poly> ::= <scalar>+

f(t=0:duration) = c[0] + c[1]t + c[2]t^2 + ... + c[n-1]t^n-1 + c[n]t^n

Parameters:

Name Type Description Default
coeffs Tuple[Scalar]

the coefficients c[] of the polynomial.

required
duration Scalar

the time span of the waveform.

required
Source code in src/bloqade/ir/control/waveform.py
@beartype
def __init__(self, coeffs: Container[ScalarType], duration: ScalarType):
    object.__setattr__(self, "coeffs", tuple(map(cast, coeffs)))
    object.__setattr__(self, "duration", cast(duration))

Pulse

Bases: PulseExpr

<pulse> ::= (<field name> <field>)+

show

show(**assignments)

Interactive visualization of the Pulse

Parameters:

Name Type Description Default
**assignments

assigning the instance value (literal) to the existing variables in the Pulse

{}
Source code in src/bloqade/ir/control/pulse.py
def show(self, **assignments):
    """
    Interactive visualization of the Pulse

    Args:
        **assignments: assigning the instance value (literal) to the
            existing variables in the Pulse

    """
    display_ir(self, assignments)

PythonFn

Bases: Instruction

<python-fn> ::= 'python-fn' <python function def> <scalar expr>

Record

Bases: Waveform

<record> ::= 'record' <waveform> <var> <side>

Rectangular

Rectangular(
    width,
    height,
    *,
    lattice_spacing_x=1.0,
    lattice_spacing_y=1.0
)

Bases: BoundedBravais

Rectangular lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1,0)
    • a2 = (0,1)
  • unit cell (1 atom(s))
    • loc (0,0)

Parameters:

Name Type Description Default
width int

number of sites in x direction.

required
height int

number of sites in y direction.

required
lattice_spacing_x (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
lattice_spacing_y (Scalar, Real)

lattice spacing in y direction. optional.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self,
    width: int,
    height: int,
    *,
    lattice_spacing_x: ScalarType = 1.0,
    lattice_spacing_y: ScalarType = 1.0,
):
    self.width = width
    self.height = height
    self.lattice_spacing_x = cast(lattice_spacing_x)
    self.lattice_spacing_y = (
        cast(lattice_spacing_y)
        if lattice_spacing_y is not None
        else self.lattice_spacing_x
    )

    super().__init__()

Sample

Bases: Waveform

<sample> ::= 'sample' <waveform> <interpolation> <scalar>

Scalar

Base class for all scalar expressions.

<scalar> ::= <literal>
| <variable>
| <default>
| <negative>
| <add>
| <mul>
| <min>
| <max>
| <slice>
| <inverval>

<mul> ::= <scalar> '*' <scalar>
<add> ::= <scalar> '+' <scalar>
<min> ::= 'min' <scalar>+
<max> ::= 'max' <scalar>+
<slice> ::= <scalar expr> '[' <interval> ']'
<interval> ::= <scalar expr> '..' <scalar expr>
<real> ::= <literal> | <var>

Sequence

Bases: SequenceExpr

Sequence of a program, which includes pulses informations.

show

show(**assignments)

Interactive visualization of the Sequence

Parameters:

Name Type Description Default
**assignments

assigning the instance value (literal) to the existing variables in the Sequence

{}
Source code in src/bloqade/ir/control/sequence.py
def show(self, **assignments):
    """
    Interactive visualization of the Sequence

    Args:
        **assignments: assigning the instance value (literal) to the
            existing variables in the Sequence

    """
    display_ir(self, assignments)

Square

Square(L1, L2=None, *, lattice_spacing=1.0)

Bases: BoundedBravais

Square lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1,0)
    • a2 = (0,1)
  • unit cell (1 atom(s))
    • loc (0,0)

Parameters:

Name Type Description Default
L1 int

number of sites in linear direction. n_atoms = L1 * L1.

required
L2 Optional[int]

number of sites in direction a2. n_atoms = L1 * L2, default is L1

None
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L1: int, L2: Optional[int] = None, *, lattice_spacing: ScalarType = 1.0
):
    if L2 is None:
        L2 = L1
    self.L1 = L1
    self.L2 = L2
    self.lattice_spacing = cast(lattice_spacing)
    super().__init__()

Triangular

Triangular(L1, L2=None, *, lattice_spacing=1.0)

Bases: BoundedBravais

Triangular lattice.

  • 2D lattice
  • primitive (cell) vector(s)
    • a1 = (1, 0)
    • a2 = (½, sqrt(3)/2)
  • unit cell (1 atom(s))
    • loc (0, 0)

Parameters:

Name Type Description Default
L int

number of sites in linear direction. n_atoms = L * L.

required
L2 Optional[int]

number of sites along a2 direction, n_atoms = L1 * L2, default is L1.

None
lattice_spacing (Scalar, Real)

lattice spacing. Defaults to 1.0.

1.0
  • Possible Next: continue with . to see possible next step in auto-prompt supported setting (IPython, IDE ...)
Source code in src/bloqade/ir/location/bravais.py
@beartype
def __init__(
    self, L1: int, L2: Optional[int] = None, *, lattice_spacing: ScalarType = 1.0
):
    if L2 is None:
        L2 = L1
    self.L1 = L1
    self.L2 = L2
    self.lattice_spacing = cast(lattice_spacing)

    super().__init__()

Variable

Bases: Real

Variable, which stores a variable name.

Parameters:

Name Type Description Default
name str

variable instance.

required

Waveform

Bases: HashTrait, CanonicalizeTrait

Waveform node in the IR.

<waveform> ::= <instruction>
    | <smooth>
    | <slice>
    | <append>
    | <negative>
    | <scale>
    | <add>
    | <record>
    | <sample>

figure

figure(**assignments)

get figure of the plotting the waveform.

Returns:

Name Type Description
figure

a bokeh figure

Source code in src/bloqade/ir/control/waveform.py
def figure(self, **assignments):
    """get figure of the plotting the waveform.

    Returns:
        figure: a bokeh figure
    """
    return get_ir_figure(self, **assignments)

cast

cast(py)
  1. cast Real number (or list/tuple of Real numbers) to Scalar Literal.

  2. cast str (or list/tuple of Real numbers) to Scalar Variable.

Parameters:

Name Type Description Default
py Union[str, Real, Tuple[Real], List[Real]]

python object to cast

required

Returns:

Type Description
Scalar

Scalar

Source code in src/bloqade/ir/scalar.py
def cast(py) -> "Scalar":
    """
    1. cast Real number (or list/tuple of Real numbers)
    to [`Scalar Literal`][bloqade.ir.scalar.Literal].

    2. cast str (or list/tuple of Real numbers)
    to [`Scalar Variable`][bloqade.ir.scalar.Variable].

    Args:
        py (Union[str,Real,Tuple[Real],List[Real]]): python object to cast

    Returns:
        Scalar
    """
    ret = trycast(py)
    if ret is None:
        raise TypeError(f"Cannot cast {type(py)} to Scalar Literal")

    return ret

var

var(py)

cast string (or list/tuple of strings) to Variable.

Parameters:

Name Type Description Default
py Union[str, List[str]]

a string or list/tuple of strings

required

Returns:

Type Description
Variable

Union[Variable]

Source code in src/bloqade/ir/scalar.py
def var(py: str) -> "Variable":
    """cast string (or list/tuple of strings)
    to [`Variable`][bloqade.ir.scalar.Variable].

    Args:
        py (Union[str, List[str]]): a string or list/tuple of strings

    Returns:
       Union[Variable]
    """
    ret = tryvar(py)
    if ret is None:
        raise TypeError(f"Cannot cast {type(py)} to Variable")

    return ret