public static CompositeTransform GetGroverDiffusionOperator(bool[] blackBoxFunc) { int n = blackBoxFunc.LongLength.BitsCeiling(); // 1. oracle var grover = new CompositeTransform(GetOracle(blackBoxFunc)); // 2. hadamar all bits foreach (int i in Enumerable.Range(0, n)) { grover = grover.Apply(Gates.H, i); } // 3. TODO: phase flip every basis except |0> (how do i do this with basic gates?? going to do a custom MultiGate for now) // from mike and ike: 'can be implemented using the techniques of section 4.3 using O(n) gates long dim = blackBoxFunc.LongLength; var elements = new Complex[dim, dim]; foreach (long i in LongExt.Range(0, dim)) { elements[i, i] = i == 0 ? 1 : -1; } grover = grover.Apply(new MultiGate(elements, n)); //4. hadamar all bits again foreach (int i in Enumerable.Range(0, n)) { grover = grover.Apply(Gates.H, i); } return(grover); }
/// <summary> /// The blackBoxFunc represents a search problem, where the goal is to find the inputs that /// result in true. This function turns the classical search problem into a quantum transformation /// by either flipping the input when the function is true, or leaving it unchanged when it is false. /// |x> -> (-1)^f(x) |x> /// </summary> public static IUnitaryTransform GetOracle(bool[] blackBoxFunc) { long dim = blackBoxFunc.LongLength; var elements = new Complex[dim, dim]; foreach (long i in LongExt.Range(0, dim)) { elements[i, i] = blackBoxFunc[i] ? -1 : 1; } return(new MultiGate(elements, 1)); }
/// <summary> /// Takes a (hopefully linear function) from int to int and turns it into /// a complex unitary transform that reproducest he function when input with /// classical bits that represent the integer input. /// </summary> public static IUnitaryTransform FromFunction( Func <long, long> func, int numBits, Func <long, long, long> powVersion = null) { long dimension = (long)Math.Pow(2, numBits); var elements = new Complex[dimension, dimension]; foreach (long i in LongExt.Range(0, dimension)) { elements[func(i), i] = 1; } return(new MultiGate( elements, (int)Math.Pow(numBits, 3), // simulated with O(L^3) gates exp => FromFunction( input => powVersion(input, exp), numBits, // same input bits powVersion))); // same method for powering }
public IUnitaryTransform Pow(long exponent) { IUnitaryTransform wtf = this; return(new CompositeTransform(LongExt.Range(0, exponent).Select(exp => wtf).ToArray())); }
public IUnitaryTransform Pow(long exponent) => new CompositeTransform(LongExt.Range(0, exponent).Select(exp => this).ToArray());