Closed weiT1993 closed 4 years ago
If you want the whole wavefunction then I would do something like this:
psi = circ.psi # get the tensor network describing the full wavefunction
psi.full_simplify_() # try and simplify the network
psi_dense = psi.to_dense(psi.site_inds, optimize=optimize)
The final step means contract the network into a single dense vector, with one dimension corresponding to the vectorization of all the physical site indices. Performance for complex circuits is going to be heavily dependent on the optimize
kwarg, i.e. the opt_einsum
path optimizer to use for this contraction. You could play with different backend
kwargs as well.
On the other hand, if you mean unbiased random sampling of bitstrings without constructing the full wavefunction (or assuming anything about it), I'm not still entirely sure what the best approach here is - quimb doens't offer anything automatically at the moment!
I ran this script to simulate all bit strings of the 10-qubit circuit example given in the tutorial.
import quimb as qu
import quimb.tensor as qtn
import random
from tqdm import tqdm
circ = qtn.Circuit(N=10, tags='PSI0')
# initial layer of hadamards
for i in range(10):
circ.apply_gate('H', i, gate_round=0)
# 8 rounds of entangling gates
for r in range(1, 9):
# even pairs
for i in range(0, 10, 2):
circ.apply_gate('CNOT', i, i + 1, gate_round=r)
# Y-rotations
for i in range(10):
circ.apply_gate('RY', 1.234, i, gate_round=r)
# odd pairs
for i in range(1, 9, 2):
circ.apply_gate('CZ', i, i + 1, gate_round=r)
# final layer of hadamards
for i in range(10):
circ.apply_gate('H', i, gate_round=r + 1)
print(circ)
psi = circ.psi # get the tensor network describing the full wavefunction
psi.full_simplify_() # try and simplify the network
psi_dense = psi.to_dense(psi.site_inds, optimize='random_greedy')
print(psi_dense)
But I encountered this error:
ValueError: The index _77d5eb00001d9 appears more than twice! If this is intentionally a 'hyper' tensor network you will need to explicitly supply `output_inds` when contracting for example.
Ah yes this is because the full simplification introduces hyper-edges, so the output indices need to be specified to the contractor. Try this as the last lines:
psi = circ.psi # get the tensor network describing the full wavefunction
psi.full_simplify_() # try and simplify the network
T = psi.contract(all, optimize='random-greedy', output_inds=psi.site_inds)
T.to_dense(psi.site_inds)
I probably need to update the to_dense
methods for the updated simplifications.
Another option would be to just use rank_simplify_
rather than full_simplify_
!
Thanks a lot. That solves it!
Great tutorial on using TN to simulate one bit string from qasm circuits. I am wondering if there is a method to simulate all the bit strings of a circuit? I want to benchmark the runtime of quimb in simulating the entire circuit of different sizes. Much appreciated!