Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/Simulation/QSharpFoundation/Diagnostics/AssertAllZero.qs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// - AssertQubit
operation AssertAllZero (qubits : Qubit[]) : Unit {
body (...) {
for (qubit in qubits) {
for qubit in qubits {
AssertQubit(Zero, qubit);
}
}
Expand All @@ -40,9 +40,8 @@ namespace Microsoft.Quantum.Diagnostics {
/// # See Also
/// - AssertQubitWithinTolerance
operation AssertAllZeroWithinTolerance(qubits : Qubit[], tolerance : Double) : Unit {

body (...) {
for (qubit in qubits) {
for qubit in qubits {
AssertQubitWithinTolerance(Zero, qubit, tolerance);
}
}
Expand Down
24 changes: 24 additions & 0 deletions src/Simulation/QSharpFoundation/Diagnostics/Facts.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.Diagnostics {
open Microsoft.Quantum.Math;

/// # Summary
/// Declares that a classical condition is true.
Expand Down Expand Up @@ -48,4 +49,27 @@ namespace Microsoft.Quantum.Diagnostics {
if (actual) { fail message; }
}

/// # Summary
/// Declares that a given floating-point value represents a finite
/// number, failing when this is not the case.
///
/// # Input
/// ## d
/// The floating-point value that is to be checked.
/// ## message
/// Failure message to be printed in the case that `d` is either
/// not finite, or not a number.
///
/// # Example
/// The following Q# code will fail when run:
/// ```qsharp
/// FiniteFact(NaN(), "NaN is not a finite number.");
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Diagnostics.Fact
function FiniteFact(d : Double, message : String) : Unit {
Fact(IsFinite(d), message);
}

}
116 changes: 116 additions & 0 deletions src/Simulation/QSharpFoundation/Math/FloatingPoint.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Quantum.Math {

/// # Summary
/// Returns a value that is not a number (i.e. NaN).
///
/// # Ouputs
/// A double-precision floating point value that is not a number.
///
/// # Remarks
/// The value output by this function follows IEEE 754 rules for how `NaN`
/// works when used with other double-precision floating point values.
/// For example, for any value `x` of type `Double`, `NaN() == x` is
/// `false`; this holds even if `x` is also `NaN()`.
///
/// # See Also
/// - Microsoft.Quantum.Math.IsNaN
/// - Microsoft.Quantum.Math.IsInfinite
/// - Microsoft.Quantum.Math.IsFinite
function NaN() : Double {
return 0.0 / 0.0;
}

/// # Summary
/// Returns whether a given floating-point value is not a number (i.e.
/// is NaN).
///
/// # Input
/// ## d
/// A floating-point value to be checked.
///
/// # Output
/// `true` if and only if `d` is not a number.
///
/// # Remarks
/// Since `NaN()` is the only floating-point value that does not equal
/// itself, this function should be used instead of checking conditions such
/// as `d == NaN()`.
///
/// # See Also
/// - Microsoft.Quantum.Math.NaN
/// - Microsoft.Quantum.Math.IsInfinite
/// - Microsoft.Quantum.Math.IsFinite
function IsNaN(d : Double) : Bool {
return d != d;
}

/// # Summary
/// Returns whether a given floating-point value is either positive or
/// negative infinity.
///
/// # Input
/// ## d
/// The floating-point value to be checked.
///
/// # Ouput
/// `true` if and only if `d` is either positive or negative infinity.
///
/// # Remarks
/// `NaN()` is not a number, and is thus neither a finite number nor
/// is it infinite. As such, both `IsInfinite(NaN())` and `IsFinite(NaN())`
/// return `false`. To check a value against `NaN()`, use `IsNaN(d)`.
///
///
/// Note that even though this function returns `true` for both
/// positive and negative infinities, these values can still be
/// discriminated by checking `d > 0.0` and `d < 0.0`.
///
/// # Example
/// ```qsharp
/// Message($"{IsInfinite(42.0)}"); // false
/// Message($"{IsInfinite(NaN())}"); // false
/// Message($"{IsInfinite(-1.0 / 0.0}"); // true
///
/// # See Also
/// - Microsoft.Quantum.Math.NaN
/// - Microsoft.Quantum.Math.IsNaN
/// - Microsoft.Quantum.Math.IsFinite
/// ```
function IsInfinite(d : Double) : Bool {
return d == 1.0 / 0.0 or d == -1.0 / 0.0;
}

/// # Summary
/// Returns whether a given floating-point value is a finite number.
///
/// # Input
/// ## d
/// The floating-point value to be checked.
///
/// # Ouput
/// `true` if and only if `d` is a finite number (i.e.: is neither infinite
/// nor NaN).
///
/// # Remarks
/// `NaN()` is not a number, and is thus neither a finite number nor
/// is it infinite. As such, both `IsInfinite(NaN())` and `IsFinite(NaN())`
/// return `false`. To check a value against `NaN()`, use `IsNaN(d)`.
///
/// # Example
/// ```qsharp
/// Message($"{IsFinite(42.0)}"); // true
/// Message($"{IsFinite(NaN())}"); // false
/// Message($"{IsFinite(-1.0 / 0.0)}"); // false
///
/// # See Also
/// - Microsoft.Quantum.Math.NaN
/// - Microsoft.Quantum.Math.IsNaN
/// - Microsoft.Quantum.Math.IsInfinite
/// ```
function IsFinite(d : Double) : Bool {
return not IsInfinite(d) and not IsNaN(d);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,39 @@ namespace Microsoft.Quantum.Tests {
EqualityFactL(ModPowL(8675309L, 5792L, 2345678L), 1936199L, "ModPowL(8675309L, 5792L, 2345678L) was incorrect.");
}

@Test("QuantumSimulator")
function NaNIsNotEqualToAnything() : Unit {
Contradiction(NaN() == NaN(), "NaN should not equal NaN.");
Contradiction(NaN() == 42.0, "NaN should not equal any finite number.");
Contradiction(NaN() == 1.0 / 0.0, "NaN should not equal any infinite value.");
}

@Test("QuantumSimulator")
function NaNIsNaN() : Unit {
Fact(IsNaN(NaN()), "NaN was not NaN.");
Contradiction(IsNaN(42.0), "42.0 should not be NaN.");
Contradiction(IsNaN(1.0 / 0.0), "+∞ should not be NaN.");
}

@Test("QuantumSimulator")
function InfinityIsInfinite() : Unit {
Contradiction(IsInfinite(NaN()), "NaN should not be infinite.");
Contradiction(IsInfinite(42.0), "42.0 should not be infinite.");
Fact(IsInfinite(1.0 / 0.0), "+∞ should be infinite.");
Fact(IsInfinite(-1.0 / 0.0), "-∞ should be infinite.");
}

@Test("QuantumSimulator")
function FiniteNumbersAreFinite() : Unit {
Contradiction(IsFinite(NaN()), "NaN should not be finite.");
Fact(IsFinite(42.0), "42.0 should be finite.");
Contradiction(IsFinite(1.0 / 0.0), "+∞ should not be finite.");
Contradiction(IsFinite(-1.0 / 0.0), "-∞ should not be finite.");
}

@Test("QuantumSimulator")
function FiniteFactIsCorrect() : Unit {
FiniteFact(42.0, "42.0 should be finite.");
}

}