1 |
|
2 |
|
3 | const flatten = require('../../utils/array').flatten
|
4 |
|
5 | function factory (type, config, load, typed) {
|
6 | const abs = load(require('./abs'))
|
7 | const add = load(require('./addScalar'))
|
8 | const divide = load(require('./divideScalar'))
|
9 | const multiply = load(require('./multiplyScalar'))
|
10 | const sqrt = load(require('./sqrt'))
|
11 | const smaller = load(require('../relational/smaller'))
|
12 | const isPositive = load(require('../utils/isPositive'))
|
13 |
|
14 | /**
|
15 | * Calculate the hypotenusa of a list with values. The hypotenusa is defined as:
|
16 | *
|
17 | * hypot(a, b, c, ...) = sqrt(a^2 + b^2 + c^2 + ...)
|
18 | *
|
19 | * For matrix input, the hypotenusa is calculated for all values in the matrix.
|
20 | *
|
21 | * Syntax:
|
22 | *
|
23 | * math.hypot(a, b, ...)
|
24 | * math.hypot([a, b, c, ...])
|
25 | *
|
26 | * Examples:
|
27 | *
|
28 | * math.hypot(3, 4) // 5
|
29 | * math.hypot(3, 4, 5) // 7.0710678118654755
|
30 | * math.hypot([3, 4, 5]) // 7.0710678118654755
|
31 | * math.hypot(-2) // 2
|
32 | *
|
33 | * See also:
|
34 | *
|
35 | * abs, norm
|
36 | *
|
37 | * @param {... number | BigNumber | Array | Matrix} args A list with numeric values or an Array or Matrix.
|
38 | * Matrix and Array input is flattened and returns a
|
39 | * single number for the whole matrix.
|
40 | * @return {number | BigNumber} Returns the hypothenusa of the input values.
|
41 | */
|
42 | const hypot = typed('hypot', {
|
43 | '... number | BigNumber': _hypot,
|
44 |
|
45 | 'Array': function (x) {
|
46 | return hypot.apply(hypot, flatten(x))
|
47 | },
|
48 |
|
49 | 'Matrix': function (x) {
|
50 | return hypot.apply(hypot, flatten(x.toArray()))
|
51 | }
|
52 | })
|
53 |
|
54 | /**
|
55 | * Calculate the hypotenusa for an Array with values
|
56 | * @param {Array.<number | BigNumber>} args
|
57 | * @return {number | BigNumber} Returns the result
|
58 | * @private
|
59 | */
|
60 | function _hypot (args) {
|
61 | // code based on `hypot` from es6-shim:
|
62 | // https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js#L1619-L1633
|
63 | let result = 0
|
64 | let largest = 0
|
65 |
|
66 | for (let i = 0; i < args.length; i++) {
|
67 | const value = abs(args[i])
|
68 | if (smaller(largest, value)) {
|
69 | result = multiply(result, multiply(divide(largest, value), divide(largest, value)))
|
70 | result = add(result, 1)
|
71 | largest = value
|
72 | } else {
|
73 | result = add(result, isPositive(value) ? multiply(divide(value, largest), divide(value, largest)) : value)
|
74 | }
|
75 | }
|
76 |
|
77 | return multiply(largest, sqrt(result))
|
78 | }
|
79 |
|
80 | hypot.toTex = `\\hypot\\left(\${args}\\right)`
|
81 |
|
82 | return hypot
|
83 | }
|
84 |
|
85 | exports.name = 'hypot'
|
86 | exports.factory = factory
|