I saw many questions about this, and tried to solve the problem, but after one hour of googling and a lots of trial & error, I still can't fix it. I hope some of you catch the problem.
This is what I get:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)
at java.util.ComparableTimSort.mergeForceCollapse(ComparableTimSort.java:392)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:191)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
...
And this is my comparator:
#Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
CollectionItem item = (CollectionItem) o;
Card card1 = CardCache.getInstance().getCard(cardId);
Card card2 = CardCache.getInstance().getCard(item.getCardId());
if (card1.getSet() < card2.getSet()) {
return -1;
} else {
if (card1.getSet() == card2.getSet()) {
if (card1.getRarity() < card2.getRarity()) {
return 1;
} else {
if (card1.getId() == card2.getId()) {
if (cardType > item.getCardType()) {
return 1;
} else {
if (cardType == item.getCardType()) {
return 0;
}
return -1;
}
}
return -1;
}
}
return 1;
}
}
Any idea?
The exception message is actually pretty descriptive. The contract it mentions is transitivity: if A > B and B > C then for any A, B and C: A > C. I checked it with paper and pencil and your code seems to have few holes:
if (card1.getRarity() < card2.getRarity()) {
return 1;
you do not return -1 if card1.getRarity() > card2.getRarity().
if (card1.getId() == card2.getId()) {
//...
}
return -1;
You return -1 if ids aren't equal. You should return -1 or 1 depending on which id was bigger.
Take a look at this. Apart from being much more readable, I think it should actually work:
if (card1.getSet() > card2.getSet()) {
return 1;
}
if (card1.getSet() < card2.getSet()) {
return -1;
};
if (card1.getRarity() < card2.getRarity()) {
return 1;
}
if (card1.getRarity() > card2.getRarity()) {
return -1;
}
if (card1.getId() > card2.getId()) {
return 1;
}
if (card1.getId() < card2.getId()) {
return -1;
}
return cardType - item.getCardType(); //watch out for overflow!
You can use the following class to pinpoint transitivity bugs in your Comparators:
/**
* #author Gili Tzabari
*/
public final class Comparators
{
/**
* Verify that a comparator is transitive.
*
* #param <T> the type being compared
* #param comparator the comparator to test
* #param elements the elements to test against
* #throws AssertionError if the comparator is not transitive
*/
public static <T> void verifyTransitivity(Comparator<T> comparator, Collection<T> elements)
{
for (T first: elements)
{
for (T second: elements)
{
int result1 = comparator.compare(first, second);
int result2 = comparator.compare(second, first);
if (result1 != -result2)
{
// Uncomment the following line to step through the failed case
//comparator.compare(first, second);
throw new AssertionError("compare(" + first + ", " + second + ") == " + result1 +
" but swapping the parameters returns " + result2);
}
}
}
for (T first: elements)
{
for (T second: elements)
{
int firstGreaterThanSecond = comparator.compare(first, second);
if (firstGreaterThanSecond <= 0)
continue;
for (T third: elements)
{
int secondGreaterThanThird = comparator.compare(second, third);
if (secondGreaterThanThird <= 0)
continue;
int firstGreaterThanThird = comparator.compare(first, third);
if (firstGreaterThanThird <= 0)
{
// Uncomment the following line to step through the failed case
//comparator.compare(first, third);
throw new AssertionError("compare(" + first + ", " + second + ") > 0, " +
"compare(" + second + ", " + third + ") > 0, but compare(" + first + ", " + third + ") == " +
firstGreaterThanThird);
}
}
}
}
}
/**
* Prevent construction.
*/
private Comparators()
{
}
}
Simply invoke Comparators.verifyTransitivity(myComparator, myCollection) in front of the code that fails.
It also has something to do with the version of JDK.
If it does well in JDK6, maybe it will have the problem in JDK 7 described by you, because the implementation method in jdk 7 has been changed.
Look at this:
Description: The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced. The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract. The previous implementation silently ignored such a situation. If the previous behavior is desired, you can use the new system property, java.util.Arrays.useLegacyMergeSort, to restore previous mergesort behaviour.
I don't know the exact reason. However, if you add the code before you use sort. It will be OK.
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
Consider the following case:
First, o1.compareTo(o2) is called. card1.getSet() == card2.getSet() happens to be true and so is card1.getRarity() < card2.getRarity(), so you return 1.
Then, o2.compareTo(o1) is called. Again, card1.getSet() == card2.getSet() is true. Then, you skip to the following else, then card1.getId() == card2.getId() happens to be true, and so is cardType > item.getCardType(). You return 1 again.
From that, o1 > o2, and o2 > o1. You broke the contract.
if (card1.getRarity() < card2.getRarity()) {
return 1;
However, if card2.getRarity() is less than card1.getRarity() you might not return -1.
You similarly miss other cases. I would do this, you can change around depending on your intent:
public int compareTo(Object o) {
if(this == o){
return 0;
}
CollectionItem item = (CollectionItem) o;
Card card1 = CardCache.getInstance().getCard(cardId);
Card card2 = CardCache.getInstance().getCard(item.getCardId());
int comp=card1.getSet() - card2.getSet();
if (comp!=0){
return comp;
}
comp=card1.getRarity() - card2.getRarity();
if (comp!=0){
return comp;
}
comp=card1.getSet() - card2.getSet();
if (comp!=0){
return comp;
}
comp=card1.getId() - card2.getId();
if (comp!=0){
return comp;
}
comp=card1.getCardType() - card2.getCardType();
return comp;
}
}
I had the same symptom. For me it turned out that another thread was modifying the compared objects while the sorting was happening in a Stream. To resolve the issue, I mapped the objects to immutable temporary objects, collected the Stream to a temporary Collection and did the sorting on that.
The origin of this exception is a wrong Comparator implementation. By checking the docs, we must implement the compare(o1, o2) method as an equivalence relation by following the rules:
if a.equals(b) is true then compare(a, b) is 0
if a.compare(b) > 0 then b.compare(a) < 0 is true
if a.compare(b) > 0 and b.compare(c) > 0 then a.compare(c) > 0 is true
You may check your code to realize where your implementation is offending one or more of Comparator contract rules. If it is hard to find it by a static analysis, you can use the data which cast the exception to check the rules.
If you try to run this code you will meet the kind this exception:
public static void main(String[] args) {
Random random = new Random();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 50000; i++) {
list.add(random.nextInt());
}
list.sort((x, y) -> {
int c = random.nextInt(3);
if (c == 0) {
return 0;
}
if (c == 1) {
return 1;
}
return -1;
});
}
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:777)
at java.util.TimSort.mergeAt(TimSort.java:514)
at java.util.TimSort.mergeCollapse(TimSort.java:441)
at java.util.TimSort.sort(TimSort.java:245)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1462)
at Test.main(Test.java:14)
The reason is when implementing the Comparator, it may meet the case of A > B and B > C and C > A and the sort method will be run around to be broken. Java prevent this case by throw exception this case:
class TimSort<T> {
.
.
.
else if (len1 == 0) {
throw new IllegalArgumentException(
"Comparison method violates its general contract!");
.
.
.
In conclusion, to handle this issue. You have to make sure the comparator will not meet the case of A > B and B > C and C > A.
I got the same error with a class like the following StockPickBean. Called from this code:
List<StockPickBean> beansListcatMap.getValue();
beansList.sort(StockPickBean.Comparators.VALUE);
public class StockPickBean implements Comparable<StockPickBean> {
private double value;
public double getValue() { return value; }
public void setValue(double value) { this.value = value; }
#Override
public int compareTo(StockPickBean view) {
return Comparators.VALUE.compare(this,view); //return
Comparators.SYMBOL.compare(this,view);
}
public static class Comparators {
public static Comparator<StockPickBean> VALUE = (val1, val2) ->
(int)
(val1.value - val2.value);
}
}
After getting the same error:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
I changed this line:
public static Comparator<StockPickBean> VALUE = (val1, val2) -> (int)
(val1.value - val2.value);
to:
public static Comparator<StockPickBean> VALUE = (StockPickBean spb1,
StockPickBean spb2) -> Double.compare(spb2.value,spb1.value);
That fixes the error.
I ran into a similar problem where I was trying to sort a n x 2 2D array named contests which is a 2D array of simple integers. This was working for most of the times but threw a runtime error for one input:-
Arrays.sort(contests, (row1, row2) -> {
if (row1[0] < row2[0]) {
return 1;
} else return -1;
});
Error:-
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.base/java.util.TimSort.mergeHi(TimSort.java:903)
at java.base/java.util.TimSort.mergeAt(TimSort.java:520)
at java.base/java.util.TimSort.mergeForceCollapse(TimSort.java:461)
at java.base/java.util.TimSort.sort(TimSort.java:254)
at java.base/java.util.Arrays.sort(Arrays.java:1441)
at com.hackerrank.Solution.luckBalance(Solution.java:15)
at com.hackerrank.Solution.main(Solution.java:49)
Looking at the answers above I tried adding a condition for equals and I don't know why but it worked. Hopefully we must explicitly specify what should be returned for all cases (greater than, equals and less than):
Arrays.sort(contests, (row1, row2) -> {
if (row1[0] < row2[0]) {
return 1;
}
if(row1[0] == row2[0]) return 0;
return -1;
});
A variation of Gili's answer to check if the comparator satisfies the requirements described in the compare method's javadoc - with a focus on completeness and readability, e.g. by naming the variables the same as in the javadoc. Note that this is O(n^3), only use it when debugging, maybe just on a subset of your elements, in order to be fast enough to finish at all.
public static <T> void verifyComparator(Comparator<T> comparator, Collection<T> elements) {
for (T x : elements) {
for (T y : elements) {
for (T z : elements) {
int x_y = comparator.compare(x, y);
int y_x = comparator.compare(y, x);
int y_z = comparator.compare(y, z);
int x_z = comparator.compare(x, z);
// javadoc: The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x))
if (Math.signum(x_y) == -Math.signum(y_x)) { // ok
} else {
System.err.println("not holding: sgn(compare(x, y)) == -sgn(compare(y, x))" //
+ " | x_y: " + x_y + ", y_x: " + y_x + ", x: " + x + ", y: " + y);
}
// javadoc: The implementor must also ensure that the relation is transitive:
// ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
if (x_y > 0 && y_z > 0) {
if (x_z > 0) { // ok
} else {
System.err.println("not holding: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0" //
+ " | x_y: " + x_y + ", y_z: " + y_z + ", x_z: " + x_z + ", x: " + x + ", y: " + y + ", z: " + z);
}
}
// javadoc: Finally, the implementor must ensure that:
// compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.
if (x_y == 0) {
if (Math.signum(x_z) == Math.signum(y_z)) { // ok
} else {
System.err.println("not holding: compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z" //
+ " | x_y: " + x_y + ", x_z: " + x_z + ", y_z: " + y_z + ", x: " + x + ", y: " + y + ", z: " + z);
}
}
}
}
}
}
I had to sort on several criterion (date, and, if same date; other things...). What was working on Eclipse with an older version of Java, did not worked any more on Android : comparison method violates contract ...
After reading on StackOverflow, I wrote a separate function that I called from compare() if the dates are the same. This function calculates the priority, according to the criteria, and returns -1, 0, or 1 to compare(). It seems to work now.
What about doing something simpler like this:
int result = card1.getSet().compareTo(card2.getSet())
if (result == 0) {
result = card1.getRarity().compareTo(card2.getRarity())
}
if (result == 0) {
result = card1.getId().compareTo(card2.getId())
}
if (result == 0) {
result = card1.getCardType().compareTo(card2.getCardType())
}
return result;
You just need to order the comparisons in order of preference.
I am building basic calculator app, with sqrt and pow options.
I want to add pow method to my app.I can do it simply to my method bellow, but it asks me for two Strings.I need this problem to be solved by using only one String.So user can enter number 4 and POW result is 16.
github for code : https://github.com/adnxy/CalculatorAt
Method for operating, using two Strings:
private double operate(String a, String b, String op) {
switch (op) {
case "+":
return Double.valueOf(a) + Double.valueOf(b);
case "-":
return Double.valueOf(a) - Double.valueOf(b);
case "x":
return Double.valueOf(a) * Double.valueOf(b);
// case "p":
// return Double.parseDouble(a) * Double.parseDouble(a);
case "s":
return Math.sqrt(Double.valueOf(a));
case "รท":
try {
return Double.valueOf(a) / Double.valueOf(b);
} catch (Exception e) {
Log.d("Calc", e.getMessage());
}
default:
return -1;
}
}
I already make two methods: onClickPow and getResultPow.
My method getResultPow is not working when I click Pow inside App.Can somebody help me with getResultPow?
public void onClickPow(View v) {
if (display == "") return;
if (!getResultPow("String a")) return;
_screen.setText(display + "\n" + String.valueOf(result));
}
private boolean getResultPow(String a) {
//1.st case, all blank
if (display == " " && currentOperator == " " && result == " ") return false;
//2.nd case, 1 number entered
if (currentOperator == "") return false;
if (result == " ") return false;
if (display != " ") {
result = String.valueOf(Double.parseDouble(a) * Double.parseDouble(a));
//_screen.setText(display + "\n" + String.valueOf(result));
updateScreen();
return true;
}
//3.rd case, two numbers entered, they need to call + and then pow
if (result == " ") return false;
if (display != " " && currentOperator != " ") {
result = String.valueOf(Double.parseDouble(a) + Double.parseDouble(a));
result = String.valueOf(Double.parseDouble(a) * Double.parseDouble(a));
//_screen.setText(display + "\n" + String.valueOf(result));
updateScreen();
return true;
}
if (currentOperator == "") return false;
String[] operation = display.split(Pattern.quote(currentOperator));
if (operation.length < 2) return false;
result = String.valueOf(Double.parseDouble(a) * Double.parseDouble(a));
return true;
//return onClickPow();
}
If I got your question you just need to use that same value two times for example:
input = Double.valueOf(tvNum.getText().toString());//Example value: 2
input2= Double.valueOf(tvNum.getText().toString());//Example value: 2
Double result = Math.pow(input,input2);//so this should do 2*2 = 4
With OverLoading in OOP, you can create multiple method with the same name (the number of paramaters can difference). See this article: What is method overloading?
I need help on figuring out why this code is giving me:
Syntax error on token ":", { expected after this token/line
108,109,110(label125,label192,label202 in the beginning)/Java Problem
public void onGPSUpdate(Location paramLocation)
{
if (paramLocation != null)
{
this.sampleCount = (1 + this.sampleCount);
label125: int i;
label192: int j;
label202: int m;
if (paramLocation.hasSpeed())
{
this.speed = (2.23693629D * paramLocation.getSpeed());
this.oldLocation = paramLocation;
this.mAvgSum += this.speed;
this.speedQ.add(Double.valueOf(this.speed));
if (this.speedQ.size() > 300)
this.mAvgSum -= ((Double)this.speedQ.remove()).doubleValue();
if (!this.speedQ.isEmpty())
break label324;
this.mAvg = 0.0D;
if (this.speed <= this.speedThreshold)
break label363;
this.THRESHOLD_STATUS = ("OVER: " + this.speedThreshold + " MPH");
if (!this.smsControlRunning)
{
smsControlOn();
this.smsControlRunning = true;
}
if (!this.blueToothPaired)
break label346;
i = 0;
if (!this.hasBlueTooth)
break label351;
j = 0;
int k = i | j;
if (!this.phoneControlRunning)
break label357;
m = 0;
label218: if ((k & m) != 0)
{
phoneControlOn();
this.phoneControlRunning = true;
}
}
while (true)
{
this.SPEED_STATUS = String.valueOf(this.speed);
this.COUNT_STATUS = (this.sampleCount + " updates");
this.MAVG_STATUS = ("mAvg: " + this.mAvg);
return;
this.speed = getSpeed(this.oldLocation, paramLocation);
break;
label324: this.mAvg = (this.mAvgSum / this.speedQ.size());
break label125;
label346: i = 1;
break label192;
label351: j = 1;
break label202;
label357: m = 1;
break label218;
label363: this.THRESHOLD_STATUS = ("UNDER: " + this.speedThreshold + " MPH");
stopAllServices();
}
}
Toast.makeText(this, "LOCATION NULL", 0).show();
}
This is probably an obvious error but I am relatively new to Android development and using Eclipse. The same code worked fine under a previous version before renaming(refactoring) the application. This was coded by another programmer who worked on the project before me and I think this could be done better using a case or switch statement instead of the break and continue we have. I am getting frustrated with it and would appreciate any advice.
Try using those labels for "real" code lines.
You're using them at variable declarations, so no real point to go.
Use somthing like...
int i;
int j;
int m;
label125: i=0;
label192: j=0;
label202: m=0;
if (paramLocation.hasSpeed())
I trying to match hardcoded latitude an longitude with dynamic latitude and longitude, but its not showing correct output, can anyone help me to sort out this error
My code is
String Log = "-122.084095";
String Lat = "37.422005";
try {
if ((Lat.equals(latitude)) && (Log.equals(longitude))) {
AudioManager audiM = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audiM.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getApplicationContext(),
"You are at home",
Toast.LENGTH_LONG).show();
} else {
AudioManager auMa = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
auMa.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(getApplicationContext(),
"You are at office ", Toast.LENGTH_LONG)
.show();
}
} catch (Exception e) {
e.printStackTrace();
}
it always goes for else part...
You don't want to use a String comparison here as you can't guarantee the level of accuracy with the real-time location.
The best way to handle this would be to determine the distance between the points and then determine if it's close enough for you to consider, approx, the same.
For this, we use distanceBetween or distanceTo
Docs are here and here
Examples can be found here. Here's one of those examples:
Location locationA = new Location("point A");
locationA.setLatitude(pointA.getLatitudeE6() / 1E6);
locationA.setLongitude(pointA.getLongitudeE6() / 1E6);
Location locationB = new Location("point B");
locationB.setLatitude(pointB.getLatitudeE6() / 1E6);
locationB.setLongitude(pointB.getLongitudeE6() / 1E6);
double distance = locationA.distanceTo(locationB);
The latitude and longitude are variables which vary from point to point, matter of fact they keep on changing while standing on the same spot, because it is not precise.
Instead of comparing the Strings, take a rounded value of the lat and long (in long or float ) and check those values within a certain range. That will help you out with the "Home" and "Office " thing.
For e.g :
String Log = "22.084095";
String Lat = "37.422005";
double lng=Double.parseDouble(Log);
double lat=Double.parseDouble(Lat);
double upprLogHome=22.1;
double lwrLogHome=21.9;
double upprLatHome=37.5;
double lwrLatHome=37.3;
// double upprLogOfc=;
// double lwrLogOfc=;
// double upprLatOfc=;
// double lwrLatOfc=;
if(lng<upprLogHome && lng>lwrLogHome && lat<upprLatHome &&lat>lwrLatHome )
{
System.out.println("You are Home");
}
/* else if(lng<upprLogOfc && lng>lwrLogOfc && lat<upprLatOfc &&lat>lwrLatOfc )
{
System.out.println("You are Home");
}*/
else
System.out.println("You are neither Home nor Ofc");
But for the negative lat long you have to reverse the process of checking.
your matching is okay but you probably should not check for a gps location like this.
You should convert the location to something where you can check that you are in 10m radius of the location.
A nicer way would be to leave the long/lat as doubles and compare the numbers.
if(lat > HOME_LAT - 0.1 && lat < HOME_LAT + 0.1 && ...same for lon... ){}
Try this,
Use google map api to pass lat and long value you will get formatted address. And also pass dynamic lat and lng value same google api you will get formatted address. And then match two formatted address you will get result. i suggest this way you can try this
Use this google api. http://maps.googleapis.com/maps/api/geocode/json?latlng=11.029494,76.954422&sensor=true
Reena, its very easy, Check out below code. You need to use "equalsIgnoreCase()" instead of
"equals".
if ((Lat.equalsIgnoreCase(latitude)) && (Log.equalsIgnoreCase(longitude))) {
should work
Example below :
// Demonstrate equals() and equalsIgnoreCase().
class equalsDemo {
public static void main(String args[]) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good-bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " +
s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " +
s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " +
s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " +
s1.equalsIgnoreCase(s4));
}
}
You can print dynamice Latitute and Longitute to Logcat and check with hardcoded Latitute and Longitute
I'm following javacv Face Detection/Recognition code, there is confusion regarding face recognition.. What I'm doing is (Sorry if it sounds stupid but I'm stuck)
1) Detect Face crop it and save it to sdcard and place path in learn.txt file (Learning part)
2) Detect Face crop it and find it in existing faces whether it exists or not, but it always return nearest position even if the face doesn't exist in sample faces..
what I'm doing wrong?
// Method, I'm using to recognize face
public Integer recognizeFace(Bitmap face, Context context) {
Log.i(TAG, "===========================================");
Log.i(TAG, "recognizeFace (single face)");
float[] projectedTestFace;
float confidence = 0.0f;
int nearest = -1; // closest match -- -1 for nothing.
int iNearest;
if (trainPersonNumMat == null) {
return null;
}
Log.i(TAG, "NUMBER OF EIGENS: " + nEigens);
// project the test images onto the PCA subspace
projectedTestFace = new float[nEigens];
// Start timing recognition
long startTime = System.nanoTime();
testFaceImg = bmpToIpl(face);
// saveBmp(face, "blah");
// convert Bitmap it IplImage
//testFaceImg = IplImage.create(face.getWidth(), face.getHeight(),
// IPL_DEPTH_8U, 4);
//face.copyPixelsToBuffer(testFaceImg.getByteBuffer());
// project the test image onto the PCA subspace
cvEigenDecomposite(testFaceImg, // obj
nEigens, // nEigObjs
new PointerPointer(eigenVectArr), // eigInput (Pointer)
0, // ioFlags
null, // userData
pAvgTrainImg, // avg
projectedTestFace); // coeffs
// LOGGER.info("projectedTestFace\n" +
// floatArrayToString(projectedTestFace));
Log.i(TAG, "projectedTestFace\n" + floatArrayToString(projectedTestFace));
final FloatPointer pConfidence = new FloatPointer(confidence);
iNearest = findNearestNeighbor(projectedTestFace, new FloatPointer(pConfidence));
confidence = pConfidence.get();
// truth = personNumTruthMat.data_i().get(i);
nearest = trainPersonNumMat.data_i().get(iNearest); // result
// get endtime and calculate time recognition process takes
long endTime = System.nanoTime();
long duration = endTime - startTime;
double seconds = (double) duration / 1000000000.0;
Log.i(TAG, "recognition took: " + String.valueOf(seconds));
Log.i(TAG, "nearest = " + nearest + ". Confidence = " + confidence);
Toast.makeText(context, "Nearest: "+nearest+" Confidence: "+confidence, Toast.LENGTH_LONG).show();
//Save the IplImage so we can see what it looks like
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "/sdcard/saved_images/" + nearest + " " + String.valueOf(seconds) + " " + String.valueOf(confidence) + " " + n + ".jpg";
Log.i(TAG, "Saving image as: " + fname);
cvSaveImage(fname, testFaceImg);
return nearest;
} // end of recognizeFace
EDIT The confidence is always negative!
Thanks in advance