Skip to content

Commit

Permalink
Port signed integer math to modern QDK (#1841)
Browse files Browse the repository at this point in the history
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
sezna and cesarzc authored Aug 22, 2024
1 parent 1700256 commit e7f02d6
Show file tree
Hide file tree
Showing 7 changed files with 592 additions and 0 deletions.
2 changes: 2 additions & 0 deletions library/signed/README.md
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.
21 changes: 21 additions & 0 deletions library/signed/qsharp.json
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"
]
}
29 changes: 29 additions & 0 deletions library/signed/src/Comparison.qs
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);
}
}
50 changes: 50 additions & 0 deletions library/signed/src/Measurement.qs
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;
Loading

0 comments on commit e7f02d6

Please sign in to comment.