docs: protected void rvfcalculate(double[] x) {
      value = 0.0;
      if (derivativeNumerator == null) {
        derivativeNumerator = new double[x.length];
        for (int d = 0; d < data.length; d++) {
          //         if (d == testMin) {
          //           d = testMax - 1;
          //           continue;
          //         }
          int[] features = data[d];
          for (int f = 0; f < features.length; f++) {
            int i = indexOf(features[f], labels[d]);
            if (dataweights == null) {
              derivativeNumerator[i] -= values[d][f];
            } else {
              derivativeNumerator[i] -= dataweights[d]*values[d][f];
            }
          }
        }
      }
      copy(derivative, derivativeNumerator);
      //    Arrays.fill(derivative, 0.0);
      double[] sums = new double[numClasses];
      double[] probs = new double[numClasses];
      //    double[] counts = new double[numClasses];
      //    Arrays.fill(counts, 0.0);
      for (int d = 0; d < data.length; d++) {
        //       if (d == testMin) {
        //         d = testMax - 1;
        //         continue;
        //       }
        int[] features = data[d];
        // activation
        Arrays.fill(sums, 0.0);
  
        for (int c = 0; c < numClasses; c++) {
          for (int f = 0; f < features.length; f++) {
            int i = indexOf(features[f], c);
            sums[c] += x[i] * values[d][f];
          }
        }
        // expectation (slower routine replaced by fast way)
        // double total = Double.NEGATIVE_INFINITY;
        // for (int c=0; c<numClasses; c++) {
        //   total = SloppyMath.logAdd(total, sums[c]);
        // }
        double total = ArrayMath.logSum(sums);
        for (int c = 0; c < numClasses; c++) {
          probs[c] = Math.exp(sums[c] - total);
          if (dataweights != null) {
            probs[c] *= dataweights[d];
          }
          for (int f = 0; f < features.length; f++) {
            int i = indexOf(features[f], c);
            derivative[i] += probs[c] * values[d][f];
          }
        }
  
        double dV = sums[labels[d]] - total;
        if (dataweights != null) {
          dV *= dataweights[d];
        }
        value -= dV;
      }
      value += prior.compute(x, derivative);
    }