microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8a151f109cece83aeea78e74d62cd6f25e7996a3

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

library/fixed_point/src/Tests.qs

122lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License.
3
4import Init.PrepareFxP;
5import Types.FixedPoint;
6import Std.Diagnostics.Fact;
7import Std.Convert.IntAsDouble;
8import Std.Math.AbsD;
9import Operations.*;
10
11@Config(Unrestricted)
12@Test()
13operation FxpMeasurementTest() : Unit {
14 for numQubits in 3..12 {
15 for numIntBits in 2..numQubits {
16 // the allowable precision should be 2.0 ^ (-numFracBits)
17 let numFracBits = numQubits - numIntBits;
18 let epsilon = 2.0^(- IntAsDouble(numFracBits));
19 let numTestCases = (2^(numIntBits - 1)) + 1;
20
21 Message($"Qubits: {numQubits}, Int bits: {numIntBits}, Frac bits: {numFracBits}, Epsilon: {epsilon}. {numTestCases} test cases");
22 // only test up to the capacity of the number, which is (2 ^ (numIntBits)) + 1 (for the frac part)
23 for testCase in 0..numTestCases {
24 let constant = (IntAsDouble(numTestCases) / 2.0) - epsilon * IntAsDouble(testCase);
25 TestConstantMeasurement(constant, numQubits, numIntBits, epsilon);
26 }
27 Message("Passed");
28 }
29 }
30}
31
32@Config(Unrestricted)
33operation TestConstantMeasurement(constant : Double, registerWidth : Int, integerWidth : Int, epsilon : Double) : Unit {
34 import Measurement.MeasureFxP;
35 use register = Qubit[registerWidth];
36 let newFxp = new FixedPoint { IntegerBits = integerWidth, Register = register };
37 PrepareFxP(constant, newFxp);
38 let measured = MeasureFxP(newFxp);
39 let difference = AbsD(constant - measured);
40 Fact(difference < epsilon, $"Difference of {difference} is outside tolerance of {epsilon}. Input was {constant} and measured result was {measured}");
41 ResetAll(register);
42}
43
44@Config(Unrestricted)
45@Test()
46operation FxpOperationTests() : Unit {
47 for i in 0..10 {
48 let constant1 = 0.2 * IntAsDouble(i);
49 let constant2 = 0.2 * IntAsDouble(100 - i);
50 TestOperation(constant1, constant2, AddFxP, (a, b) -> a + b, "Add");
51 TestOperation(constant1, constant2, SubtractFxP, (a, b) -> a - b, "Subtract");
52 TestOperation3(constant1, constant2, (a, b, c) => MultiplyFxP(a, b, c), (a, b) -> a * b, "Multiply");
53 // manually test square, since it requires higher precision to test well
54 TestSquare(constant1);
55 }
56}
57@Config(Unrestricted)
58operation TestSquare(a : Double) : Unit {
59 import Measurement.MeasureFxP;
60 Message($"Testing Square({a})");
61 use resultRegister = Qubit[30];
62 let resultFxp = new FixedPoint { IntegerBits = 8, Register = resultRegister };
63 PrepareFxP(0.0, resultFxp);
64
65 use aRegister = Qubit[30];
66 let aFxp = new FixedPoint { IntegerBits = 8, Register = aRegister };
67 PrepareFxP(a, aFxp);
68
69 SquareFxP(aFxp, resultFxp);
70 let measured = MeasureFxP(resultFxp);
71 Fact(AbsD(a * a - measured) < 0.001, $"Difference of {AbsD(a * a - measured)} is outside of the expected range. Expected {a * a} and measured result was {measured}. (Inputs were Square({a})");
72 ResetAll(resultRegister);
73 ResetAll(aRegister);
74}
75
76@Config(Unrestricted)
77// assume the second register that `op` takes is the result register
78operation TestOperation(a : Double, b : Double, op : (FixedPoint, FixedPoint) => (), reference : (Double, Double) -> Double, name : String) : Unit {
79 import Measurement.MeasureFxP;
80 Message($"Testing {name}({a}, {b})");
81 use register1 = Qubit[20];
82 let aFxp = new FixedPoint { IntegerBits = 8, Register = register1 };
83 PrepareFxP(a, aFxp);
84
85 use register2 = Qubit[20];
86 let bFxp = new FixedPoint { IntegerBits = 8, Register = register2 };
87 PrepareFxP(b, bFxp);
88
89 op(aFxp, bFxp);
90 let measured = MeasureFxP(bFxp);
91
92 let expected = reference(a, b);
93 let difference = expected - measured;
94 Fact(difference < 0.001, $"Difference of {difference} is outside of the expected range. Expected {expected} and measured result was {measured}. (Inputs were {name}({a}, {b}))");
95 ResetAll(register1 + register2);
96}
97
98@Config(Unrestricted)
99// assume the third register that `op` takes is the result register
100operation TestOperation3(a : Double, b : Double, op : (FixedPoint, FixedPoint, FixedPoint) => (), reference : (Double, Double) -> Double, name : String) : Unit {
101 import Measurement.MeasureFxP;
102
103 Message($"Testing {name}({a}, {b})");
104 use register1 = Qubit[24];
105 let aFxp = new FixedPoint { IntegerBits = 8, Register = register1 };
106 PrepareFxP(a, aFxp);
107
108 use register2 = Qubit[24];
109 let bFxp = new FixedPoint { IntegerBits = 8, Register = register2 };
110 PrepareFxP(b, bFxp);
111
112 use resultRegister = Qubit[24];
113 let result = new FixedPoint { IntegerBits = 8, Register = resultRegister };
114
115 op(aFxp, bFxp, result);
116 let measured = MeasureFxP(result);
117
118 let expected = reference(a, b);
119 let difference = expected - measured;
120 Fact(difference < 0.001, $"Difference of {difference} is outside of the expected range. Expected {expected} and measured result was {measured}. (Inputs were {name}({a}, {b}))");
121 ResetAll(register1 + register2);
122}