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>");
        }
Exemple #5
0
        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));
        }