0

I have a dataset which looks like this (Original data is here):

var irisjson = [
    {"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": 4.9, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": 4.7, "sepalWidth": 3.2, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"}....]

I want to calculate Euclidean Distance and find the closest points. The function I wrote is as follows:

function findClosest(irisjson){

    var result = [];
    //Calculate Euc. Dist
    for(var i=0; i < irisjson.length; i++){
        for(var j = 1; j < irisjson.length-1 ; j++){
            var a1, a2 , a3 , a4 ;

            a1 = irisjson[i].sepalLength -
                    irisjson[j].sepalLength;

            a2 = irisjson[i].sepalWidth -
                    irisjson[j].sepalWidth;

            a3 = Math.pow(a1, 2);
            a4 = Math.pow(a2, 2);

            result[i] = Math.sqrt(a3 + a4);


        }
        console.log(result[i]);
    }
}

When I print the result to console, I see 1.1045361017187265 in the first line. However, when I manually test it, as follows, I see result 0.5385164807134502:

a1 = irisjson[0].sepalLength -
            irisjson[1].sepalLength;

    a2 = irisjson[0].sepalWidth -
            irisjson[1].sepalWidth;

    a3 = Math.pow(a1, 2);
    a4 = Math.pow(a2, 2);

    result = Math.sqrt(a3 + a4);
    console.log("res:", result);

Any ideas on why I receive different results?

I would appreciate any help, Thanks!

supaplex
  • 157
  • 4
  • 18
  • 2
    I'm getting the results you're expecting - see: https://jsfiddle.net/stvsg0we/. That said, are you not (incorrectly) over-writing previous results on the line 'result[i] = Math.sqrt(a3 + a4);'? – Joseph Redfern Jul 03 '15 at 11:56
  • 1
    You are right @JosephRedfern it prints the correct results for three lines of JSON code. But I have a longer list and it doesn't print the correct results. It might have something to do with over-writing you mentioned. But I couldn't understand. Can you try to explain more? Thank you very much! – supaplex Jul 03 '15 at 12:04
  • Can you update your question to include a little more data, such that the issues is more easily re-producible? – Joseph Redfern Jul 03 '15 at 12:11
  • I have updated the question @JosephRedfern You can find the data from here: https://raw.githubusercontent.com/vega/vega/master/examples/data/iris.json – supaplex Jul 03 '15 at 12:13
  • 1
    OK, I see the problem now - it is due to the over-writing. Are you wanting to find the closest single pair of points? – Joseph Redfern Jul 03 '15 at 12:15
  • Yes, I need to find the closest single pair of points @JosephRedfern – supaplex Jul 03 '15 at 12:17

1 Answers1

0

Currently, you're over-writing result[i] several times with the line

result[i] = Math.sqrt(a3 + a4);

Do you actually need to store distances between ALL irises? You could keep track of the current minimum (and the indices of the two irises), and update as appropriate. Get rid of the results array, and replace it with an object that looks like:

minPair = {'irisA': i, 'irisB': j, distance: 0};

where i and j are indices into the irises list.

For every loop iteration, check if the calculated distance is less than minPair.distance. If so, update minPaid.irisA, minPaid.irisB and minPair.distance to the appropriate value.

Once you've finished looping, you can log minPair to see which to irises have the minimum distance.

Joseph Redfern
  • 939
  • 1
  • 6
  • 13
  • Yes, I need to store distances between all irises since I will use that information later on. – supaplex Jul 03 '15 at 12:42
  • 1
    In that case, I'd keep the results[] array, but also add the minPair object and update it as described. You could change results to be an array of arrays, where results[i][j] == distance between i and j. – Joseph Redfern Jul 03 '15 at 12:43