qmath#

Common functions

Classes

QR(*args, **kwargs)

Customized backward of QR for better numerical stability.

SVD(*args, **kwargs)

Customized backward of SVD for better numerical stability.

Functions

amplitude_encoding(data, nqubit)

Encode data into quantum states using amplitude encoding.

block_sample(probs[, shots, block_size])

Sample from a probability distribution using block sampling.

decimal_to_list(n, base[, ndigit])

Convert from decimal integer to list of digits.

evolve_den_mat(state, matrix, nqudit, wires)

Perform the evolution of density matrices.

evolve_state(state, matrix, nqudit, wires[, ...])

Perform the evolution of quantum states.

expectation(state, observable[, den_mat, chi])

A function that calculates the expectation value of an observable on a quantum state.

generalized_distance(state1, state2)

Calculate the generalized distance.

get_prob_mps(mps_lst, wire)

Calculate the probability distribution (|0⟩ and |1⟩ probabilities) for a specific wire in an MPS.

inner_product_mps(tensors0, tensors1[, form])

Computes the inner product of two matrix product states.

int_to_bitstring(x, n[, debug])

Convert from integer to bit string.

inverse_permutation(permute_shape)

Calculate the inversed permutation.

is_density_matrix(rho)

Check if a tensor is a valid density matrix.

is_positive_definite(mat)

Check if the matrix is positive definite.

is_power(n, base)

Check if an integer is a power of the given base.

is_power_of_two(n)

Check if an integer is a power of two.

is_unitary(matrix[, rtol, atol])

Check if a tensor is a unitary matrix.

linear_map_mw(state_tsr, j, b)

Calculate the linear mapping for Meyer-Wallach measure.

list_to_decimal(digits, base)

Convert from list of digits to decimal integer.

measure(state[, shots, with_prob, wires, ...])

A function that performs a measurement on a quantum state and returns the results.

meyer_wallach_measure(state_tsr)

Calculate Meyer-Wallach entanglement measure.

meyer_wallach_measure_brennen(state_tsr)

Calculate Meyer-Wallach entanglement measure, proposed by Brennen.

multi_kron(lst)

Calculate the Kronecker/tensor/outer product for a list of tensors.

partial_trace(rho, nqudit, trace_lst[, qudit])

Calculate the partial trace for a batch of density matrices.

safe_inverse(x[, epsilon])

Safe inversion.

sample2expval(sample)

Get the expectation value according to the measurement results.

sample_sc_mcmc(prob_func, proposal_sampler)

Get the samples of the probability distribution function via SC-MCMC method.

slice_state_vector(state, nqubit, wires, bits)

Get the sliced state vectors according to wires and bits.

split_tensor(tensor[, center_left])

Split a tensor by QR.

state_to_tensors(state, nsite[, qudit])

Convert a quantum state to a list of tensors.

torchqr_grad(a, q, r, dq, dr)

Get the gradient for QR.

class QR(*args, **kwargs)[source]#

Bases: Function

Customized backward of QR for better numerical stability.

static backward(ctx, dq, dr)[source]#
static forward(a)[source]#
generate_vmap_rule = True#
static setup_context(ctx, inputs, output)[source]#
class SVD(*args, **kwargs)[source]#

Bases: Function

Customized backward of SVD for better numerical stability.

See https://readpaper.com/paper/2971614414

static backward(ctx, du, ds, dvh)[source]#
static forward(a)[source]#
generate_vmap_rule = True#
static setup_context(ctx, inputs, output)[source]#
amplitude_encoding(data: Any, nqubit: int) Tensor[source]#

Encode data into quantum states using amplitude encoding.

This function takes a batch of data and encodes each sample into a quantum state using amplitude encoding. The quantum state is represented by a complex-valued tensor of shape \((\text{batch}, 2^{\text{nqubit}})\). The data is normalized to have unit norm along the last dimension before encoding. If the data size is smaller than \(2^{\text{nqubit}}\), the remaining amplitudes are set to zero. If the data size is larger than \(2^{\text{nqubit}}\), only the first \(2^{\text{nqubit}}\) elements are used.

Parameters:
  • data (Any) – The input data to be encoded. It should have shape \((\text{batch}, ...)\) where \(...\) can be any dimensions. If it is not a torch.Tensor object, it will be converted to one.

  • nqubit (int) – The number of qubits to use for encoding.

Returns:

The encoded quantum states as complex-valued tensors of shape \((\text{batch}, 2^{\text{nqubit}}, 1)\).

Return type:

Tensor

Examples

>>> data = [[0.5, 0.5], [0.7, 0.3]]
>>> amplitude_encoding(data, nqubit=2)
tensor([[[0.7071+0.j],
        [0.7071+0.j],
        [0.0000+0.j],
        [0.0000+0.j]],
        [[0.9487+0.j],
        [0.3162+0.j],
        [0.0000+0.j],
        [0.0000+0.j]]])
block_sample(probs: Tensor, shots: int = 1024, block_size: int = 16777216) list[source]#

Sample from a probability distribution using block sampling.

Parameters:
  • probs (Tensor) – The probability distribution to sample from.

  • shots (int) – The number of samples to draw. Default: 1024

  • block_size (int) – The block size for sampling. Default: 2**24

decimal_to_list(n: int, base: int, ndigit: int | None = None) list[int][source]#

Convert from decimal integer to list of digits.

evolve_den_mat(state: Tensor, matrix: Tensor, nqudit: int, wires: list[int], qudit: int = 2) Tensor[source]#

Perform the evolution of density matrices.

Parameters:
  • state (Tensor) – The batched state tensor.

  • matrix (Tensor) – The evolution matrix.

  • nqudit (int) – The number of the qudits.

  • wires (list[int]) – The indices of the qudits that the quantum operation acts on.

  • qudit (int) – The dimension of the qudits. Default: 2

evolve_state(state: Tensor, matrix: Tensor, nqudit: int, wires: list[int], qudit: int = 2) Tensor[source]#

Perform the evolution of quantum states.

Parameters:
  • state (Tensor) – The batched state tensor.

  • matrix (Tensor) – The evolution matrix.

  • nqudit (int) – The number of the qudits.

  • wires (list[int]) – The indices of the qudits that the quantum operation acts on.

  • qudit (int) – The dimension of the qudits. Default: 2

expectation(state: Tensor | list[Tensor], observable: Observable, den_mat: bool = False, chi: int | None = None) Tensor[source]#

A function that calculates the expectation value of an observable on a quantum state.

The expectation value is the average measurement outcome of the observable on the quantum state. It is a real number that represents the mean of the probability distribution of the measurement outcomes.

Parameters:
  • state (Tensor | list[Tensor]) – The quantum state to measure. It can be a list of tensors representing a matrix product state, or a tensor representing a density matrix or a state vector.

  • observable (Observable) – The observable to measure. It is an instance of Observable class that implements the measurement basis and the corresponding gates.

  • den_mat (bool) – Whether to use density matrix representation. Default: False

  • chi (int | None) – The bond dimension of the matrix product state. It is only used when the state is a list of tensors. Default: None (which means no truncation)

Returns:

The expectation value of the observable on the quantum state. It is a scalar tensor with real values.

Return type:

Tensor

generalized_distance(state1: Tensor, state2: Tensor) Tensor[source]#

Calculate the generalized distance.

See https://readpaper.com/paper/2945680873 Eq.(20)

Note

Implemented according to https://arxiv.org/pdf/quant-ph/0310137.pdf Eq.(4)

Parameters:
  • state1 (Tensor) – Input with the shape of \((\text{batch}, 2^n, 1)\).

  • state2 (Tensor) – Input with the shape of \((\text{batch}, 2^n, 1)\).

Returns:

The generalized distance.

Return type:

Tensor

get_prob_mps(mps_lst: list[Tensor], wire: int) Tensor[source]#

Calculate the probability distribution (|0⟩ and |1⟩ probabilities) for a specific wire in an MPS.

This function computes the probability of measuring |0⟩ and |1⟩ for the k-th qubit in a quantum state represented as a Matrix Product State (MPS). It does this by: 1. Contracting the tensors to the left of the target tensor 2. Contracting the tensors to the right of the target tensor 3. Computing the final contraction with the target tensor

Parameters:
  • mps_lst (list[Tensor]) – A list of MPS tensors representing the quantum state. Each 3-dimensional tensor should have shape (bond_dim_left, physical_dim, bond_dim_right).

  • wire (int) – The index of the target qubit to compute probabilities for.

Returns:

A tensor containing [P(|0⟩), P(|1⟩)] probabilities for the target qubit.

Return type:

Tensor

inner_product_mps(tensors0: list[Tensor], tensors1: list[Tensor], form: str = 'norm') Tensor | list[Tensor][source]#

Computes the inner product of two matrix product states.

Parameters:
  • tensors0 (list[Tensor]) – The tensors of the first MPS, each with shape \((..., d_0, d_1, d_2)\), where \(d_0\) is the bond dimension of the left site, \(d_1\) is the physical dimension, and \(d_2\) is the bond dimension of the right site.

  • tensors1 (list[Tensor]) – The tensors of the second MPS, each with shape \((..., d_0, d_1, d_2)\), where \(d_0\) is the bond dimension of the left site, \(d_1\) is the physical dimension, and \(d_2\) is the bond dimension of the right site.

  • form (str) – The form of the output. If 'log', returns the logarithm of the absolute value of the inner product. If 'list', returns a list of norms at each step. Otherwise, returns the inner product as a scalar. Default: 'norm'

Returns:

The inner product of the two MPS, or a list of norms at each step.

Raises:

AssertionError – If the tensors have incompatible shapes or lengths.

Return type:

Tensor | list[Tensor]

int_to_bitstring(x: int, n: int, debug: bool = False) str[source]#

Convert from integer to bit string.

inverse_permutation(permute_shape: list[int]) list[int][source]#

Calculate the inversed permutation.

Parameters:

permute_shape (list[int]) – Shape of permutation.

Returns:

A list of integers that is the inverse of permute_shape.

Return type:

list[int]

is_density_matrix(rho: Tensor) bool[source]#

Check if a tensor is a valid density matrix.

A density matrix is a positive semi-definite Hermitian matrix with trace one.

Parameters:

rho (Tensor) – The tensor to check. It can be either 2D or 3D. If 3D, the first dimension is assumed to be the batch dimension.

Returns:

True if the tensor is a density matrix, False otherwise.

Return type:

bool

is_positive_definite(mat: Tensor) bool[source]#

Check if the matrix is positive definite.

is_power(n: int, base: int) bool[source]#

Check if an integer is a power of the given base.

is_power_of_two(n: int) bool[source]#

Check if an integer is a power of two.

is_unitary(matrix: Tensor, rtol: float = 1e-05, atol: float = 0.0001) bool[source]#

Check if a tensor is a unitary matrix.

Parameters:
  • matrix (Tensor) – Square matrix.

  • rtol (float) – Relative tolerance. Default: 1e-5

  • atol (float) – Absolute tolerance. Default: 1e-4

Returns:

True if matrix is unitary, False otherwise.

Return type:

bool

linear_map_mw(state_tsr: Tensor, j: int, b: int) Tensor[source]#

Calculate the linear mapping for Meyer-Wallach measure.

See https://readpaper.com/paper/2945680873 Eq.(18)

Note

Project on state with local projectors on the j th qubit. See https://arxiv.org/pdf/quant-ph/0305094.pdf Eq.(2)

Parameters:
  • state_tsr (Tensor) – Input with the shape of \((\text{batch}, 2, ..., 2)\).

  • j (int) – The j th qubit to project on, from \(0\) to \(\text{nqubit}-1\).

  • b (int) – The basis of projection, \(\ket{0}\) or \(\ket{1}\).

Returns:

Non-normalized state tensor after the linear mapping.

Return type:

Tensor

list_to_decimal(digits: list[int], base: int) int[source]#

Convert from list of digits to decimal integer.

measure(state: Tensor, shots: int = 1024, with_prob: bool = False, wires: int | list[int] | None = None, den_mat: bool = False, block_size: int = 16777216) dict | list[dict][source]#

A function that performs a measurement on a quantum state and returns the results.

The measurement is done by sampling from the probability distribution of the quantum state. The results are given as a dictionary or a list of dictionaries, where each key is a bit string representing the measurement outcome, and each value is either the number of occurrences or a tuple of the number of occurrences and the probability.

Parameters:
  • state (Tensor) – The quantum state to measure. It can be a tensor of shape \((2^n,)\) or \((2^n, 1)\) representing a state vector, or a tensor of shape \((\text{batch}, 2^n)\) or \((\text{batch}, 2^n, 1)\) representing a batch of state vectors. It can also be a tensor of shape \((2^n, 2^n)\) representing a density matrix or \((\text{batch}, 2^n, 2^n)\) representing a batch of density matrices.

  • shots (int) – The number of times to sample from the quantum state. Default: 1024

  • with_prob (bool) – A flag that indicates whether to return the probabilities along with the number of occurrences. Default: False

  • wires (int | list[int] | None) – The wires to measure. It can be an integer or a list of integers specifying the indices of the wires. Default: None (which means all wires are measured)

  • den_mat (bool) – Whether the state is a density matrix or not. Default: False

  • block_size (int) – The block size for sampling. Default: 2**24

Returns:

The measurement results. If the state is a single state vector, it returns a dictionary where each key is a bit string representing the measurement outcome, and each value is either the number of occurrences or a tuple of the number of occurrences and the probability. If the state is a batch of state vectors, it returns a list of dictionaries with the same format for each state vector in the batch.

Return type:

dict | list[dict]

meyer_wallach_measure(state_tsr: Tensor) Tensor[source]#

Calculate Meyer-Wallach entanglement measure.

See https://readpaper.com/paper/2945680873 Eq.(19)

Parameters:

state_tsr (Tensor) – Input with the shape of \((\text{batch}, 2, ..., 2)\).

Returns:

The value of Meyer-Wallach measure.

Return type:

Tensor

meyer_wallach_measure_brennen(state_tsr: Tensor) Tensor[source]#

Calculate Meyer-Wallach entanglement measure, proposed by Brennen.

See https://arxiv.org/pdf/quant-ph/0305094.pdf Eq.(6)

Note

This implementation is slower than meyer_wallach_measure when \(\text{nqubit} \ge 8\).

Parameters:

state_tsr (Tensor) – Input with the shape of \((\text{batch}, 2, ..., 2)\).

Returns:

The value of Meyer-Wallach measure.

Return type:

Tensor

multi_kron(lst: list[Tensor]) Tensor[source]#

Calculate the Kronecker/tensor/outer product for a list of tensors.

Parameters:

lst (list[Tensor]) – A list of tensors.

Returns:

The Kronecker/tensor/outer product of the input.

Return type:

Tensor

partial_trace(rho: Tensor, nqudit: int, trace_lst: list[int], qudit: int = 2) Tensor[source]#

Calculate the partial trace for a batch of density matrices.

Parameters:
  • rho (Tensor) – Density matrices with the shape of \((\text{batch}, \text{qudit}^{\text{nqudit}}, \text{qudit}^{\text{nqudit}})\).

  • nqudit (int) – Total number of qudits.

  • trace_lst (list[int]) – A list of qudits to be traced.

  • qudit (int) – The dimension of the qudits. Default: 2

Returns:

Reduced density matrices.

Return type:

Tensor

safe_inverse(x: Any, epsilon: float = 1e-12) Any[source]#

Safe inversion.

sample2expval(sample: dict) Tensor[source]#

Get the expectation value according to the measurement results.

sample_sc_mcmc(prob_func: Callable, proposal_sampler: Callable, shots: int = 1024, num_chain: int = 5) defaultdict[source]#

Get the samples of the probability distribution function via SC-MCMC method.

slice_state_vector(state: Tensor, nqubit: int, wires: list[int], bits: str, normalize: bool = True) Tensor[source]#

Get the sliced state vectors according to wires and bits.

split_tensor(tensor: Tensor, center_left: bool = True) tuple[Tensor, Tensor][source]#

Split a tensor by QR.

state_to_tensors(state: Tensor, nsite: int, qudit: int = 2) list[Tensor][source]#

Convert a quantum state to a list of tensors.

torchqr_grad(a, q, r, dq, dr)[source]#

Get the gradient for QR.