def test_transfer_operators(): assert (paulis.decompose_transfer_operator(ket=0, bra=0) == paulis.Qp(0)) assert (paulis.decompose_transfer_operator(ket=0, bra=1) == paulis.Sp(0)) assert (paulis.decompose_transfer_operator(ket=1, bra=0) == paulis.Sm(0)) assert (paulis.decompose_transfer_operator(ket=1, bra=1) == paulis.Qm(0)) assert (paulis.decompose_transfer_operator( ket=BitString.from_binary(binary="00"), bra=BitString.from_binary("00")) == paulis.Qp(0) * paulis.Qp(1)) assert (paulis.decompose_transfer_operator( ket=BitString.from_binary(binary="01"), bra=BitString.from_binary("01")) == paulis.Qp(0) * paulis.Qm(1)) assert (paulis.decompose_transfer_operator( ket=BitString.from_binary(binary="01"), bra=BitString.from_binary("10")) == paulis.Sp(0) * paulis.Sm(1)) assert (paulis.decompose_transfer_operator( ket=BitString.from_binary(binary="00"), bra=BitString.from_binary("11")) == paulis.Sp(0) * paulis.Sp(1)) assert (paulis.decompose_transfer_operator(ket=0, bra=0, qubits=[1]) == paulis.Qp(1)) assert (paulis.decompose_transfer_operator(ket=1, bra=0, qubits=[1]) == paulis.Sm(1)) assert (paulis.decompose_transfer_operator(ket=1, bra=1, qubits=[1]) == paulis.Qm(1))
def test_bit_flip(simulator, p, controlled): qubit = 0 if controlled: U = gates.X(target=1) + gates.CX(1, 0) H = paulis.Qm(0) NM = BitFlip(p, 2) else: U = gates.X(target=0) NM = BitFlip(p, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1, noise=NM)
def test_bit_flip(simulator, p, controlled): qubit = 0 if controlled: U = gates.X(target=1) + gates.CX(1, 0) H = paulis.Qm(0) NM = BitFlip(p, 2) else: U = gates.X(target=0) NM = BitFlip(p, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1000, noise=NM) assert (numpy.isclose(E, 1.0 - p, atol=1.e-1))
def test_repetition_works(simulator, p): qubit = 0 H = paulis.Qm(qubit) U = gates.X(target=qubit) + gates.X(target=qubit) O = ExpectationValue(U=U, H=H) NM = BitFlip(p, 1) E = simulate(O, backend=simulator, samples=1, noise=NM)
def get_generator(gate) -> paulis.QubitHamiltonian: """ get the generator of a gaussian gate as a Qubit hamiltonian. Relies on the name of the gate. Parameters ---------- gate: QGateImpl: QGateImpl object or inheritor thereof, with name corresponding to its generator in some fashion. Returns ------- QubitHamiltonian: the generator of the gate acting, on the gate's target. """ if gate.name.lower() == 'rx': gen = paulis.X(gate.target[0]) elif gate.name.lower() == 'ry': gen = paulis.Y(gate.target[0]) elif gate.name.lower() == 'rz': gen = paulis.Z(gate.target[0]) elif gate.name.lower() == 'phase': gen = paulis.Qm(gate.target[0]) else: print(gate.name.lower()) raise TequilaException( 'cant get the generator of a non Gaussian gate, you fool!') return gen
def QubitExcitation(angle: typing.Union[numbers.Real, Variable, typing.Hashable], target: typing.List, control=None, assume_real: bool = False): """ A Qubit Excitation, as described under "qubit perspective" in https://doi.org/10.1039/D0SC06627C For the Fermionic operators under corresponding Qubit encodings: Use the chemistry interface Parameters ---------- angle: the angle of the excitation unitary target: even number of qubit indices interpreted as [0,1,2,3....] = [(0,1), (2,3), ...] i.e. as qubit excitations from 0 to 1, 2 to 3, etc control: possible control qubits assume_real: assume the wavefunction on which this acts is always real (cheaper gradients: see https://doi.org/10.1039/D0SC06627C) Returns ------- QubitExcitation gate wrapped into a tequila circuit """ try: assert len(target) % 2 == 0 except: raise Exception("QubitExcitation: Needs an even number of targets") generator = paulis.I() p0a = paulis.I() p0b = paulis.I() for i in range(len(target) // 2): generator *= paulis.Sp(target[2 * i]) * paulis.Sm(target[2 * i + 1]) p0a *= paulis.Qp(target[2 * i]) * paulis.Qm(target[2 * i + 1]) p0b *= paulis.Qm(target[2 * i]) * paulis.Qp(target[2 * i + 1]) generator = (1.0j * (generator - generator.dagger())).simplify() p0 = paulis.I() - p0a - p0b return QCircuit.wrap_gate( impl.QubitExcitationImpl(angle=angle, generator=generator, p0=p0, assume_real=assume_real))
def test_double_cnot_bit_flip(simulator, p): qubit = 1 U = gates.X(0) + gates.X(2) + gates.CX(0, 1) + gates.CX(2, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) NM = BitFlip(p, 2) E = simulate(O, backend=simulator, samples=1, noise=NM)
def test_double_cnot_bit_flip(simulator, p): qubit = 1 U = gates.X(0) + gates.X(2) + gates.CX(0, 1) + gates.CX(2, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) NM = BitFlip(p, 2) E = simulate(O, backend=simulator, samples=1000, noise=NM) assert (numpy.isclose(E, 2 * (p - p * p), atol=1.e-1))
def test_convenience(): i = numpy.random.randint(0, 10, 1)[0] assert paulis.X(i) + paulis.I(i) == paulis.X(i) + 1.0 assert paulis.Qp(i) == 0.5 * (1.0 + paulis.Z(i)) assert paulis.Qm(i) == 0.5 * (1.0 - paulis.Z(i)) assert paulis.Sp(i) == 0.5 * (paulis.X(i) + 1.j * paulis.Y(i)) assert paulis.Sm(i) == 0.5 * (paulis.X(i) - 1.j * paulis.Y(i)) i = numpy.random.randint(0, 10, 1)[0] assert paulis.Qp(i) == (0.5 + 0.5 * paulis.Z(i)) assert paulis.Qm(i) == (0.5 - 0.5 * paulis.Z(i)) assert paulis.Sp(i) == (0.5 * paulis.X(i) + 0.5j * paulis.Y(i)) assert paulis.Sm(i) == (0.5 * paulis.X(i) - 0.5j * paulis.Y(i)) assert -1.0 * paulis.Y(i) == -paulis.Y(i) test = paulis.Z(i) test *= -1.0 assert test == -paulis.Z(i) test = paulis.Z(i) test += 1.0 assert test == paulis.Z(i) + 1.0 test = paulis.X(i) test += paulis.Y(i + 1) assert test == paulis.X(i) + paulis.Y(i + 1) test = paulis.X(i) test -= paulis.Y(i) test += 3.0 test = -test assert test == -1.0 * (paulis.X(i) - paulis.Y(i) + 3.0) test = paulis.X([0, 1, 2, 3]) assert test == QubitHamiltonian.from_string("X(0)X(1)X(2)X(3)", False) test = paulis.Y([0, 1, 2, 3]) assert test == QubitHamiltonian.from_string("Y(0)Y(1)Y(2)Y(3)", False) test = paulis.Z([0, 1, 2, 3]) assert test == QubitHamiltonian.from_string("Z(0)Z(1)Z(2)Z(3)", False)
def __init__(self, angle, target=None, generator=None, p0=None, assume_real=True, control=None, compile_options=None): angle = assign_variable(angle) if generator is None: assert target is not None assert p0 is None generator = paulis.I() p0a = paulis.I() p0b = paulis.I() for i in range(len(target) // 2): generator *= paulis.Sp(target[2 * i]) * paulis.Sm( target[2 * i + 1]) p0a *= paulis.Qp(target[2 * i]) * paulis.Qm(target[2 * i + 1]) p0b *= paulis.Qm(target[2 * i]) * paulis.Qp(target[2 * i + 1]) generator = (1.0j * (generator - generator.dagger())).simplify() p0 = paulis.I() - p0a - p0b else: assert generator is not None assert p0 is not None super().__init__(name="QubitExcitation", parameter=angle, target=self.extract_targets(generator), control=control) self.generator = generator if control is not None: # augment p0 for control qubits # Qp = 1/2(1+Z) = |0><0| p0 = p0 * paulis.Qp(control) self.p0 = p0 self.assume_real = assume_real if compile_options is None: self.compile_options = "optimize" else: self.compile_options = compile_options
def test_bit_flip_phoenics(simulator, p): qubit = 0 H = paulis.Qm(qubit) U = gates.Rx(target=qubit, angle=tq.Variable('a')) O = ExpectationValue(U=U, H=H) NM = BitFlip(p, 1) result = tq.optimizers.optimizer_phoenics.minimize(objective=O, maxiter=3, samples=1, backend=simulator, noise=NM)
def test_bit_flip_scipy_hessian(simulator, p, method): qubit = 0 H = paulis.Qm(qubit) U = gates.Rx(target=qubit, angle=tq.Variable('a')) O = ExpectationValue(U=U, H=H) NM = BitFlip(p, 1) result = tq.optimizer_scipy.minimize(objective=O, samples=1, backend=simulator, method=method, noise=NM, tol=1.e-4, silent=False)
def get_generator(gate): if gate.name.lower() == 'rx': gen = paulis.X(gate.target[0]) elif gate.name.lower() == 'ry': gen = paulis.Y(gate.target[0]) elif gate.name.lower() == 'rz': gen = paulis.Z(gate.target[0]) elif gate.name.lower() == 'phase': gen = paulis.Qm(gate.target[0]) else: print(gate.name.lower()) raise TequilaException( 'cant get the generator of a non Gaussian gate, you fool!') return gen
def test_special_operators(): # sigma+ sigma- as well as Q+ and Q- assert (paulis.Sp(0) * paulis.Sp(0) == QubitHamiltonian.zero()) assert (paulis.Sm(0) * paulis.Sm(0) == QubitHamiltonian.zero()) assert (paulis.Qp(0) * paulis.Qp(0) == paulis.Qp(0)) assert (paulis.Qm(0) * paulis.Qm(0) == paulis.Qm(0)) assert (paulis.Qp(0) * paulis.Qm(0) == QubitHamiltonian.zero()) assert (paulis.Qm(0) * paulis.Qp(0) == QubitHamiltonian.zero()) assert (paulis.Sp(0) * paulis.Sm(0) == paulis.Qp(0)) assert (paulis.Sm(0) * paulis.Sp(0) == paulis.Qm(0)) assert (paulis.Sp(0) + paulis.Sm(0) == paulis.X(0)) assert (paulis.Qp(0) + paulis.Qm(0) == paulis.I(0))
def make_generator(self, include_controls=False): if self.generator and include_controls and self.is_controlled(): return paulis.Qm(self.control) * self.generator return self.generator