// register x - initially loaded with x // register N - initially loaded with N // control - control bit // other registers - initially 0 // after computation register B changes and contains: [(a*x) mod N] // Insecure version: registers widths etc. are not checked public static void CMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { ulong power2 = 1; for (int i = 0; i < x.Width; i++, power2 *= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // adding [(2^i * a) + B] modulo N comp.AddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } // if control == 0 // then B register contains still 0 // so we copy X register into B register comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); }
public static void AddModuloQFTPhi(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register b, params RegisterRef[] controls) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, ctrl, b, controls }; comp.AddParametricGate("AddModuloQFTPhi", parameters); return; } else { comp.Group = true; } comp.AddQFTPhi(a, b, controls); comp.InverseAddQFTPhi(N, b); comp.InverseQFT(b); comp.CNot(ctrl, b[b.Width - 1]); comp.QFT(b); comp.AddQFTPhi(N, b, ctrl); comp.InverseAddQFTPhi(a, b, controls); comp.InverseQFT(b); comp.SigmaX(b[b.Width - 1]); comp.CNot(ctrl, b[b.Width - 1]); comp.SigmaX(b[b.Width - 1]); comp.QFT(b); comp.AddQFTPhi(a, b, controls); }
// register A - initially loaded with a // register B - initially loaded with b // register C - initially 0, exactly one bit wider than A, stores overflow bit // register N - initially loaded with N // after computation in register B: (a+b) mod N // other registers dont change their states // register B must be exactly one bit wider than A to store carry bit // register B must be exactly one bit wider than N to store carry bit // registers A, N must be the same length // Insecure version: registers widths etc. are not checked public static void AddModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, ulong valueN) { RegisterRef carry = b[b.Width - 1]; RegisterRef overflow = c[c.Width - 1]; comp.Add(a, b, c); comp.InverseAdd(N, b, c); comp.SigmaX(carry); comp.CNot(overflow, carry); comp.SigmaX(carry); //resetting N comp.LoadNumber(N, valueN, overflow); comp.Add(N, b, c); // now we have [(a+b) mod N] in B register // next steps lead to recover the initial state of registers N and overflow bit //setting N back comp.LoadNumber(N, valueN, overflow); comp.InverseAdd(a, b, c); comp.CNot(overflow, carry); comp.Add(a, b, c); }
// register x - initially loaded with x // register b - initially loaded with 0 // after computation register b changes and contains: [(a*x) mod N] // Secure version: throws Exceptions if arguments are invalid public static void CMultModulo( this QuantumComputer comp, Register x, Register b, RegisterRef control, ulong valueA, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, x, b, control, valueA, valueN }; comp.AddParametricGate("CMultModulo", parameters); return; } else { comp.Group = true; } Validate(x, b, valueN); Register a = comp.NewRegister(0, x.Width - 1); Register c = comp.NewRegister(0, x.Width); Register N = comp.NewRegister(valueN, x.Width - 1); comp.CMultModulo(a, b, c, N, x, control, valueA, valueN); comp.DeleteRegister(ref N); comp.DeleteRegister(ref c); comp.DeleteRegister(ref a); }
public static void InverseAddModuloQFT(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register b, params RegisterRef[] controls) { Validate(a, b, N); comp.QFT(b); comp.InverseAddModuloQFTPhi(a, N, ctrl, b, controls); comp.InverseQFT(b); }
// Insecure version: registers widths etc. are not checked public static void InverseAddModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, ulong valueN) { RegisterRef carry = b[b.Width - 1]; RegisterRef overflow = c[c.Width - 1]; comp.InverseAdd(a, b, c); comp.CNot(overflow, carry); comp.Add(a, b, c); //resetting N: comp.LoadNumber(N, valueN, overflow); comp.InverseAdd(N, b, c); //setting N back: comp.LoadNumber(N, valueN, overflow); comp.SigmaX(carry); comp.CNot(overflow, carry); comp.SigmaX(carry); comp.Add(N, b, c); comp.InverseAdd(a, b, c); }
public static void ControlledUaGate(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register x, Register reg0, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, ctrl, x, reg0, control }; comp.AddParametricGate("ControlledUaGate", parameters); return; } else { comp.Group = true; } Validate(x, N); int? invA = Quantum.Utils.InversionModulo((int)a, (int)N); if (invA == null) { throw new ArgumentException("No inversion for specified a = " + a); } comp.MultModuloQFT(a, N, ctrl, x, reg0, control); comp.Swap(x, reg0, control); comp.InverseMultModuloQFT((ulong)invA, N, ctrl, x, reg0, control); }
public static void Swap(this QuantumComputer comp, Register r1, Register r2, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, r1, r2, control }; comp.AddParametricGate("Swap", parameters); return; } else { comp.Group = true; } Validate(r1, r2); Register root = comp.GetRootRegister(r1, r2, control); int target1 = r1.OffsetToRoot; int target2 = r2.OffsetToRoot; int ctrl = control.OffsetToRoot; for (int i = 0; i < r1.Width; i++) { //comp.Toffoli(root[target1 + i], root[target2 + i], root[ctrl]); //comp.Toffoli(root[target2 + i], root[target1 + i], root[ctrl]); //comp.Toffoli(root[target1 + i], root[target2 + i], root[ctrl]); root.Toffoli(target1 + i, target2 + i, ctrl); root.Toffoli(target2 + i, target1 + i, ctrl); root.Toffoli(target1 + i, target2 + i, ctrl); } }
public static void AddModuloQFT(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register b, params RegisterRef[] controls) { Validate(a, b, N); comp.QFT(b); comp.AddModuloQFTPhi(a, N, ctrl, b, controls); comp.InverseQFT(b); }
public static void CNot(this QuantumComputer comp, RegisterRef target, RegisterRef control) { Register root = comp.GetRootRegister(control, target); int c = control.OffsetToRoot; int t = target.OffsetToRoot; root.CNot(t, c); }
/// <summary> /// Swaps the values of two given qubits. /// </summary> /// <param name="comp">The <see cref="Quantum.QuantumComputer"/> instance.</param> /// <param name="r1">The reference to the first swapped qubit.</param> /// <param name="r2">The reference to the second swapped qubit.</param> public static void Swap(this QuantumComputer comp, RegisterRef r1, RegisterRef r2) { Register root = comp.GetRootRegister(r1, r2); int target1 = r1.OffsetToRoot; int target2 = r2.OffsetToRoot; root.CNot(target1, target2); root.CNot(target2, target1); root.CNot(target1, target2); }
/// <summary> /// Computes the least significant bit of sum of two given bits. /// Used with <see cref="Carry(QuantumComputer, RegisterRef, RegisterRef, RegisterRef, RegisterRef)"/> to perform addition. /// </summary> /// <param name="comp">The QuantumComputer instance.</param> /// <param name="refA">The reference to first qubit being sumed.</param> /// <param name="refB">The reference to second qubit being sumed.</param> /// <param name="refTarget">The reference to qubit for storing the result.</param> public static void Sum(this QuantumComputer comp, RegisterRef refA, RegisterRef refB, RegisterRef refTarget) { Register root = comp.GetRootRegister(refA, refB, refTarget); int a = refA.OffsetToRoot; int b = refB.OffsetToRoot; int target = refTarget.OffsetToRoot; root.CNot(target, a); root.CNot(target, b); }
/// <summary> /// Inversion of <see cref="Carry(QuantumComputer, RegisterRef, RegisterRef, RegisterRef, RegisterRef)"/> method. /// </summary> /// <param name="comp">The QuantumComputer instance.</param> /// <param name="rc0">The reference to previous carry qubit.</param> /// <param name="ra0">The reference to qubit, for which the carry bit was computed, in the first register.</param> /// <param name="rb0">The reference to qubit, for which the carry bit was computed, in the second register.</param> /// <param name="rc1">The reference to qubit storing the resulted carry value.</param> public static void InverseCarry(this QuantumComputer comp, RegisterRef rc0, RegisterRef ra0, RegisterRef rb0, RegisterRef rc1) { Register root = comp.GetRootRegister(rc0, ra0, rb0, rc1); int c0 = rc0.OffsetToRoot; int a0 = ra0.OffsetToRoot; int b0 = rb0.OffsetToRoot; int c1 = rc1.OffsetToRoot; root.Toffoli(c1, c0, b0); root.CNot(b0, a0); root.Toffoli(c1, a0, b0); }
public static void MultModuloQFT(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register x, Register b, RegisterRef control) { Validate(a, b, N); comp.QFT(b); for (int i = 0; i < x.Width; i++) { //Console.WriteLine("MultModulo i = {2}, a = {0}, N = {1}", a, N, i); comp.AddModuloQFTPhi(((((ulong)1 << i) * a) % N), N, ctrl, b, x[i], control); } comp.InverseQFT(b); }
// Insecure version: registers widths etc. are not checked public static void InverseCMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, c, N, x, control, valueA, valueN }; comp.AddParametricGate("InverseCMultModulo", parameters); return; } else { comp.Group = true; } // if control == 0 // then the X register is copied into B register // so we uncopy it remaining 0 comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); ulong power2 = (ulong)(Math.Pow(2, x.Width - 1)); for (int i = x.Width - 1; i >= 0; i--, power2 /= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // inverse adding [(2^i * a) + B] modulo N comp.InverseAddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } }
public static void PhaseKick(this QuantumComputer comp, double gamma, RegisterRef target, params RegisterRef[] controls) { if (controls.Length == 0) { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.PhaseKick(gamma, t); } else { Register root = comp.GetRootRegister(target, comp.GetRootRegister(controls)); int t = target.OffsetToRoot; root.PhaseKick(gamma, t, controls.Select <RegisterRef, int>(x => x.OffsetToRoot).ToArray <int>()); } }
public static void InverseCPhaseShift(this QuantumComputer comp, int dist, RegisterRef target, params RegisterRef[] controls) { if (controls.Length == 0) { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.InverseCPhaseShift(dist, t); } else { Register root = comp.GetRootRegister(target, comp.GetRootRegister(controls)); int t = target.OffsetToRoot; root.InverseCPhaseShift(dist, t, controls.Select <RegisterRef, int>(x => x.OffsetToRoot).ToArray <int>()); } }
public static void InverseSwap(this QuantumComputer comp, RegisterRef r1, RegisterRef r2) { if (comp.Group) { object[] parameters = new object[] { comp, r1, r2 }; comp.AddParametricGate("InverseSwap", parameters); return; } else { comp.Group = true; } comp.Swap(r1, r2); }
public static void CPhaseShift(this QuantumComputer comp, int dist, RegisterRef target, params RegisterRef[] controls) { if (controls.Length == 0) { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.CPhaseShift(dist, t); } else { Register root = comp.GetRootRegister(target, comp.GetRootRegister(controls)); int t = target.OffsetToRoot; root.CPhaseShift(dist, t, controls.Select<RegisterRef, int>(x => x.OffsetToRoot).ToArray<int>()); } }
public static void InverseSwap(this QuantumComputer comp, Register r1, Register r2, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, r1, r2, control }; comp.AddParametricGate("InverseSwap", parameters); return; } else { comp.Group = true; } comp.Swap(r1, r2, control); }
public static void InverseSum(this QuantumComputer comp, RegisterRef refA, RegisterRef refB, RegisterRef refTarget) { if (comp.Group) { object[] parameters = new object[] { comp, refA, refB, refTarget }; comp.AddParametricGate("Sum", parameters); return; } else { comp.Group = true; } comp.Sum(refA, refB, refTarget); }
public static void RotateZ(this QuantumComputer comp, double gamma, RegisterRef target, RegisterRef?control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.RotateZ(gamma, t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.RotateZ(gamma, t); } }
public static void MultModuloQFT(this QuantumComputer comp, ulong a, ulong N, Register x, Register b, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, x, b, control }; comp.AddParametricGate("MultModuloQFT", parameters); return; } else { comp.Group = true; } Register ctrl = comp.NewRegister(0, 1); comp.MultModuloQFT(a, N, ctrl, x, b, control); }
public static void Hadamard(this QuantumComputer comp, RegisterRef target, RegisterRef? control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.Hadamard(t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.Hadamard(t); } }
public static void Gate1(this QuantumComputer comp, Complex[,] matrix, RegisterRef target, RegisterRef?control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.Gate1(matrix, t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.Gate1(matrix, t); } }
public static void Hadamard(this QuantumComputer comp, RegisterRef target, RegisterRef?control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.Hadamard(t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.Hadamard(t); } }
public static void Gate1(this QuantumComputer comp, Complex[,] matrix, RegisterRef target, RegisterRef? control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.Gate1(matrix, t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.Gate1(matrix, t); } }
// register x - initially loaded with x // register N - initially loaded with N // control - control bit // other registers - initially 0 // after computation register B changes and contains: [(a*x) mod N] // Insecure version: registers widths etc. are not checked public static void CMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, c, N, x, control, valueA, valueN }; comp.AddParametricGate("CMultModulo", parameters); return; } else { comp.Group = true; } ulong power2 = 1; for (int i = 0; i < x.Width; i++, power2 *= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // adding [(2^i * a) + B] modulo N comp.AddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } // if control == 0 // then B register contains still 0 // so we copy X register into B register comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); }
public static void InverseControlledUaGate(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register x, Register reg0, RegisterRef control) { Validate(x, N); int? invA = Utils.InversionModulo((int)a, (int)N); if (invA == null) { throw new ArgumentException("No inversion for specified a"); } //Console.WriteLine("InverseControlledUa a = {0}, N = {1}", a, N); comp.MultModuloQFT((ulong)invA, N, ctrl, x, reg0, control); comp.Swap(reg0[0, reg0.Width - 1], x, control); comp.InverseMultModuloQFT(a, N, ctrl, x, reg0, control); }
public static void InverseControlledUaGate(this QuantumComputer comp, ulong a, ulong N, Register x, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, x, control }; comp.AddParametricGate("InverseControlledUaGate", parameters); return; } else { comp.Group = true; } Register ctrl = comp.NewRegister(0, 1); Register reg0 = comp.NewRegister(0, x.Width); comp.InverseControlledUaGate(a, N, ctrl, x, reg0, control); }
public static void AddModuloQFT(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register b, params RegisterRef[] controls) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, ctrl, b, controls }; comp.AddParametricGate("AddModuloQFT", parameters); return; } else { comp.Group = true; } Validate(a, b, N); comp.QFT(b); comp.AddModuloQFTPhi(a, N, ctrl, b, controls); comp.InverseQFT(b); }
/// <summary> /// The controlled Swap. Swaps the values of two given qubits, if the control qubit is set. /// </summary> /// <param name="comp">The <see cref="Quantum.QuantumComputer"/> instance.</param> /// <param name="r1">The reference to the first swapped qubit.</param> /// <param name="r2">The reference to the second swapped qubit.</param> /// <param name="control">The reference to the control qubit.</param> public static void Swap(this QuantumComputer comp, Register r1, Register r2, RegisterRef control) { Validate(r1, r2); Register root = comp.GetRootRegister(r1, r2, control); int target1 = r1.OffsetToRoot; int target2 = r2.OffsetToRoot; int ctrl = control.OffsetToRoot; for (int i = 0; i < r1.Width; i++) { //comp.Toffoli(root[target1 + i], root[target2 + i], root[ctrl]); //comp.Toffoli(root[target2 + i], root[target1 + i], root[ctrl]); //comp.Toffoli(root[target1 + i], root[target2 + i], root[ctrl]); root.Toffoli(target1 + i, target2 + i, ctrl); root.Toffoli(target2 + i, target1 + i, ctrl); root.Toffoli(target1 + i, target2 + i, ctrl); } }
// register A - initially loaded with a // register B - initially loaded with b // register C - initially 0, exactly one bit wider than A, stores overflow bit // register N - initially loaded with N // after computation in register B: (a+b) mod N // other registers dont change their states // register B must be exactly one bit wider than A to store carry bit // register B must be exactly one bit wider than N to store carry bit // registers A, N must be the same length // Insecure version: registers widths etc. are not checked public static void AddModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, c, N, valueN }; comp.AddParametricGate("AddModulo", parameters); return; } else { comp.Group = true; } RegisterRef carry = b[b.Width - 1]; RegisterRef overflow = c[c.Width - 1]; comp.Add(a, b, c); comp.InverseAdd(N, b, c); comp.SigmaX(carry); comp.CNot(overflow, carry); comp.SigmaX(carry); //resetting N comp.LoadNumber(N, valueN, overflow); comp.Add(N, b, c); // now we have [(a+b) mod N] in B register // next steps lead to recover the initial state of registers N and overflow bit //setting N back comp.LoadNumber(N, valueN, overflow); comp.InverseAdd(a, b, c); comp.CNot(overflow, carry); comp.Add(a, b, c); }
// register x - initially loaded with x // register b - initially loaded with 0 // after computation register b changes and contains: [(a*x) mod N] // Secure version: throws Exceptions if arguments are invalid public static void CMultModulo( this QuantumComputer comp, Register x, Register b, RegisterRef control, ulong valueA, ulong valueN) { Validate(x, b, valueN); Register a = comp.NewRegister(0, x.Width - 1); Register c = comp.NewRegister(0, x.Width); Register N = comp.NewRegister(valueN, x.Width - 1); comp.CMultModulo(a, b, c, N, x, control, valueA, valueN); comp.DeleteRegister(ref N); comp.DeleteRegister(ref c); comp.DeleteRegister(ref a); }
public static void InverseAddModuloQFTPhi(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register b, params RegisterRef[] controls) { comp.InverseAddQFTPhi(a, b, controls); comp.InverseQFT(b); comp.SigmaX(b[b.Width - 1]); comp.CNot(ctrl, b[b.Width - 1]); comp.SigmaX(b[b.Width - 1]); comp.QFT(b); comp.AddQFTPhi(a, b, controls); comp.InverseAddQFTPhi(N, b, ctrl); comp.InverseQFT(b); comp.CNot(ctrl, b[b.Width - 1]); comp.QFT(b); comp.AddQFTPhi(N, b); comp.InverseAddQFTPhi(a, b, controls); }
// Swap two bits public static void Swap(this QuantumComputer comp, RegisterRef r1, RegisterRef r2) { if (comp.Group) { object[] parameters = new object[] { comp, r1, r2 }; comp.AddParametricGate("Swap", parameters); return; } else { comp.Group = true; } Register root = comp.GetRootRegister(r1, r2); int target1 = r1.OffsetToRoot; int target2 = r2.OffsetToRoot; root.CNot(target1, target2); root.CNot(target2, target1); root.CNot(target1, target2); }
// Insecure version: registers widths etc. are not checked public static void InverseAddModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, c, N, valueN }; comp.AddParametricGate("InverseAddModulo", parameters); return; } else { comp.Group = true; } RegisterRef carry = b[b.Width - 1]; RegisterRef overflow = c[c.Width - 1]; comp.InverseAdd(a, b, c); comp.CNot(overflow, carry); comp.Add(a, b, c); //resetting N: comp.LoadNumber(N, valueN, overflow); comp.InverseAdd(N, b, c); //setting N back: comp.LoadNumber(N, valueN, overflow); comp.SigmaX(carry); comp.CNot(overflow, carry); comp.SigmaX(carry); comp.Add(N, b, c); comp.InverseAdd(a, b, c); }
public static void Sum(this QuantumComputer comp, RegisterRef refA, RegisterRef refB, RegisterRef refTarget) { if (comp.Group) { object[] parameters = new object[] { comp, refA, refB, refTarget }; comp.AddParametricGate("Sum", parameters); return; } else { comp.Group = true; } Register root = comp.GetRootRegister(refA, refB, refTarget); int a = refA.OffsetToRoot; int b = refB.OffsetToRoot; int target = refTarget.OffsetToRoot; root.CNot(target, a); root.CNot(target, b); }
public static void InverseMultModuloQFT(this QuantumComputer comp, ulong a, ulong N, RegisterRef ctrl, Register x, Register b, RegisterRef control) { if (comp.Group) { object[] parameters = new object[] { comp, a, N, ctrl, x, b, control }; comp.AddParametricGate("InverseMultModuloQFT", parameters); return; } else { comp.Group = true; } Validate(a, b, N); comp.QFT(b); for (int i = x.Width - 1; i >= 0; i--) { comp.InverseAddModuloQFTPhi(((((ulong)1 << i) * a) % N), N, ctrl, b, x[i], control); } comp.InverseQFT(b); }
// Oracle is working on input register x (of width n) // and output register y (of width 1) public static void Oracle(this QuantumComputer comp, int target, Register x, Register y) { var controlBits = new RegisterRef[x.Width]; for (int i = 0; i < x.Width; i++) { if ((target & (1 << i)) == 0) { x.SigmaX(i); } controlBits[i] = x[i]; } comp.Toffoli(y[0], controlBits); // Toffoli(<target_bit>, ... <control_bits> ...) for (int i = 0; i < x.Width; i++) { if ((target & (1 << i)) == 0) { x.SigmaX(i); } } }
public static void InverseCarry(this QuantumComputer comp, RegisterRef rc0, RegisterRef ra0, RegisterRef rb0, RegisterRef rc1) { if (comp.Group) { object[] parameters = new object[] { comp, rc0, ra0, rb0, rc1 }; comp.AddParametricGate("InverseCarry", parameters); return; } else { comp.Group = true; } Register root = comp.GetRootRegister(rc0, ra0, rb0, rc1); int c0 = rc0.OffsetToRoot; int a0 = ra0.OffsetToRoot; int b0 = rb0.OffsetToRoot; int c1 = rc1.OffsetToRoot; root.Toffoli(c1, c0, b0); root.CNot(b0, a0); root.Toffoli(c1, a0, b0); }
public static void Carry(this QuantumComputer comp, RegisterRef rc0, RegisterRef ra0, RegisterRef rb0, RegisterRef rc1) { if (comp.Group) { object[] parameters = new object[] { comp, rc0, ra0, rb0, rc1 }; comp.AddParametricGate("Carry", parameters); return; } else { comp.Group = true; } Register root = comp.GetRootRegister(rc0, ra0, rb0, rc1); int c0 = rc0.OffsetToRoot; int a0 = ra0.OffsetToRoot; int b0 = rb0.OffsetToRoot; int c1 = rc1.OffsetToRoot; root.Toffoli(c1, a0, b0); root.CNot(b0, a0); root.Toffoli(c1, c0, b0); }
public static void RotateZ(this QuantumComputer comp, double gamma, RegisterRef target, RegisterRef? control = null) { if (control.HasValue) { Register root = comp.GetRootRegister(control.Value, target); int c = control.Value.OffsetToRoot; int t = target.OffsetToRoot; root.RotateZ(gamma, t, c); } else { Register root = comp.GetRootRegister(target); int t = target.OffsetToRoot; root.RotateZ(gamma, t); } }
public static void Toffoli(this QuantumComputer comp, RegisterRef target, params RegisterRef[] controls) { Register root = comp.GetRootRegister(comp.GetRootRegister(controls), target); root.Toffoli(target.OffsetToRoot, controls.Select<RegisterRef, int>(x => x.OffsetToRoot).ToArray<int>()); }
// Insecure version: registers widths etc. are not checked public static void InverseCMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { // if control == 0 // then the X register is copied into B register // so we uncopy it remaining 0 comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); ulong power2 = (ulong)(Math.Pow(2, x.Width - 1)); for (int i = x.Width - 1; i >= 0; i--, power2 /= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // inverse adding [(2^i * a) + B] modulo N comp.InverseAddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } }
public static void InverseSwap(this QuantumComputer comp, Register r1, Register r2, RegisterRef control) { comp.Swap(r1, r2, control); }
public static void InverseSwap(this QuantumComputer comp, RegisterRef r1, RegisterRef r2) { comp.Swap(r1, r2); }