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
Example #2
0
    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