Beispiel #1
0
def test_initialization():
    H = paulis.I()
    for i in range(10):
        H += paulis.pauli(qubit=numpy.random.randint(0,5,3), type=numpy.random.choice(["X", "Y", "Z"],1))

    for H1 in [H, paulis.I(), paulis.Zero(), paulis.X(0), paulis.Y(1), 1.234*paulis.Z(2)]:
        string = str(H1)
        ofstring = str(H1.to_openfermion())
        H2 = QubitHamiltonian.from_string(string=string)
        assert H1 == H2
        H3 = QubitHamiltonian.from_string(string=ofstring, openfermion_format=True)
        assert H1 == H3
Beispiel #2
0
def test_amp_damp(simulator, p):
    qubit = 0
    H = (0.5) * (paulis.I(0) - paulis.Z(0))
    U = gates.X(target=qubit)
    O = ExpectationValue(U=U, H=H)
    NM = AmplitudeDamp(p, 1)
    E = simulate(O, backend=simulator, samples=1, noise=NM)
Beispiel #3
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))
Beispiel #4
0
 def __init__(self, phase, target: list, control: list = None):
     assert (phase is not None)
     super().__init__(eigenvalues_magnitude=0.5,
                      name='Phase',
                      parameter=phase,
                      target=target,
                      control=control)
     self.generator = paulis.Z(target) - paulis.I(target)
Beispiel #5
0
def test_rz_phase_flip_1(simulator, p, angle):
    U = gates.X(target=0) + gates.H(1) + gates.CRz(control=0, target=1, angle=Variable('a')) + gates.H(1)
    H = paulis.Z(1) * paulis.I(0)
    O = ExpectationValue(U, H)
    NM = PhaseFlip(p, 2)
    E = simulate(O, backend=simulator, variables={'a': angle}, samples=1000, noise=NM)
    print(E)
    assert (numpy.isclose(E, ((1.0 - 2 * p) ** 2) * numpy.cos(angle), atol=1.e-1))
Beispiel #6
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
Beispiel #7
0
def test_rx_bit_flip_1(simulator, p, angle):
    U = gates.X(target=0) + gates.CRx(control=0, target=1, angle="a")
    H = paulis.Z(1) * paulis.I(0)
    NM = BitFlip(p, 2)
    O = ExpectationValue(U=U, H=H)

    E = simulate(O, backend=simulator, samples=1000, variables={'a': angle}, noise=NM)
    print(E)
    print(p + numpy.cos(angle) - p * numpy.cos(angle))
    assert (numpy.isclose(E, p + numpy.cos(angle) - p * numpy.cos(angle), atol=1.e-1))
Beispiel #8
0
def test_rz_phase_flip_1(simulator, p, angle):

    U = gates.X(target=0) + gates.H(1) + gates.CRz(
        control=0, target=1, angle=Variable('a')) + gates.H(1)
    H = paulis.Z(1) * paulis.I(0)
    O = ExpectationValue(U, H)
    NM = PhaseFlip(p, 2)
    E = simulate(O,
                 backend=simulator,
                 variables={'a': angle},
                 samples=1,
                 noise=NM)
    print(E)
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))
Beispiel #10
0
def test_rx_bit_flip_1(simulator, p, angle):

    qubit = 1
    U = gates.X(target=0) + gates.CRx(control=0, target=1, angle=Variable('a'))
    H = paulis.Z(1) * paulis.I(0)
    NM = BitFlip(p, 2)

    O = ExpectationValue(U=U, H=H)

    E = simulate(O,
                 backend=simulator,
                 samples=1,
                 variables={'a': angle},
                 noise=NM)
    print(E)
    print(p + numpy.cos(angle) - p * numpy.cos(angle))
Beispiel #11
0
def test_binarypauli_conversion():
    '''
    Testing PauliString's built-in binary form conversion
    '''
    H, n_qubits, binary_sol, coeff_sol = prepare_test_hamiltonian()

    word1 = H.paulistrings[0].binary(n_qubits)
    word2 = H.paulistrings[1].binary(n_qubits)
    word3 = H.paulistrings[2].binary(n_qubits)
    word4 = paulis.I().paulistrings[0].binary(n_qubits)

    assert (word1.coeff == coeff_sol[0])
    assert (all(word1.binary == binary_sol[0, :]))
    assert (word2.coeff == coeff_sol[1])
    assert (all(word2.binary == binary_sol[1, :]))
    assert (word3.coeff == coeff_sol[2])
    assert (all(word3.binary == binary_sol[2, :]))
    assert (all(word4.binary == np.zeros(2 * n_qubits)))
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)
Beispiel #13
0
def H(target: typing.Union[list, int],
      control: typing.Union[list, int] = None,
      power=None,
      angle=None,
      *args,
      **kwargs) -> QCircuit:
    """
    Notes
    ----------
    Hadamard gate

    Parameters
    ----------
    target
        int or list of int
    control
        int or list of int
    power
        numeric type (fixed exponent) or hashable type (parametrized exponent)
        angle
        similar to power, but will be interpreted as
        .. math::
           U(\\text{angle})=e^{-i\\frac{angle}{2} generator}
        the default is angle=pi
        .. math::
           U(\\pi) = H
        If angle and power are given both, tequila will combine them

    Returns
    -------
    QCircuit object

    """
    coef = 1 / np.sqrt(2)
    generator = lambda q: coef * (paulis.Z(q) + paulis.X(q)) - paulis.I(q)
    return _initialize_power_gate(name="H",
                                  power=power,
                                  angle=angle,
                                  target=target,
                                  control=control,
                                  generator=generator,
                                  *args,
                                  **kwargs)
Beispiel #14
0
def SWAP(first: int,
         second: int,
         control: typing.Union[int, list] = None,
         power: float = None,
         *args,
         **kwargs) -> QCircuit:
    """
    Notes
    ----------
    SWAP gate, order of targets does not matter

    Parameters
    ----------
    first: int
        target qubit
    second: int
        target qubit
    control
        int or list of ints
    power
        numeric type (fixed exponent) or hashable type (parametrized exponent)

    Returns
    -------
    QCircuit

    """

    target = [first, second]
    generator = 0.5 * (paulis.X(target) + paulis.Y(target) + paulis.Z(target) -
                       paulis.I(target))
    if power is None or power in [1, 1.0]:
        return QGate(name="SWAP",
                     target=target,
                     control=control,
                     generator=generator)
    else:
        return GeneralizedRotation(angle=power * np.pi,
                                   control=control,
                                   generator=generator,
                                   eigenvalues_magnitude=0.25)
Beispiel #15
0
def Y(target: typing.Union[list, int],
      control: typing.Union[list, int] = None,
      power=None,
      angle=None,
      *args,
      **kwargs) -> QCircuit:
    """
    Notes
    ----------
    Pauli Y Gate

    Parameters
    ----------
    target:
        int or list of int
    control
        int or list of int
    power
        numeric type (fixed exponent) or hashable type (parametrized exponent)
    angle
        similar to power, but will be interpreted as
        .. math::
           U(\\text{angle})=e^{-i\\frac{angle}{2} (1-Y)}
        the default is angle=pi
        .. math::
           U(\\pi) = Y
        If angle and power are given both, tequila will combine them

    Returns
    -------
    QCircuit object

    """
    generator = lambda q: paulis.Y(q) - paulis.I(q)
    return _initialize_power_gate(name="Y",
                                  power=power,
                                  angle=angle,
                                  target=target,
                                  control=control,
                                  generator=generator)