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()); }
/// <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); }
public Complex GetAmplitude(ComputationalBasis basis) { switch (basis.AmpIndex) { case 0: return(AmpZero); case 1: return(AmpOne); default: throw new ArgumentOutOfRangeException(nameof(basis)); } }
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()); }
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)); }