2018-10-30 18:48:56 +03:00
// Copyright (c) Microsoft Corporation. All rights reserved.
2018-09-25 01:38:18 +03:00
// Licensed under the MIT license.
//////////////////////////////////////////////////////////////////////
2018-10-30 18:48:56 +03:00
// This file contains parts of the testing harness.
2018-09-25 01:38:18 +03:00
// You should not modify anything in this file.
// The tasks themselves can be found in Tasks.qs file.
//////////////////////////////////////////////////////////////////////
2018-10-30 18:48:56 +03:00
namespace Quantum.Kata.SimonsAlgorithm {
2019-05-04 02:46:04 +03:00
open Microsoft.Quantum.Diagnostics;
2020-07-29 01:57:29 +03:00
open Microsoft.Quantum.Arrays;
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
2020-07-29 01:57:29 +03:00
operation ApplyOracleA (qs : Qubit[], oracle : ((Qubit[], Qubit) => Unit is Adj)) : Unit is Adj {
oracle(Most(qs), Tail(qs));
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2020-07-29 01:57:29 +03:00
operation ApplyOracleWithOutputArrA (qs : Qubit[], oracle : ((Qubit[], Qubit[]) => Unit is Adj), outputSize : Int) : Unit is Adj {
2019-05-04 02:46:04 +03:00
let N = Length(qs);
2020-07-29 01:57:29 +03:00
oracle(qs[0 .. (N - 1) - outputSize], qs[N - outputSize ...]);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
operation AssertTwoOraclesAreEqual (
2018-10-30 18:48:56 +03:00
nQubits : Range,
2019-05-04 02:46:04 +03:00
oracle1 : ((Qubit[], Qubit) => Unit is Adj),
oracle2 : ((Qubit[], Qubit) => Unit is Adj)) : Unit {
2018-10-30 18:48:56 +03:00
let sol = ApplyOracleA(_, oracle1);
let refSol = ApplyOracleA(_, oracle2);
2021-01-30 12:35:47 +03:00
for i in nQubits {
2019-05-04 02:46:04 +03:00
AssertOperationsEqualReferenced(i+1, sol, refSol);
2018-09-25 01:38:18 +03:00
}
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
operation AssertTwoOraclesWithOutputArrAreEqual (
2018-10-30 18:48:56 +03:00
inputSize : Int,
outputSize : Int,
2019-05-04 02:46:04 +03:00
oracle1 : ((Qubit[], Qubit[]) => Unit is Adj),
oracle2 : ((Qubit[], Qubit[]) => Unit is Adj)) : Unit {
2018-10-30 18:48:56 +03:00
let sol = ApplyOracleWithOutputArrA(_, oracle1, outputSize);
let refSol = ApplyOracleWithOutputArrA(_, oracle2, outputSize);
2019-05-04 02:46:04 +03:00
AssertOperationsEqualReferenced(inputSize + outputSize, sol, refSol);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
2020-10-09 11:51:28 +03:00
@Test("QuantumSimulator")
2020-10-15 14:36:23 +03:00
operation Q11_Oracle_CountBits () : Unit {
2018-10-30 18:48:56 +03:00
AssertTwoOraclesAreEqual(1 .. 10, Oracle_CountBits, Oracle_CountBits_Reference);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
2020-10-09 11:51:28 +03:00
@Test("QuantumSimulator")
2020-10-15 14:36:23 +03:00
operation Q12_Oracle_BitwiseRightShift () : Unit {
2021-01-30 12:35:47 +03:00
for n in 2 .. 6 {
2018-10-30 18:48:56 +03:00
AssertTwoOraclesWithOutputArrAreEqual(n, n, Oracle_BitwiseRightShift, Oracle_BitwiseRightShift_Reference);
}
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
2019-05-04 02:46:04 +03:00
operation AssertTwoOraclesWithIntArrAreEqual (A : Int[], oracle1 : ((Qubit[], Qubit, Int[]) => Unit is Adj), oracle2 : ((Qubit[], Qubit, Int[]) => Unit is Adj)) : Unit {
2018-10-30 18:48:56 +03:00
AssertTwoOraclesAreEqual(Length(A) .. Length(A), oracle1(_, _, A), oracle2(_, _, A));
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2020-10-09 11:51:28 +03:00
@Test("QuantumSimulator")
2020-10-15 14:36:23 +03:00
operation Q13_Oracle_OperatorOutput () : Unit {
2018-10-30 18:48:56 +03:00
// cross-tests
// the mask for all 1's should behave the same as Oracle_CountBits
2022-03-14 20:31:37 +03:00
mutable A = [1, size = 11];
2018-10-30 18:48:56 +03:00
let L = Length(A);
2021-01-30 12:35:47 +03:00
for i in 2 .. L {
2018-10-30 18:48:56 +03:00
AssertTwoOraclesAreEqual(i .. i, Oracle_OperatorOutput(_, _, A[0 .. i - 1]), Oracle_OperatorOutput_Reference(_, _, A[0 .. i - 1]));
}
set A = [1, 1, 0, 0];
AssertTwoOraclesWithIntArrAreEqual(A, Oracle_OperatorOutput, Oracle_OperatorOutput_Reference);
2018-09-25 01:38:18 +03:00
2022-03-14 20:31:37 +03:00
set A = [0, size = 5];
2018-10-30 18:48:56 +03:00
AssertTwoOraclesWithIntArrAreEqual(A, Oracle_OperatorOutput, Oracle_OperatorOutput_Reference);
2018-09-25 01:38:18 +03:00
2018-10-30 18:48:56 +03:00
set A = [1, 0, 1, 1, 1];
AssertTwoOraclesWithIntArrAreEqual(A, Oracle_OperatorOutput, Oracle_OperatorOutput_Reference);
2018-09-25 01:38:18 +03:00
2018-10-30 18:48:56 +03:00
set A = [0, 1, 0, 0];
AssertTwoOraclesWithIntArrAreEqual(A, Oracle_OperatorOutput, Oracle_OperatorOutput_Reference);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
operation AssertTwoOraclesWithIntMatrixAreEqual (
2018-10-30 18:48:56 +03:00
A : Int[][],
2019-05-04 02:46:04 +03:00
oracle1 : ((Qubit[], Qubit[], Int[][]) => Unit is Adj),
oracle2 : ((Qubit[], Qubit[], Int[][]) => Unit is Adj)) : Unit {
2018-10-30 18:48:56 +03:00
let inputSize = Length(A[0]);
let outputSize = Length(A);
AssertTwoOraclesWithOutputArrAreEqual(inputSize, outputSize, oracle1(_, _, A), oracle2(_, _, A));
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
operation AssertTwoOraclesWithDifferentOutputsAreEqual (
2018-10-30 18:48:56 +03:00
inputSize : Int,
2019-05-04 02:46:04 +03:00
oracle1 : ((Qubit[], Qubit[]) => Unit is Adj),
oracle2 : ((Qubit[], Qubit) => Unit is Adj)) : Unit {
2018-10-30 18:48:56 +03:00
let sol = ApplyOracleWithOutputArrA(_, oracle1, 1);
let refSol = ApplyOracleA(_, oracle2);
2019-05-04 02:46:04 +03:00
AssertOperationsEqualReferenced(inputSize + 1, sol, refSol);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2020-10-09 11:51:28 +03:00
@Test("QuantumSimulator")
2020-10-15 14:36:23 +03:00
operation Q14_Oracle_MultidimensionalOperatorOutput () : Unit {
2018-10-30 18:48:56 +03:00
mutable A = [[1, 1], [0, 0]];
AssertTwoOraclesWithIntMatrixAreEqual(A, Oracle_MultidimensionalOperatorOutput, Oracle_MultidimensionalOperatorOutput_Reference);
set A = [[1, 0], [0, 1], [1, 1]];
AssertTwoOraclesWithIntMatrixAreEqual(A, Oracle_MultidimensionalOperatorOutput, Oracle_MultidimensionalOperatorOutput_Reference);
set A = [[0, 1, 0], [1, 0, 1]];
AssertTwoOraclesWithIntMatrixAreEqual(A, Oracle_MultidimensionalOperatorOutput, Oracle_MultidimensionalOperatorOutput_Reference);
// cross-test for bitwise right shift oracle
set A = [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]];
AssertTwoOraclesWithOutputArrAreEqual(4, 4, Oracle_MultidimensionalOperatorOutput(_, _, A), Oracle_BitwiseRightShift_Reference);
// cross-test for 1-dimensional output
mutable B = [1, 0, 1, 0, 1];
AssertTwoOraclesWithDifferentOutputsAreEqual(5, Oracle_MultidimensionalOperatorOutput(_, _, [B]), Oracle_OperatorOutput_Reference(_, _, B));
// cross-test for bit counting oracle
2022-03-14 20:31:37 +03:00
set B = [1, size = 5];
2018-10-30 18:48:56 +03:00
AssertTwoOraclesWithDifferentOutputsAreEqual(5, Oracle_MultidimensionalOperatorOutput(_, _, [B]), Oracle_CountBits_Reference);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
2020-10-09 11:51:28 +03:00
@Test("QuantumSimulator")
2020-10-15 14:36:23 +03:00
operation Q21_StatePrep () : Unit {
2021-01-30 12:35:47 +03:00
for N in 1 .. 10 {
use qs = Qubit[N];
// apply operation that needs to be tested
SA_StatePrep(qs);
2018-10-30 18:48:56 +03:00
2021-01-30 12:35:47 +03:00
// apply adjoint reference operation
Adjoint SA_StatePrep_Reference(qs);
2018-10-30 18:48:56 +03:00
2021-01-30 12:35:47 +03:00
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
2018-09-25 01:38:18 +03:00
}
}
2018-10-30 18:48:56 +03:00
2018-09-25 01:38:18 +03:00
// ------------------------------------------------------
2018-10-30 18:48:56 +03:00
operation cs_helper (N : Int, Matrix : Int[][]) : (Int[], ((Qubit[], Qubit[]) => Unit)) {
let Uf = Oracle_MultidimensionalOperatorOutput_Reference(_, _, Matrix);
return (Simon_Algorithm(N, Uf), Uf);
2018-09-25 01:38:18 +03:00
}
2018-10-30 18:48:56 +03:00
}