def compile_controlled_phase(gate) -> QCircuit: """ Compile multi-controlled phase gates to 1q - phase gate and multi-controlled Rz gates. Parameters ---------- gate: the gate. Returns ------- QCircuit, the result of compilation. """ if not isinstance(gate, PhaseGateImpl): return QCircuit.wrap_gate(gate) if len(gate.control) == 0: return QCircuit.wrap_gate(gate) phase = gate.parameter result = QCircuit() result += Phase(target=gate.control[0], control=gate.control[1:], phi=phase / 2) result += Rz(target=gate.target, control=gate.control, angle=phase) return compile_controlled_phase(result)
def hadamard_axbxc(gate) -> QCircuit: """ Decompose 1 control parametrized hadamard into single qubit rotation and CNOT. Parameters ---------- gate: the gate Returns ------- QCircuit, the result of compilation. """ if not isinstance(gate, PowerGateImpl) or gate.name not in [ 'H', 'h', 'hadamard' ]: return QCircuit.wrap_gate(gate) power = gate.parameter target = gate.target a = power.wrap(a_calc) b = power.wrap(b_calc) theta = power.wrap(theta_calc) phase = power * jnp.pi / 2 result = QCircuit() result += Rz((a - b) / 2, target) result += CNOT(gate.control, target) result += Rz(-(a + b) / 2, target) result += Ry(-theta / 2, target) result += CNOT(gate.control, target) result += Ry(theta / 2, target) result += Rz(a, target) result += Phase(numpy.pi * power / 2, gate.control) return result
def compile_controlled_power(gate: PowerGateImpl) -> QCircuit: """ Recompilation of a controlled-power gate Basis change into Z then recompilation of controled Z, then change basis back :param gate: The power gate :return: set of gates wrapped in QCircuit class """ if not gate.is_controlled(): return QCircuit.wrap_gate(gate) if not isinstance(gate, PowerGateImpl): return QCircuit.wrap_gate(gate) if len(gate.target) > 1: return compile_controlled_power(gate=compile_multitarget(gate=gate)) power = gate.power target = gate.target control = gate.control result = QCircuit() result += Phase(target=control[0], control=control[1:], phi=power * pi / 2) result += change_basis(target=target, name=gate.name) result += Rz(target=target, control=control, angle=power * pi) result += change_basis(target=target, name=gate.name, daggered=True) result.n_qubits = result.max_qubit() + 1 return result
def do_compile_trotterized_gate(generator, steps, factor, randomize, control): """ Todo: Jakob, plz write """ assert (generator.is_hermitian()) circuit = QCircuit() factor = factor / steps for index in range(steps): paulistrings = generator.paulistrings if randomize: numpy.random.shuffle(paulistrings) for ps in paulistrings: coeff = to_float(ps.coeff) if len(ps._data) == 0 and len(control) > 0: circuit += Phase(target=control[0], control=control[1:], phi=-factor * coeff / 2) elif len(ps._data) > 0: circuit += ExpPauli(paulistring=ps.naked(), angle=factor * coeff, control=control) else: # ignore global phases pass return circuit
def compile_controlled_phase(gate) -> QCircuit: if not isinstance(gate, PhaseGateImpl): return QCircuit.wrap_gate(gate) if len(gate.control) == 0: return QCircuit.wrap_gate(gate) count = len(gate.control) result = QCircuit() phase = gate.parameter if count == 1: result += H(target=gate.target) result += CNOT(gate.control, gate.target) result += H(target=gate.target) result += Phase(gate.parameter + numpy.pi, target=gate.target) elif count == 2: result += Rz(angle=phase / (2**2), target=gate.control[0]) result += Rz(angle=phase / (2**(1)), target=gate.control[1], control=gate.control[0]) result += Rz(angle=phase, target=gate.target, control=gate.control) elif count >= 3: result += Rz(angle=phase / (2**count), target=gate.control[0]) for i in range(1, count): result += Rz(angle=phase / (2**(count - i)), target=gate.control[i], control=gate.control[0:i]) result += Rz(angle=phase, target=gate.target, control=gate.control) return result
def test_moments(): c = QCircuit() c += CNOT(target=0, control=(1, 2, 3)) c += H(target=[0, 1]) c += Rx(angle=numpy.pi, target=[0, 3]) c += Z(target=1) c += Phase(phi=numpy.pi, target=4) moms = c.moments assert len(moms) == 3 assert (moms[0].gates[1].parameter == assign_variable(numpy.pi)) assert (moms[0].gates[1].target == (4, ))
def test_circuit_from_moments(): c = QCircuit() c += CNOT(target=0, control=(1, 2, 3)) c += Phase(phi=numpy.pi, target=4) c += Rx(angle=Variable('a'), target=[0, 3]) c += H(target=[0, 1]) c += Rx(angle=Variable('a'), target=[2, 3]) ## table[1] should equal 1 at this point, len(moments should be 3) c += Z(target=1) c += Rx(angle=Variable('a'), target=[0, 3]) moms = c.moments c2 = QCircuit.from_moments(moms) assert c == c2
def test_canonical_moments(): c = QCircuit() c += CNOT(target=0, control=(1, 2, 3)) c += Rx(angle=Variable('a'), target=[0, 3]) c += H(target=[0, 1]) c += Rx(angle=Variable('a'), target=[2, 3]) c += Rx(angle=Variable('a'), target=[0, 3]) c += Z(target=1) c += Phase(phi=numpy.pi, target=4) moms = c.canonical_moments assert len(moms) == 6 assert (moms[0].gates[1].parameter == assign_variable(numpy.pi)) assert (moms[0].gates[1].target == (4, )) assert hasattr(moms[3].gates[0], 'axis') assert len(moms[0].qubits) == 5
def hadamard_axbxc(gate) -> QCircuit: if not isinstance(gate, PowerGateImpl) or gate.name not in [ 'H', 'h', 'hadamard' ]: return QCircuit.wrap_gate(gate) power = gate.parameter target = gate.target a = power.wrap(a_calc) b = power.wrap(b_calc) theta = power.wrap(theta_calc) phase = power * jnp.pi / 2 result = QCircuit() result += Rz((a - b) / 2, target) result += CNOT(gate.control, target) result += Rz(-(a + b) / 2, target) result += Ry(-theta / 2, target) result += CNOT(gate.control, target) result += Ry(theta / 2, target) result += Rz(a, target) result += Phase(numpy.pi * power / 2, gate.control) return result
def get_axbxc_decomp(gate): """ Break down single controlled parametrized power gates into CNOT and rotations. Parameters ---------- gate: the gate. Returns ------- QCircuit; the result of compilation. """ if not isinstance(gate, PowerGateImpl) or gate.name not in ['X', 'Y', 'Z']: return QCircuit.wrap_gate(gate) power = gate.parameter target = gate.target result = QCircuit() if gate.name == 'X': a = -numpy.pi / 2 b = numpy.pi / 2 theta = power * numpy.pi ''' result+=Phase(numpy.pi*power/2,gate.control) result+=Rz(-(a-b)/2,target) result+=CNOT(gate.control,target) #result+=Rz(-(a+b)/2,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) result+=Rz(a,target=target) ''' ''' result+=Rz((a-b)/2,target) result+=CNOT(gate.control,target) #result+=Rz(-(a+b)/2,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) ''' result += Rx(angle=theta, target=target, control=gate.control) result += Phase(numpy.pi * power / 2, gate.control) elif gate.name == 'Y': ### off by global phase of Exp[ pi power /2] theta = power * numpy.pi ''' result+=Phase(numpy.pi*power/2,gate.control) result+=CNOT(gate.control,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) ''' a = 0 b = 0 # result+=Rz((a-b)/2,target) result += CNOT(gate.control, target) # result+=Rz(-(a+b)/2,target) result += Ry(-theta / 2, target) result += CNOT(gate.control, target) result += Ry(theta / 2, target) # result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) elif gate.name == 'Z': a = 0 b = power * numpy.pi theta = 0 result += Rz(b / 2, target) result += CNOT(gate.control, target) result += Rz(-b / 2, target) result += CNOT(gate.control, target) # result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) ''' result+=Rz(b/2,target) result+=CNOT(gate.control,target) result+=Rz(-b/2,target) result+=CNOT(gate.control,target) ''' return result
def get_axbxc_decomp(gate): if not isinstance(gate, PowerGateImpl) or gate.name not in ['X', 'Y', 'Z']: return QCircuit.wrap_gate(gate) power = gate.parameter target = gate.target result = QCircuit() if gate.name == 'X': a = -numpy.pi / 2 b = numpy.pi / 2 theta = power * numpy.pi ''' result+=Phase(numpy.pi*power/2,gate.control) result+=Rz(-(a-b)/2,target) result+=CNOT(gate.control,target) #result+=Rz(-(a+b)/2,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) result+=Rz(a,target=target) ''' ''' result+=Rz((a-b)/2,target) result+=CNOT(gate.control,target) #result+=Rz(-(a+b)/2,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) ''' result += Rx(angle=theta, target=target, control=gate.control) result += Phase(numpy.pi * power / 2, gate.control) elif gate.name == 'Y': ### off by global phase of Exp[ pi power /2] theta = power * numpy.pi ''' result+=Phase(numpy.pi*power/2,gate.control) result+=CNOT(gate.control,target) result+=Ry(-theta/2,target) result+=CNOT(gate.control,target) result+=Ry(theta/2,target) ''' a = 0 b = 0 # result+=Rz((a-b)/2,target) result += CNOT(gate.control, target) # result+=Rz(-(a+b)/2,target) result += Ry(-theta / 2, target) result += CNOT(gate.control, target) result += Ry(theta / 2, target) # result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) elif gate.name == 'Z': a = 0 b = power * numpy.pi theta = 0 result += Rz(b / 2, target) result += CNOT(gate.control, target) result += Rz(-b / 2, target) result += CNOT(gate.control, target) # result+=Rz(a,target) result += Phase(numpy.pi * power / 2, gate.control) ''' result+=Rz(b/2,target) result+=CNOT(gate.control,target) result+=Rz(-b/2,target) result+=CNOT(gate.control,target) ''' return result