@Override
  public double[][] learn(double[] x, double[] y) {
    try {
      lambda = Double.parseDouble(lambdaField.getText().trim());
      if (lambda < 0.0) {
        JOptionPane.showMessageDialog(
            this, "Invalid \u03BB: " + lambda, "Error", JOptionPane.ERROR_MESSAGE);
        return null;
      }
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(
          this, "Invalid \u03BB: " + lambdaField.getText(), "Error", JOptionPane.ERROR_MESSAGE);
      return null;
    }

    double[][] data = dataset[datasetIndex].toArray(new double[dataset[datasetIndex].size()][]);
    int[] label = dataset[datasetIndex].toArray(new int[dataset[datasetIndex].size()]);

    LogisticRegression logit = new LogisticRegression(data, label, lambda);
    for (int i = 0; i < label.length; i++) {
      label[i] = logit.predict(data[i]);
    }
    double trainError = error(label, label);

    System.out.format("training error = %.2f%%\n", 100 * trainError);

    double[][] z = new double[y.length][x.length];
    for (int i = 0; i < y.length; i++) {
      for (int j = 0; j < x.length; j++) {
        double[] p = {x[j], y[i]};
        z[i][j] = logit.predict(p);
      }
    }

    return z;
  }