/**
   * This method applies a stacked autoencoders model to a given dataset and make predictions
   *
   * @param ctxt JavaSparkContext
   * @param deeplearningModel Stacked Autoencoders model
   * @param test Testing dataset as a JavaRDD of labeled points
   * @return
   */
  public JavaPairRDD<Double, Double> test(
      JavaSparkContext ctxt,
      final DeepLearningModel deeplearningModel,
      JavaRDD<LabeledPoint> test,
      MLModel mlModel)
      throws MLModelBuilderException {

    Scope.enter();

    if (deeplearningModel == null) {
      throw new MLModelBuilderException("DeeplearningModel is Null");
    }

    int numberOfFeatures = mlModel.getFeatures().size();
    List<Feature> features = mlModel.getFeatures();
    String[] names = new String[numberOfFeatures + 1];
    for (int i = 0; i < numberOfFeatures; i++) {
      names[i] = features.get(i).getName();
    }
    names[numberOfFeatures] = mlModel.getResponseVariable();

    Frame testData = DeeplearningModelUtils.javaRDDToFrame(names, test);
    Frame testDataWithoutLabels = testData.subframe(0, testData.numCols() - 1);
    int numRows = (int) testDataWithoutLabels.numRows();
    Vec predictionsVector = deeplearningModel.score(testDataWithoutLabels).vec(0);
    double[] predictionValues = new double[numRows];
    for (int i = 0; i < numRows; i++) {
      predictionValues[i] = predictionsVector.at(i);
    }
    Vec labelsVector = testData.vec(testData.numCols() - 1);
    double[] labels = new double[numRows];
    for (int i = 0; i < numRows; i++) {
      labels[i] = labelsVector.at(i);
    }

    Scope.exit();

    ArrayList<Tuple2<Double, Double>> tupleList = new ArrayList<Tuple2<Double, Double>>();
    for (int i = 0; i < labels.length; i++) {
      tupleList.add(new Tuple2<Double, Double>(predictionValues[i], labels[i]));
    }

    return ctxt.parallelizePairs(tupleList);
  }