예제 #1
0
        public IQuantumState Transform(IQuantumState input)
        {
            if (input.Dimension != 2 * InnerTransform.Dimension)
            {
                throw new ArgumentException(nameof(input));
            }

            var firstHalf = new Complex[Dimension / 2];
            var secHalf   = new Complex[Dimension / 2];

            for (long i = 0; i < Dimension; i++)
            {
                // first half of vector is just copied over as an identity
                if (i < Dimension / 2)
                {
                    firstHalf[i] = input.GetAmplitude(new ComputationalBasis(i, NumQubits));
                }
                else
                {
                    secHalf[i - (Dimension / 2)] = input.GetAmplitude(new ComputationalBasis(i, NumQubits));
                }
            }

            var transformedSecHalf = InnerTransform.Transform(new MultiQubit(secHalf));

            return(new MultiQubit(firstHalf.Concat(transformedSecHalf).ToArray()));
        }
예제 #2
0
 public IQuantumState Transform(IQuantumState input)
 {
     if (input.Dimension != 2)
     {
         throw new ArgumentException(nameof(input));
     }
     return(Transform(new Qubit(input.GetAmplitude("0"), input.GetAmplitude("1"))));
 }
예제 #3
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());
        }
예제 #4
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);
        }
예제 #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));
        }