Skip to content
Draft
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
617 changes: 617 additions & 0 deletions examples/gate_based.ipynb

Large diffs are not rendered by default.

284 changes: 284 additions & 0 deletions examples/qutip-dqpt.ipynb

Large diffs are not rendered by default.

190 changes: 190 additions & 0 deletions examples/qutip_simulation.ipynb

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions qse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"magnetic",
"Qbit",
"Qbits",
"Operator",
"operators_to_qutip",
"Signal",
"utils",
"visualise",
Expand All @@ -21,6 +23,7 @@

__version__ = importlib.metadata.version("qse")

from qse.operator import Operator, operators_to_qutip
from qse.qbit import Qbit
from qse.qbits import Qbits
from qse.signal import Signal
Expand Down
10 changes: 1 addition & 9 deletions qse/lattices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,4 @@
"triangular",
]

from .lattices import (
chain,
hexagonal,
kagome,
ring,
square,
torus,
triangular,
)
from .lattices import chain, hexagonal, kagome, ring, square, torus, triangular
106 changes: 106 additions & 0 deletions qse/operator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import qutip as qp


class Operator:
"""
Represents an operator in a quantum system.

Parameters
----------
operator: str | list[str]
The type of qubit operator.
Currently only "X", "Y", "Z" are supported. "N" the number operator is
supported for QuTiP. If a list, must be equal in length to the size of
the qubits tuple.
qubits: int | list[int]
A single integer or list of integers representing the qubits
the operator acts on.
coef: float
The coefficient associated with the term.
nqubits: int
The total number of qubits in the system.
"""

def __init__(self, operator, qubits, coef, nqubits):
if isinstance(qubits, int):
qubits = [qubits]
if isinstance(operator, str):
operator = [operator] * len(qubits)

assert len(qubits) == len(operator)

self.operator = operator
self.qubits = qubits
self.coef = coef
self.nqubits = nqubits

def to_str(self):
"""
Generates a string representation of the operator.

The string is constructed as a tensor product of identity (I) and operator,
where the operator is placed at the positions specified by `qubits`.

Returns
-------
str
A string of length `nqubits`, with "I" at all positions except for the
qubits in `qubits`, which are replaced by the operator.
"""
op = ["I"] * self.nqubits
for qi, op_str in zip(self.qubits, self.operator):
op[qi] = op_str
return "".join(op)

def to_qutip(self):
"""
Generates a QuTiP representation of the operator.

Returns
-------
qutip.Qobj
The QuTiP operator.
"""
op = [qp.qeye(2)] * self.nqubits
for qi, op_str in zip(self.qubits, self.operator):
op[qi] = _qutip_converter(op_str)
return self.coef * qp.tensor(op)

def __repr__(self):
return f"{self.coef:.2f} " + " ".join(
[f"{op}{q}" for op, q in zip(self.operator, self.qubits)]
)


def _qutip_converter(op):
if op == "X":
return qp.sigmax()

if op == "Y":
return qp.sigmay()

if op == "Z":
return qp.sigmaz()

if op == "N":
return 0.5 * (1 - qp.sigmaz())


def operators_to_qutip(operator_list):
"""
Sum together a list of Operators into a single QuTiP Qobj.

Parameters
----------
operator_list : list[Operator]
A list of Operators.

Returns
-------
qutip.Qobj
The QuTiP operator.
"""
operator = 0
for op in operator_list:
operator += op.coef * op.to_qutip()
return operator
45 changes: 42 additions & 3 deletions qse/qbits.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

import numpy as np
from ase.cell import Cell
from ase.geometry import (
find_mic,
)
from ase.geometry import find_mic

from qse.operator import Operator
from qse.qbit import Qbit
from qse.visualise import draw as _draw

Expand Down Expand Up @@ -1283,6 +1282,46 @@ def to_pulser(self):

return Register.from_coordinates(self.positions[:, :2], prefix="q")

def compute_interaction_hamiltonian(
self,
distance_func,
interaction,
tol=1e-8,
):
"""
Compute the interaction Hamiltonian the system of qubits.

This function constructs a list of interaction terms between pairs of qubits,
based on their distances and a specified interaction type. Only terms with
coefficients above a given tolerance are included.

Parameters
----------
distance_func : callable
A function that takes a distance (float) and returns the interaction
coefficient (float).
interaction : str
The type of interaction (e.g., "X", "Y", "Z") for the Hamiltonian terms.
tol : float, optional
Tolerance threshold for including interaction terms. Terms with absolute
coefficients less than `tol` are discarded. Default is 1e-8.

Returns
-------
list of InteractionTerm
A list of `InteractionTerm` objects, each representing a non-negligible
interaction between a pair of qubits.
"""
ops = []

for i in range(self.nqbits - 1):
for j in range(i + 1, self.nqbits):
coef = distance_func(self.get_distance(i, j))
if np.abs(coef) > tol:
ops.append(Operator(interaction, (i, j), coef, self.nqbits))

return ops


def _norm_vector(v):
normv = np.linalg.norm(v)
Expand Down
9 changes: 1 addition & 8 deletions tests/qse/lattices_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@
import pytest

import qse
from qse.lattices import (
chain,
hexagonal,
kagome,
ring,
square,
triangular,
)
from qse.lattices import chain, hexagonal, kagome, ring, square, triangular

_lattice_spacings = [0.5, 3.1]
_repeats = [2, 3]
Expand Down