Git Product home page Git Product logo

Comments (3)

tobiashagge avatar tobiashagge commented on June 2, 2024

I have verified that adding ResetAll(qubits) at the end of AssertEqualOnBasisVector seems to address the behavior. Not sure whether the absence of the added line is the bug or if some tolerance code is not behaving to spec.

from qsharp-runtime.

swernli avatar swernli commented on June 2, 2024

Thanks for the detailed issue, @tobiashagge! There are a few points to go over in this and I will get into more detail below, but the summary is that your suggestion of this being an issue with the tolerance in AssertEqualOnBasisVector is correct. I’ll work on a PR to resolve this.

Regarding your first point in your expected behavior above:

When the theta = .1, an exception, but one that does not claim that the expected value should be "Zero".

This is actually the expected error message, and is consistent with the behavior of our other assert APIs. Most of the different assert operations are built from calls to these two operations:

operation AssertQubit (expected : Result, q : Qubit) : Unit is Adj + Ctl {
AssertMeasurement([PauliZ], [q], expected, $"Qubit in invalid state. Expecting: {expected}");
}

And
operation AssertQubitWithinTolerance(expected : Result, q : Qubit, tolerance : Double) : Unit is Adj + Ctl {
AssertMeasurementProbability([PauliZ], [q], expected, 1.0, $"Qubit in invalid state. Expecting: {expected} with tolerance {tolerance}", tolerance);
}

The other asserts use combinations of gate operations, entanglement, and calls to these two functions to enforce the assertion. Some target qubit or auxiliary qubit deviating from the expected state is the trigger for the assertion, and that’s why you see the message they use.

For your second point regarding the difference in behavior between the two angles in your example,

When theta=.001, the program should complete without throwing an exception.

Here is where the problem with tolerance comes in. Because the AssertOperationsEqualInPlace does not have a tolerance parameter and instead uses a hard-coded value, it should use the least permissive tolerance possible to adequately enforce the assertion. The value used in this case is 1e-5 which is definitely too permissive. Picking the perfect value is tricky given that floating point precision can vary by platform and standard library (see for example C numeric limits and Machine Epsilon). The underlying C++ full state simulator that checks for qubits in the Zero state on release has an epsilon of approx 2e-16 on Windows. Looking through our codebase, there are a few other places where we rely on an epsilon/tolerance, and it seems the best value to standardize behind is 1e-15 since that’s what the Q# implementation of Double conversions uses:

function Floor(value : Double) : Int {
let (truncated, remainder, isPositive) = ExtendedTruncation(value);
if AbsD(remainder) <= 1e-15 {
return truncated;
} else {
return isPositive ? truncated | truncated - 1;
}
}

Combining this with your suggestion of including a ResetAll before the qubits are released will bring the behavior of AssertOperationsEqualInPlace in line with our other assertion utilities.

On that note of other assertion utilities, if your goal is to have an efficient validation that two unitaries are equivalent for all input states, I would suggest switching to AssertOperationsEqualReferenced instead. As noted in the docs, AssertOperationsEqualInPlace requires both additional qubits and multiple calls to the provided unitaries, while AssertOperationsEqualReferenced uses Choi–Jamiołkowski isomorphism to perform the same validation with only one call to the underlying unitaries. Using the examples you posted above, AssertOperationsEqualReferenced correctly asserts on both inputs and runs faster. This is the same strategy we use in our test cases to validate equivalence of different decompositions of quantum gates, and is quite handy.

from qsharp-runtime.

swernli avatar swernli commented on June 2, 2024

Hmm… looks like 1e-15 is a reasonable value for the full state simulator, but fails the tests for the stabilizer simulator based on the noise levels. To make these tests still pass, I’ll use the same tolerance used by the other tests:

function Accuracy () : Double {
return 1E-10;
}

That’s the value that gets passed for other test operations that call AssertQubitInStateWithinTolerance.

from qsharp-runtime.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.