Conversation
The ancilla chain evaluates the geq predicate, so the residual angle and the g/s output polarity both have to match int_comparator. They were inverted, which cancelled out only when the state equals round(value), the single case the docstring example covers. Bit 0 of the state was also dropped from the chain when that bit of round(value) is 0, so a state one above an even round(value) returned the interpolated probability instead of certainty. Also correct sup in the interval description: the stated rule and the worked example both require a width-1 interval.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The documented contract for
QCmp.interpolation_comparatoris set by twoclauses of its docstring. The Returns clause:
and the interpolation rule:
with
inf := a - 0.5for a statea. Together withfunction='g'beingdocumented as
>, that fixes the answer: the flag must readP(state > value), wherestateis spread over the unit interval[state - 0.5, state + 0.5].The docstring example pins the same thing numerically. State
'110'is 3,value = 3.3 = inf + 0.8, so the rule givesP(smaller) = 0.8and the exampleprints
0.2forfunction='g'.0.2isP(state > value), notP(state < value), sogmust be the>direction.The implementation returns the other direction almost everywhere. Probability
of the comparison qubit reading
|1>for each state of a 2-qubit register,reuse=True:Precisely,
developreturns the complement of the documented answer at everystate except two:
state == round(value), where it is correct. This is the case the docstringexample covers.
state == round(value) + 1whenround(value)is even, where it returns theinterpolated probability instead of a sharp 0 or 1. The
value=2.0,growabove shows this: state 3 reads 0.5 where the answer is 1.
Classifying every measurement of the sweeps below against those three
categories leaves nothing unaccounted for (
other: 0in both):The
value=4.0rows are the out-of-range case: no 2-qubit state is above 4.0,yet
gflags every state.int_comparatoron the same out-of-range integersreturns 0 for
gand 1 fors.For integer
value,interpolation_comparatorshould agree withint_comparatorexcept atstate == value, where it smooths to 0.5:Root cause
pyqpanda-algorithm/pyqpanda_alg/QCmp/QCmp.py,interpolation_comparator(lines 174-289 on develop, body from line 224).
The ancilla chain is
int_comparator's chain with the bit-0 comparisonsoftened by an
RYcoin:_qorwhere the corresponding bit ofvalue_intis0,
TOFFOLIwhere it is 1. That chain evaluatesstate >= value_int,propagating the bit-0 result only while the higher bits are equal. Three things
do not line up with it:
int_comparator, which pre-flipsq_cmpfors/seqand leaves it alone forg/geq.interpolation_comparatorpre-flips forg, so the chain result iscomplemented for the wrong mode.
value_res = value - value_int + 0.5isP(state < value), while the slotit feeds in the chain needs
P(state > value).value_intis 0, the chain dropsq_state[0](
circuit << RY(q_anc_cmp[0], angle)), so a state differing fromvalue_intonly in bit 0 is treated as equal to it.(1) and (2) cancel when
state == value_int, which is why the interpolatedprobability at that state is right and the direction elsewhere is not. (3) is
independent and produces the second exception above.
The docstring also gives the interval as
inf:=a-0.5tosup:=a+1.5. Awidth-2 interval would make the stated rule read
delta/2rather thandelta,and would not give the example's 0.2, so this looks like a typo for
a+0.5;this PR changes that one token so the description matches the rule and the
example.
Fix
Three changes, in the same style as
int_comparator:The third one makes bit 0 behave like the rest of the chain:
q_state[0] = 1against a 0 bit means strictly greater, so the flag is set outright, and the
coin applies only on the equal branch.
Cost, where bit 0 of
round(value)is 0, is an uncontrolledRYbecoming azero-controlled
RYplus aCNOT. Measured onvalue=2.4, 3-qubit register,function='g',reuse=True: two-qubit gates 0 to 2, depth 6 to 9,Xcount 6to 7. Where bit 0 of
round(value)is 1 the bit-0 construction is untouchedand only the polarity
Xmoves between the two modes; onvalue=3.3, sameregister and mode, depth stays 6 and two-qubit gates stay 1, with the
Xcountgoing 6 to 5 for
gand 5 to 6 fors.Verification
The
developcolumn of the repro table becomes thedocumentedcolumn inevery row.
Exhaustive check against
P(state > value)andP(state < value), with eachstate treated as the unit interval
[state - 0.5, state + 0.5]:[0.0, 0.2, 0.5, 0.9, 1.0, 1.3, 1.5, 2.0, 2.5, 2.7, 3.0, 3.3, 4.0, 5.0, 6.5, 7.0, 8.0, 15.0, 16.0, 31.0, 100.0], registers of 2, 3 and 4qubits,
reuseboth ways, both modes, every basis state: 2352 checks, 0mismatch above 1e-9, largest absolute error 1.11e-16. On develop the same
sweep is 2156 mismatches.
k/20fork = 1..179(0.05 to 8.95), 3-qubit register,reuse=True, both modes, every basis state: 2864 checks, 0 mismatch above1e-9, largest absolute error 2.22e-16. On develop the same sweep is 2560
mismatches.
The docstring example is unchanged to within floating-point rounding: develop
prints
{'0': 0.7999999999999997, '1': 0.20000000000000023}and this branchprints
{'0': 0.7999999999999997, '1': 0.20000000000000018}, a difference of5e-17. The docstring literal is left as it is.
On a 3-qubit uniform superposition through the
value=2.4,function='g',reuse=Truecircuit, the state-register marginals are unchanged: 0.5 on eachof the three qubits and 0.125 on each of the 8 joint outcomes, before and
after. Note that with
reuse=Truethis function does not uncomputeq_anc_cmp[0], before or after this change: on that circuit it reads 0.9 ondevelop and 0.55 here, where
int_comparatorunderreuse=Truereturns itsancillas to
|0>. That is existing behaviour and this PR does not change it.Tests
test/QAlgBase/Test_comparator_interpolation_comparator.pyexisted but everyline was commented out. Un-commented it, brought it up to the current
pyqpanda3 API, and extended it to 49 tests: the docstring example, interpolated
probabilities for non-integer values in both modes, the sharp answers outside
the interpolated interval, integer values checked against the classical
predicate over every state of 2- and 3-qubit registers, values above the
register range, the upper and lower edges of the range,
reuseagreement, asuperposition whose flag probability is the mean of the basis results, the
ValueErroron negative input and theNameErroron an unknownfunction.Against the unpatched module the new file is 27 failed, 22 passed.
This does not conflict with #42, which changes
qft_qubit_comparatorin thesame file; a local test merge of the two branches is clean and the combined
suite is 90 passed.