public static double svm_predict_probability(svm_model model, svm_node[] x, double[] prob_estimates) {
        if ((model.param.svm_type == svm_parameter.C_SVC || model.param.svm_type == svm_parameter.NU_SVC)
                && model.probA != null && model.probB != null) {
            int i;
            int nr_class = model.nr_class;
            double[] dec_values = new double[nr_class * (nr_class - 1) / 2];
            svm_predict_values(model, x, dec_values);

            double min_prob = 1e-7;
            double[][] pairwise_prob = new double[nr_class][nr_class];

            int k = 0;
            for (i = 0; i < nr_class; i++) {
                for (int j = i + 1; j < nr_class; j++) {
                    pairwise_prob[i][j] = Math.min(Math.max(sigmoid_predict(dec_values[k], model.probA[k], model.probB[k]), min_prob), 1 - min_prob);
                    pairwise_prob[j][i] = 1 - pairwise_prob[i][j];
                    k++;
                }
            }
            multiclass_probability(nr_class, pairwise_prob, prob_estimates);

            int prob_max_idx = 0;
            for (i = 1; i < nr_class; i++) {
                if (prob_estimates[i] > prob_estimates[prob_max_idx]) {
                    prob_max_idx = i;
                }
            }
            return model.label[prob_max_idx];
        } else {
            return svm_predict(model, x);
        }
    }