Qx.Math (Qx - Quantum Computing Simulator v0.11.0)

View Source

Utility module: a documented tier-2 escape hatch below the circuit API (normal use never reaches it — normalize/1 and probabilities/1 are the supported surface).

Core mathematical functions for quantum mechanics calculations.

The public surface of this module is normalize/1 and probabilities/1 — the two state utilities used throughout Qx and taught in the tutorials.

The remaining linear-algebra helpers (kron/2, inner_product/2, outer_product/2, trace/1, unitary?/1, apply_gate/2, identity/1, complex/2) are deprecated and will be removed in Qx 1.0. Each carries a drop-in Nx/Complex replacement in its deprecation notice.

Summary

Functions

Applies a quantum gate (unitary matrix) to a quantum state.

Creates a complex number from real and imaginary parts.

identity(n) deprecated

Creates the identity matrix of given size.

Computes the inner product (dot product) of two quantum states.

kron(a, b) deprecated

Computes the Kronecker (tensor) product of two matrices.

Normalizes a quantum state vector to unit magnitude.

Computes the outer product of two quantum states.

Computes the probability amplitudes from a quantum state vector.

trace(matrix) deprecated

Computes the trace of a matrix.

unitary?(matrix) deprecated

Checks if a matrix is unitary (U† U = I).

Functions

apply_gate(gate, state)

This function is deprecated. Use `Nx.dot/2`. Will be removed in Qx 1.0.

Applies a quantum gate (unitary matrix) to a quantum state.

Examples

iex> state = Nx.tensor([1.0, 0.0])
iex> x_gate = Nx.tensor([[0.0, 1.0], [1.0, 0.0]])
iex> Qx.Math.apply_gate(x_gate, state)
#Nx.Tensor<
  f32[2]
  [0.0, 1.0]
>

complex(real, imag \\ 0.0)

This function is deprecated. Use `Complex.new/2`. Will be removed in Qx 1.0.

Creates a complex number from real and imaginary parts.

Examples

iex> c = Qx.Math.complex(1.0, 2.0)
iex> Complex.real(c)
1.0
iex> Complex.imag(c)
2.0

identity(n)

This function is deprecated. Use `Nx.eye/1`. Will be removed in Qx 1.0.

Creates the identity matrix of given size.

Returns a generic n × n real-valued identity tensor (delegates to Nx.eye/1). Not gate-shaped: the 2×2 c64 single-qubit identity matrix used by gate factories is internal and is not exposed at the public surface.

Examples

iex> Qx.Math.identity(2)
#Nx.Tensor<
  s32[2][2]
  [
    [1, 0],
    [0, 1]
  ]
>

inner_product(state1, state2)

This function is deprecated. Use `Nx.sum(Nx.multiply(Nx.conjugate(state1), state2))`. Will be removed in Qx 1.0.

Computes the inner product (dot product) of two quantum states.

Examples

iex> state1 = Nx.tensor([1.0, 0.0])
iex> state2 = Nx.tensor([0.0, 1.0])
iex> Qx.Math.inner_product(state1, state2)
#Nx.Tensor<
  c64
  0.0+0.0i
>

kron(a, b)

This function is deprecated. Inline the Nx pipeline: `a |> Nx.reshape({m, 1, n, 1}) |> Nx.multiply(Nx.reshape(b, {1, p, 1, q})) |> Nx.reshape({m * p, n * q})`. Will be removed in Qx 1.0.

Computes the Kronecker (tensor) product of two matrices.

The Kronecker product is fundamental in quantum mechanics for combining quantum states and operators across multiple qubits.

Examples

iex> a = Nx.tensor([[1, 2], [3, 4]])
iex> b = Nx.tensor([[0, 5], [6, 7]])
iex> Qx.Math.kron(a, b)
#Nx.Tensor<
  s32[4][4]
  [
    [0, 5, 0, 10],
    [6, 7, 12, 14],
    [0, 15, 0, 20],
    [18, 21, 24, 28]
  ]
>

normalize(state)

@spec normalize(Nx.Tensor.t()) :: Nx.Tensor.t()

Normalizes a quantum state vector to unit magnitude.

This is a host function: it performs a single Nx.to_number/1 sync to check the norm, then delegates to a pure defn kernel. Composing it inside your own defn is therefore not supported — inline the kernel (state / Nx.sqrt(Nx.sum(Nx.abs(state) ** 2))) in that case.

Examples

iex> state = Nx.tensor([1.0, 1.0])
iex> Qx.Math.normalize(state)
#Nx.Tensor<
  f32[2]
  [0.70710677, 0.70710677]
>

Raises

  • Qx.StateNormalizationError - If the input has zero norm (an all-zero vector has no defined normalization; this previously returned a silent NaN tensor)

outer_product(state1, state2)

This function is deprecated. Use `Nx.outer(state1, Nx.conjugate(state2))`. Will be removed in Qx 1.0.

Computes the outer product of two quantum states.

Examples

iex> state1 = Nx.tensor([1.0, 0.0])
iex> state2 = Nx.tensor([0.0, 1.0])
iex> Qx.Math.outer_product(state1, state2)
#Nx.Tensor<
  c64[2][2]
  [
    [0.0+0.0i, 1.0+0.0i],
    [0.0+0.0i, 0.0+0.0i]
  ]
>

probabilities(state)

@spec probabilities(Nx.Tensor.t()) :: Nx.Tensor.t()

Computes the probability amplitudes from a quantum state vector.

Examples

iex> state = Nx.tensor([0.7071, 0.7071])
iex> Qx.Math.probabilities(state)
#Nx.Tensor<
  f32[2]
  [0.49999037, 0.49999037]
>

trace(matrix)

This function is deprecated. Use `Nx.sum(Nx.take_diagonal(matrix))`. Will be removed in Qx 1.0.

Computes the trace of a matrix.

Examples

iex> matrix = Nx.tensor([[1.0, 2.0], [3.0, 4.0]])
iex> Qx.Math.trace(matrix)
#Nx.Tensor<
  f32
  5.0
>

unitary?(matrix)

This function is deprecated. Check U†U ≈ I directly with Nx (recipe in the docs). Will be removed in Qx 1.0.
@spec unitary?(Nx.Tensor.t()) :: boolean()

Checks if a matrix is unitary (U† U = I).

Examples

iex> pauli_x = Nx.tensor([[0.0, 1.0], [1.0, 0.0]])
iex> Qx.Math.unitary?(pauli_x)
true

iex> not_unitary = Nx.tensor([[2.0, 0.0], [0.0, 2.0]])
iex> Qx.Math.unitary?(not_unitary)
false

Replacement recipe

Check U†U ≈ I directly with Nx:

{n, m} = Nx.shape(matrix)

unitary? =
  n == m and
    matrix
    |> Nx.conjugate()
    |> Nx.transpose()
    |> Nx.dot(matrix)
    |> Nx.subtract(Nx.as_type(Nx.eye(n), Nx.type(matrix)))
    |> Nx.abs()
    |> Nx.reduce_max()
    |> Nx.to_number()
    |> Kernel.<(1.0e-6)