This repository was archived by the owner on Nov 7, 2024. It is now read-only.

Description
So I spent a little time sketching some abstractions for quantum states and operators.
The intention is for this sort of thing to work:
# First, create a tensor network for your state.
# For example:
psi_node = Node(np.rand(2,2,2)) # pure state on 3 qubits
op_node = Node(np.rand(2,2)) # operator on 1 qubit
psi = QuantumKet([psi_node[i] for i in range(3)])
rho_1 = psi.reduced_density([2, 3]) # trace out sites 2 and 3
op_1 = QuantumOperator([op_node[0]], [op_node[1]]) # global operator on a 1-qubit space
expval = (op_1 @ rho_1).trace()
op_3 = op_1.tensor(QuantumIdentity(2))
expval = psi.adjoint() @ op_3 @ psi
print(contractors.greedy(expval.nodes).tensor)
print(contractors.greedy(expval.nodes).tensor) # same result as above
...and so on.
It would be natural to also have FiniteMPS.as_quantum_state(), which would return a QuantumKet for the MPS network.
Thoughts?
By the way, for a natural representation of a local operator it would be good to allow Edges that are not attached to any nodes. Currently, this is not supported. I suppose one could use copy tensors instead...
Also, I realize one could drop the "quantum" terminology here (see "tensor trains"), but quantum is cool right now, so...