docs: public static void step(long seed, Neurons[] neurons, DeepLearningModel.DeepLearningModelInfo minfo, boolean training, double[] responses) {
      try {
        for (int i=1; i<neurons.length-1; ++i) {
          neurons[i].fprop(seed, training);
        }
        if (minfo.get_params().autoencoder) {
          neurons[neurons.length - 1].fprop(seed, training);
          if (training) {
            for (int i=neurons.length-1; i>0; --i) {
              neurons[i].bprop();
            }
          }
        } else {
          if (minfo.get_params().classification) {
            ((Neurons.Softmax) neurons[neurons.length - 1]).fprop();
            if (training) {
              for (int i = 1; i < neurons.length - 1; i++)
                Arrays.fill(neurons[i]._e.raw(), 0);
              int target_label;
              if (Double.isNaN(responses[0])) { //missing response
                target_label = Neurons.missing_int_value;
              } else {
                assert ((double) (int) responses[0] == responses[0]); //classification -> integer labels expected
                target_label = (int) responses[0];
              }
              ((Neurons.Softmax) neurons[neurons.length - 1]).bprop(target_label);
            }
          } else {
            ((Neurons.Linear) neurons[neurons.length - 1]).fprop();
            if (training) {
              for (int i = 1; i < neurons.length - 1; i++)
                Arrays.fill(neurons[i]._e.raw(), 0);
              float target_value;
              if (Double.isNaN(responses[0])) { //missing response
                target_value = Neurons.missing_real_value;
              } else {
                target_value = (float) responses[0];
              }
              ((Neurons.Linear) neurons[neurons.length - 1]).bprop(target_value);
            }
          }
          if (training) {
            for (int i=neurons.length-2; i>0; --i)
              neurons[i].bprop();
          }
        }
      }
      catch(RuntimeException ex) {
        Log.warn(ex.getMessage());
        minfo.set_unstable();
        throw new Job.JobCancelledException("Canceling job due to numerical instability.");
      }
    }