docs: public static DoubleAD logSum(DoubleAD[] logInputs, int fromIndex, int toIndex) {
      if (logInputs.length == 0)
        throw new IllegalArgumentException();
      if(fromIndex >= 0 && toIndex < logInputs.length && fromIndex >= toIndex)
        return new DoubleAD(Double.NEGATIVE_INFINITY,Double.NEGATIVE_INFINITY);
      int maxIdx = fromIndex;
      double max = logInputs[fromIndex].getval();
      double maxdot = logInputs[fromIndex].getdot();
  
      for (int i = fromIndex+1; i < toIndex; i++) {
        if (logInputs[i].getval() > max) {
          maxIdx = i;
          maxdot = logInputs[i].getdot();
          max = logInputs[i].getval();
        }
      }
  
      DoubleAD ret = new DoubleAD();
      boolean haveTerms = false;
      double intermediate = 0.0;
      double intermediateDot = 0.0;
      double curEXP;
      double cutoff = max - SloppyMath.LOGTOLERANCE;
      // we avoid rearranging the array and so test indices each time!
      for (int i = fromIndex; i < toIndex; i++) {
        if (i != maxIdx && logInputs[i].getval() > cutoff) {
          haveTerms = true;
          curEXP = Math.exp(logInputs[i].getval() - max);
          intermediate += curEXP;
          intermediateDot += curEXP*logInputs[i].getdot();
        }
      }
      if (haveTerms) {
        ret.setval(max + Math.log(1.0 + intermediate));
        ret.setdot((maxdot + intermediateDot)/(1.0 + intermediate));
      } else {
        ret.setval(max);
        ret.setdot(maxdot);
      }
        return ret;
    }