microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
library/fixed_point/src/Reciprocal.qs
47lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | import Types.FixedPoint; |
| 5 | import Signed.Operations.ComputeReciprocalI, Signed.Operations.Invert2sSI; |
| 6 | import Std.Diagnostics.Fact; |
| 7 | import Std.Arrays.Tail, Std.Arrays.Zipped; |
| 8 | import Std.Math.Min; |
| 9 | |
| 10 | /// # Summary |
| 11 | /// Computes the reciprocal of a number stored in a quantum register with |
| 12 | /// the fixed-point representation. |
| 13 | /// |
| 14 | /// # Description |
| 15 | /// Given a register in the state $\ket{x}$ for a fixed-point number $x$, |
| 16 | /// computes the reciprocal $1 / x$ into the state of the `result` |
| 17 | /// register. |
| 18 | /// |
| 19 | /// # Input |
| 20 | /// ## x |
| 21 | /// Fixed-point number to be inverted. |
| 22 | /// ## result |
| 23 | /// Fixed-point number that will hold the result. Must be initialized to $\ket{0.0}$. |
| 24 | @Config(Unrestricted) |
| 25 | operation ComputeReciprocalFxP(x : FixedPoint, result : FixedPoint) : Unit is Adj { |
| 26 | body (...) { |
| 27 | Controlled ComputeReciprocalFxP([], (x, result)); |
| 28 | } |
| 29 | controlled (controls, ...) { |
| 30 | let (p, xs) = x!; |
| 31 | let (pRes, rs) = result!; |
| 32 | let n = Length(xs); |
| 33 | |
| 34 | Fact(p + pRes - 1 + n >= Length(rs), "Output register is too wide."); |
| 35 | use sign = Qubit(); |
| 36 | use tmpRes = Qubit[2 * n]; |
| 37 | CNOT(Tail(xs), sign); |
| 38 | (Controlled Invert2sSI)([sign], xs); |
| 39 | ComputeReciprocalI(xs, tmpRes); |
| 40 | (Controlled ApplyToEachCA)(controls, (CNOT, Zipped(tmpRes[p + pRes-1 + n-Length(rs)..Min([n + p + pRes, 2 * n-1])], rs))); |
| 41 | (Controlled Invert2sSI)([sign], ((rs))); |
| 42 | (Adjoint ComputeReciprocalI)(xs, tmpRes); |
| 43 | (Controlled Adjoint Invert2sSI)([sign], (xs)); |
| 44 | CNOT(Tail(xs), sign); |
| 45 | } |
| 46 | } |