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))
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)
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)
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)
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
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)
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))
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" )