UNPKG

2.88 kBJavaScriptView Raw
1'use strict'
2
3const size = require('../../utils/array').size
4const deepForEach = require('../../utils/collection/deepForEach')
5const reduce = require('../../utils/collection/reduce')
6const containsCollections = require('../../utils/collection/containsCollections')
7
8function factory (type, config, load, typed) {
9 const add = load(require('../arithmetic/add'))
10 const divide = load(require('../arithmetic/divide'))
11 const improveErrorMessage = load(require('./utils/improveErrorMessage'))
12
13 /**
14 * Compute the mean value of matrix or a list with values.
15 * In case of a multi dimensional array, the mean of the flattened array
16 * will be calculated. When `dim` is provided, the maximum over the selected
17 * dimension will be calculated. Parameter `dim` is zero-based.
18 *
19 * Syntax:
20 *
21 * math.mean(a, b, c, ...)
22 * math.mean(A)
23 * math.mean(A, dim)
24 *
25 * Examples:
26 *
27 * math.mean(2, 1, 4, 3) // returns 2.5
28 * math.mean([1, 2.7, 3.2, 4]) // returns 2.725
29 *
30 * math.mean([[2, 5], [6, 3], [1, 7]], 0) // returns [3, 5]
31 * math.mean([[2, 5], [6, 3], [1, 7]], 1) // returns [3.5, 4.5, 4]
32 *
33 * See also:
34 *
35 * median, min, max, sum, prod, std, var
36 *
37 * @param {... *} args A single matrix or or multiple scalar values
38 * @return {*} The mean of all values
39 */
40 const mean = typed('mean', {
41 // mean([a, b, c, d, ...])
42 'Array | Matrix': _mean,
43
44 // mean([a, b, c, d, ...], dim)
45 'Array | Matrix, number | BigNumber': _nmeanDim,
46
47 // mean(a, b, c, d, ...)
48 '...': function (args) {
49 if (containsCollections(args)) {
50 throw new TypeError('Scalar values expected in function mean')
51 }
52
53 return _mean(args)
54 }
55 })
56
57 mean.toTex = undefined // use default template
58
59 return mean
60
61 /**
62 * Calculate the mean value in an n-dimensional array, returning a
63 * n-1 dimensional array
64 * @param {Array} array
65 * @param {number} dim
66 * @return {number} mean
67 * @private
68 */
69 function _nmeanDim (array, dim) {
70 try {
71 const sum = reduce(array, dim, add)
72 const s = Array.isArray(array) ? size(array) : array.size()
73 return divide(sum, s[dim])
74 } catch (err) {
75 throw improveErrorMessage(err, 'mean')
76 }
77 }
78
79 /**
80 * Recursively calculate the mean value in an n-dimensional array
81 * @param {Array} array
82 * @return {number} mean
83 * @private
84 */
85 function _mean (array) {
86 let sum = 0
87 let num = 0
88
89 deepForEach(array, function (value) {
90 try {
91 sum = add(sum, value)
92 num++
93 } catch (err) {
94 throw improveErrorMessage(err, 'mean', value)
95 }
96 })
97
98 if (num === 0) {
99 throw new Error('Cannot calculate mean of an empty array')
100 }
101
102 return divide(sum, num)
103 }
104}
105
106exports.name = 'mean'
107exports.factory = factory