Skip to content

Commit 13441bc

Browse files
committed
Merge master
2 parents 8f39577 + 75e38b2 commit 13441bc

File tree

3 files changed

+122
-4
lines changed

3 files changed

+122
-4
lines changed

src/others/minkowski-distance.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
(function (exports) {
2+
'use strict';
3+
4+
var minkowskiDistance = (function () {
5+
6+
function chebyshevDistance (x, y, lx, p, mathfn) {
7+
var ret = -p;
8+
var i;
9+
10+
for (i = 0; i < lx; i += 1) {
11+
ret = mathfn(ret, Math.abs(x[i] - y[i]));
12+
}
13+
14+
return ret;
15+
}
16+
17+
function minkowskiDistance (x, lx, y, ly, p) {
18+
var d;
19+
var i;
20+
21+
if (lx !== ly) {
22+
throw 'Both vectors should have same dimension';
23+
}
24+
25+
if (isNaN(p)) {
26+
throw 'The order "p" must be a number';
27+
}
28+
29+
if (p === Number.POSITIVE_INFINITY) {
30+
return chebyshevDistance(x, y, lx, p, Math.max);
31+
} else if (p === Number.NEGATIVE_INFINITY) {
32+
return chebyshevDistance(x, y, lx, p, Math.min);
33+
} else if (p < 1) {
34+
throw 'Order less than 1 will violate the triangle inequality';
35+
} else {
36+
d = 0;
37+
38+
for (i = 0; i < lx; i += 1) {
39+
d += Math.pow(Math.abs(x[i] - y[i]), p);
40+
}
41+
42+
return isNaN(d)
43+
? 0
44+
: Math.pow(d, 1 / p);
45+
46+
}
47+
48+
}
49+
50+
/**
51+
* The Minkowski distance between two points gets generalized
52+
* metric distance
53+
* when p === 1, this becomes same as Manhattan Distance
54+
* when p === 2, this becomes same as Euclidean Distance
55+
* when p === Positive or Negative Infinity,
56+
* this becomes chebyshev distance
57+
*
58+
* @public
59+
* @module others/minkowski-distance
60+
*
61+
* @example
62+
* var dist = require('path-to-algorithms/src/others/' +
63+
* 'minkowski-distance').minkowskiDistance;
64+
* console.log(dist([0, 1], [1, 1], 2)); // 1
65+
*
66+
* @param {Array} x source point
67+
* @param {Array} y target point
68+
* @param {Number} p order of Minkowski distance
69+
* @returns {Number} distance between two points, if distance
70+
* is NaN, then this returns 0
71+
*/
72+
return function (x, y, p) {
73+
return minkowskiDistance (x, x.length, y, y.length, p);
74+
};
75+
}());
76+
77+
exports.minkowskiDistance = minkowskiDistance;
78+
79+
}(typeof exports === 'undefined' ? window : exports));

src/shuffle/fisheryates.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,9 @@
2020
function shuffle(array) {
2121
var size = array.length;
2222
var rand;
23-
var temp;
2423
for (var i = 0; i < size; i += 1) {
2524
rand = Math.floor(i + Math.random() * (size - i));
26-
temp = array[rand];
27-
array[rand] = array[i];
28-
array[i] = temp;
25+
[array[rand], array[i]] = [array[i], array[rand]];
2926
}
3027
return array;
3128
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
var mod = require('../../src/others/minkowski-distance.js');
4+
var minkowskiDistance = mod.minkowskiDistance;
5+
6+
describe('Minkowski Distance', function () {
7+
it('should return 1 with points (0, 1), (1, 1) in order 1.', function () {
8+
expect(minkowskiDistance([0, 1], [1, 1], 1)).toBe(1);
9+
});
10+
it('should return 2 with points (0, 1), (1, 1) in order 2.', function () {
11+
expect(minkowskiDistance([0, 1], [1, 1], 2)).toBe(1);
12+
});
13+
it('should return 2 with points (0, 1, 4), (1, 1, 6) in order Positive Infinity.', function () {
14+
expect(minkowskiDistance([0, 1, 4], [1, 1, 6], Number.POSITIVE_INFINITY)).toBe(2);
15+
});
16+
it('should return 0 with points (0, 1, 4), (1, 1, 6) in order Negative Infinity.', function () {
17+
expect(minkowskiDistance([0, 1, 4], [1, 1, 6], Number.NEGATIVE_INFINITY)).toBe(0);
18+
});
19+
it('should return 8.372966759705923 with points (0, 3, 4, 5), (7, 6, 3, -1) in order 3.', function () {
20+
expect(minkowskiDistance([0, 3, 4, 5], [7, 6, 3, -1], 3)).toBe(8.372966759705923);
21+
});
22+
it('should throw when both vectors don\'t have same dimension', function () {
23+
expect(function () {
24+
minkowskiDistance([1, 2], [1], 1)
25+
}).toThrow('Both vectors should have same dimension');
26+
});
27+
it('should throw when p is not defined', function () {
28+
expect(function () {
29+
minkowskiDistance([1, 2], [1, 2])
30+
}).toThrow('The order "p" must be a number');
31+
});
32+
it('should throw when p is not a number', function () {
33+
expect(function () {
34+
minkowskiDistance([1, 2], [1, 2], NaN)
35+
}).toThrow('The order "p" must be a number');
36+
});
37+
it('should throw when p is less than 1', function () {
38+
expect(function () {
39+
minkowskiDistance([1, 2], [1, 2], 0)
40+
}).toThrow('Order less than 1 will violate the triangle inequality');
41+
});
42+
});

0 commit comments

Comments
 (0)