def backward(self):
        """Backward recursion. 

        Upon completion, the following list of length T is available: 
        * smth: marginal smoothing probabilities

        Note
        ----
        Performs the forward step in case it has not been performed before. 
        """
        if not self.filt:
            self.forward()
        self.smth = [self.filt[-1]]
        log_trans = np.log(self.hmm.trans_mat)
        ctg = np.zeros(self.hmm.dim)  # cost to go (log-lik of y_{t+1:T} given x_t=k)
        for filt, next_ft in reversed(list(zip(self.filt[:-1], 
                                               self.logft[1:]))):
            new_ctg = np.empty(self.hmm.dim)
            for k in range(self.hmm.dim):
                new_ctg[k] = rs.log_sum_exp(log_trans[k, :] + next_ft + ctg)
            ctg = new_ctg
            smth = rs.exp_and_normalise(np.log(filt) + ctg)
            self.smth.append(smth)
        self.smth.reverse()
Backward recursion. 

        Upon completion, the following list of length T is available: 
        * smth: marginal smoothing probabilities

        Note
        ----
        Performs the forward step in case it has not been performed before.