code: public static IntDoubleVector estimateGradientFd(Function fn, IntDoubleVector x, double epsilon) {
          int numParams = fn.getNumDimensions();
          IntDoubleVector gradFd = new IntDoubleDenseVector(numParams);                      
          for (int j=0; j<numParams; j++) {
              // Test the deriviative d/dx_j(f_i(\vec{x}))
              IntDoubleVector d = new IntDoubleDenseVector(numParams);
              d.set(j, 1);
              double dotFd = getGradDotDirApprox(fn, x, d, epsilon);
              if (Double.isNaN(dotFd)) {
                  log.warn("Hit NaN");
              }
              gradFd.set(j, dotFd);
          }
          return gradFd;
      }
docs: Estimates a gradient of a function by an independent finite-difference computation along each
  dimension of the domain of the function.
  
  @param fn Function on which to approximate the gradient.
  @param x Point at which to approximate the gradient.
  @param epsilon The size of the finite difference step.
  @return The approximate gradient.