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 test_simple_arithmetic(): qubit = random.randint(0, 5) primitives = [paulis.X, paulis.Y, paulis.Z] assert (paulis.X(qubit).conjugate() == paulis.X(qubit)) assert (paulis.Y(qubit).conjugate() == -1 * paulis.Y(qubit)) assert (paulis.Z(qubit).conjugate() == paulis.Z(qubit)) assert (paulis.X(qubit).transpose() == paulis.X(qubit)) assert (paulis.Y(qubit).transpose() == -1 * paulis.Y(qubit)) assert (paulis.Z(qubit).transpose() == paulis.Z(qubit)) for P in primitives: assert (P(qubit) * P(qubit) == QubitHamiltonian(1.0)) n = random.randint(0, 10) nP = QubitHamiltonian.zero() for i in range(n): nP += P(qubit) assert (n * P(qubit) == nP) for i, Pi in enumerate(primitives): i1 = (i + 1) % 3 i2 = (i + 2) % 3 assert (Pi(qubit) * primitives[i1](qubit) == 1j * primitives[i2](qubit)) assert (primitives[i1](qubit) * Pi(qubit) == -1j * primitives[i2](qubit)) for qubit2 in random.randint(6, 10, 5): if qubit2 == qubit: continue P = primitives[random.randint(0, 2)] assert (Pi(qubit) * primitives[i1](qubit) * P(qubit2) == 1j * primitives[i2](qubit) * P(qubit2)) assert (P(qubit2) * primitives[i1](qubit) * Pi(qubit) == -1j * P(qubit2) * primitives[i2](qubit))
def Zero(*args, **kwargs) -> QubitHamiltonian: """ Initialize 0 Operator Returns ------- QubitHamiltonian """ return QubitHamiltonian.zero()
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)
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