code: private void backward(int[] o, double[][] beta, double[] scaling) {
          int n = o.length - 1;
          for (int i = 0; i < numStates; i++) {
              beta[n][i] = 1.0 / scaling[n];
          }
  
          for (int t = n; t-- > 0;) {
              for (int i = 0; i < numStates; i++) {
                  double sum = 0.;
  
                  for (int j = 0; j < numStates(); j++) {
                      sum += beta[t + 1][j] * a[i][j] * b[j][o[t + 1]];
                  }
  
                  beta[t][i] = sum / scaling[t];
              }
          }
      }
docs: Scaled backward procedure without underflow.
  
  @param o an observation sequence.
  @param beta on output, beta(i, j) holds the scaled total probability of
  starting up in state i at time j.
  @param scaling on input, it should hold scaling factors computed by
  forward procedure.