Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Implements fixed-point conversion functions (#575)
Browse files Browse the repository at this point in the history
* Implements #559.

* Apply suggestions from code review

Co-authored-by: Mariia Mykhailova <mamykhai@microsoft.com>

* Use new UDT fields.

Co-authored-by: Mariia Mykhailova <mamykhai@microsoft.com>
  • Loading branch information
msoeken and tcNickolas authored Apr 22, 2022
1 parent 3536d35 commit a084a1f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 27 deletions.
54 changes: 51 additions & 3 deletions Numerics/src/FixedPoint/Convert.qs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,66 @@ namespace Microsoft.Quantum.Convert {
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Math;

/// # 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.
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 = PowD(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 integerBits (including the sign big)
/// Assumed number of integer bits (including the sign bit).
/// ## bits
/// Bit-string representation of approximated number
internal function BoolArrayAsFixedPoint(integerBits : Int, bits : Bool[]) : Double {
/// Bit-string representation of approximated number.
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) / PowD(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.
function DoubleAsFixedPoint(integerBits : Int, fractionalBits : Int, value : Double) : Double {
return BoolArrayAsFixedPoint(integerBits, FixedPointAsBoolArray(integerBits, fractionalBits, value));
}

}
28 changes: 4 additions & 24 deletions Numerics/src/FixedPoint/Init.qs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

namespace Microsoft.Quantum.Arithmetic {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Math;
Expand All @@ -16,28 +17,7 @@ namespace Microsoft.Quantum.Arithmetic {
/// Fixed-point number (of type FixedPoint) to initialize.
operation PrepareFxP(constant : Double, fp : FixedPoint)
: Unit is Adj + Ctl {
// NB: We can't omit the body (...) declaration here, as the `set`
// statements below prevent automatic adjoint generation.
body (...) {
let n = Length(fp::Register);
let sign = constant < 0.;
mutable rescaledConstant = PowD(2., IntAsDouble(n - fp::IntegerBits)) * AbsD(constant) + 0.5;
mutable keepAdding = sign;
for i in 0..n - 1 {
let intConstant = Floor(rescaledConstant);
set rescaledConstant = 0.5 * rescaledConstant;
mutable currentBit = (intConstant &&& 1) == (sign ? 0 | 1);
if keepAdding {
set keepAdding = currentBit;
set currentBit = not currentBit;
}
if currentBit {
X(fp::Register[i]);
}
}
}
controlled auto;
adjoint self;
adjoint controlled auto;
let bits = FixedPointAsBoolArray(fp::IntegerBits, Length(fp::Register) - fp::IntegerBits, constant);
ApplyPauliFromBitString(PauliX, true, bits, fp::Register);
}
}
}

0 comments on commit a084a1f

Please sign in to comment.