Пример #1
0
def KetBra(ket: QubitWaveFunction,
           bra: QubitWaveFunction,
           hermitian: bool = False,
           threshold: float = 1.e-6,
           n_qubits=None):
    """
    Notes
    ----------
    Initialize the general KetBra operator
    .. math::
        H = \\lvert ket \\rangle \\langle bra \\rvert

    e.g.
    wfn1 = tq.QubitWaveFunction.from_string("1.0*|00> + 1.0*|11>").normalize()
    wfn2 = tq.QubitWaveFunction.from_string("1.0*|00>")
    operator = tq.paulis.KetBra(ket=wfn1, bra=wfn1)
    initializes the transfer operator from the all-zero state to a Bell state

    Parameters
    ----------
    ket: QubitWaveFunction:
         QubitWaveFunction which defines the ket element
         can also be given as string or array or integer
    bra: QubitWaveFunction:
         QubitWaveFunction which defines the bra element
         can also be given as string or array or integer
    hermitian: bool: (Default False)
         if True the hermitian version H + H^\dagger is returned
    threshold: float: (Default 1.e-6)
         elements smaller than the threshold will be ignored
    n_qubits: only needed if ket and/or bra are passed down as integers

    Returns
    -------
    a tequila QubitHamiltonian (not necessarily hermitian)

    """
    H = QubitHamiltonian.zero()
    ket = QubitWaveFunction(state=ket, n_qubits=n_qubits)
    bra = QubitWaveFunction(state=bra, n_qubits=n_qubits)

    for k1, v1 in bra.items():
        for k2, v2 in ket.items():
            c = v1.conjugate() * v2
            if not numpy.isclose(c, 0.0, atol=threshold):
                H += c * decompose_transfer_operator(bra=k1, ket=k2)
    if hermitian:
        return H.split()[0]
    else:
        return H.simplify(threshold=threshold)
Пример #2
0
 def apply_gate(cls, state: QubitWaveFunction, gate: QGate, qubits: dict, variables) -> QubitWaveFunction:
     result = QubitWaveFunction()
     n_qubits = len(qubits.keys())
     for s, v in state.items():
         s.nbits = n_qubits
         result += v * cls.apply_on_standard_basis(gate=gate, basisfunction=s, qubits=qubits, variables=variables)
     return result
Пример #3
0
def test_random_instances(target_space):

    # can happen that a tests fails, just start again ... if all tests fail: start to worry
    # it happens from time to time that UPS can not disentangle
    # it will throw the error/
    # OpenVQEException: Could not disentangle the given state after 100 restarts
    qubits = len(target_space)
    coeffs = numpy.random.uniform(0, 1, qubits)

    wfn = QubitWaveFunction()
    for i, c in enumerate(coeffs):
        wfn += c * QubitWaveFunction.from_string("1.0|" + target_space[i] +
                                                 ">")
    wfn = wfn.normalize()

    try:
        UPS = UnaryStatePrep(target_space=target_space)
        U = UPS(wfn=wfn)

        # now the coeffs are normalized
        bf2c = dict()
        for i, c in enumerate(coeffs):
            bf2c[target_space[i]] = coeffs[i]

        wfn2 = tequila.simulators.simulator_api.simulate(U,
                                                         initial_state=0,
                                                         variables=None)

        for k, v in wfn.items():
            assert (numpy.isclose(wfn2[k], v))

    except TequilaUnaryStateException:
        print("caught a tolerated excpetion")
Пример #4
0
def test_unary_states(target_space: list):
    UPS = UnaryStatePrep(target_space=target_space)
    qubits = len(target_space)
    coeff = 1.0 / numpy.sqrt(
        qubits
    )  # fails for the 3-Qubit Case because the wrong sign is picked in the solution
    coeffs = [coeff for i in range(qubits)]

    wfn = QubitWaveFunction()
    for i, c in enumerate(coeffs):
        wfn += c * QubitWaveFunction.from_string("1.0|" + target_space[i] +
                                                 ">")

    U = UPS(wfn=wfn)
    wfn = BackendCircuitSymbolic(abstract_circuit=U,
                                 variables=None).simulate(variables=None)

    checksum = 0.0
    for k, v in wfn.items():
        assert (v.imag == 0.0)
        vv = numpy.float(v.real)
        cc = numpy.float(coeff.real)
        assert (numpy.isclose(vv, cc, atol=1.e-4))
        checksum += vv

    assert (numpy.isclose(checksum, qubits * coeff, atol=1.e-4))
Пример #5
0
def Projector(wfn, threshold=0.0, n_qubits=None) -> QubitHamiltonian:
    """
    Notes
    ----------
    Initialize a projector given by

    .. math::
        H = \\lvert \\Psi \\rangle \\langle \\Psi \\rvert

    Parameters
    ----------
    wfn: QubitWaveFunction or int, or string, or array :
        The wavefunction onto which the projector projects
        Needs to be passed down as tequilas QubitWaveFunction type
        See the documentation on how to initialize a QubitWaveFunction from
        integer, string or array (can also be passed down diretly as one of those types)


    threshold: float: (Default value = 0.0)
        neglect small parts of the operator

    n_qubits: only needed when an integer is given as wavefunction

    Returns
    -------

    """

    wfn = QubitWaveFunction(state=wfn, n_qubits=n_qubits)

    H = QubitHamiltonian.zero()
    for k1, v1 in wfn.items():
        for k2, v2 in wfn.items():
            c = v1.conjugate() * v2
            if not numpy.isclose(c, 0.0, atol=threshold):
                H += c * decompose_transfer_operator(bra=k1, ket=k2)
    assert (H.is_hermitian())
    return H
Пример #6
0
def strip_sympy_zeros(wfn: QubitWaveFunction):
    result = QubitWaveFunction()
    for k, v in wfn.items():
        if v != 0:
            result[k] = v
    return result