Exemplo n.º 1
0
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))
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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))
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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))
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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))
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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))
Exemplo n.º 15
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