def _create_normalize_state(self, solver): if "rk" in solver: norm = Norm() log.info('Normalizing state during RK solution.') return lambda s: s / K.cast(norm(s), dtype=s.dtype) else: return lambda s: s
def __init__(self, hamiltonian, dt, solver="exp", callbacks=[], accelerators=None, memory_device="/CPU:0"): if isinstance(hamiltonian, hamiltonians.HAMILTONIAN_TYPES): ham = hamiltonian else: ham = hamiltonian(0) if not isinstance(ham, hamiltonians.HAMILTONIAN_TYPES): raise TypeError("Hamiltonian type {} not understood." "".format(type(ham))) self.nqubits = ham.nqubits if dt <= 0: raise_error(ValueError, f"Time step dt should be positive but is {dt}.") self.dt = dt if (accelerators is not None and (not isinstance(ham, hamiltonians.TrotterHamiltonian) or solver != "exp")): raise_error( NotImplementedError, "Distributed evolution is only " "implemented using the Trotter " "exponential solver.") if isinstance(ham, hamiltonians.TrotterHamiltonian): ham.circuit(dt, accelerators, memory_device) self.solver = solvers.factory[solver](self.dt, hamiltonian) self.callbacks = callbacks if "rk" in solver: norm = Norm() self.normalize_state = lambda s: s / K.cast(norm(s), dtype=s.dtype) log.info('Normalizing state during RK solution.') else: self.normalize_state = lambda s: s self.accelerators = accelerators def calculate_callbacks(state): for callback in self.callbacks: callback.append(callback(state)) if accelerators is None: self._calculate_callbacks = calculate_callbacks else: def calculate_callbacks_distributed(state): with K.device(memory_device): if not isinstance(state, (np.ndarray, K.Tensor)): state = state.vector calculate_callbacks(state) self._calculate_callbacks = calculate_callbacks_distributed