UNPKG

3.42 kBJavaScriptView Raw
1import { containsCollections } from '../../utils/collection.js';
2import { flatten } from '../../utils/array.js';
3import { factory } from '../../utils/factory.js';
4import { improveErrorMessage } from './utils/improveErrorMessage.js';
5var name = 'median';
6var dependencies = ['typed', 'add', 'divide', 'compare', 'partitionSelect'];
7export var createMedian = /* #__PURE__ */factory(name, dependencies, _ref => {
8 var {
9 typed,
10 add,
11 divide,
12 compare,
13 partitionSelect
14 } = _ref;
15
16 /**
17 * Recursively calculate the median of an n-dimensional array
18 * @param {Array} array
19 * @return {Number} median
20 * @private
21 */
22 function _median(array) {
23 try {
24 array = flatten(array.valueOf());
25 var num = array.length;
26
27 if (num === 0) {
28 throw new Error('Cannot calculate median of an empty array');
29 }
30
31 if (num % 2 === 0) {
32 // even: return the average of the two middle values
33 var mid = num / 2 - 1;
34 var right = partitionSelect(array, mid + 1); // array now partitioned at mid + 1, take max of left part
35
36 var left = array[mid];
37
38 for (var i = 0; i < mid; ++i) {
39 if (compare(array[i], left) > 0) {
40 left = array[i];
41 }
42 }
43
44 return middle2(left, right);
45 } else {
46 // odd: return the middle value
47 var m = partitionSelect(array, (num - 1) / 2);
48 return middle(m);
49 }
50 } catch (err) {
51 throw improveErrorMessage(err, 'median');
52 }
53 } // helper function to type check the middle value of the array
54
55
56 var middle = typed({
57 'number | BigNumber | Complex | Unit': function numberBigNumberComplexUnit(value) {
58 return value;
59 }
60 }); // helper function to type check the two middle value of the array
61
62 var middle2 = typed({
63 'number | BigNumber | Complex | Unit, number | BigNumber | Complex | Unit': function numberBigNumberComplexUnitNumberBigNumberComplexUnit(left, right) {
64 return divide(add(left, right), 2);
65 }
66 });
67 /**
68 * Compute the median of a matrix or a list with values. The values are
69 * sorted and the middle value is returned. In case of an even number of
70 * values, the average of the two middle values is returned.
71 * Supported types of values are: Number, BigNumber, Unit
72 *
73 * In case of a (multi dimensional) array or matrix, the median of all
74 * elements will be calculated.
75 *
76 * Syntax:
77 *
78 * math.median(a, b, c, ...)
79 * math.median(A)
80 *
81 * Examples:
82 *
83 * math.median(5, 2, 7) // returns 5
84 * math.median([3, -1, 5, 7]) // returns 4
85 *
86 * See also:
87 *
88 * mean, min, max, sum, prod, std, variance, quantileSeq
89 *
90 * @param {... *} args A single matrix or or multiple scalar values
91 * @return {*} The median
92 */
93
94 return typed(name, {
95 // median([a, b, c, d, ...])
96 'Array | Matrix': _median,
97 // median([a, b, c, d, ...], dim)
98 'Array | Matrix, number | BigNumber': function ArrayMatrixNumberBigNumber(array, dim) {
99 // TODO: implement median(A, dim)
100 throw new Error('median(A, dim) is not yet supported'); // return reduce(arguments[0], arguments[1], ...)
101 },
102 // median(a, b, c, d, ...)
103 '...': function _(args) {
104 if (containsCollections(args)) {
105 throw new TypeError('Scalar values expected in function median');
106 }
107
108 return _median(args);
109 }
110 });
111});
\No newline at end of file