public IDictionary <Register, long> Simulate(IQuantumState input) { DateTime start = DateTime.UtcNow; var res = transform.Transform(input); var ret = new Dictionary <Register, long>(); foreach (var reg in regs) { double[] probs = res.GetDistribution(reg); double randomDouble = randomSource.NextDouble(); double accum = 0; for (long regValue = 0; regValue < probs.LongLength; regValue++) { accum += probs[regValue]; if (accum > randomDouble) { ret[reg] = regValue; break; } } } GatesProcessed += transform.NumGates; Console.WriteLine($"Time elapsed: {DateTime.UtcNow - start}"); Console.WriteLine($"Gates processed: {transform.NumGates}"); return(ret); }
public void OrderFindTest() { long x = 2; long n = 3; int r = 2; // 2 ^ 2 = 3 + 1 int l = n.BitsCeiling(); int t = OrderFindingTransform.GetPercision(n); var regs = OrderFindingTransform.Registers(t, l).ToArray(); IUnitaryTransform orderfinder = OrderFindingTransform.Get(x, n, t); var regTwo = MultiQubit.BasisVector(1, l); var regOne = new MultiQubit(Enumerable.Range(0, t).Select(i => Qubit.ClassicZero).ToArray()); var input = new MultiQubit(regOne, regTwo); IQuantumState res = orderfinder.Transform(input); string inputStr = input.Print(regs); inputStr.Should().Be("+1.00|0>|1>"); string outStr = res.Print(regs); // all first register options evenly divide 2^t and reduce to fractiosn // with a denominator of r = 2 // in this case 0 and 32 over 2^6 equal 0 and 1/2 // therefore answer is 2 outStr.Should().Be("+0.50|0>|1>+0.50|0>|2>+0.50|32>|1>+-0.50|32>|2>"); }
public void PhaseHadamarTest() { long x = 2; long n = 3; int l = n.BitsCeiling(); int t = l;// OrderFindingTransform.GetPercision(n); var regs = OrderFindingTransform.Registers(t, l).ToArray(); IUnitaryTransform orderfinder = PhaseEstimator.GetPhaseHadamar(t, l); var regTwo = MultiQubit.BasisVector(1, l); var regOne = new MultiQubit(Enumerable.Range(0, t).Select(i => Qubit.ClassicZero).ToArray()); var input = new MultiQubit(regOne, regTwo); IQuantumState res = orderfinder.Transform(input); string inputStr = input.Print(regs); inputStr.Should().Be("+1.00|0>|1>"); string outStr = res.Print(regs); // first reg is unchanged, second reg is maximally mixed outStr.Should().Be("+0.50|0>|1>+0.50|1>|1>+0.50|2>|1>+0.50|3>|1>"); }
public void OrderStartTest() { long x = 2; long n = 3; int l = n.BitsCeiling(); int t = l;// OrderFindingTransform.GetPercision(n); var regs = OrderFindingTransform.Registers(t, l).ToArray(); IUnitaryTransform orderfinder = OrderFindingTransform.GetStart(x, n, t); var regTwo = MultiQubit.BasisVector(1, l); var regOne = new MultiQubit(Enumerable.Range(0, t).Select(i => Qubit.ClassicZero).ToArray()); var input = new MultiQubit(regOne, regTwo); IQuantumState res = orderfinder.Transform(input); string inputStr = input.Print(regs); inputStr.Should().Be("+1.00|0>|1>"); string outStr = res.Print(regs); outStr.Should().Be("+0.50|0>|1>+0.50|1>|2>+0.50|2>|1>+0.50|3>|2>"); }
public IQuantumState Transform(IQuantumState input) { if (transform.Dimension > input.Dimension) { throw new ArgumentException(nameof(transform.Dimension)); } var newAmps = new Complex[Dimension]; // foreach basis vector in the state for (long i = 0; i < Dimension; i++) { bool[] basis = new ComputationalBasis(i, NumQubits).GetLabels(); Complex origAmp = input.GetAmplitude(basis); // apply the subroutine to part of that basis IQuantumState res = transform.Transform( new MultiQubit( applyToQubitIndexes .Select(index => basis[index] ? Qubit.ClassicOne : Qubit.ClassicZero) .ToArray())); // redistribute the result to every possible basis for (long j = 0; j < transform.Dimension; j++) { bool[] subRoutineBasis = new ComputationalBasis(j, transform.NumQubits).GetLabels(); Complex amp = res.GetAmplitude(subRoutineBasis); for (int indexIndex = 0; indexIndex < transform.NumQubits; indexIndex++) { int qubitIndex = applyToQubitIndexes[indexIndex]; basis[qubitIndex] = subRoutineBasis[indexIndex]; } long ampIndex = ComputationalBasis.FromLabels(basis).AmpIndex; newAmps[ampIndex] += origAmp * amp; } } // weirder return(new MultiQubit(newAmps)); }