docs: private StochasticGradientTrainer createStochasticGradientTrainer(int numExamples) {
      Preconditions.checkState(opts.contains(CommonOptions.STOCHASTIC_GRADIENT));
  
      long iterationsOption = parsedOptions.valueOf(sgdIterations);
      int batchSize = numExamples;
      if (parsedOptions.has(sgdBatchSize)) {
        batchSize = parsedOptions.valueOf(sgdBatchSize);
      }
      long numIterations = (int) Math.ceil(iterationsOption * numExamples / ((double) batchSize));
      double initialStepSize = parsedOptions.valueOf(sgdInitialStep);
      double l2Regularization = parsedOptions.valueOf(sgdL2Regularization);
  
      LogFunction log = LogFunctions.getLogFunction();
      StochasticGradientTrainer trainer = null;
      if (!parsedOptions.has(sgdAdagrad)) {
        trainer = StochasticGradientTrainer.createWithStochasticL2Regularization(
            numIterations, batchSize, initialStepSize, !parsedOptions.has(sgdNoDecayStepSize),
            !parsedOptions.has(sgdNoReturnAveragedParameters), parsedOptions.valueOf(sgdClipGradients),
            l2Regularization, parsedOptions.valueOf(sgdRegularizationFrequency), log);
      } else {
        trainer = StochasticGradientTrainer.createAdagrad(
            numIterations, batchSize, initialStepSize, !parsedOptions.has(sgdNoDecayStepSize),
            !parsedOptions.has(sgdNoReturnAveragedParameters), parsedOptions.valueOf(sgdClipGradients),
            l2Regularization, parsedOptions.valueOf(sgdRegularizationFrequency), log);
      }
  
      return trainer;
    }