From d962327b777cefe3ead2337b047f91953b221dee Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Fri, 15 Nov 2019 18:07:40 +0000 Subject: [PATCH 1/5] Started writing unit tests for new standard library functionality. --- Standard/src/Arithmetic/Reflections.qs | 52 ++++++++++++------- Standard/tests/AmplitudeAmplificationTests.qs | 1 + Standard/tests/Arithmetic/ReflectionTests.qs | 29 +++++++++++ 3 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 Standard/tests/Arithmetic/ReflectionTests.qs diff --git a/Standard/src/Arithmetic/Reflections.qs b/Standard/src/Arithmetic/Reflections.qs index e3240c9c464..81e2af3afdc 100644 --- a/Standard/src/Arithmetic/Reflections.qs +++ b/Standard/src/Arithmetic/Reflections.qs @@ -3,27 +3,39 @@ namespace Microsoft.Quantum.Arithmetic { open Microsoft.Quantum.Convert; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Logical; - ///Flip the sign of just one amplitude - operation ReflectAboutInteger(index : Int, reg : LittleEndian): Unit is Adj + Ctl { - let nQubits = Length(reg!); - let bitstring = IntAsBoolArray(index, nQubits); - if (nQubits < 2) { - within { - if (not bitstring[0]) { - X(reg![0]); - } - } apply { - Z(reg![0]); - } - } else { - within { - ApplyToEachCA(CControlledCA(X), Zip(bitstring, reg!)); - } apply { - (Controlled Z)(Most(reg!), Tail(reg!)); //The true complexity of this operation is in O(nQubits) - } + /// # Summary + /// Reflects a quantum register about a given classical integer. + /// + /// # Description + /// Given a quantum register initially in the state $\sum_i \alpha_i \ket{i}$, + /// where each $\ket{i}$ is a basis state representing an integer $i$, + /// reflects the state of the register about the basis state for a given + /// integer $\ket{j}$, + /// $$ + /// \sum_i (-1)^{ \delta_{ij} } \alpha_i \ket{i} + /// $$ + /// + /// # Input + /// ## index + /// The classical integer indexing the basis state about which to reflect. + /// + /// # Remarks + /// This operation is implemented in-place, without explicit allocation of + /// additional auxillary qubits. + operation ReflectAboutInteger(index : Int, reg : LittleEndian) : Unit is Adj + Ctl { + within { + // We want to reduce to the problem of reflecting about the all-ones + // state. To do that, we apply our reflection within an application + // of X instructions that flip all the zeros in our index. + ApplyToEachCA( + CControlledCA(X), + Zip(Mapped(Not, IntAsBoolArray(index, Length(reg!))), reg!) + ); + } apply { + (Controlled Z)(Most(reg!), Tail(reg!)); } - } //_amplitudeSignFlip - + } } diff --git a/Standard/tests/AmplitudeAmplificationTests.qs b/Standard/tests/AmplitudeAmplificationTests.qs index fb98ac602ba..8f0ce1952e2 100644 --- a/Standard/tests/AmplitudeAmplificationTests.qs +++ b/Standard/tests/AmplitudeAmplificationTests.qs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + namespace Microsoft.Quantum.Tests { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; diff --git a/Standard/tests/Arithmetic/ReflectionTests.qs b/Standard/tests/Arithmetic/ReflectionTests.qs new file mode 100644 index 00000000000..5002490cd97 --- /dev/null +++ b/Standard/tests/Arithmetic/ReflectionTests.qs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Tests { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Arithmetic; + open Microsoft.Quantum.Diagnostics; + + operation ManuallyReflectAboutFive(register : Qubit[]) : Unit is Adj + Ctl { + within { + X(register[1]); + } apply { + Controlled Z(register[0..1], register[2]); + } + } + + operation ReflectAboutFiveUsingLibrary(register : Qubit[]) : Unit is Adj + Ctl { + let littleEndian = LittleEndian(register); + ReflectAboutInteger(5, littleEndian); + } + + operation ReflectAboutIntegerTest() : Unit { + AssertOperationsEqualReferenced(3, + ReflectAboutFiveUsingLibrary, + ManuallyReflectAboutFive + ); + } + +} From b21a5cf10eb8b471cbcd222feeed3dcb6fe8fad5 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Fri, 15 Nov 2019 18:16:05 +0000 Subject: [PATCH 2/5] Testing new array fn. --- Standard/tests/ArrayTests.qs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Standard/tests/ArrayTests.qs b/Standard/tests/ArrayTests.qs index 528c2f968ba..68f513a5b46 100644 --- a/Standard/tests/ArrayTests.qs +++ b/Standard/tests/ArrayTests.qs @@ -153,6 +153,14 @@ namespace Microsoft.Quantum.Tests { } } + function IsEmptyTest() : Unit { + Fact(IsEmpty(new Int[0])); + Fact(IsEmpty(new Qubit[0])); + Fact(IsEmpty(new (Double, Int -> String)[0])); + Fact(not IsEmpty([PauliX, PauliZ])); + Fact(not IsEmpty([""])); + } + } From af9525e381c917e6598ae72bba1e62beb1a60e91 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Fri, 15 Nov 2019 18:34:27 +0000 Subject: [PATCH 3/5] Fixes to Runtime project. --- MachineLearning/src/Runtime/Runtime.csproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MachineLearning/src/Runtime/Runtime.csproj b/MachineLearning/src/Runtime/Runtime.csproj index 51305f555db..e9e8700740f 100644 --- a/MachineLearning/src/Runtime/Runtime.csproj +++ b/MachineLearning/src/Runtime/Runtime.csproj @@ -2,6 +2,11 @@ netstandard2.1 x64 + Microsoft.Quantum.MachineLearning.Runtime + + + + True From 0a0f53ca93fcdf47814954cc4ddc24924c13b363 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Fri, 15 Nov 2019 18:35:02 +0000 Subject: [PATCH 4/5] Added more tests. --- Standard/src/Math/Functions.qs | 14 +++++++------- Standard/tests/ArrayTests.qs | 10 +++++----- Standard/tests/Logical/PredicateTests.qs | 6 ++++++ Standard/tests/Math/MathTests.qs | 6 ++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Standard/src/Math/Functions.qs b/Standard/src/Math/Functions.qs index 0f2cf4d4cd4..7fc4cd2300e 100644 --- a/Standard/src/Math/Functions.qs +++ b/Standard/src/Math/Functions.qs @@ -611,7 +611,7 @@ namespace Microsoft.Quantum.Math { } - /// # Summary + /// # Summary /// Returns the squared 2-norm of a vector. /// /// # Description @@ -625,12 +625,12 @@ namespace Microsoft.Quantum.Math { /// # Output /// The squared 2-norm of `array`. function SquaredNorm(array : Double[]) : Double { - mutable ret = 0.0; - for (element in array) { - set ret += element * element; - } - return ret; - } + mutable ret = 0.0; + for (element in array) { + set ret += element * element; + } + return ret; + } /// # Summary diff --git a/Standard/tests/ArrayTests.qs b/Standard/tests/ArrayTests.qs index 68f513a5b46..16facb12f07 100644 --- a/Standard/tests/ArrayTests.qs +++ b/Standard/tests/ArrayTests.qs @@ -154,11 +154,11 @@ namespace Microsoft.Quantum.Tests { } function IsEmptyTest() : Unit { - Fact(IsEmpty(new Int[0])); - Fact(IsEmpty(new Qubit[0])); - Fact(IsEmpty(new (Double, Int -> String)[0])); - Fact(not IsEmpty([PauliX, PauliZ])); - Fact(not IsEmpty([""])); + Fact(IsEmpty(new Int[0]), "Empty array marked as non-empty."); + Fact(IsEmpty(new Qubit[0]), "Empty array marked as non-empty."); + Fact(IsEmpty(new (Double, Int -> String)[0]), "Empty array marked as non-empty."); + Fact(not IsEmpty([PauliX, PauliZ]), "Non-empty array marked as empty."); + Fact(not IsEmpty([""]), "Non-empty array marked as empty."); } } diff --git a/Standard/tests/Logical/PredicateTests.qs b/Standard/tests/Logical/PredicateTests.qs index 75270552c88..02735428208 100644 --- a/Standard/tests/Logical/PredicateTests.qs +++ b/Standard/tests/Logical/PredicateTests.qs @@ -96,4 +96,10 @@ namespace Microsoft.Quantum.Tests { Fact(not LessThanOrEqualL(32L, -13L), "LessThanOrEqualL returned wrong output."); } + function NearlyEqualDTest() : Unit { + Fact(NearlyEqualD(1.0, 1.0), "Exactly equal numbers marked as not nearly equal."); + Fact(NearlyEqualDTest(1.0, 1.0 + 1e-15), "Nearly equal numbers marked as not nearly equal."); + Fact(not NearlyEqualD(1.0, 1000.0), "Not nearly equal numbers marked as nearly equal."); + } + } diff --git a/Standard/tests/Math/MathTests.qs b/Standard/tests/Math/MathTests.qs index 0476d1cb770..2202e670cb4 100644 --- a/Standard/tests/Math/MathTests.qs +++ b/Standard/tests/Math/MathTests.qs @@ -150,6 +150,12 @@ namespace Microsoft.Quantum.Canon { } } } + + function SquaredNormTest() : Unit { + NearEqualityFactD(SquaredNorm([2.0]), 4.0); + NearEqualityFactD(SquaredNorm([1.0, 1.0]), 2.0); + NearEqualityFactD(SquaredNorm([3.0, 4.0], 25.0)); + } } From 57a5fddc336e01c65436abe60172c07a88124fcd Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Fri, 15 Nov 2019 20:12:58 +0000 Subject: [PATCH 5/5] Added tesets for rest of functionality added to M.Q.Std. --- Standard/src/Measurement/Reset.qs | 4 ++-- Standard/tests/ArrayTests.qs | 2 +- Standard/tests/CombinatorTests.qs | 27 ++++++++++++++++++++++++ Standard/tests/Logical/PredicateTests.qs | 2 +- Standard/tests/Math/MathTests.qs | 2 +- Standard/tests/Measurement/ResetTests.qs | 24 +++++++++++++++++++++ 6 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 Standard/tests/Measurement/ResetTests.qs diff --git a/Standard/src/Measurement/Reset.qs b/Standard/src/Measurement/Reset.qs index bdc45200efe..f9687a7a678 100644 --- a/Standard/src/Measurement/Reset.qs +++ b/Standard/src/Measurement/Reset.qs @@ -17,7 +17,7 @@ namespace Microsoft.Quantum.Measurement { } - /// # Summary + /// # Summary /// Sets a qubit to a given computational basis state by measuring the /// qubit and applying a bit flip if needed. /// @@ -30,7 +30,7 @@ namespace Microsoft.Quantum.Measurement { /// # Remarks /// As an invariant of this operation, calling `M(q)` immediately /// after `SetToBasisState(result, q)` will return `result`. - operation SetToBasisState(desired : Result, target : Qubit) : Unit { + operation SetToBasisState(desired : Result, target : Qubit) : Unit { if (desired != M(target)) { X(target); } diff --git a/Standard/tests/ArrayTests.qs b/Standard/tests/ArrayTests.qs index 16facb12f07..0cf9e169289 100644 --- a/Standard/tests/ArrayTests.qs +++ b/Standard/tests/ArrayTests.qs @@ -156,7 +156,7 @@ namespace Microsoft.Quantum.Tests { function IsEmptyTest() : Unit { Fact(IsEmpty(new Int[0]), "Empty array marked as non-empty."); Fact(IsEmpty(new Qubit[0]), "Empty array marked as non-empty."); - Fact(IsEmpty(new (Double, Int -> String)[0]), "Empty array marked as non-empty."); + Fact(IsEmpty(new (Double, (Int -> String))[0]), "Empty array marked as non-empty."); Fact(not IsEmpty([PauliX, PauliZ]), "Non-empty array marked as empty."); Fact(not IsEmpty([""]), "Non-empty array marked as empty."); } diff --git a/Standard/tests/CombinatorTests.qs b/Standard/tests/CombinatorTests.qs index 5376e10e04b..9834abaec41 100644 --- a/Standard/tests/CombinatorTests.qs +++ b/Standard/tests/CombinatorTests.qs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + namespace Microsoft.Quantum.Tests { open Microsoft.Quantum.Math; open Microsoft.Quantum.Canon; @@ -349,4 +350,30 @@ namespace Microsoft.Quantum.Tests { AssertOperationsEqualReferenced(2, ApplyIfElseBCACase(false, _), ApplyToEachA(X, _)); } + operation ApplyXToSecondQubit(qubits : Qubit[]) : Unit is Adj + Ctl { + X(qubits[1]); + } + + operation ApplyToElementTest() : Unit { + AssertOperationsEqualReferenced(3, + ApplyToElement(X, 1, _), + ApplyXToSecondQubit + ); + + AssertOperationsEqualReferenced(3, + ApplyToElementC(X, 1, _), + ApplyXToSecondQubit + ); + + AssertOperationsEqualReferenced(3, + ApplyToElementA(X, 1, _), + ApplyXToSecondQubit + ); + + AssertOperationsEqualReferenced(3, + ApplyToElementCA(X, 1, _), + ApplyXToSecondQubit + ); + } + } diff --git a/Standard/tests/Logical/PredicateTests.qs b/Standard/tests/Logical/PredicateTests.qs index 02735428208..5c970d97e46 100644 --- a/Standard/tests/Logical/PredicateTests.qs +++ b/Standard/tests/Logical/PredicateTests.qs @@ -98,7 +98,7 @@ namespace Microsoft.Quantum.Tests { function NearlyEqualDTest() : Unit { Fact(NearlyEqualD(1.0, 1.0), "Exactly equal numbers marked as not nearly equal."); - Fact(NearlyEqualDTest(1.0, 1.0 + 1e-15), "Nearly equal numbers marked as not nearly equal."); + Fact(NearlyEqualD(1.0, 1.0 + 1e-15), "Nearly equal numbers marked as not nearly equal."); Fact(not NearlyEqualD(1.0, 1000.0), "Not nearly equal numbers marked as nearly equal."); } diff --git a/Standard/tests/Math/MathTests.qs b/Standard/tests/Math/MathTests.qs index 2202e670cb4..3a8c27b1321 100644 --- a/Standard/tests/Math/MathTests.qs +++ b/Standard/tests/Math/MathTests.qs @@ -154,7 +154,7 @@ namespace Microsoft.Quantum.Canon { function SquaredNormTest() : Unit { NearEqualityFactD(SquaredNorm([2.0]), 4.0); NearEqualityFactD(SquaredNorm([1.0, 1.0]), 2.0); - NearEqualityFactD(SquaredNorm([3.0, 4.0], 25.0)); + NearEqualityFactD(SquaredNorm([3.0, 4.0]), 25.0); } } diff --git a/Standard/tests/Measurement/ResetTests.qs b/Standard/tests/Measurement/ResetTests.qs new file mode 100644 index 00000000000..45056d785e2 --- /dev/null +++ b/Standard/tests/Measurement/ResetTests.qs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Tests { + open Microsoft.Quantum.Measurement; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + + operation CheckSetToBasisState(desired : Result) : Unit { + using (q = Qubit()) { + Ry(0.1234, q); + SetToBasisState(desired, q); + AssertQubit(desired, q); + Reset(q); + } + } + + operation SetToBasisStateTest() : Unit { + for (desired in [Zero, One]) { + CheckSetToBasisState(desired); + } + } + +}