This PR makes it so that we apply SVD on every two-qubit gate tensor before contracting it to the state. This means that gates such as XXPhase and locally equivalent ones (CX, CZ, ZZPhase, etc) are cheaper to apply since they can be decomposed using only 2 singular values instead of the usual 4. This reduces the overhead of MPS methods by a factor of 2 when using these special gates and by a factor of 4 in TTN.
The change for MPS is straightforward: decompose the gate tensor, remove any zero singular value and replace any contraction of gate_tensor with a contraction with U and V.
The change for TTN is a bit more involved, but simpler than it looks. Before we'd apply the gate_tensor to the leaf node with the qubit q0 and "push a message tensor" with the open bonds corresponding to the input and output of q1 all the way to the leaf node containing q1. Now, we do the same but with a previous step that decomposes gate_tensor into U and V, and applying U instead of gate_tensor to q0. That way, the open bond that we push through with the message tensor is the shared bond between U and V (which has dimension 4 in general, but 2 in the case of XXPhase etc). Once the message tensor reaches the leaf node containing q1 we contract it along with V to get the resulting state.
In both cases the is equivalent as what we'd get in the develop branch (that's why none of the tests need to change), but some of the virtual bonds during execution will have smaller dimension.
Related PRs
Have a look at #82 first, since this branch has that one as its base.
Bugfixes
Additionally, I've added an unrelated bugfix in Config of general.py. There was a problem when a Config object was created, it raised the error "Cannot fix both truncation fidelity and chi".
Checklist
[x] I have performed a self-review of my code.
[x] I have commented hard-to-understand parts of my code.
Description
This PR makes it so that we apply SVD on every two-qubit gate tensor before contracting it to the state. This means that gates such as XXPhase and locally equivalent ones (CX, CZ, ZZPhase, etc) are cheaper to apply since they can be decomposed using only 2 singular values instead of the usual 4. This reduces the overhead of MPS methods by a factor of 2 when using these special gates and by a factor of 4 in TTN.
The change for MPS is straightforward: decompose the gate tensor, remove any zero singular value and replace any contraction of
gate_tensor
with a contraction withU
andV
.The change for TTN is a bit more involved, but simpler than it looks. Before we'd apply the
gate_tensor
to the leaf node with the qubitq0
and "push a message tensor" with the open bonds corresponding to the input and output ofq1
all the way to the leaf node containingq1
. Now, we do the same but with a previous step that decomposesgate_tensor
intoU
andV
, and applyingU
instead ofgate_tensor
toq0
. That way, the open bond that we push through with the message tensor is the shared bond betweenU
andV
(which has dimension 4 in general, but 2 in the case of XXPhase etc). Once the message tensor reaches the leaf node containingq1
we contract it along withV
to get the resulting state.In both cases the is equivalent as what we'd get in the develop branch (that's why none of the tests need to change), but some of the virtual bonds during execution will have smaller dimension.
Related PRs
Have a look at #82 first, since this branch has that one as its base.
Bugfixes
Additionally, I've added an unrelated bugfix in
Config
of general.py. There was a problem when a Config object was created, it raised the error "Cannot fix both truncation fidelity and chi".Checklist