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))
Example #2
0
def test_endianness_simulators():
    tests = [
        "000111", "111000", "101010", "010101", "10010010001",
        "111100101000010"
    ]

    for string in tests:
        number = int(string, 2)
        binary = BitString.from_binary(binary=string)
        c = QCircuit()
        for i, v in enumerate(binary):
            if v == 1:
                c += gates.X(target=i)

        c += gates.Measurement(target=[x for x in range(len(string))])

        wfn_cirq = simulate(c, initial_state=0, backend="cirq")
        counts_cirq = simulate(c, samples=1, backend="cirq")
        counts_qiskit = simulate(c, samples=1, backend="qiskit")
        print("counts_cirq  =", type(counts_cirq))
        print("counts_qiskit=", type(counts_qiskit))
        print("counts_cirq  =", counts_cirq)
        print("counts_qiskit=", counts_qiskit)
        assert (counts_cirq == counts_qiskit)
        assert (wfn_cirq.state == counts_cirq.state)
Example #3
0
def test_endianness_simulators():
    tests = ["000111",
             "111000",
             "101010",
             "010101",
             "10010010001",
             "111100101000010"]

    for string in tests:
        binary = BitString.from_binary(binary=string)
        c = QCircuit()
        for i, v in enumerate(binary):
            if v == 1:
                c += gates.X(target=i)
            if v == 0:
                c += gates.Z(target=i)

        wfn_cirq = simulate(c, initial_state=0, backend="cirq")
        counts_cirq = simulate(c, samples=1, backend="cirq")
        counts_qiskit = simulate(c, samples=1, backend="qiskit")
        print("counts_cirq  =", type(counts_cirq))
        print("counts_qiskit=", type(counts_qiskit))
        print("counts_cirq  =", counts_cirq)
        print("counts_qiskit=", counts_qiskit)
        assert (counts_cirq.isclose(counts_qiskit))
        assert (wfn_cirq.state == counts_cirq.state)
Example #4
0
def test_constructor():
    for i in range(15):
        bita = BitString.from_int(integer=i)
        bita_lsb = BitStringLSB.from_int(integer=i)
        bitb = BitString.from_int(integer=bita)
        bitc = BitString.from_int(integer=bita_lsb)
        bitd = BitString.from_array(array=bita)
        bite = BitString.from_array(array=bita_lsb)
        bitf = BitString.from_binary(binary=bita)
        bitg = BitString.from_binary(binary=bita_lsb)
        assert (bita == bitb)
        assert (bita == bitc)
        assert (bita == bitd)
        assert (bita == bite)
        assert (bita == bitf)
        assert (bita == bitg)
Example #5
0
    def convert_measurements(self,
                             backend_result,
                             target_qubits=None) -> QubitWaveFunction:
        """
        Transform backend evaluation results into QubitWaveFunction
        Parameters
        ----------
        backend_result:
            the return value of backend simulation.

        Returns
        -------
        QubitWaveFunction
            results transformed to tequila native QubitWaveFunction
        """

        result = QubitWaveFunction()
        # todo there are faster ways

        for k, v in backend_result.frequencies(binary=True).items():
            converted_key = BitString.from_bitstring(
                other=BitString.from_binary(binary=k))
            result._state[converted_key] = v

        if target_qubits is not None:
            mapped_target = [self.qubit_map[q].number for q in target_qubits]
            mapped_full = [
                self.qubit_map[q].number for q in self.abstract_qubits
            ]
            keymap = KeyMapRegisterToSubregister(subregister=mapped_target,
                                                 register=mapped_full)
            result = result.apply_keymap(keymap=keymap)

        return result
Example #6
0
def test_notation(silent=True):
    qpm = 2
    S = 2

    # State |-201>_(abc) represented with 2 qubits per mode
    # in Qubits
    # |01 00 00 00 00 | 00 00 01 00 00 | 00 00 00 01 00 >
    test1 = BitString.from_binary(binary='010000000000000100000000000100')
    paths = PhotonicPaths(path_names=['a', 'b', 'c'], S=S, qpm=qpm)

    wfn1 = QubitWaveFunction.from_int(i=test1)
    test1x = PhotonicStateVector(paths=paths, state=wfn1)
    test1y = PhotonicStateVector.from_string(
        paths=paths, string='1.0|10000>_a|00100>_b|00010>_c')
    if not silent:
        print("got      = ", test1x)
        print("expected = ", test1y)
    assert (test1x == test1y)

    # Do a 332 State:
    # Photonic notation: (one photon in each mode and I added -2 and +2 modes)
    # |1-11>_a+|000>_b+|-111>_c
    # Qudit Notation: With modes -2 ... 2
    #   | 0 0 0 1 0 >_a | 0 1 0 0 0 >_b | 0 0 0 1 0 >_c
    # + | 0 0 1 0 0 >_a | 0 0 1 0 0 >_b | 0 0 1 0 0 >_c
    # + | 0 1 0 0 0 >_a | 0 0 0 1 0 >_b | 0 0 0 1 0 >_c
    # Qubit notation: (using 2 qubits for each mode)
    #   | 00 00 00 01 00 >_a | 00 01 00 00 00 >_b | 00 00 00 01 00 >_c
    # + | 00 00 01 00 00 >_a | 00 00 01 00 00 >_b | 00 00 01 00 00 >_c
    # + | 00 01 00 00 00 >_a | 00 00 00 01 00 >_b | 00 00 00 01 00 >_c

    string = '1.0|00010>_a|01000>b|00010>_c+1.0|00100>_a|00100>_b|00100>_c+1.0|01000>_a|00010>_b|00010>_c'
    test_332x = PhotonicStateVector.from_string(paths=paths, string=string)

    q1 = BitString.from_binary('000000010000010000000000000100')
    q2 = BitString.from_binary('000001000000000100000000010000')
    q3 = BitString.from_binary('000100000000000001000000000100')
    wfn = QubitWaveFunction()
    for q in [q1, q2, q3]:
        wfn += QubitWaveFunction.from_int(i=q)
    test_332y = PhotonicStateVector(paths=paths, state=wfn)
    if not silent:
        print("got      = ", test_332y)
        print("expected = ", test_332x)
    assert (test_332x == test_332y)
Example #7
0
def test_endianness():
    tests = [
        "000111", "111000", "101010", "010101", "10010010001",
        "111100101000010"
    ]

    for string in tests:
        bits = len(string)
        i1 = BitString.from_int(int(string, 2))
        i2 = BitString.from_binary(binary=string)
        assert (i1 == i2)

        i11 = BitStringLSB.from_int(int(string, 2))
        i22 = BitStringLSB.from_binary(binary=string[::-1])
        assert (i11 == i22)
        assert (i11.integer == i1.integer)
        assert (i22.integer == i2.integer)
        assert (i11.integer == i2.integer)
        assert (i1 == BitString.from_bitstring(i11))
        assert (i1 == BitString.from_bitstring(i22))
        assert (i2 == BitString.from_bitstring(i11))
Example #8
0
    def __init__(self,
                 target_space: typing.List[BitString],
                 max_repeat: int = 100,
                 use_symbolic_solution: bool = False):
        """
        :param target_space: Give the target space by its basis functions
        e.g. target_space = ['00', '11']
        :param use_symbolic_solution: Solve for angles purely symbolic (fails a lot of times due to sign errors)
        the sympy interface is probably not used correctly. If False numerical solvers are used which work better
        :param max_repeat: maximum numbers of repetitions for numerical solver
        the target space can be given as list of strings (binaries) or BitString objects
        """

        self._use_symbolic_solver = use_symbolic_solution
        self.max_repeat = max_repeat

        if isinstance(target_space, QubitWaveFunction):
            target_space = [f for f in target_space.keys()]
        if isinstance(target_space[0], str):
            target_space = [
                BitString.from_binary(binary=i) for i in target_space
            ]

        self._n_qubits = target_space[0].nbits

        abstract_coefficients = dict()
        for bf in target_space:
            abstract_coefficients[bf] = sympy.var("c(" + bf.binary + ")")

        # code is currenty unstable but can still succeed if input is shuffled
        # todo: that should not happen, but untill it is fixed I will increase success probability
        count = 0
        success = False

        while (not success and count < self.max_repeat):
            try:
                count += 1
                IMPL = UnaryStatePrepImpl()
                abstract_angles = [
                    sympy.var(IMPL.alphabet(i))
                    for i in range(len(target_space) - 1)
                ]
                self._abstract_circuit = IMPL.get_circuit(
                    s=[i.binary for i in target_space])
                self._abstract_circuit.n_qubits = self._n_qubits
                success = True
            except NotImplementedError:
                numpy.random.shuffle(target_space)

        if not success:
            raise TequilaUnaryStateException(
                "Could not disentangle the given state after " + str(count) +
                " restarts")

        # get the equations to determine the angles
        simulator = BackendCircuitSymbolic(
            abstract_circuit=self._abstract_circuit, variables={})
        simulator.convert_to_numpy = False
        variables = None  # {k:k.name.evalf() for k in self._abstract_circuit.extract_variables()}
        wfn = simulator.simulate(initial_state=BitString.from_int(
            0, nbits=self.n_qubits),
                                 variables=variables)
        wfn.n_qubits = self._n_qubits
        equations = []
        for k in target_space:
            equations.append(wfn[k] - abstract_coefficients[k])

        normeq = -sympy.Integer(1)
        for c in abstract_coefficients.values():
            normeq += c**2
        equations.append(normeq)

        # this gives back multiple solutions and some of them sometimes have sign errors ...
        if (self._use_symbolic_solver):
            solutions = sympy.solve(equations,
                                    *tuple(abstract_angles),
                                    check=True,
                                    dict=True)[1]
            if len(abstract_angles) != len(solutions):
                raise TequilaUnaryStateException(
                    "Could definetely not solve for the angles in UnaryStatePrep!"
                )
            self._angle_solutions = solutions

        self._target_space = target_space
        self._abstract_angles = abstract_angles
        self._equations = equations
        self._abstract_coeffs = abstract_coefficients

        if self._n_qubits < len(self._target_space):
            print(
                "WARNING: UnaryStatePrep initialized with more basis states than qubits -> that might not work"
            )