ngnrsaa / qflex

Flexible Quantum Circuit Simulator (qFlex) implements an efficient tensor network, CPU-based simulator of large quantum circuits.
Apache License 2.0
97 stars 25 forks source link

Improve documentation regarding how states are printed. #90

Closed s-mandra closed 5 years ago

s-mandra commented 5 years ago

In #88, I would expect that amplitude[0].second correspond to the quantum state |11000> (where qubit=5 is in last position). However, it corresponds to the state |00011>. Similarly, amplitude[1].second should correspond to |11001>, and instead correspond to |10011>. Am I doing/assuming something wrong?

s-mandra commented 5 years ago

You can check the amplitudes here.

95-martin-orion commented 5 years ago

The order of output states is determined by get_output_states, which naively orders them based on the appearance of their "terminal cuts" in the ordering file. For example, if the ordering has:

cut () 3
cut () 1
cut () 2

Then the state will be printed as |312>. The best way to resolve this would be to modify get_output_states to respect the qubit indices when constructing the output_states vector.

On a related note, we may want to print some kind of index-mapping for the user since the "final" qubits can be interspersed with the others; e.g. with 6 qubits and final qubits at indices 1, 2, and 4, the output is: |012345> --> |035> |124> {amplitudes}

s-mandra commented 5 years ago

On a related note, we may want to print some kind of index-mapping for the user since the "final" qubits can be interspersed with the others; e.g. with 6 qubits and final qubits at indices 1, 2, and 4, the output is: |012345> --> |035> |124> {amplitudes}

As user, I would prefer to specify the final state as one would expect (|012345>) and having qFlex figure out how to rearrange the user-provided string to do the right calculation. Otherwise, I need to understand how the mapping is done. Since the ordering is known since the beginning, it shouldn't be hard to do. Any thoughts?

95-martin-orion commented 5 years ago

As user, I would prefer to specify the final state as one would expect (|012345>) and having qFlex figure out how to rearrange the user-provided string to do the right calculation.

The issue here is that there are two sources for final state: the explicit final-conf argument to the qFlex binary, and the "final qubits" region defined by the "terminal cuts" in the ordering file. Since there can be several states for qubits in the final region, we print them separately from the rest, which inevitably messes up the order.

Using the example above, if we assume that qubit 0, 3, and 5 each have final state |0> then the states we'll return (and how we print them) are:

|000000> (|000> |000>)
|000010> (|000> |001>)
|001000> (|000> |010>)
|001010> (|000> |011>)
|010000> (|000> |100>)
|010010> (|000> |101>)
|011000> (|000> |110>)
|011010> (|000> |111>)

At this point, the question becomes: is it clearer to maintain the qubit ordering, or to extract the qubits that change between states?

s-mandra commented 5 years ago

At this point, the question becomes: is it clearer to maintain the qubit ordering, or to extract the qubits that change between states?

I think it's about taste, but in my case I prefer to keep the qubit ordering.

s-mandra commented 5 years ago

The order of output states is determined by get_output_states, which naively orders them based on the appearance of their "terminal cuts" in the ordering file. For example, if the ordering has:

cut () 3
cut () 1
cut () 2

Then the state will be printed as |312>. The best way to resolve this would be to modify get_output_states to respect the qubit indices when constructing the output_states vector.

On a related note, we may want to print some kind of index-mapping for the user since the "final" qubits can be interspersed with the others; e.g. with 6 qubits and final qubits at indices 1, 2, and 4, the output is: |012345> --> |035> |124> {amplitudes}

There is something that puzzles me here. Following your reasoning, in #88 I should expect |50123> (since we only have cut () 5) but instead I get |53210> (the whole string is inverted).

s-mandra commented 5 years ago

On a related issue, I've noticed that my convention for -x and -y is inverted. I assumed I == x-axis (while, it's the opposite). Need to fix.

s-mandra commented 5 years ago

The order of output states is determined by get_output_states, which naively orders them based on the appearance of their "terminal cuts" in the ordering file. For example, if the ordering has:

cut () 3
cut () 1
cut () 2

Then the state will be printed as |312>. The best way to resolve this would be to modify get_output_states to respect the qubit indices when constructing the output_states vector. On a related note, we may want to print some kind of index-mapping for the user since the "final" qubits can be interspersed with the others; e.g. with 6 qubits and final qubits at indices 1, 2, and 4, the output is: |012345> --> |035> |124> {amplitudes}

There is something that puzzles me here. Following your reasoning, in #88 I should expect |50123> (since we only have cut () 5) but instead I get |53210> (the whole string is inverted).

For instance, I'm running:

./qflex.x -x 3 -y 2 -d 2 -f 1 -c circuits/test.txt -g grid/test.txt -o ordering/test.txt --final-conf=1100

(where */test.txt are from the tests/evaluate_circuit_test.cpp) and I get:

The number of qubits read from the file: 0, does not match I*J: 6.
1.75kB allocated.
Total time: 0.002477384s
00000 --> 1100 0: 0.106694120914 0.0441941169702
00000 --> 1100 1: -0.0183058194816 -0.257582463324

where I assume that the last qubit is 5, and the first four qubits are 0123. However, the state |11000> as an amplitude 0.19508-i0.04419. On the contrary, the state |00011> has the amplitude printed by qFlex.

s-mandra commented 5 years ago

Found the problem. For some strange reasons, Quirk invert the qubits order :( Here an example. The state |10> should be clearly 0 and |01> = 1, however in Quirk they are inverted.

s-mandra commented 5 years ago

For now, let's improve the documentation explaining how the qubits are ordered once states are printed.

alankao64 commented 5 years ago

On a related issue, I've noticed that my convention for -x and -y is inverted. I assumed I == x-axis (while, it's the opposite). Need to fix.

Currently, the coordinate system is zero indexed with the top left corner as the origin. I added a note on this in the branch documentation_fixes, but it still is confusing and not the normal assumption. Are you suggesting that we change our coordinate system entirely? I think Orion and I were discussing that this will no longer be an issue once we move away from requiring a square grid.

s-mandra commented 5 years ago

On a related issue, I've noticed that my convention for -x and -y is inverted. I assumed I == x-axis (while, it's the opposite). Need to fix.

Currently, the coordinate system is zero indexed with the top left corner as the origin. I added a note on this in the branch documentation_fixes, but it still is confusing and not the normal assumption. Are you suggesting that we change our coordinate system entirely? I think Orion and I were discussing that this will no longer be an issue once we move away from requiring a square grid.

Don't worry, I just fixed the --help to reflect this. For now, let's keep the code as it is and just expand a bit the documentation to explain the user how qFlex outputs things.

95-martin-orion commented 5 years ago

...the order for the final output is something like |315>, correct? If true, we need to update docs accordingly. Thanks!

This is correct, but instead of documenting the inconsistency we should first try to adjust the output (by modifying get_output_states) so that it follows the usual ordering (e.g. |012345>). I can look into this, if you'd like.

s-mandra commented 5 years ago

...the order for the final output is something like |315>, correct? If true, we need to update docs accordingly. Thanks!

This is correct, but instead of documenting the inconsistency we should first try to adjust the output (by modifying get_output_states) so that it follows the usual ordering (e.g. |012345>). I can look into this, if you'd like.

That would be nice, thanks!

alankao64 commented 5 years ago

but instead of documenting the inconsistency

Do we still want to create an outputs_format.md file?