QTensor
El módulo qtensor define la clase QTensor y funciones auxiliares relacionadas para representar y manipular estados cuánticos y operadores en forma dispersa.
The QTensor wraps an array, storing it in the optimal storage format
based on its shape and sparsity. It supports a variety of quantum objects, including:
Kets (vectores columna de forma
(2**N, 1))Bras (vectores fila de forma
(1, 2**N))Operadores / Matrices de densidad (matrices cuadradas de forma
(2**N, 2**N))Escalares (matrices
(1, 1))
Ejemplos de creación de distintos objetos cuánticos:
import numpy as np
from qilisdk.core.qtensor import QTensor
# 1‑qubit |0> ket
psi_ket = QTensor(np.array([[1], [0]]))
print("Ket:", psi_ket.dense(), "is_ket?", psi_ket.is_ket())
print("-" * 20)
# 1‑qubit <0| bra
psi_bra = QTensor(np.array([[1, 0]]))
print("Bra:", psi_bra.dense(), "is_bra?", psi_bra.is_bra())
print("-" * 20)
# Density matrix |0><0|
rho = QTensor(np.array([[1, 0], [0, 0]]))
print("Density matrix:\n", rho.dense(), "is_density_matrix?", rho.is_density_matrix())
print("-" * 20)
# Scalar 0.5
scalar = QTensor(np.array([[0.5]]))
print("Scalar:", scalar.dense(), "is_scalar?", scalar.is_scalar())
Salida
Ket: [[1]
[0]] is_ket? True
--------------------
Bra: [[1 0]] is_bra? True
--------------------
Density matrix:
[[1 0]
[0 0]] is_density_matrix? True
--------------------
Scalar: [[0.5]] is_scalar? True
Constructores auxiliares
También existen varios constructores para objetos cuánticos comunes:
ket()para kets de la base computacional
bra()para bras de la base computacional
basis_state()para estados de base N-dimensionales con un único 1 en el índice especificado
identity()para operadores identidad de dimensión especificada
zero()para generar vectores de estado en el estado de todo ceros.
one()para generar vectores de estado en el estado de todo unos.
ghz()para generar estados GHZ con un número de qubits especificado
uniform()para generar estados de superposición uniforme con un número de qubits especificado
from qilisdk.core.qtensor import QTensor
# Single‑qubit
print("ket(0):\n", QTensor.ket(0), "\nis_ket?", QTensor.ket(0).is_ket())
print("bra(1):\n", QTensor.bra(1), "\nis_bra?", QTensor.bra(1).is_bra())
# Fock basis in N=4 Hilbert space
print("basis_state(2,4):\n", QTensor.basis_state(2, 4), "\nshape:", QTensor.basis_state(2, 4).shape)
# GHZ state for 2 qubits
print("GHZ state for 2 qubits:\n", QTensor.ghz(2))
# Identity operators
print("Identity (4x4):\n", QTensor.identity(2))
Salida
ket(0):
[[1.]
[0.]]
is_ket? True
bra(1):
[[0. 1.]]
is_bra? True
basis_state(2,4):
[[0.]
[0.]
[1.]
[0.]]
shape: (4, 1)
Propiedades y operaciones de objetos cuánticos
Sea cual sea el método de almacenamiento interno, se pueden obtener vistas densas o dispersas:
.data: obtiene el contenido como una matriz dispersa de SciPy (siempre en formato CSR).dense(): convierte a un array denso de NumPy (usar con precaución para tensores grandes)o accediendo directamente a elementos por valor con
qtensor[i, j]
También están disponibles operaciones matriciales comunes:
.adjoint(): traspuesta conjugada.conjugate(): conjugada compleja elemento a elemento.transpose(): traspuesta matricial.exp(): exponencial matricial.log(): logaritmo matricial.sqrt(): raíz cuadrada matricial.rank(): calcula el rango del operador.pow(exponent): potencia matricial.norm(order="l2"): norma vectorial o matricial.normalized(order='l2'): normaliza a norma unitaria.eig(): obtiene los valores propios y vectores propios.trace(): calcula la traza de un operador.dot(other): producto interior de Frobenius con otro QTensor
Así como algunas transformaciones específicas para objetos cuánticos:
.entropy_von_neumann(): calcula la entropía de von Neumann de una matriz de densidad.entropy_renyi(alpha): calcula la entropía de Rényi de una matriz de densidad para un orden alpha dado.magic(alpha): calcula la magia (no-estabilizabilidad) de un estado puro mediante la entropía de Rényi de estabilizador.commutator(other): calcula el conmutador con otro operador.anticommutator(other): calcula el anticonmutador con otro operador.fidelity(other): calcula la fidelidad entre dos estados cuánticos.probabilities(): calcula la distribución de probabilidad de cada estado en la base computacional.sample(nshots): obtiene muestras de medida en la base computacional a partir de un estado o de una matriz de densidad.expectation_value(operator): calcula el valor esperado de un operador en este estado.partial_trace(keep): traza parcial.reset_qubits(qubits): restablece los qubits especificados a 0.dagger(): alias de adjoint
Ejemplos:
import numpy as np
from qilisdk.core.qtensor import QTensor
# Adjoint of a non-Hermitian operator
A = QTensor(np.array([[1+1j, 2], [3, 4]]))
A_dag = A.adjoint()
print("A:\n", A.dense())
print("A†:\n", A_dag.dense())
# Matrix exponential of Pauli-X
X = QTensor(np.array([[0, 1], [1, 0]]))
expX = X.exp()
print("exp(X):\n", np.round(expX.dense(), 3))
# Norm of a ket and a density matrix
ket0 = QTensor(np.array([[1], [0]]))
dm = ket0.to_density_matrix()
print("||ket0|| =", ket0.norm())
print("trace norm(dm) =", dm.norm(order='l2'))
# Partial trace of a Bell state
from qilisdk.core.qtensor import ket, tensor_prod
bell = (tensor_prod([ket(0), ket(0)]) + tensor_prod([ket(1), ket(1)])).unit()
rho_bell = bell.to_density_matrix()
print("rho_bell:\n", rho_bell)
rhoA = rho_bell.ptrace([0])
print("rho_A:\n", rhoA.dense())
Salida
A:
[[1.+1.j 2.+0.j]
[3.+0.j 4.+0.j]]
A†:
[[1.-1.j 3.+0.j]
[2.+0.j 4.+0.j]]
exp(X):
[[1.543 1.175]
[1.175 1.543]]
||ket0|| = 1.0
trace norm(dm) = 1.0
rho_bell:
QTensor(shape=4x4, nnz=4):
[[0.5 0. 0. 0.5]
[0. 0. 0. 0. ]
[0. 0. 0. 0. ]
[0.5 0. 0. 0.5]]
rho_A:
[[0.5 0. ]
[0. 0.5]]
Utilidades adicionales
Producto tensorial con
tensor_prod()Valor esperado con
expect_val()
from qilisdk.core.qtensor import QTensor, expect_val, ket, tensor_prod
import numpy as np
# Two‑qubit Hadamard tensor
H = QTensor(np.array([[1, 1], [1, -1]]) / np.sqrt(2))
H2 = tensor_prod([H, H])
print("H ⊗ H:\n", np.round(H2.dense(), 3))
# Expectation of Z⊗Z on |00>
Z = QTensor(np.array([[1, 0], [0, -1]]))
zz = tensor_prod([Z, Z])
psi00 = tensor_prod([ket(0), ket(0)])
rho00 = psi00.to_density_matrix()
ev = expect_val(zz, rho00)
print("⟨ZZ⟩ on |00> =", ev)
Salida
H ⊗ H:
[[ 0.5 0.5 0.5 0.5]
[ 0.5 -0.5 0.5 -0.5]
[ 0.5 0.5 -0.5 -0.5]
[ 0.5 -0.5 -0.5 0.5]]
⟨ZZ⟩ on |00> = 1.0
Visualización de estados cuánticos
También puede visualizar estados de un solo qubit en la esfera de Bloch usando .draw():
from qilisdk.core import QTensor
state = QTensor.ket(0)
state.draw()
El aspecto de este gráfico se puede personalizar usando un objeto QTensorStyle, que permite establecer colores, densidad de puntos y otros elementos visuales:
from qilisdk.core import QTensor
from qilisdk.utils.visualization import QTensorStyle
state = QTensor.ket(0)
style = QTensorStyle(
sphere_color="blue",
arrow_color="lightblue",
draw_center_circle=True,
sphere_points=100,
draw_reference_points=True,
)
state.draw(style=style)