-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port fixed point library to modern QDK (#1838)
This PR ports the classic QDK FixedPoint library to the modern QDK. There is still some work to be done (a README, some tests), but this is a good MVP for the library to go in 1.8. --------- Co-authored-by: César Zaragoza Cortés <[email protected]>
- Loading branch information
Showing
12 changed files
with
726 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"author": "Microsoft", | ||
"license": "MIT", | ||
"dependencies": { | ||
"Signed": { | ||
"github": { | ||
"owner": "microsoft", | ||
"repo": "qsharp", | ||
"ref": "adcefe8", | ||
"path": "library/signed" | ||
} | ||
}, | ||
"Unstable": { | ||
"github": { | ||
"owner": "Microsoft", | ||
"repo": "qsharp", | ||
"ref": "adcefe8", | ||
"path": "library/unstable" | ||
} | ||
} | ||
}, | ||
"files": [ | ||
"src/Comparison.qs", | ||
"src/Convert.qs", | ||
"src/Facts.qs", | ||
"src/Init.qs", | ||
"src/Main.qs", | ||
"src/Measurement.qs", | ||
"src/Operations.qs", | ||
"src/Polynomial.qs", | ||
"src/Reciprocal.qs", | ||
"src/Tests.qs", | ||
"src/Types.qs" | ||
] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import Types.FixedPoint; | ||
import Facts.AssertFormatsAreIdenticalFxP; | ||
import Signed.Comparison.CompareGTSI; | ||
|
||
/// # Summary | ||
/// Compares two fixed-point numbers stored in quantum registers, and | ||
/// controls a flip on the result. | ||
/// | ||
/// # Input | ||
/// ## fp1 | ||
/// First fixed-point number to be compared. | ||
/// ## fp2 | ||
/// Second fixed-point number to be compared. | ||
/// ## result | ||
/// Result of the comparison. Will be flipped if `fp1 > fp2`. | ||
/// | ||
/// # Remarks | ||
/// The current implementation requires the two fixed-point numbers | ||
/// to have the same point position and the same number of qubits. | ||
operation CompareGreaterThanFxP(fp1 : FixedPoint, fp2 : FixedPoint, result : Qubit) : Unit is Adj + Ctl { | ||
AssertFormatsAreIdenticalFxP([fp1, fp2]); | ||
|
||
CompareGTSI((fp1::Register), (fp2::Register), result); | ||
} | ||
|
||
export CompareGreaterThanFxP; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import Std.Convert.IntAsDouble, Std.Convert.BoolArrayAsInt; | ||
import Std.Math.AbsD, Std.Math.Floor; | ||
import Std.Arrays.Most, Std.Arrays.Tail; | ||
|
||
/// # Summary | ||
/// Computes fixed-point approximation for a double and returns it as `Bool` array. | ||
/// | ||
/// # Input | ||
/// ## integerBits | ||
/// Assumed number of integer bits (including the sign bit). | ||
/// ## fractionalBits | ||
/// Assumed number of fractional bits. | ||
/// ## value | ||
/// Value to be approximated. | ||
/// | ||
/// # Example | ||
/// Note that the first element in the Boolean array is the least-significant bit. | ||
/// ```qsharp | ||
/// let bits = FixedPointAsBoolArray(2, 2, 1.25); // bits = [true, false, true, false] | ||
/// let bits = FixedPointAsBoolArray(2, 2, 1.3); // bits = [true, false, true, false], approximated | ||
/// let bits = FixedPointAsBoolArray(2, 2, -1.75); // bits = [true, false, false, true], two's complement | ||
/// ``` | ||
function FixedPointAsBoolArray(integerBits : Int, fractionalBits : Int, value : Double) : Bool[] { | ||
let numBits = integerBits + fractionalBits; | ||
let sign = value < 0.0; | ||
|
||
mutable result = [false, size = numBits]; | ||
mutable rescaledConstant = 2.0^IntAsDouble(fractionalBits) * AbsD(value) + 0.5; | ||
mutable keepAdding = sign; | ||
|
||
for idx in 0..numBits - 1 { | ||
let intConstant = Floor(rescaledConstant); | ||
set rescaledConstant = rescaledConstant / 2.0; | ||
mutable currentBit = (intConstant &&& 1) == (sign ? 0 | 1); | ||
if keepAdding { | ||
set keepAdding = currentBit; | ||
set currentBit = not currentBit; | ||
} | ||
if currentBit { | ||
set result w/= idx <- true; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/// # Summary | ||
/// Returns the double value of a fixed-point approximation from of a `Bool` array. | ||
/// | ||
/// # Input | ||
/// ## integerBits | ||
/// Assumed number of integer bits (including the sign bit). | ||
/// ## bits | ||
/// Bit-string representation of approximated number. | ||
/// | ||
/// # Example | ||
/// Note that the first element in the Boolean array is the least-significant bit. | ||
/// ```qsharp | ||
/// let value = BoolArrayAsFixedPoint(2, [true, false, true, false]); // value = 1.25 | ||
/// let value = BoolArrayAsFixedPoint(2, [true, false, false, true]); // value = -1.75 | ||
/// ``` | ||
|
||
function BoolArrayAsFixedPoint(integerBits : Int, bits : Bool[]) : Double { | ||
let numBits = Length(bits); | ||
let intPart = (Tail(bits) ? -(1 <<< (numBits - 1)) | 0) + BoolArrayAsInt(Most(bits)); | ||
return IntAsDouble(intPart) / (2.0^IntAsDouble(numBits - integerBits)); | ||
} | ||
|
||
/// # Summary | ||
/// Discretizes a double value as a fixed-point approximation and returns its value as a double. | ||
/// | ||
/// # Input | ||
/// ## integerBits | ||
/// Assumed number of integer bits (including the sign bit). | ||
/// ## fractionalBits | ||
/// Assumed number of fractional bits. | ||
/// ## value | ||
/// Value to be approximated. | ||
/// | ||
/// # Example | ||
/// ```qsharp | ||
/// let value = DoubleAsFixedPoint(2, 2, 1.3); // value = 1.25 | ||
/// let value = DoubleAsFixedPoint(2, 2, 0.8); // value = 0.75 | ||
/// ``` | ||
function DoubleAsFixedPoint(integerBits : Int, fractionalBits : Int, value : Double) : Double { | ||
return BoolArrayAsFixedPoint(integerBits, FixedPointAsBoolArray(integerBits, fractionalBits, value)); | ||
} | ||
|
||
export | ||
FixedPointAsBoolArray, | ||
BoolArrayAsFixedPoint, | ||
DoubleAsFixedPoint; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import Types.FixedPoint; | ||
import Std.Arrays.IsEmpty, Std.Arrays.Rest; | ||
import Std.Diagnostics.Fact, Std.Diagnostics.CheckAllZero; | ||
|
||
/// # Summary | ||
/// Asserts that a quantum fixed-point number is | ||
/// initialized to zero. | ||
/// | ||
/// # Description | ||
/// This assertion succeeds when all qubits are in state $\ket{0}$, | ||
/// representing that the register encodes the fixed-point number $0.0$. | ||
operation AssertAllZeroFxP(fp : FixedPoint) : Unit { | ||
Fact(CheckAllZero(fp::Register), "Quantum fixed-point number was not zero."); | ||
} | ||
|
||
/// # Summary | ||
/// Assert that all fixed-point numbers in the provided array | ||
/// have identical point positions and qubit numbers. | ||
/// | ||
/// # Input | ||
/// ## fixedPoints | ||
/// Array of quantum fixed-point numbers that will be checked for | ||
/// compatibility (using assertions). | ||
function AssertFormatsAreIdenticalFxP(fixedPoints : FixedPoint[]) : Unit { | ||
if IsEmpty(fixedPoints) { | ||
return (); | ||
} | ||
let (position, register) = fixedPoints[0]!; | ||
Fact(position > 0, "Point position must be greater than zero."); | ||
let n = Length(register); | ||
for fp in Rest(fixedPoints) { | ||
Fact(fp::IntegerBits == position, "FixedPoint numbers must have identical binary point position."); | ||
Fact(Length(fp::Register) == n, "FixedPoint numbers must have identical number of qubits."); | ||
} | ||
} | ||
|
||
/// # Summary | ||
/// Assert that all fixed-point numbers in the provided array | ||
/// have identical point positions when counting from the least- | ||
/// significant bit. I.e., number of bits minus point position must | ||
/// be constant for all fixed-point numbers in the array. | ||
/// | ||
/// # Input | ||
/// ## fixedPoints | ||
/// Array of quantum fixed-point numbers that will be checked for | ||
/// compatibility (using assertions). | ||
function AssertPointPositionsIdenticalFxP(fixedPoints : FixedPoint[]) : Unit { | ||
if IsEmpty(fixedPoints) { | ||
return (); | ||
} | ||
let (position, register) = fixedPoints[0]!; | ||
Fact(position > 0, "Point position must be greater than zero."); | ||
let n = Length(register); | ||
for fp in Rest(fixedPoints) { | ||
Fact((Length(fp::Register) - fp::IntegerBits) == (n - position), "FixedPoint numbers must have identical point alignment."); | ||
} | ||
} | ||
|
||
export AssertAllZeroFxP, AssertFormatsAreIdenticalFxP, AssertPointPositionsIdenticalFxP; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import Types.FixedPoint; | ||
import Convert.FixedPointAsBoolArray; | ||
|
||
/// # Summary | ||
/// Initialize a quantum fixed-point number to a classical constant. | ||
/// | ||
/// # Input | ||
/// ## constant | ||
/// Constant to which to initialize the quantum fixed-point number. | ||
/// ## fp | ||
/// Fixed-point number (of type FixedPoint) to initialize. | ||
operation PrepareFxP(constant : Double, fp : FixedPoint) : Unit is Adj + Ctl { | ||
let bits = FixedPointAsBoolArray(fp::IntegerBits, Length(fp::Register) - fp::IntegerBits, constant); | ||
ApplyPauliFromBitString(PauliX, true, bits, fp::Register); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
export Init.PrepareFxP, Measurement.MeasureFxP, Reciprocal.ComputeReciprocalFxP, Types.FixedPoint; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import Types.FixedPoint; | ||
import Convert.BoolArrayAsFixedPoint; | ||
import Std.Arrays.ForEach; | ||
import Std.Convert.ResultArrayAsBoolArray; | ||
|
||
|
||
/// # Summary | ||
/// Measure a fixed-point number, returns its value as Double, and resets | ||
/// all the register to zero. | ||
/// | ||
/// # Input | ||
/// ## fp | ||
/// Fixed-point number to measure. | ||
operation MeasureFxP(fp : FixedPoint) : Double { | ||
let measurements = MResetEachZ(fp::Register); | ||
let bits = ResultArrayAsBoolArray(measurements); | ||
return BoolArrayAsFixedPoint(fp::IntegerBits, bits); | ||
} |
Oops, something went wrong.