-
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 signed integer math to modern QDK (#1841)
This PR ports the classic QDK's signed int math functionality to the modern QDK. It is not intended to provide the perfect API -- it is just a port, that other libraries will build upon, primarily the fixed point library. --------- Co-authored-by: César Zaragoza Cortés <[email protected]>
- Loading branch information
Showing
7 changed files
with
592 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,2 @@ | ||
# Signed | ||
The `signed` library defines signed quantum integer primitives and operations. |
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 @@ | ||
{ | ||
"author": "Microsoft", | ||
"license": "MIT", | ||
"dependencies": { | ||
"Unstable": { | ||
"github": { | ||
"owner": "Microsoft", | ||
"repo": "qsharp", | ||
"ref": "d1fb2a1", | ||
"path": "library/unstable" | ||
} | ||
} | ||
}, | ||
"files": [ | ||
"src/Comparison.qs", | ||
"src/Measurement.qs", | ||
"src/Operations.qs", | ||
"src/Tests.qs", | ||
"src/Utils.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 Std.Arrays.Tail, Std.Arrays.Zipped, Std.Arrays.Most, Std.Arrays.Rest; | ||
import Std.Diagnostics.Fact; | ||
import Unstable.Arithmetic.ApplyIfGreaterLE; | ||
|
||
/// # Summary | ||
/// Wrapper for signed integer comparison: `result = xs > ys`. | ||
/// | ||
/// # Input | ||
/// ## xs | ||
/// First $n$-bit number | ||
/// ## ys | ||
/// Second $n$-bit number | ||
/// ## result | ||
/// Will be flipped if $xs > ys$ | ||
operation CompareGTSI(xs : Qubit[], ys : Qubit[], result : Qubit) : Unit is Adj + Ctl { | ||
use tmp = Qubit(); | ||
within { | ||
CNOT(Tail(xs), tmp); | ||
CNOT(Tail(ys), tmp); | ||
} apply { | ||
X(tmp); | ||
Controlled ApplyIfGreaterLE([tmp], (X, xs, ys, result)); | ||
X(tmp); | ||
CCNOT(tmp, Tail(ys), result); | ||
} | ||
} |
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,50 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import Std.Diagnostics.Fact; | ||
import Operations.Invert2sSI; | ||
|
||
/// # Summary | ||
/// Measures a signed integer of a given width. | ||
/// If the width is 4, the qubit register will be measured as a 4-bit signed integer. | ||
/// This means that bit n is the sign bit, and bits n-1 to 0 are the integer value. | ||
/// If fewer than `width` qubits are provided, the remaining bits are assumed to be 0. | ||
/// For example, if qubit register `[q1, q2, q3]` is passed in, but the width is 5, | ||
/// the integer value will be measured as `[0, 0, q1, q2, q3]`, with the first 0 being | ||
/// the sign bit (positive). This is in contrast to the standard library `MeasureInteger`, | ||
/// which always measures unsigned integers up to and including 63 qubits in width. | ||
/// If the length of the qubit register passed in is greater than the width, this operation | ||
/// will throw an error. | ||
/// | ||
/// # Input | ||
/// ## target | ||
/// A qubit register representing the signed integer to be measured. | ||
/// | ||
/// ## width | ||
/// The width of the signed integer to be measured. | ||
operation MeasureSignedInteger(target : Qubit[], width : Int) : Int { | ||
let nBits = Length(target); | ||
Fact(nBits <= 64, $"`Length(target)` must be less than or equal to 64, but was {nBits}."); | ||
Fact(nBits <= width, $"`Length(target)` must be less than or equal to `width`, but was {nBits}."); | ||
Fact(nBits > 0, $"`width` must be greater than 0, but was {width}."); | ||
|
||
mutable coefficient = 1; | ||
let signBit = MResetZ(target[nBits - 1]); | ||
if (signBit == One) { | ||
Operations.Invert2sSI(target); | ||
set coefficient = -1; | ||
} | ||
|
||
mutable number = 0; | ||
for i in 0..nBits - 2 { | ||
if (MResetZ(target[i]) == One) { | ||
set number |||= 1 <<< i; | ||
} | ||
} | ||
|
||
ResetAll(target); | ||
|
||
number * coefficient | ||
} | ||
|
||
export MeasureSignedInteger; |
Oops, something went wrong.