code: def backward_sampling_qmc(self, M):
          
          self._check_h_orders()
          u = qmc.sobol(M, self.T)
          # the final particles have not been sorted
          hT = hilbert.hilbert_sort(self.X[-1])
          # searchsorted to avoid having to sort in place u according to u[:,T-1]
          idx = np.searchsorted(np.cumsum(self.wgt[-1].W[hT]), u[:, -1])
          paths = [self.X[-1][hT][idx], ]
          for t in reversed(range(self.T - 1)):
              idx = np.empty(M, 'int')
              for m, xn in enumerate(paths[-1]):
                  lwm = self.wgt[t].lw + self.model.logpt(t + 1, self.X[t], xn)
                  # use ordered version here
                  cw = np.cumsum(rs.exp_and_normalise(lwm[self.h_orders[t]]))
                  idx[m] = np.searchsorted(cw, u[m, t])
              paths.append(self.X[t][self.h_orders[t]][idx])
          paths.reverse()
          return paths
docs: QMC version of backward sampling.
          
          Parameters
          ----------
          M : int
              number of trajectories
  
          Note
          ----
          Use this only on the history of a SQMC algorithm.