docs: private void computeDir(double[] dir, double[] fg, QNInfo qn)
        throws SurpriseConvergence {
      System.arraycopy(fg, 0, dir, 0, fg.length);
  
      int mmm = qn.size();
      double[] as = new double[mmm];
  
      for (int i = mmm - 1; i >= 0; i--) {
        as[i] = qn.getRho(i) * ArrayMath.innerProduct(qn.getS(i), dir);
        plusAndConstMult(dir, qn.getY(i), -as[i], dir);
      }
  
      // multiply by hessian approximation
      qn.applyInitialHessian(dir);
  
      for (int i = 0; i < mmm; i++) {
        double b = qn.getRho(i) * ArrayMath.innerProduct(qn.getY(i), dir);
        plusAndConstMult(dir, qn.getS(i), as[i] - b, dir);
      }
  
      ArrayMath.multiplyInPlace(dir, -1);
    }