docs: def transition_matrix_metropolis_1d(E, d=1.0):
      r"""Transition matrix describing the Metropolis chain jumping
      between neighbors in a discrete 1D energy landscape.
  
      Parameters
      ----------
      E : (M,) ndarray
          Energies in units of kT
      d : float (optional)
          Diffusivity of the chain, d in (0, 1]
  
      Returns
      -------
      P : (M, M) ndarray
          Transition matrix of the Markov chain
  
      Notes
      -----
      Transition probabilities are computed as
      .. math::
          p_{i,i-1} &=& 0.5 d \min \left{ 1.0, \mathrm{e}^{-(E_{i-1} - E_i)} \right}, \\
          p_{i,i+1} &=& 0.5 d \min \left{ 1.0, \mathrm{e}^{-(E_{i+1} - E_i)} \right}, \\
          p_{i,i}   &=& 1.0 - p_{i,i-1} - p_{i,i+1}.
  
      """
      # check input
      if (d <= 0 or d > 1):
          raise ValueError('Diffusivity must be in (0,1]. Trying to set the invalid value', str(d))
      # init
      n = len(E)
      P = np.zeros((n, n))
      # set offdiagonals
      P[0, 1] = 0.5 * d * min(1.0, math.exp(-(E[1] - E[0])))
      for i in range(1, n - 1):
          P[i, i - 1] = 0.5 * d * min(1.0, math.exp(-(E[i - 1] - E[i])))
          P[i, i + 1] = 0.5 * d * min(1.0, math.exp(-(E[i + 1] - E[i])))
      P[n - 1, n - 2] = 0.5 * d * min(1.0, math.exp(-(E[n - 2] - E[n - 1])))
      # normalize
      P += np.diag(1.0 - np.sum(P, axis=1))
      # done
      return P