code: private double computeLearningRate(int i) {
          if (gradAccum[i] < 0) {
              throw new RuntimeException("Gradient accumulator is < 0: " + gradAccum[i]);
          }
          if (updAccum[i] < 0) {
              throw new RuntimeException("Update accumulator is < 0: " + updAccum[i]);
          }
  
          double learningRate = Math.sqrt((updAccum[i] + prm.constantAddend) / (gradAccum[i] + prm.constantAddend));        
          assert !Double.isNaN(learningRate);
          // We shouldn't ever worry about infinities because of the constantAdded being > 0.
          assert !Double.isInfinite(learningRate);
          
          return learningRate;
      }
docs: The entire point of this method is to carefully compute the following:
  <p>
  Math.sqrt(updAccum[i] + prm.constantAddend) / Math.sqrt(gradAccum[i] + prm.constantAddend);
  </p>
  without running into boundary cases.
  
  @param i The index of the parameter for which to compute the learning rate.
  @return The learning rate for that parameter.