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
17 changes: 17 additions & 0 deletions Standard/src/Canon/Enumeration/Deprecated.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Quantum.Canon {

@Deprecated("Microsoft.Quantum.Canon.DecomposedIntoTimeStepsCA")
function DecomposeIntoTimeStepsCA<'T>(
(nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)),
trotterOrder : Int
)
: ((Double, 'T) => Unit is Adj + Ctl) {
return DecomposedIntoTimeStepsCA((nSteps, op), trotterOrder);
}

}


99 changes: 67 additions & 32 deletions Standard/src/Canon/Enumeration/Trotter.qs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ namespace Microsoft.Quantum.Canon {
/// op(0, deltaT, target);
/// op(1, deltaT, target);
/// ```
/// and
/// ```qsharp
/// and
/// ```qsharp
/// _Trotter1ImplCA((2, op), deltaT, target);
/// ```
operation _Trotter1ImplCA<'T> ((nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T) : Unit is Adj + Ctl {
for (idx in 0 .. nSteps - 1)
{
for (idx in 0 .. nSteps - 1) {
op(idx, stepSize, target);
}
}
Expand Down Expand Up @@ -71,17 +70,19 @@ namespace Microsoft.Quantum.Canon {
/// op(1, deltaT / 2.0, target);
/// op(0, deltaT / 2.0, target);
/// ```
/// and
/// ```qsharp
/// and
/// ```qsharp
/// _Trotter2ImplCA((2, op), deltaT, target);
/// ```
operation _Trotter2ImplCA<'T> ((nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T) : Unit is Adj + Ctl
{
for (idx in 0 .. nSteps - 1)
{
operation _Trotter2ImplCA<'T>(
(nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)),
stepSize : Double, target : 'T
)
: Unit is Adj + Ctl {
for (idx in 0 .. nSteps - 1) {
op(idx, stepSize * 0.5, target);
}

for (idx in nSteps - 1 .. -1 .. 0)
{
op(idx, stepSize * 0.5, target);
Expand All @@ -108,16 +109,20 @@ namespace Microsoft.Quantum.Canon {
/// Multiplier on size of each step of the simulation.
/// ## target
/// A quantum register on which the operations act.
operation _TrotterArbitraryImplCA<'T> (order:Int, (nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T)
operation _TrotterArbitraryImplCA<'T>(
order : Int,
(nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)),
stepSize : Double, target : 'T
)
: Unit is Adj + Ctl {
if (order > 2) {
let stepSizeOuter = _TrotterStepSize(order);
let stepSizeInner = 1.0 - 4.0 * stepSizeOuter;
_TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeInner * stepSize, target);
_TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order - 2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order - 2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order - 2, (nSteps, op), stepSizeInner * stepSize, target);
_TrotterArbitraryImplCA(order - 2, (nSteps, op), stepSizeOuter * stepSize, target);
_TrotterArbitraryImplCA(order - 2, (nSteps, op), stepSizeOuter * stepSize, target);
} elif (order == 2) {
_Trotter2ImplCA((nSteps, op), stepSize, target);
} else {
Expand All @@ -128,7 +133,13 @@ namespace Microsoft.Quantum.Canon {
/// # Summary
/// Computes Trotter step size in recursive implementation of
/// Trotter simulation algorithm.
function _TrotterStepSize (order: Int) : Double {
///
/// # Remarks
/// This operation uses a different indexing convention than that of
/// [quant-ph/0508139](https://arxiv.org/abs/quant-ph/0508139). In
/// particular, `DecomposedIntoTimeStepsCA(_, 4)` corresponds to the
/// scalar $p_2(\lambda)$ in quant-ph/0508139.
function _TrotterStepSize(order : Int) : Double {
return 1.0 / (4.0 - PowD(4.0, 1.0 / (IntAsDouble(order) - 1.0)));
}

Expand All @@ -150,31 +161,55 @@ namespace Microsoft.Quantum.Canon {
/// input (type `Double`) for decomposition.
/// ## trotterOrder
/// Selects the order of the Trotter–Suzuki integrator to be used.
/// Order 1 and even orders 2,4,6,... are currently supported.
/// Order 1 and even orders 2, 4, 6,... are currently supported.
///
/// # Output
/// Returns a unitary implementing the Trotter–Suzuki integrator, where
/// the first parameter `Double` is the integration step size, and the
/// second parameter is the target acted upon.
///
/// # Remarks
/// When called with `order` equal to `1`, this function returns an operation
/// that can be simulated by the lowest-order Trotter–Suzuki integrator
/// $$
/// \begin{align}
/// S_1(\lambda) = \prod_{j = 1}^{m} e^{H_j \lambda},
/// \end{align}
/// $$
/// where we have followed the notation of
/// [quant-ph/0508139](https://arxiv.org/abs/quant-ph/0508139)
/// and let $\lambda$ be the evolution time (represented by the first input
/// of the returned operation), and have let $\{H_j\}_{j = 1}^{m}$ be the
/// set of (skew-Hermitian) dynamical generators being integrated such that
/// `op(j, lambda, _)` is simulated by the unitary operator
/// $e^{H_j \lambda}$.
///
/// Similarly, an `order` of `2` returns the second-order symmetric
/// Trotter–Suzuki integrator
/// $$
/// \begin{align}
/// S_2(\lambda) = \prod_{j = 1}^{m} e^{H_k \lambda / 2}
/// \prod_{j' = m}^{1} e^{H_{j'} \lambda / 2}.
/// \end{align}
/// $$
///
/// Higher even values of `order` are implemented using the recursive
/// construction of [quant-ph/0508139](https://arxiv.org/abs/quant-ph/0508139).
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecomposedIntoTimeStepsCA(_, 4) actually corresponds to $S_4(\lambda)$ in quant-ph/0508139.

The difference in indexing occurs in the definition of _TrotterStepSize(order: Int).

Whereas we set let stepSizeOuter = _TrotterStepSize(order); in the implementation of _TrotterArbitraryImplCA<'T>, they define the function _AlternateStepSize(order: Int) such that our stepSizeOuter is equal to _AlternateStepSize(order/2).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, my apologies for misunderstanding where the index convention differed. I'll fix that, then.

/// # References
/// We use the implementation in
/// - [ *D. W. Berry, G. Ahokas, R. Cleve, B. C. Sanders* ](https://arxiv.org/abs/quant-ph/0508139)
function DecomposeIntoTimeStepsCA<'T> ((nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), trotterOrder : Int) : ((Double, 'T) => Unit is Adj + Ctl)
{
if (trotterOrder == 1)
{
function DecomposedIntoTimeStepsCA<'T>(
(nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)),
trotterOrder : Int
)
: ((Double, 'T) => Unit is Adj + Ctl) {
if (trotterOrder == 1) {
return _Trotter1ImplCA((nSteps, op), _, _);
}
elif (trotterOrder == 2)
{
} elif (trotterOrder == 2) {
return _Trotter2ImplCA((nSteps, op), _, _);
}
elif(trotterOrder % 2 ==0){
} elif(trotterOrder % 2 == 0) {
return _TrotterArbitraryImplCA(trotterOrder, (nSteps, op), _, _);
}
else
{
} else {
fail $"Odd order {trotterOrder} not yet supported.";
}
}
Expand Down