Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit d7288cb

Browse files
committed
Extends #257 (fixing #256) to QuantumProcessorDispatcher sim as well
1 parent edc3ad2 commit d7288cb

File tree

3 files changed

+41
-34
lines changed

3 files changed

+41
-34
lines changed

src/Simulation/Common/Utils.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
// Licensed under the MIT License.
33

44
using Microsoft.Quantum.Simulation.Core;
5+
using System;
56
using System.Collections.Generic;
67
using System.Diagnostics;
78

89
namespace Microsoft.Quantum.Simulation.Common
910
{
10-
public class CommonUtils
11+
public static class CommonUtils
1112
{
1213
/// <summary>
1314
/// Removes PauliI terms from observable and corresponding qubits from qubits.
@@ -25,7 +26,7 @@ public static void PruneObservable(IQArray<Pauli> observable, IQArray<Qubit> qub
2526
/// <summary>
2627
/// Returns IEnumerable&lt;T&gt; that contains sub-sequence of <paramref name="sequenceToPrune"/>[i], such that <paramref name="sequence"/>[i] is not equal to <paramref name="value"/>.
2728
/// </summary>
28-
public static IEnumerable<T> PrunedSequence<U,T>(IQArray<U> sequence, U value, IQArray<T> sequenceToPrune )
29+
public static IEnumerable<T> PrunedSequence<U,T>(IQArray<U> sequence, U value, IQArray<T> sequenceToPrune)
2930
{
3031
for (uint i = 0; i < sequence.Length; ++i)
3132
{
@@ -63,5 +64,19 @@ public static (long, long) Reduce(long numerator, long denominatorPower)
6364

6465
return (numNew, denomPowerNew);
6566
}
67+
68+
public static IEnumerable<TResult> SelectAggregates<TSource, TResult>(
69+
this IEnumerable<TSource> source,
70+
Func<TResult, TSource, TResult> aggregate,
71+
TResult initial = default
72+
)
73+
{
74+
var acc = initial;
75+
foreach (var element in source)
76+
{
77+
acc = aggregate(acc, element);
78+
yield return acc;
79+
}
80+
}
6681
}
6782
}

src/Simulation/Simulators/QCTraceSimulator/InterfaceUtils.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,5 @@ public static partial class Extensions
7474
{
7575
return InterfaceType(t, typeof(IControllable<>));
7676
}
77-
78-
internal static IEnumerable<TResult> SelectAggregates<TSource, TResult>(
79-
this IEnumerable<TSource> source,
80-
Func<TResult, TSource, TResult> aggregate,
81-
TResult initial = default
82-
)
83-
{
84-
var acc = initial;
85-
foreach (var element in source)
86-
{
87-
acc = aggregate(acc, element);
88-
yield return acc;
89-
}
90-
}
9177
}
9278
}

src/Simulation/Simulators/QuantumProcessor/random.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,45 @@
33

44
using Microsoft.Quantum.Simulation.Core;
55
using System;
6+
using System.Linq;
7+
using Microsoft.Quantum.Simulation.Common;
68

79
namespace Microsoft.Quantum.Simulation.QuantumProcessor
810
{
911
public partial class QuantumProcessorDispatcher
1012
{
1113
public static long SampleDistribution(IQArray<double> unnormalizedDistribution, double uniformZeroOneSample)
1214
{
13-
double total = 0.0;
14-
foreach (double prob in unnormalizedDistribution)
15+
if (unnormalizedDistribution.Any(prob => prob < 0.0))
1516
{
16-
if (prob < 0)
17-
{
18-
throw new ExecutionFailException("Random expects array of non-negative doubles.");
19-
}
20-
total += prob;
17+
throw new ExecutionFailException("Random expects array of non-negative doubles.");
2118
}
2219

20+
var total = unnormalizedDistribution.Sum();
2321
if (total == 0)
2422
{
2523
throw new ExecutionFailException("Random expects array of non-negative doubles with positive sum.");
2624
}
2725

28-
double sample = uniformZeroOneSample * total;
29-
double sum = unnormalizedDistribution[0];
30-
for (int i = 0; i < unnormalizedDistribution.Length - 1; ++i)
31-
{
32-
if (sum >= sample)
33-
{
34-
return i;
35-
}
36-
sum += unnormalizedDistribution[i];
37-
}
38-
return unnormalizedDistribution.Length;
26+
var sample = uniformZeroOneSample * total;
27+
28+
return unnormalizedDistribution
29+
// Get the unnormalized CDF of the distribution.
30+
.SelectAggregates((double acc, double x) => acc + x)
31+
// Look for the first index at which the CDF is bigger
32+
// than the random sample of 𝑈(0, 1) that we were given
33+
// as a parameter.
34+
.Select((cumulativeProb, idx) => (cumulativeProb, idx))
35+
.Where(item => item.cumulativeProb >= sample)
36+
// Cast that index to long, and default to returning
37+
// the last item.
38+
.Select(
39+
item => (long)item.idx
40+
)
41+
.DefaultIfEmpty(
42+
unnormalizedDistribution.Length - 1
43+
)
44+
.First();
3945
}
4046

4147
public class QuantumProcessorDispatcherRandom : Quantum.Intrinsic.Random

0 commit comments

Comments
 (0)