tensorflow / quantum

Hybrid Quantum-Classical Machine Learning in TensorFlow
https://www.tensorflow.org/quantum
Apache License 2.0
1.79k stars 572 forks source link

typo in Quantum data tutorial #715

Closed phyjoon closed 10 months ago

phyjoon commented 2 years ago

Hello team!

I was following the Quantum data tutorial and just realized there's a very minor yet misleading typo in the mathematical expression.

In Section 2.1, $V(\theta)$ should be $$V(\theta) = \prod{i=1}^n \exp(-i\theta (X{i}X{i+1}+Y{i}Y{i+1}+Z{i}Z{i+1}))$$ rather than $$V(\theta) = \exp(-i\theta\sum{i=1}^n (X{i}X{i+1}+Y{i}Y{i+1}+Z{i}Z{i+1}))$$ since tfq.util.exponential works correctly when its input Pauli sum is commuting. The above expression matches the Hamiltonian ansatz (L4) of the original paper.

Thank you!

phyjoon commented 2 years ago

I think the function v_theta(qubits) also needs to be changed.

lockwo commented 2 years ago

It is probably worth adding that equation in, maybe incorporating something about how V(theta) is doing the trotterized approximation via:

image

But, why should the function be changed? The code implements a 10 trotter step approximate of the exp(-i theta H), which is what L4 seems to indicate.

phyjoon commented 2 years ago

Because tfq.util.exponential is intended to use on commuting PauliSum objects, while ref_paulis isn't commuting?

lockwo commented 2 years ago

Ref pauli's (in the first data point) contains the following:

1.000*X((0, 0))*X((0, 1))+1.000*Y((0, 0))*Y((0, 1))+1.000*Z((0, 0))*Z((0, 1))
1.000*X((0, 1))*X((0, 2))+1.000*Y((0, 1))*Y((0, 2))+1.000*Z((0, 1))*Z((0, 2))
1.000*X((0, 2))*X((0, 3))+1.000*Y((0, 2))*Y((0, 3))+1.000*Z((0, 2))*Z((0, 3))
1.000*X((0, 3))*X((0, 4))+1.000*Y((0, 3))*Y((0, 4))+1.000*Z((0, 3))*Z((0, 4))
1.000*X((0, 4))*X((0, 5))+1.000*Y((0, 4))*Y((0, 5))+1.000*Z((0, 4))*Z((0, 5))
1.000*X((0, 5))*X((0, 6))+1.000*Y((0, 5))*Y((0, 6))+1.000*Z((0, 5))*Z((0, 6))
1.000*X((0, 6))*X((0, 7))+1.000*Y((0, 6))*Y((0, 7))+1.000*Z((0, 6))*Z((0, 7))
1.000*X((0, 7))*X((0, 8))+1.000*Y((0, 7))*Y((0, 8))+1.000*Z((0, 7))*Z((0, 8))
1.000*X((0, 8))*X((0, 9))+1.000*Y((0, 8))*Y((0, 9))+1.000*Z((0, 8))*Z((0, 9))
1.000*X((0, 9))*X((0, 10))+1.000*Y((0, 9))*Y((0, 10))+1.000*Z((0, 9))*Z((0, 10))

Each term in the hamiltonian is Xi X(i+1)+ Yi Y(i+1)+ Zi Z(i+1) which does commute with the next term X(i+1) X(i+2)+ Y(i+1) Y(i+2)+ Z(i+1)i Z(i+2) right?. I verified this numerically with: print(ref_paulis[0].matrix() @ ref_paulis[1].matrix() == ref_paulis[1].matrix() @ ref_paulis[0].matrix())

Results in

[[ True  True  True  True]
 [ True  True  True  True]
 [ True  True  True  True]
 [ True  True  True  True]]

If the terms don't commute, there should be an error, e.g. ValueError: Given an operator has non-commutable terms, whose exponentiation is not supported yet: X((0, 0))*X((0, 1)) and Y((0, 1))*Z((0, 2))

phyjoon commented 2 years ago

Two qubit operators on (i, i+1) and (i+1, i+2) don't commute.

image
lockwo commented 2 years ago

I think each element of the input list is treated separately, not as a sum. So [H1 + H2] will throw error if they don't commute, but [H1, H2] won't throw error because it considers them different hamiltonians (and those are different list elements I mentioned).