New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
density matrix measurements, comp basis measurements, circuit run #1274
Conversation
This might be helpful in adding @hodgestar as co-authors in a commit. https://help.github.com/en/github/committing-changes-to-your-project/creating-a-commit-with-multiple-authors |
Hi @sarsid! I'd like to recommend that we land #1090 separately. It's a stand alone piece of work and coupling PRs together into big PRs where it can be avoided generally makes things harder to review and land. I can show you how to merge that branch into this one if you need to it make progress before #1090 lands. I would also recommend making the formatting changes you have made (I assume using black or your editor?) in a separate PR to this one. Lumping them into one PR also makes reviewing harder since one doesn't know which changes are intentional or meaningful. I'm also happy to help with this if you need! I've started work on the docs for #1090, so hopefully it can land this week. |
I think I agree that the two PRs should be kept separate. Initially, I wanted to make them the same since I was trying to use the code in #1090 but right now the two don't interact much. Wrt the formatting changes, they were put inadvertently and I'll make sure to revert them but thanks for pointing them out. Let me know what you think of the code in this PR and if you think there's some redundancy between the two (I think there should be but I can't quite put a finger on it). |
I have now merged #1090. |
I think I am pretty happy now with all my functions and variable names (for now). I would say we should leave the variable name changing and moving gates and measurement to separate files for a different PR (it can just be a restructuring one !). I was wondering how to check if it passes current tests (I am not sure what changes were there on Travis). |
You can either run it on your local machine by the command |
I will reiterate @BoxiLi suggestion. If you find that tests pass locally, then switch from draft to review ready. You can also set the 'ready for review' label with your group membership permissions. I will take a look over the code now, but will not fully review it until you mark it as ready for such. Would be best if tests were in place before this. Take a look at the codeclimate issues. They don't have to fixed, they are just suggestions. |
I am happy with the general style of the code. |
540773e
to
73a68a1
Compare
Some Updates:
|
Well, it's a statistical average, so it can deviate. I don't think it has anything to do with Python 3.8. But probably it can be avoided? I guess its the same question as #1268 I'm thinking, what about adding a |
Seems like a good idea, maybe we can add it as optional parameter to both Also, regarding Python 3.8, I was saying because both times it only failed in that test run, also never failed in any of my runs. Should I make tolerance higher ? |
qutip/qip/circuit.py
Outdated
|
||
for i in range(num_runs): | ||
final_state = self.run(state, cbits=[]) | ||
state_freq[tuple([complex(a) for a in final_state.full()])] += 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be quite vulnerable to floating-point error and global phase. The ideal way would be to check if the fidelity of two states is smaller than some threshold.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, will do ! I guess the state output can just be the first instance (I'm assuming it doesn't matter much what the small deviations are)
Ok.... Let me try restart the CI test once |
Consider what you're doing from a statistical sense here. If everything works correctly, then you're effectively trying a two-tail hypothesis test that your test binomial distribution has a probability of 0.25, given you made import scipy.stats
def success(n, p, tol):
dist = scipy.stats.binom(n, p)
return dist.cdf(n * (p+tol)) - dist.cdf(n * (p-tol)) where You have to consider what is most appropriate to fix the test, and what you can reasonably test in ~1 second of runtime. You don't want to increase the tolerance too much, because then you can get a lot of false positives even if something is broken. If you can bump the number of runs up to 100,000 and set the tolerance at 0.01, you'll have a per-test failure rate of ~3e-13, which is more like what we'd want. If you keep it at 4096, the tolerance should be more like 0.05 (which is pretty big tbh). |
Thanks for the excellent analysis. I don't think it's feasible to do 100,000 given the current. efficiency. It did give me incentive to make it somewhat faster. What is a good guideline for the maximum time a test can take. It seems like I can maybe do 150 runs in ~ 1s. In any case, it doesnt seem feasible to do even 4096 claims without taking quite a bit of time. Any ideas on how to structure the test differently ? |
Hmmm... 4000/150~25 second. That's not very short actually. The total time for a whole round of qutip CI test costs 15min~20min on Travis. Just ideas. Tests here seem to be two-folded:
So maybe we can split it. The teleportation circuit test can be done without measurement. Just check the final state tracing out the ancillary qubits. The test for measurement can probably be done for single or two On a different matter, I'm wondering if running the statistics takes so long, for such a small teleportation circuit, is it still advantageous in any case? Since we are doing simulation and have the full quantum state, one can actually calculate all 4 possible final states, classically mix them into a density matrix with the corresponding measurement probability and calculate the exact statistics distribution. I doubt that will be slower than 25s, although coding will be harder I suppose. |
I added the teleportation circuit because it seemed like a simple enough example to test both classically controlled gates and measurements. I have some separate (non-circuit based) examples in the other file. Maybe the run_statistics test can be not on the teleportation circuit and something even simpler ? Re: the idea for run_statistics, do you mean tracking the various probability elements during each measurement (along with the state) ? Seems like a decent idea ! |
Updates:
|
Again, I am not sure why some unrelated tests are failing ! |
These failing tests are different from those random failing we've been seeing before. I also have this in my scheduler PR, but it is completely unrelated to the PR. It starts to appear yesterday, but nothing was merged in the last three weeks. Does anyone have a clue? The error seems to come from the core data part @jakelishman @Ericgig. Scipy made a release 4 days ago and we are using one of the private attributes. |
There's also been some changes to how Hermitian eigenvalues and vectors are calculated (which actually is good news for us in general), which may has a bit of a knock-on for some of the The new data layer types will fix the matrix multiplication issue permanently, because we'll not be duplicating/reusing large tracts of |
@quantshah @BoxiLi @hodgestar I have wrapped up the two measurement functions in the ps. I'll fix the tests all at once after we decide on the api |
The only concern I have for this API is that now |
qutip/measurement.py
Outdated
ops : Qobj or list of Qobjs | ||
- measurement observable | ||
or | ||
- list of measurement operators M_i or kets | ||
Either: | ||
1. specifying a POVM s.t. E_i = dagger(M_i) * M_i | ||
2. projection operators if ops correspond to | ||
projectors (s.t. E_i = dagger(M_i) = M_i) | ||
3. kets (transformed to projectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please highlight the difference also here or in the function documentation:
- if
ops
is list, it is measurement povm or projective - if
ops
is qobj, it is measurement observerable
Probably also give an extra emphasis in the rst
doc.
qutip/measurement.py
Outdated
ops : list of Qobjs | ||
list of measurement operators M_i or kets | ||
Either: | ||
1. specifying a POVM s.t. E_i = dagger(M_i) * M_i | ||
2. projection operators if ops correspond to | ||
projectors (s.t. E_i = dagger(M_i) = M_i) | ||
3. kets (transformed to projectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
qutip/measurement.py
Outdated
Returns | ||
------- | ||
case : ops is a measurement observable (Qobj) | ||
measured_value : float | ||
The result of the measurement (one of the eigenvalues of op). | ||
state : Qobj | ||
The new state (a ket if a ket was given, otherwise a density | ||
matrix). | ||
case : ops is a list of measurement operators (list of Qobjs) | ||
index : float | ||
The resultant index of the measurement. | ||
state : Qobj | ||
The new state (a ket if a ket was given, otherwise a density | ||
matrix). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a good way to do it? @nathanshammah @ajgpitch @quantshah @hodgestar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- please add a line descriptor under each variable, e.g., case (which is repeated twice on line 450 and 456).
- using :class:
qutip.Qobj
would make it clickable and take one to the API. Or even just :class:.Qobj
.
I suggest we merge it after the tests and the codeclimate issues are (partially) fixed. We can make an update PR for doc if necessary. |
Addressed all the above concerns, made measurement documentation to be as Alex indicated in email! |
I find it's good to go. If there is no other big suggestions, I'll merge. Nice work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me, great work! I added some suggestions that you @sarsid should be able to commit directly. You need to add ticks like "" and "
" just after :class: and :func: to be picked up by Sphinx. This is a general feature of restructured text.
Co-authored-by: Nathan Shammah <nathan.shammah@gmail.com>
Co-authored-by: Nathan Shammah <nathan.shammah@gmail.com>
Thanks for the fixes! |
Great work @sarsid. (turns out that everytime I was writing `, it did not render here.) |
If useful, you can escape backticks in markdown with a \, so you can write \` to get one. If you need a single backtick in an inline code block, you can use two backticks to start the code block, so to get |
Checklist
Thank you for contributing to QuTiP! Please make sure you have finished the following tasks before opening the PR.
You can use pycodestyle to check your code automatically
Delete this checklist after you have completed all the tasks. If you have not finished them all, you can also open a Draft Pull Request to let the others know this on-going work and keep this checklist in the PR description.
Description
This PR is supposed to mark on-going additions to a new class
qutip.qip.circuit.Measurement
as well as an elementaryqutip.qip.circuit.Measurement.QubitCircuit.run()
function to exactly simulate quantum circuits. The major functions added right now are:Measurement.density_measurement(self, measurement_ops, state)
: This adds generalized state/density matrix measurements given a list of observables. Still needs addition of checks to see if the list of observables is validMeasurement.measurement_comp_basis(self, state)
: This adds measurement statistics for specific qubit measurements in the computational basis and also returns the collapsed states (without changing the dimensions).QubitCircuit.run(self, state, cbits)
: Given a ket input to the circuit, applies gates and measurements from the circuit and returns the resultant ket.Right now, the measurement module is very bare-bones and splintered between the previous code
from @hodgestar and the new code added by me. The eigenstate based measurements are slightly different than the measurements usually used on circuits (or I might be missing something). Ofc, in the case of measurements on all qubits, they amount to the same result. I have not added tests yet but I have added a basic quantum teleportation notebook. It will be nice to get feedback on testing methods as well as what kind of notebooks the community is interested in. Also, any other feature requests on this module would also be appreciated.
PS: I have also added measurement code from Simon's PR here so maybe we can either add him as a contributor to this PR or figure out something else.
Update:
Related issues or PRs
Adds to #1090
Changelog
Adds partial and complete measurements to state vectors/density matrices and a basic run function