Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #763 from ruhleder/feature/median-absolute-deviation
Add median absolute deviation
- Loading branch information
Showing
3 changed files
with
126 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
'use strict'; | ||
|
||
var flatten = require('../../utils/array').flatten; | ||
|
||
function factory (type, config, load, typed) { | ||
var abs = load(require('../arithmetic/abs')); | ||
var map = load(require('../matrix/map')); | ||
var median = load(require('../statistics/median')); | ||
var subtract = load(require('../arithmetic/subtract')); | ||
|
||
/** | ||
* Compute the median absolute deviation of a matrix or a list with values. | ||
* The median absolute deviation is defined as the median of the absolute | ||
* deviations from the median. | ||
* | ||
* Syntax: | ||
* | ||
* math.mad(a, b, c, ...) | ||
* math.mad(A) | ||
* | ||
* Examples: | ||
* | ||
* math.mad(10, 20, 30); // returns 10 | ||
* math.mad([1, 2, 3]); // returns 1 | ||
* math.mad([[1, 2, 3], [4, 5, 6]]); // returns 1.5 | ||
* | ||
* See also: | ||
* | ||
* median, abs, map, subtract | ||
* | ||
* @param {Array | Matrix} array | ||
* A single matrix or multiple scalar values. | ||
* @return {*} The median absolute deviation. | ||
*/ | ||
var mad = typed('mad', { | ||
// mad([a, b, c, d, ...]) | ||
'Array | Matrix': _mad, | ||
|
||
// mad(a, b, c, d, ...) | ||
'...': function (args) { | ||
return _mad(args); | ||
} | ||
}); | ||
|
||
mad.toTex = undefined; // use default template | ||
|
||
return mad; | ||
|
||
function _mad(array) { | ||
array = flatten(array.valueOf()); | ||
|
||
if (array.length === 0) { | ||
throw new Error('Cannot calculate median absolute deviation of an empty array'); | ||
} | ||
|
||
var med = median(array); | ||
return median(map(array, function (value) { | ||
return abs(subtract(value, med)); | ||
})); | ||
} | ||
} | ||
|
||
exports.name = 'mad'; | ||
exports.factory = factory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
var assert = require('assert'); | ||
var approx = require('../../../tools/approx'); | ||
var math = require('../../../index'); | ||
var BigNumber = math.type.BigNumber; | ||
var DenseMatrix = math.type.DenseMatrix; | ||
var mad = math.mad; | ||
|
||
describe('mad', function() { | ||
|
||
it('should return the median absolute deviation of numbers', function() { | ||
assert.equal(mad(10), 0); | ||
assert.equal(mad(4,6,8), 2); | ||
assert.equal(mad(1, 10, 20, 30), 9.5); | ||
}); | ||
|
||
it('should return the median absolute deviation of big numbers', function() { | ||
assert.deepEqual(mad(new BigNumber(4),new BigNumber(6),new BigNumber(8)), | ||
new BigNumber(2)); | ||
}); | ||
|
||
it('should return the median absolute deviation from an array', function() { | ||
assert.equal(mad([10]), 0); | ||
assert.equal(mad([4,6,8]), 2); | ||
assert.equal(mad([1, 10, 20, 30]), 9.5); | ||
}); | ||
|
||
it('should return the median absolute deviation from an 1d matrix', function() { | ||
assert.equal(mad(new DenseMatrix([10])), 0); | ||
assert.equal(mad(new DenseMatrix([4,6,8])), 2); | ||
assert.equal(mad(new DenseMatrix([1, 10, 20, 30])), 9.5); | ||
}); | ||
|
||
it('should return the median absolute deviation element from a 2d array', function() { | ||
assert.deepEqual(mad([ | ||
[2,4,6], | ||
[1,3,5] | ||
]), 1.5); | ||
}); | ||
|
||
it('should return the median absolute deviation element from a 2d matrix', function() { | ||
assert.deepEqual(mad(new DenseMatrix([ | ||
[2,4,6], | ||
[1,3,5] | ||
])), 1.5); | ||
}); | ||
|
||
it('should throw an error if called with invalid number of arguments', function() { | ||
assert.throws(function() {mad()}); | ||
}); | ||
|
||
it('should throw an error if called with an empty array', function() { | ||
assert.throws(function() {mad([])}); | ||
}); | ||
|
||
it('should LaTeX mad', function () { | ||
var expression = math.parse('mad(1,2,3)'); | ||
assert.equal(expression.toTex(), '\\mathrm{mad}\\left(1,2,3\\right)'); | ||
}); | ||
|
||
}); |