Esempio n. 1
0
        /// <summary>
        /// The probabilities of each possible register value indexed by that value.
        /// </summary>
        public static double[] GetDistribution(this IQuantumState state, Register reg)
        {
            int  regSize     = reg.QubitIndexes.Count();
            long maxRegValue = (long)Math.Pow(2, regSize);

            // probabilities indexed by register value
            double[] regProbabilities = new double[maxRegValue];
            // go through every probability
            for (long i = 0; i < state.Dimension; i++)
            {
                var basis = new ComputationalBasis(i, state.NumQubits());
                var amp   = state.GetAmplitude(basis);
                if (amp.Magnitude < ComplexExt.Precision)
                {
                    continue;
                }

                var labels         = basis.GetLabels();
                var registerLabels = new List <bool>();
                foreach (var index in reg.QubitIndexes)
                {
                    registerLabels.Add(labels[index]);
                }
                long regValue = ComputationalBasis.FromLabels(registerLabels.ToArray()).AmpIndex;
                regProbabilities[regValue] += amp.Magnitude * amp.Magnitude;
            }

            return(regProbabilities);
        }
Esempio n. 2
0
        public static string Print(this IQuantumState state, params Register[] registers)
        {
            var           test = state.ToArray().Where(b => b.Magnitude > ComplexExt.Precision);
            StringBuilder sb   = new StringBuilder();

            for (long i = 0; i < state.Dimension; i++)
            {
                var basis = new ComputationalBasis(i, state.NumQubits());
                var amp   = state.GetAmplitude(basis);
                if (amp.Magnitude < ComplexExt.Precision)
                {
                    continue;
                }
                sb.Append($"+{(amp.Imaginary == 0 ? amp.Real.ToString("F2") : amp.ToString("F2"))}");

                var labels = basis.GetLabels();
                foreach (var register in registers)
                {
                    var registerLabels = new List <bool>();
                    foreach (var index in register.QubitIndexes)
                    {
                        registerLabels.Add(labels[index]);
                    }
                    long regValue = ComputationalBasis.FromLabels(registerLabels.ToArray()).AmpIndex;
                    sb.Append($"|{regValue}>");
                }
            }
            return(sb.ToString());
        }
Esempio n. 3
0
        public void BasisTests()
        {
            var b1 = ComputationalBasis.FromLabels("101".ToBits());

            b1.AmpIndex.Should().Be(5);
            b1.GetLabels().Should().BeEquivalentTo("101".ToBits());

            var b2 = ComputationalBasis.FromLabels("001".ToBits());

            b2.AmpIndex.Should().Be(1);
            b2.GetLabels().Should().BeEquivalentTo("001".ToBits());

            var b3 = ComputationalBasis.FromLabels("1001".ToBits());

            b3.AmpIndex.Should().Be(9);
            b3.GetLabels().Should().BeEquivalentTo("1001".ToBits());

            var b4 = ComputationalBasis.FromLabels("00".ToBits());

            b4.AmpIndex.Should().Be(0);
            b4.GetLabels().Should().BeEquivalentTo("00".ToBits());
        }
Esempio n. 4
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));
        }