Q 샤프

Q 샤프(Q#)는 양자 알고리즘을 표현하기 위해 사용되는 도메인 특화 언어이다. 양자 개발 키트의 일부로서 마이크로소프트가 처음 공개하였다.

**예시**
다음의 소스 코드는 공식 마이크로소프트 Q# 라이브러리 저장소에서 가져온 멀티플렉서이다.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.Quantum.Canon {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Arithmetic;
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;
/// # Summary
/// Applies a multiply-controlled unitary operation $U$ that applies a
/// unitary $V_j$ when controlled by n-qubit number state $\ket{j}$.
///
/// $U = \sum^{N-1}_{j=0}\ket{j}\bra{j}\otimes V_j$.
///
/// # Input
/// ## unitaryGenerator
/// A tuple where the first element `Int` is the number of unitaries $N$,
/// and the second element `(Int -> ('T => () is Adj + Ctl))`
/// is a function that takes an integer $j$ in $0,N-1$ and outputs the unitary
/// operation $V_j$.
///
/// ## index
/// $n$-qubit control register that encodes number states $\ket{j}$ in
/// little-endian format.
///
/// ## target
/// Generic qubit register that $V_j$ acts on.
///
/// # Remarks
/// `coefficients` will be padded with identity elements if
/// fewer than $2^n$ are specified. This implementation uses
/// $n-1$ auxiliary qubits.
///
/// # References
/// -  *Andrew M. Childs, Dmitri Maslov, Yunseong Nam, Neil J. Ross, Yuan Su*,
///      arXiv:1711.10980(https://arxiv.org/abs/1711.10980)
operation MultiplexOperationsFromGenerator(unitaryGenerator : (Int, (Int -> ('T => Unit is Adj + Ctl))), index: LittleEndian, target: 'T) : Unit is Ctl + Adj {
let (nUnitaries, unitaryFunction) = unitaryGenerator;
let unitaryGeneratorWithOffset = (nUnitaries, 0, unitaryFunction);
if Length(index!) == 0 {
fail "MultiplexOperations failed. Number of index qubits must be greater than 0.";
}
if nUnitaries > 0 {
let auxiliary = ;
Adjoint MultiplexOperationsFromGeneratorImpl(unitaryGeneratorWithOffset, auxiliary, index, target);
}
}
/// # Summary
/// Implementation step of `MultiplexOperationsFromGenerator`.
/// # See Also
/// - Microsoft.Quantum.Canon.MultiplexOperationsFromGenerator
internal operation MultiplexOperationsFromGeneratorImpl(unitaryGenerator : (Int, Int, (Int -> ('T => Unit is Adj + Ctl))), auxiliary: Qubit, index: LittleEndian, target: 'T)
: Unit {
body (...) {
let nIndex = Length(index!);
let nStates = 2^nIndex;
let (nUnitaries, unitaryOffset, unitaryFunction) = unitaryGenerator;
let nUnitariesLeft = MinI(nUnitaries, nStates / 2);
let nUnitariesRight = MinI(nUnitaries, nStates);
let leftUnitaries = (nUnitariesLeft, unitaryOffset, unitaryFunction);
let rightUnitaries = (nUnitariesRight - nUnitariesLeft, unitaryOffset + nUnitariesLeft, unitaryFunction);
let newControls = LittleEndian(Most(index!));
if nUnitaries > 0 {
if Length(auxiliary) == 1 and nIndex == 0 {
// Termination case
(Controlled Adjoint (unitaryFunction(unitaryOffset)))(auxiliary, target);
} elif Length(auxiliary) == 0 and nIndex >= 1 {
// Start case
let newauxiliary = Tail(index!);
if nUnitariesRight > 0 {
MultiplexOperationsFromGeneratorImpl(rightUnitaries, newauxiliary, newControls, target);
}
within {
X(newauxiliary);
} apply {
MultiplexOperationsFromGeneratorImpl(leftUnitaries, newauxiliary, newControls, target);
}
} else {
// Recursion that reduces nIndex by 1 and sets Length(auxiliary) to 1.
let controls = Tail(index!) + auxiliary;
use newauxiliary = Qubit();
use andauxiliary = QubitMaxI(0, Length(controls) - 2);
within {
ApplyAndChain(andauxiliary, controls, newauxiliary);
} apply {
if nUnitariesRight > 0 {
MultiplexOperationsFromGeneratorImpl(rightUnitaries, newauxiliary, newControls, target);
}
within {
(Controlled X)(auxiliary, newauxiliary);
} apply {
MultiplexOperationsFromGeneratorImpl(leftUnitaries, newauxiliary, newControls, target);
}
}
}
}
}
adjoint auto;
controlled (controlRegister, ...) {
MultiplexOperationsFromGeneratorImpl(unitaryGenerator, auxiliary + controlRegister, index, target);
}
adjoint controlled auto;
}
/// # Summary
/// Applies multiply-controlled unitary operation $U$ that applies a
/// unitary $V_j$ when controlled by n-qubit number state $\ket{j}$.
///
/// $U = \sum^{N-1}_{j=0}\ket{j}\bra{j}\otimes V_j$.
///
/// # Input
/// ## unitaryGenerator
/// A tuple where the first element `Int` is the number of unitaries $N$,
/// and the second element `(Int -> ('T => () is Adj + Ctl))`
/// is a function that takes an integer $j$ in $0,N-1$ and outputs the unitary
/// operation $V_j$.
///
/// ## index
/// $n$-qubit control register that encodes number states $\ket{j}$ in
/// little-endian format.
///
/// ## target
/// Generic qubit register that $V_j$ acts on.
///
/// # Remarks
/// `coefficients` will be padded with identity elements if
/// fewer than $2^n$ are specified. This version is implemented
/// directly by looping through n-controlled unitary operators.
operation MultiplexOperationsBruteForceFromGenerator(unitaryGenerator : (Int, (Int -> ('T => Unit is Adj + Ctl))), index: LittleEndian, target: 'T)
: Unit is Adj + Ctl {
let nIndex = Length(index!);
let nStates = 2^nIndex;
let (nUnitaries, unitaryFunction) = unitaryGenerator;
for idxOp in 0..MinI(nStates,nUnitaries) - 1 {
(ControlledOnInt(idxOp, unitaryFunction(idxOp)))(index!, target);
}
}
/// # Summary
/// Returns a multiply-controlled unitary operation $U$ that applies a
/// unitary $V_j$ when controlled by n-qubit number state $\ket{j}$.
///
/// $U = \sum^{2^n-1}_{j=0}\ket{j}\bra{j}\otimes V_j$.
///
/// # Input
/// ## unitaryGenerator
/// A tuple where the first element `Int` is the number of unitaries $N$,
/// and the second element `(Int -> ('T => () is Adj + Ctl))`
/// is a function that takes an integer $j$ in $0,N-1$ and outputs the unitary
/// operation $V_j$.
///
/// # Output
/// A multiply-controlled unitary operation $U$ that applies unitaries
/// described by `unitaryGenerator`.
///
/// # See Also
/// - Microsoft.Quantum.Canon.MultiplexOperationsFromGenerator
function MultiplexerFromGenerator(unitaryGenerator : (Int, (Int -> (Qubit => Unit is Adj + Ctl)))) : ((LittleEndian, Qubit) => Unit is Adj + Ctl) {
return MultiplexOperationsFromGenerator(unitaryGenerator, _, _);
}
/// # Summary
/// Returns a multiply-controlled unitary operation $U$ that applies a
/// unitary $V_j$ when controlled by n-qubit number state $\ket{j}$.
///
/// $U = \sum^{2^n-1}_{j=0}\ket{j}\bra{j}\otimes V_j$.
///
/// # Input
/// ## unitaryGenerator
/// A tuple where the first element `Int` is the number of unitaries $N$,
/// and the second element `(Int -> ('T => () is Adj + Ctl))`
/// is a function that takes an integer $j$ in $0,N-1$ and outputs the unitary
/// operation $V_j$.
///
/// # Output
/// A multiply-controlled unitary operation $U$ that applies unitaries
/// described by `unitaryGenerator`.
///
/// # See Also
/// - Microsoft.Quantum.Canon.MultiplexOperationsBruteForceFromGenerator
function MultiplexerBruteForceFromGenerator(unitaryGenerator : (Int, (Int -> (Qubit => Unit is Adj + Ctl)))) : ((LittleEndian, Qubit) => Unit is Adj + Ctl) {
return MultiplexOperationsBruteForceFromGenerator(unitaryGenerator, _, _);
}
/// # Summary
/// Computes a chain of AND gates
///
/// # Description
/// The auxiliary qubits to compute temporary results must be specified explicitly.
/// The length of that register is `Length(ctrlRegister) - 2`, if there are at least
/// two controls, otherwise the length is 0.
internal operation ApplyAndChain(auxRegister : Qubit, ctrlRegister : Qubit, target : Qubit)
: Unit is Adj {
if Length(ctrlRegister) == 0 {
X(target);
} elif Length(ctrlRegister) == 1 {
CNOT(Head(ctrlRegister), target);
} else {
EqualityFactI(Length(auxRegister), Length(ctrlRegister) - 2, "Unexpected number of auxiliary qubits");
let controls1 = ctrlRegister0..0 + auxRegister;
let controls2 = Rest(ctrlRegister);
let targets = auxRegister + target;
ApplyToEachA(ApplyAnd, Zipped3(controls1, controls2, targets));
}
}
}

**각주**

**외부 링크**
qsharp-language
분류:자유-오픈 소스 소프트웨어
분류:마이크로소프트의 자유 소프트웨어
분류:MIT 라이선스 소프트웨어
분류:마이크로소프트의 프로그래밍 언어