microsoft / qsharp

Azure Quantum Development Kit, including the Q# programming language, resource estimator, and Quantum Katas
https://microsoft.github.io/qsharp/
MIT License
423 stars 86 forks source link

Operations for state preparation #891

Open msoeken opened 9 months ago

msoeken commented 9 months ago

Is your feature request related to a problem? Please describe. Operations for uniform and arbitrary state preparation.

Describe the solution you'd like

Single-qubit state preparation and uniform state preparation:

/// # Summary
/// Prepares a single qubit `target` such the probability of being measured 0 is `p0 / (p0 + p1)`
/// and being measured 1 is `p1 / (p0 + p1)`
operation PrepareSingleQubit(p0 : Double, p1 : Double, target : Qubit) : Unit is Adj+Ctl {}

/// # Summary
/// Prepares a state on `qs` that has the same amplitude for the first `numStates` basis states
operation PrepareUniformSuperposition(numStates : Int, qs : Qubit[]) : Unit is Adj+Ctl {}

Arbitrary state preparation (requires UDT for garbage qubit initialization):

newtype PrepareArbitrarySuperposition = (
    /// Number of address qubits
    NIndexQubits: Int,
    /// Number of garbage qubits (depends on target error)
    NGarbageQubits: Int,
    /// Prepare operation with default Select operation
    Prepare: (Qubit[], Qubit[], Qubit[]) => Unit is Adj + Ctl,
    /// Prepare operation with custom Select operation
    PrepareWithSelect: ((Bool[][], Qubit[], Qubit[]) => Unit is Adj + Ctl, Qubit[], Qubit[], Qubit[]) => Unit is Adj + Ctl
);

function MakePrepareArbitrarySuperposition(targetError : Double, coefficients : Double[])
    : PrepareArbitrarySuperposition {}

function MakePrepareArbitrarySuperpositionWithData(targetError : Double, coefficients : Double[], data: Bool[][])
    : PrepareArbitrarySuperposition {}

Here are examples on how to use arbitrary state preparation:

let prepare = MakePrepareArbitrarySuperposition(0.001, [0.1, 0.2, 0.3]);

use address = Qubit[prepare::NIndexQubits];
use garbage = Qubit[prepare::NGarbageQubits];

prepare::Prepare(address, address, [], garbage);

Or when also preparing additional data with each coefficient:

let prepare = MakePrepareArbitrarySuperpositionWithData(0.001, [0.1, 0.2, 0.3], [[false, false], [true, true], [false, false]]);

use address = Qubit[prepare::NIndexQubits];
use data = Qubit[2];
use garbage = Qubit[prepare::NGarbageQubits];

prepare::Prepare(address, address, data, garbage);
sezna commented 1 month ago

Would stabilizing the state preparation code from the Unstable library solve this issue? If so, we should discuss that.

CC @DmitryVasilevsky @tcNickolas

tcNickolas commented 1 month ago

I'm all in favor of stabilizing our state preparation library! It is core functionality for a high-level language