We are trying to implement QFT using tensor networks.
To create initial MPS we tried using the MPS function that converts 2^N array into MPS. But using this MPS and then applying QFT circuit didn’t give the correct results.
However when we create MPS by multiplying each element in the array to the basis state MPS and then adding all the MPS gave the correct result.
We don’t understand why this is happening and it isn’t efficient for large value of N.
Here is the code that we use to create both MPS
input_array = [1,1,0,1,5,6,7,8]
N = 3
s = siteinds("Qubit",N)
cutoff = 1E-18
maxdim = 25
ψmps = MPS(input_array,s;cutoff=cutoff,maxdim=maxdim)
normalize!(ψmps)
orthogonalize!(ψmps,1)
function generate_basis_states(n)
basis_states = []
for i in 0:(2^n - 1)
binary_str = bitstring(i)[end-n+1:end] # Get last n bits of bitstring
int_array = [parse(Int, b) for b in binary_str] # Convert characters to integers
push!(basis_states, int_array)
end
return basis_states
end
basis_states = generate_basis_states(N)
arry = input_array / norm(input_array) # Input
print(arry)
ψ = arry[1] *MPS(s, string.(basis_states[1]))
for i in 2:2^N
ψ += arry[i] * MPS(s, string.(basis_states[i]))
end
Hi Shardul,
Glad you are trying ITensor. From what I understand, you are asking two different questions:
how to get correct results by converting an 2^N (full state vector) array into an MPS then applying a QFT circuit.
how to make the code efficient for larger values of N?
Correct?
As for question 2, there is no way to ultimately make this approach efficient since as you know, it is by definition an exponentially scaling approach, even just to form the initial array. Does that answer your question about the efficiency aspect, or were you finding it was running very slowly even for moderate values of N (such as 2 \leq N \leq 30, say?). What kind of N’s were you expecting to reach?
As far as question 1, it sounds like there is a bug in your code, so I would recommend writing various tests of each part to ensure that you are using the code features correctly. For example, when you make a specific input array such as just [1,0,0,0,0,0,0,0], do you get the resulting state that you are expecting if you make the MPS then contract all the tensors back together to re-form the full tensor again?
Question 2 : Sorry when I meant large N, I was exactly talking about the range you mentioned.
Question 1 : Sorry I didn’t get the debugging step you suggested. The MPS I am creating using the MPS function that converts an 2^N array into MPS is not giving correct results for QFT. The [1,0,0,0,0,0,0,0] is correctly formed in both the methods I mentioned.
Hi Shardul,
About the efficiency of the code, since the approach you are taking scales exponentially by definition, the efficiency will rapidly degrade, and you will need to time each part (this can be done even as simply as just printing out things before and after each major step) to see which part is taking the most time. Then it’s easier to discuss how to speed up that “bottleneck” part, but it’s hard to discuss before knowing what is the actual bottleneck.
As far as debugging goes, it’s very unlikely that the ITensor functions you are using are behaving incorrectly. So more likely, there may just be an error in your code’s logic somewhere or an improper use of one of the functions. The [1,0,0,0…] check is a good one, and did you also try [0,1,0,0,0…] and [0,0,1,0,…] ? The reason I mention those cases is because our MPS constructor assumes a certain ordering convention of those array entries, and it is important to be sure you are assuming the same ordering in your approach. (E.g. generalized column-major versus row-major ordering.)