State preparation
State Preparation Routines
Section titled “State Preparation Routines”
density_mat(state)
Section titled “
density_mat(state)
”Computes the density matrix from a pure state vector.
| PARAMETER | DESCRIPTION |
|---|---|
state
|
The pure state vector :math:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
The density matrix :math:
TYPE:
|
Source code in qadence/states.py
333334335336337338339340341342343344345def density_mat(state: Tensor) -> DensityMatrix: """ Computes the density matrix from a pure state vector.
Arguments: state: The pure state vector :math:`|\\psi\\rangle`.
Returns: Tensor: The density matrix :math:`\\rho = |\psi \\rangle \\langle\\psi|`. """ if isinstance(state, DensityMatrix): return state return DensityMatrix(torch.einsum("bi,bj->bij", (state, state.conj())))
fidelity(rho, sigma)
Section titled “
fidelity(rho, sigma)
”Calculate the fidelity between two quantum states represented by density matrices.
The fidelity is defined as F(ρ,σ) = Tr[√(√ρ σ √ρ)], or equivalently, F(ρ,σ) = ||√ρ·√σ||₁ where ||·||₁ is the trace norm.
| PARAMETER | DESCRIPTION |
|---|---|
rho
|
First density matrix of shape [batch_size, dim, dim]
TYPE:
|
sigma
|
Second density matrix of shape [batch_size, dim, dim]
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
Fidelity between each pair of density matrices in the batch, shape [batch_size] |
Source code in qadence/states.py
673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720def fidelity(rho: DensityMatrix, sigma: DensityMatrix) -> Tensor: """Calculate the fidelity between two quantum states represented by density matrices.
The fidelity is defined as F(ρ,σ) = Tr[√(√ρ σ √ρ)], or equivalently, F(ρ,σ) = ||√ρ·√σ||₁ where ||·||₁ is the trace norm.
Args: rho: First density matrix of shape [batch_size, dim, dim] sigma: Second density matrix of shape [batch_size, dim, dim]
Returns: Fidelity between each pair of density matrices in the batch, shape [batch_size] """
# Compute square root of rho rho_eigvals, rho_eigvecs = torch.linalg.eigh(rho)
# Ensure non-negative eigenvalues rho_eigvals = torch.clamp(rho_eigvals, min=0)
# Compute square root using eigendecomposition sqrt_eigvals = torch.sqrt(rho_eigvals)
# Compute √ρ for each batch element sqrt_rho = torch.zeros_like(rho) for i in range(rho.shape[0]): sqrt_rho[i] = torch.mm( rho_eigvecs[i], torch.mm( torch.diag(sqrt_eigvals[i]).to(dtype=rho_eigvecs.dtype), rho_eigvecs[i].t().conj() ), )
# Compute √ρ σ √ρ for each batch element inner_product = torch.zeros_like(rho) for i in range(rho.shape[0]): inner_product[i] = torch.mm(sqrt_rho[i], torch.mm(sigma[i], sqrt_rho[i]))
# Compute eigenvalues of inner product inner_eigvals = torch.linalg.eigvalsh(inner_product)
# Ensure non-negative eigenvalues inner_eigvals = torch.clamp(inner_eigvals, min=0)
# Compute the fidelity as the sum of the square roots of eigenvalues fidelity_values = torch.sum(torch.sqrt(inner_eigvals), dim=1)
return fidelity_values
ghz_block(n_qubits)
Section titled “
ghz_block(n_qubits)
”Generates the abstract ghz state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ChainBlock
|
A ChainBlock representing the GHZ state. |
Examples:
from qadence.states import ghz_block
block = ghz_block(n_qubits=2)print(block)ChainBlock(0,1)├── H(0)└── ChainBlock(0,1) └── CNOT(0, 1)Source code in qadence/states.py
454455456457458459460461462463464465466467468469470471472473def ghz_block(n_qubits: int) -> ChainBlock: """ Generates the abstract ghz state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits.
Returns: A ChainBlock representing the GHZ state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import ghz_block
block = ghz_block(n_qubits=2) print(block) ``` """ cnots = chain(CNOT(i - 1, i) for i in range(1, n_qubits)) return chain(H(0), cnots)
ghz_state(n_qubits, batch_size=1)
Section titled “
ghz_state(n_qubits, batch_size=1)
”Creates a GHZ state.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
batch_size
|
How many bitstrings to use.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import ghz_state
print(ghz_state(n_qubits=2, batch_size=2))tensor([[0.7071+0.j, 0.0000+0.j, 0.0000+0.j, 0.7071+0.j], [0.7071+0.j, 0.0000+0.j, 0.0000+0.j, 0.7071+0.j]])Source code in qadence/states.py
259260261262263264265266267268269270271272273274275276277278def ghz_state(n_qubits: int, batch_size: int = 1) -> Tensor: """ Creates a GHZ state.
Arguments: n_qubits (int): The number of qubits. batch_size (int): How many bitstrings to use.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import ghz_state
print(ghz_state(n_qubits=2, batch_size=2)) ``` """ norm = 1 / torch.sqrt(torch.tensor(2)) return norm * (zero_state(n_qubits, batch_size) + one_state(n_qubits, batch_size))
is_normalized(wf, atol=NORMALIZATION_ATOL)
Section titled “
is_normalized(wf, atol=NORMALIZATION_ATOL)
”Checks if a wave function is normalized.
| PARAMETER | DESCRIPTION |
|---|---|
wf
|
The wave function as a torch tensor.
TYPE:
|
atol
|
The tolerance.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
A bool. |
Examples:
from qadence.states import uniform_state, is_normalized
print(is_normalized(uniform_state(2)))TrueSource code in qadence/states.py
522523524525526527528529530531532533534535536537538539540541542543544def is_normalized(wf: Tensor, atol: float = NORMALIZATION_ATOL) -> bool: """ Checks if a wave function is normalized.
Arguments: wf (torch.Tensor): The wave function as a torch tensor. atol (float) : The tolerance.
Returns: A bool.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import uniform_state, is_normalized
print(is_normalized(uniform_state(2))) ``` """ if wf.dim() == 1: wf = wf.unsqueeze(0) sum_probs: Tensor = (wf.abs() ** 2).sum(dim=1) ones = torch.ones_like(sum_probs) return torch.allclose(sum_probs, ones, rtol=0.0, atol=atol) # type: ignore[no-any-return]
normalize(wf)
Section titled “
normalize(wf)
”Normalizes a wavefunction or batch of wave functions.
| PARAMETER | DESCRIPTION |
|---|---|
wf
|
Normalized wavefunctions.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import uniform_state, normalize
print(normalize(uniform_state(2, 2)))tensor([[0.5000+0.j, 0.5000+0.j, 0.5000+0.j, 0.5000+0.j], [0.5000+0.j, 0.5000+0.j, 0.5000+0.j, 0.5000+0.j]])Source code in qadence/states.py
499500501502503504505506507508509510511512513514515516517518519def normalize(wf: Tensor) -> Tensor: """ Normalizes a wavefunction or batch of wave functions.
Arguments: wf (torch.Tensor): Normalized wavefunctions.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import uniform_state, normalize
print(normalize(uniform_state(2, 2))) ``` """ if wf.dim() == 1: return wf / torch.sqrt((wf.abs() ** 2).sum()) else: return wf / torch.sqrt((wf.abs() ** 2).sum(1)).unsqueeze(1)
one_block(n_qubits)
Section titled “
one_block(n_qubits)
”Generates the abstract one state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
KronBlock
|
A KronBlock representing the one state. |
Examples:
from qadence.states import one_block
block = one_block(n_qubits=2)print(block)KronBlock(0,1)├── X(0)└── X(1)Source code in qadence/states.py
372373374375376377378379380381382383384385386387388389390def one_block(n_qubits: int) -> KronBlock: """ Generates the abstract one state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits.
Returns: A KronBlock representing the one state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import one_block
block = one_block(n_qubits=2) print(block) ``` """ return _from_op(X, n_qubits=n_qubits)
one_state(n_qubits, batch_size=1)
Section titled “
one_state(n_qubits, batch_size=1)
”Generates the one state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
batch_size
|
The batch size.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import one_state
state = one_state(n_qubits=2)print(state)tensor([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]])Source code in qadence/states.py
173174175176177178179180181182183184185186187188189190191192193def one_state(n_qubits: int, batch_size: int = 1) -> Tensor: """ Generates the one state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits. batch_size (int): The batch size.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import one_state
state = one_state(n_qubits=2) print(state) ``` """ bitstring = "1" * n_qubits return _state_from_bitstring(bitstring, batch_size)
overlap(s0, s1)
Section titled “
overlap(s0, s1)
”Computes the exact overlap between two statevectors.
| PARAMETER | DESCRIPTION |
|---|---|
s0
|
A statevector or batch of statevectors.
TYPE:
|
s1
|
A statevector or batch of statevectors.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor with the result. |
Examples:
from qadence.states import rand_bitstring
print(rand_bitstring(N=8))11110110Source code in qadence/states.py
567568569570571572573574575576577578579580581582583584585586587def overlap(s0: torch.Tensor, s1: torch.Tensor) -> torch.Tensor: """ Computes the exact overlap between two statevectors.
Arguments: s0 (torch.Tensor): A statevector or batch of statevectors. s1 (torch.Tensor): A statevector or batch of statevectors.
Returns: A torch.Tensor with the result.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import rand_bitstring
print(rand_bitstring(N=8)) ``` """ from qadence.overlap import overlap_exact
return overlap_exact(s0, s1)
partial_trace(rho, keep_indices)
Section titled “
partial_trace(rho, keep_indices)
”Compute the partial trace of a density matrix for a system of several qubits with batch size.
This function also permutes qubits according to the order specified in keep_indices.
| PARAMETER | DESCRIPTION |
|---|---|
rho
|
Density matrix of shape [batch_size, 2n_qubits, 2n_qubits].
TYPE:
|
keep_indices
|
Index of the qubit subsystems to keep.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DensityMatrix
|
Reduced density matrix after the partial trace,
TYPE:
|
DensityMatrix
|
of shape [batch_size, 2n_keep, 2n_keep]. |
Source code in qadence/states.py
601602603604605606607608609610611612613614615616617def partial_trace(rho: DensityMatrix, keep_indices: list[int]) -> DensityMatrix: """ Compute the partial trace of a density matrix for a system of several qubits with batch size.
This function also permutes qubits according to the order specified in keep_indices.
Args: rho (DensityMatrix) : Density matrix of shape [batch_size, 2**n_qubits, 2**n_qubits]. keep_indices (list[int]): Index of the qubit subsystems to keep.
Returns: DensityMatrix: Reduced density matrix after the partial trace, of shape [batch_size, 2**n_keep, 2**n_keep]. """ from pyqtorch.utils import dm_partial_trace
return dm_partial_trace(rho.permute((1, 2, 0)), keep_indices).permute((2, 0, 1))
pmf(wf)
Section titled “
pmf(wf)
”Converts a wave function into a torch Distribution.
| PARAMETER | DESCRIPTION |
|---|---|
wf
|
The wave function as a torch tensor.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Distribution
|
A torch.distributions.Distribution. |
Examples:
from qadence.states import uniform_state, pmf
print(pmf(uniform_state(2)).probs)tensor([[0.2500, 0.2500, 0.2500, 0.2500]])Source code in qadence/states.py
479480481482483484485486487488489490491492493494495496def pmf(wf: Tensor) -> Distribution: """ Converts a wave function into a torch Distribution.
Arguments: wf (torch.Tensor): The wave function as a torch tensor.
Returns: A torch.distributions.Distribution.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import uniform_state, pmf
print(pmf(uniform_state(2)).probs) ``` """ return Categorical(torch.abs(torch.pow(wf, 2)))
product_block(bitstring)
Section titled “
product_block(bitstring)
”Creates an abstract product state from a bitstring.
| PARAMETER | DESCRIPTION |
|---|---|
bitstring
|
A bitstring.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
KronBlock
|
A KronBlock representing the product state. |
Examples:
from qadence.states import product_block
print(product_block("1100"))KronBlock(0,1,2,3)├── X(0)├── X(1)├── I(2)└── I(3)Source code in qadence/states.py
414415416417418419420421422423424425426427428429430431def product_block(bitstring: str) -> KronBlock: """ Creates an abstract product state from a bitstring.
Arguments: bitstring (str): A bitstring.
Returns: A KronBlock representing the product state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import product_block
print(product_block("1100")) ``` """ return _block_from_bitstring(bitstring)
product_state(bitstring, batch_size=1, endianness=Endianness.BIG, backend=BackendName.PYQTORCH)
Section titled “
product_state(bitstring, batch_size=1, endianness=Endianness.BIG, backend=BackendName.PYQTORCH)
”Creates a product state from a bitstring.
| PARAMETER | DESCRIPTION |
|---|---|
bitstring
|
A bitstring.
TYPE:
|
batch_size
|
Batch size.
TYPE:
|
backend
|
The backend to use. Default is "pyqtorch".
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ArrayLike
|
A torch.Tensor. |
Examples:
from qadence.states import product_state
print(product_state("1100", backend="pyqtorch"))print(product_state("1100", backend="horqrux"))tensor([[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]Source code in qadence/states.py
196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227@singledispatchdef product_state( bitstring: str, batch_size: int = 1, endianness: Endianness = Endianness.BIG, backend: BackendName = BackendName.PYQTORCH,) -> ArrayLike: """ Creates a product state from a bitstring.
Arguments: bitstring (str): A bitstring. batch_size (int) : Batch size. backend (BackendName): The backend to use. Default is "pyqtorch".
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import product_state
print(product_state("1100", backend="pyqtorch")) print(product_state("1100", backend="horqrux")) ``` """ if batch_size: logger.debug( "The input `batch_size` is going to be deprecated. " "For now, default batch_size is set to 1." ) return run(product_block(bitstring), backend=backend, endianness=endianness)
purity(rho, order=2)
Section titled “
purity(rho, order=2)
”Compute the n-th purity of a density matrix.
| PARAMETER | DESCRIPTION |
|---|---|
rho
|
Density matrix.
TYPE:
|
order
|
Exponent n.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
Tr[rho ** n]
TYPE:
|
Source code in qadence/states.py
656657658659660661662663664665666667668669670def purity(rho: DensityMatrix, order: int = 2) -> Tensor: """Compute the n-th purity of a density matrix.
Args: rho (DensityMatrix): Density matrix. order (int, optional): Exponent n.
Returns: Tensor: Tr[rho ** n] """ # Compute eigenvalues eigenvalues = torch.linalg.eigvalsh(rho)
# Compute the sum of eigenvalues raised to power n return torch.sum(eigenvalues**order, dim=1)
rand_bitstring(N)
Section titled “
rand_bitstring(N)
”Creates a random bistring.
| PARAMETER | DESCRIPTION |
|---|---|
N
|
The length of the bitstring.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
A string. |
Examples:
from qadence.states import rand_bitstring
print(rand_bitstring(N=8))00111010Source code in qadence/states.py
547548549550551552553554555556557558559560561562563564def rand_bitstring(N: int) -> str: """ Creates a random bistring.
Arguments: N (int): The length of the bitstring.
Returns: A string.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import rand_bitstring
print(rand_bitstring(N=8)) ``` """ return "".join(str(random.randint(0, 1)) for _ in range(N))
rand_product_block(n_qubits)
Section titled “
rand_product_block(n_qubits)
”Creates a block representing a random abstract product state.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
KronBlock
|
A KronBlock representing the product state. |
Examples:
from qadence.states import rand_product_block
print(rand_product_block(n_qubits=2))KronBlock(0,1)├── I(0)└── I(1)Source code in qadence/states.py
434435436437438439440441442443444445446447448449450451def rand_product_block(n_qubits: int) -> KronBlock: """ Creates a block representing a random abstract product state.
Arguments: n_qubits (int): The number of qubits.
Returns: A KronBlock representing the product state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import rand_product_block
print(rand_product_block(n_qubits=2)) ``` """ return product_block(rand_bitstring(n_qubits))
rand_product_state(n_qubits, batch_size=1)
Section titled “
rand_product_state(n_qubits, batch_size=1)
”Creates a random product state.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
batch_size
|
How many bitstrings to use.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import rand_product_state
print(rand_product_state(n_qubits=2, batch_size=2))tensor([[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j], [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]])Source code in qadence/states.py
235236237238239240241242243244245246247248249250251252253254255256def rand_product_state(n_qubits: int, batch_size: int = 1) -> Tensor: """ Creates a random product state.
Arguments: n_qubits (int): The number of qubits. batch_size (int): How many bitstrings to use.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import rand_product_state
print(rand_product_state(n_qubits=2, batch_size=2)) ``` """ wf_batch = torch.zeros(batch_size, 2**n_qubits, dtype=DTYPE) rand_pos = torch.randint(0, 2**n_qubits, (batch_size,)) wf_batch[torch.arange(batch_size), rand_pos] = torch.tensor(1.0 + 0j, dtype=DTYPE) return wf_batch
random_state(n_qubits, batch_size=1, backend=BackendName.PYQTORCH, type=StateGeneratorType.HAAR_MEASURE_FAST)
Section titled “
random_state(n_qubits, batch_size=1, backend=BackendName.PYQTORCH, type=StateGeneratorType.HAAR_MEASURE_FAST)
”Generates a random state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
backend
|
The backend to use.
TYPE:
|
batch_size
|
The batch size.
TYPE:
|
type
|
StateGeneratorType.
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import random_state, StateGeneratorTypefrom qadence.states import random_state, is_normalized, pmffrom qadence.types import BackendNamefrom torch.distributions import Distribution
### We have the following options:print([g.value for g in StateGeneratorType])
n_qubits = 2# The default is StateGeneratorType.HAAR_MEASURE_FASTstate = random_state(n_qubits=n_qubits)print(state)
### Lets initialize a state using random rotations, i.e., StateGeneratorType.RANDOM_ROTATIONS.random = random_state(n_qubits=n_qubits, type=StateGeneratorType.RANDOM_ROTATIONS)print(random)['RandomRotations', 'HaarMeasureFast', 'HaarMeasureSlow']tensor([[-0.2882+0.2396j, 0.3849+0.1940j, -0.1423-0.0967j, 0.3746-0.7097j]])tensor([[0.7091+0.0000j, 0.0000+0.6975j, 0.0000-0.0739j, 0.0727+0.0000j]])Source code in qadence/states.py
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327def random_state( n_qubits: int, batch_size: int = 1, backend: str = BackendName.PYQTORCH, type: StateGeneratorType = StateGeneratorType.HAAR_MEASURE_FAST,) -> Tensor: """ Generates a random state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits. backend (str): The backend to use. batch_size (int): The batch size. type : StateGeneratorType.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import random_state, StateGeneratorType from qadence.states import random_state, is_normalized, pmf from qadence.types import BackendName from torch.distributions import Distribution
### We have the following options: print([g.value for g in StateGeneratorType])
n_qubits = 2 # The default is StateGeneratorType.HAAR_MEASURE_FAST state = random_state(n_qubits=n_qubits) print(state)
### Lets initialize a state using random rotations, i.e., StateGeneratorType.RANDOM_ROTATIONS. random = random_state(n_qubits=n_qubits, type=StateGeneratorType.RANDOM_ROTATIONS) print(random) ``` """
if type == StateGeneratorType.HAAR_MEASURE_FAST: state = concat(tuple(_rand_haar_fast(n_qubits) for _ in range(batch_size)), dim=0) elif type == StateGeneratorType.HAAR_MEASURE_SLOW: state = concat(tuple(_rand_haar_slow(n_qubits) for _ in range(batch_size)), dim=0) elif type == StateGeneratorType.RANDOM_ROTATIONS: state = run(_abstract_random_state(n_qubits, batch_size)) # type: ignore assert all(list(map(is_normalized, state))) return state
uniform_block(n_qubits)
Section titled “
uniform_block(n_qubits)
”Generates the abstract uniform state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
KronBlock
|
A KronBlock representing the uniform state. |
Examples:
from qadence.states import uniform_block
block = uniform_block(n_qubits=2)print(block)KronBlock(0,1)├── H(0)└── H(1)Source code in qadence/states.py
351352353354355356357358359360361362363364365366367368369def uniform_block(n_qubits: int) -> KronBlock: """ Generates the abstract uniform state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits.
Returns: A KronBlock representing the uniform state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import uniform_block
block = uniform_block(n_qubits=2) print(block) ``` """ return _from_op(H, n_qubits=n_qubits)
uniform_state(n_qubits, batch_size=1)
Section titled “
uniform_state(n_qubits, batch_size=1)
”Generates the uniform state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
batch_size
|
The batch size.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import uniform_state
state = uniform_state(n_qubits=2)print(state)tensor([[0.5000+0.j, 0.5000+0.j, 0.5000+0.j, 0.5000+0.j]])Source code in qadence/states.py
127128129130131132133134135136137138139140141142143144145146147def uniform_state(n_qubits: int, batch_size: int = 1) -> Tensor: """ Generates the uniform state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits. batch_size (int): The batch size.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import uniform_state
state = uniform_state(n_qubits=2) print(state) ``` """ norm = 1 / torch.sqrt(torch.tensor(2**n_qubits)) return norm * torch.ones(batch_size, 2**n_qubits, dtype=DTYPE)
von_neumann_entropy(rho, eps=1e-12)
Section titled “
von_neumann_entropy(rho, eps=1e-12)
”Calculate the von Neumann entropy of a quantum density matrix.
The von Neumann entropy is defined as S(ρ) = -Tr(ρ log₂ ρ) = -∑ᵢ λᵢ log₂ λᵢ, where λᵢ are the eigenvalues of ρ.
| PARAMETER | DESCRIPTION |
|---|---|
rho
|
Density matrix of shape [batch_size, dim, dim]
TYPE:
|
eps
|
Small value to avoid log(0) for zero eigenvalues
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
Von Neumann entropy for each density matrix in the batch, shape [batch_size] |
Source code in qadence/states.py
620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653def von_neumann_entropy(rho: DensityMatrix, eps: float = 1e-12) -> torch.Tensor: """Calculate the von Neumann entropy of a quantum density matrix.
The von Neumann entropy is defined as S(ρ) = -Tr(ρ log₂ ρ) = -∑ᵢ λᵢ log₂ λᵢ, where λᵢ are the eigenvalues of ρ.
Args: rho: Density matrix of shape [batch_size, dim, dim] eps: Small value to avoid log(0) for zero eigenvalues
Returns: Von Neumann entropy for each density matrix in the batch, shape [batch_size] """
# Compute eigenvalues for each density matrix in the batch # For a Hermitian density matrix, eigenvalues should be real and non-negative eigenvalues = torch.linalg.eigvalsh(rho)
# Normalize eigenvalues to ensure they sum to 1 (trace preservation) # This step might be redundant but helps with numerical stability eigenvalues = eigenvalues / torch.sum(eigenvalues, dim=1, keepdim=True)
# Filter out very small eigenvalues to avoid numerical issues valid_eigenvalues = eigenvalues.clone() valid_eigenvalues[valid_eigenvalues < eps] = eps
# Compute the entropy: -∑ᵢ λᵢ log₂ λᵢ # Using natural logarithm and converting to base 2 log_base_conversion = torch.log(torch.tensor(2.0, device=rho.device)) entropy = -torch.sum( valid_eigenvalues * torch.log(valid_eigenvalues) / log_base_conversion, dim=1 )
return entropy
zero_block(n_qubits)
Section titled “
zero_block(n_qubits)
”Generates the abstract zero state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
KronBlock
|
A KronBlock representing the zero state. |
Examples:
from qadence.states import zero_block
block = zero_block(n_qubits=2)print(block)KronBlock(0,1)├── I(0)└── I(1)Source code in qadence/states.py
393394395396397398399400401402403404405406407408409410411def zero_block(n_qubits: int) -> KronBlock: """ Generates the abstract zero state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits.
Returns: A KronBlock representing the zero state.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import zero_block
block = zero_block(n_qubits=2) print(block) ``` """ return _from_op(I, n_qubits=n_qubits)
zero_state(n_qubits, batch_size=1)
Section titled “
zero_state(n_qubits, batch_size=1)
”Generates the zero state for a specified number of qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
The number of qubits for which the zero state is to be generated.
TYPE:
|
batch_size
|
The batch size for the zero state.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
A torch.Tensor. |
Examples:
from qadence.states import zero_state
state = zero_state(n_qubits=2)print(state)tensor([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])Source code in qadence/states.py
150151152153154155156157158159160161162163164165166167168169170def zero_state(n_qubits: int, batch_size: int = 1) -> Tensor: """ Generates the zero state for a specified number of qubits.
Arguments: n_qubits (int): The number of qubits for which the zero state is to be generated. batch_size (int): The batch size for the zero state.
Returns: A torch.Tensor.
Examples: ```python exec="on" source="material-block" result="json" from qadence.states import zero_state
state = zero_state(n_qubits=2) print(state) ``` """ bitstring = "0" * n_qubits return _state_from_bitstring(bitstring, batch_size)