public void PhaseStartTest()
        {
            var eigenvector = new Qubit(0, 1);
            var phaseTest   = PhaseEstimator.GatePhaseEstimatorStart(Gates.S, 2);
            var res         = phaseTest.Transform(new MultiQubit(new[]
            {
                Qubit.ClassicZero, Qubit.ClassicZero, // t register set to zero
                eigenvector
            }));

            // sanity check
            res.TwoNorm().Should().BeApproximately(1, AssertionHelpers.Precision);

            // hand calced
            var resArr = res.ToArray();

            resArr[0].ShouldBe(0);
            resArr[1].ShouldBe(0.5);
            resArr[2].ShouldBe(0);
            resArr[3].ShouldBe(0.5 * Complex.ImaginaryOne);
            resArr[4].ShouldBe(0);
            resArr[5].ShouldBe(-0.5);
            resArr[6].ShouldBe(0);
            resArr[7].ShouldBe(-0.5 * Complex.ImaginaryOne);
        }
        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 PhaseEstComplexity()
 {
     // complexity = (sum(2^n) from 0 to n) + n + n*(n+1) / 2
     // todo: add back swaps
     PhaseEstimator.GatePhaseEstimator(Gates.X, 2).NumGates.Should().Be(3 + 2 + 1 + 2 + 3 * 1);
     PhaseEstimator.GatePhaseEstimator(Gates.X, 3).NumGates.Should().Be(6 + 3 + 1 + 2 + 4 + 3 * 1);
     PhaseEstimator.GatePhaseEstimator(Gates.X, 4).NumGates.Should().Be(10 + 4 + 1 + 2 + 4 + 8 + 3 * 2);
     PhaseEstimator.GatePhaseEstimator(Gates.X, 5).NumGates.Should().Be(15 + 5 + 1 + 2 + 4 + 8 + 16 + 3 * 2);
 }
        public void PhaseTestTwo()
        {
            var eigenvector = new Qubit(ComplexExt.OneOverRootTwo, -ComplexExt.OneOverRootTwo);
            var phaseTest   = PhaseEstimator.GatePhaseEstimator(Gates.X, 4);
            var res         = phaseTest.Transform(new MultiQubit(new[]
            {
                // t register set to zero
                Qubit.ClassicZero, Qubit.ClassicZero, Qubit.ClassicZero, Qubit.ClassicZero,
                eigenvector,
            }));

            // sanity check
            res.TwoNorm().Should().BeApproximately(1, AssertionHelpers.Precision);

            // should be the same eigenvector
            res.TrueChance(4).Should().BeApproximately(0.5, AssertionHelpers.Precision);

            // eignenvalue is -1 -> i = e^(2pitheta) -> theta = 1/2
            res.TrueChance(0).Should().BeApproximately(1, AssertionHelpers.Precision); // 1/2 bit
            res.TrueChance(1).Should().BeApproximately(0, AssertionHelpers.Precision); // 1/4 bit
            res.TrueChance(2).Should().BeApproximately(0, AssertionHelpers.Precision); // 1/8 bit
            res.TrueChance(3).Should().BeApproximately(0, AssertionHelpers.Precision); // 1/16 bit
        }