Source code for quantum_launcher.utils

 1from typing import Iterable, Dict, Tuple, Set, List
 2from quantum_launcher.import_management import DependencyError
 3try:
 4    from qiskit.quantum_info import SparsePauliOp
 5except ImportError as e:
 6    raise DependencyError(e, 'qiskit') from e
 7
 8
[docs] 9def qubo_to_hamiltonian(qubo: Iterable[Iterable[int]] | Dict[Tuple[str, str], float], offset: float = 0) -> SparsePauliOp: 10 """ 11 Convert a QUBO into a quadratic Hamiltonian in the form of a SparsePauliOp. 12 13 Args: 14 qubo (Iterable[Iterable[int]] | Dict[Tuple[str, str], float]): Quadratic Unconstrained Binary Optimization written in the form of matrix or dictionary[Tuple[key, key], value]. 15 offset (float, optional): The offset (constant) value that will be added to identity. Defaults to 0. 16 17 Returns: 18 SparsePauliOp: _description_ 19 """ 20 21 if isinstance(qubo, dict): 22 return _qubo_dict_into_hamiltonian(qubo, offset) 23 elif isinstance(qubo, Iterable): 24 return _qubo_matrix_into_hamiltonian(qubo, offset) 25 raise ValueError("QUBO must be a matrix or a dictionary")
26 27 28def _qubo_matrix_into_hamiltonian(qubo: Iterable[Iterable[int]], offset: float = 0) -> SparsePauliOp: 29 N = len(qubo) 30 assert all(len(row) == N for row in qubo), "QUBO matrix must be square" 31 32 sparse_list: List[Tuple[str, List, float]] = [] 33 constant: float = offset 34 for ind_r, row in enumerate(qubo): 35 val = row[ind_r] 36 constant += val/2 37 sparse_list.append(('Z', [ind_r], -val / 2)) 38 for ind_c, val in enumerate(row[ind_r + 1:], ind_r + 1): 39 if val != 0: 40 constant += val / 4 41 sparse_list.append(('Z', [ind_r], -val / 4)) 42 sparse_list.append(('Z', [ind_c], -val / 4)) 43 sparse_list.append(('ZZ', [ind_r, ind_c], val / 4)) 44 hamiltonian: SparsePauliOp = SparsePauliOp.from_sparse_list(sparse_list, N) 45 hamiltonian += SparsePauliOp.from_sparse_list([('I', [0], constant)], N) 46 return hamiltonian.simplify() 47 48 49def _qubo_dict_into_hamiltonian(qubo: Dict[Tuple[str, str], float], offset: float = 0) -> SparsePauliOp: 50 label_set: Set[str] = set() 51 for (arg1, arg2) in sorted(qubo.keys()): 52 if arg1 not in label_set: 53 label_set.add(arg1) 54 if arg2 not in label_set: 55 label_set.add(arg2) 56 57 labels = {label: i for i, label in enumerate(sorted(label_set))} 58 59 N: int = len(labels) 60 61 sparse_list: List[Tuple[str, List, float]] = [] 62 constant: float = offset 63 for (arg1, arg2), coeff in qubo.items(): 64 if arg1 == arg2: 65 constant += coeff / 2 66 sparse_list.append(('Z', [labels[arg1]], -coeff / 2)) 67 else: 68 constant += coeff / 4 69 sparse_list.append(('ZZ', [labels[arg1], labels[arg2]], coeff / 4)) 70 sparse_list.append(('Z', [labels[arg1]], -coeff / 4)) 71 sparse_list.append(('Z', [labels[arg2]], -coeff / 4)) 72 73 hamiltonian = SparsePauliOp.from_sparse_list(sparse_list, N) 74 hamiltonian += SparsePauliOp.from_sparse_list([('I', [0], constant)], N) 75 76 return hamiltonian.simplify()