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 add_basis_state(self, state: Dict[str, Dict[int, int]], coeff=1): if isinstance(state, str): state = self.string_to_basis_state(string=state) qubit_string = BitString.from_int(integer=0, nbits=self.n_qubits) for p, v in state.items(): for m, occ in v.items(): mode = self.get_mode(p, m) occ = BitString.from_int(integer=occ, nbits=mode.n_qubits) for i, q in enumerate(mode.qubits): qubit_string[q] = occ[i] self._state += QubitWaveFunction.from_int(i=qubit_string, coeff=coeff)
def reference_state(self, reference_orbitals: list = None, n_qubits: int = None) -> BitString: """Does a really lazy workaround ... but it works :return: Hartree-Fock Reference as binary-number Parameters ---------- reference_orbitals: list: give list of doubly occupied orbitals default is None which leads to automatic list of the first n_electron/2 orbitals Returns ------- """ if reference_orbitals is None: reference_orbitals = [i for i in range(self.n_electrons // 2)] spin_orbitals = sorted([2 * i for i in reference_orbitals] + [2 * i + 1 for i in reference_orbitals]) if n_qubits is None: n_qubits = 2 * self.n_orbitals string = "" for i in spin_orbitals: string += str(i) + "^ " fop = openfermion.FermionOperator(string, 1.0) op = QubitHamiltonian(qubit_hamiltonian=self.transformation(fop)) from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction wfn = QubitWaveFunction.from_int(0, n_qubits=n_qubits) wfn = wfn.apply_qubitoperator(operator=op) assert (len(wfn.keys()) == 1) keys = [k for k in wfn.keys()] return keys[-1]
def test_ketbra_random(n_qubits): ket = numpy.random.uniform(0.0, 1.0, 2**n_qubits) bra = QubitWaveFunction.from_int(0, n_qubits=n_qubits) operator = paulis.KetBra(ket=ket, bra=bra) result = operator * bra assert result == QubitWaveFunction.from_array(ket)
def test_ketbra(): ket = QubitWaveFunction.from_string("1.0*|00> + 1.0*|11>").normalize() operator = paulis.KetBra(ket=ket, bra="|00>") result = operator * QubitWaveFunction.from_int(0, n_qubits=2) assert (result == ket)