@Override
 public void save(final int t, final AugmentedPredictionErrors pe) {
   DataBlock U = pe.getTransformedPredictionErrors();
   Matrix L = pe.getCholeskyFactor();
   DataBlock D = L.diagonal();
   Matrix E = pe.E();
   int nvars = E.getColumnsCount();
   n += nvars;
   LogSign sld = D.sumLog();
   det += sld.value;
   Q.subMatrix(0, nd, nd + 1, nd + 1 + nvars).copy(E.subMatrix());
   Q.row(nd).range(nd + 1, nd + 1 + nvars).copy(U);
   ec.tstoolkit.maths.matrices.ElementaryTransformations.fastGivensTriangularize(Q.subMatrix());
 }
  @Override
  public boolean collapse(AugmentedState state) {
    if (state.getInfo() != StateInfo.Forecast) {
      return false;
    }
    if (!isPositive(Q.diagonal().drop(0, 1))) {
      return false;
    }

    // update the state vector
    Matrix A = new Matrix(state.B());
    int d = A.getColumnsCount();
    Matrix S = new Matrix(a());
    LowerTriangularMatrix.rsolve(S, A.subMatrix().transpose());
    DataBlock D = b().deepClone();
    LowerTriangularMatrix.lsolve(S, D);
    for (int i = 0; i < d; ++i) {
      DataBlock col = A.column(i);
      state.a().addAY(-Q.get(d, i), col);
      state.P().addXaXt(1, col);
    }
    state.dropAllConstraints();
    return true;
  }
 @Override
 public boolean canCollapse() {
   return !isPositive(Q.diagonal().drop(0, 1));
 }