@Override
 public double value(final Vec mu) {
   double result = 0.0;
   for (int i = 0; i < ds.length(); i++) {
     final double trans = binClassifier.value(ds.data().row(i));
     final double sigmoid = MathTools.sigmoid(trans);
     final double underLog =
         mu.get(target.label(i)) * sigmoid + (1 - mu.get(target.label(i))) * (1 - sigmoid);
     result -= Math.log(underLog);
   }
   result += c * VecTools.multiply(MxTools.multiply(laplacian, mu), mu);
   return result;
 }
    @Override
    public Vec gradient(final Vec mu) {
      final Vec grad = new ArrayVec(mu.dim());
      for (int k = 0; k < grad.dim(); k++) {
        final TIntList idxs = classesIdxs.get(k);
        double val = 0.0;
        for (final TIntIterator listIter = idxs.iterator(); listIter.hasNext(); ) {
          final Vec x = ds.data().row(listIter.next());
          final double trans = binClassifier.value(x);
          final double sigmoid = MathTools.sigmoid(trans);
          val -= (2 * sigmoid - 1) / (mu.get(k) * sigmoid + (1 - mu.get(k)) * (1 - sigmoid));
          grad.set(k, val);
        }
      }

      final double norm = VecTools.norm(grad);
      VecTools.scale(grad, 1 / norm);

      for (int k = 0; k < grad.dim(); k++) {
        final double val = VecTools.multiply(laplacian.row(k), mu);
        grad.adjust(k, val);
      }
      return grad;
    }