code: public static IntDoubleVector estimateGradientSpsa(Function fn, IntDoubleVector x, int numSamples) {
          int numParams = fn.getNumDimensions();
          // The gradient estimate
          IntDoubleVector grad = new IntDoubleDenseVector(numParams);
          for (int k=0; k<numSamples; k++) {   
              // Get a random direction
              IntDoubleVector d = getRandomBernoulliDirection(numParams);
              double scaler = getGradDotDirApprox(fn, x, d);
              for (int i=0; i< numParams; i++) {
                  grad.add(i, scaler * 1.0 / d.get(i));
              }
          }
          grad.scale(1.0 / numSamples);
          return grad;
      }
docs: Estimates a gradient of a function by simultaneous perterbations
  stochastic approximation (SPSA) (Spall, 1992).
  
  @param fn Function on which to approximate the gradient.
  @param x Point at which to approximate the gradient.
  @param numSamples Number of samples to take, which will be averaged
  together (typically 1).
  @return The gradient approximation.