UNPKG

2.4 kBJavaScriptView Raw
1import { factory } from '../../utils/factory.js';
2import { xgcdNumber } from '../../plain/number/index.js';
3var name = 'xgcd';
4var dependencies = ['typed', 'config', 'matrix', 'BigNumber'];
5export var createXgcd = /* #__PURE__ */factory(name, dependencies, (_ref) => {
6 var {
7 typed,
8 config,
9 matrix,
10 BigNumber
11 } = _ref;
12
13 /**
14 * Calculate the extended greatest common divisor for two values.
15 * See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm.
16 *
17 * Syntax:
18 *
19 * math.xgcd(a, b)
20 *
21 * Examples:
22 *
23 * math.xgcd(8, 12) // returns [4, -1, 1]
24 * math.gcd(8, 12) // returns 4
25 * math.xgcd(36163, 21199) // returns [1247, -7, 12]
26 *
27 * See also:
28 *
29 * gcd, lcm
30 *
31 * @param {number | BigNumber} a An integer number
32 * @param {number | BigNumber} b An integer number
33 * @return {Array} Returns an array containing 3 integers `[div, m, n]`
34 * where `div = gcd(a, b)` and `a*m + b*n = div`
35 */
36 return typed(name, {
37 'number, number': function numberNumber(a, b) {
38 var res = xgcdNumber(a, b);
39 return config.matrix === 'Array' ? res : matrix(res);
40 },
41 'BigNumber, BigNumber': _xgcdBigNumber // TODO: implement support for Fraction
42
43 });
44 /**
45 * Calculate xgcd for two BigNumbers
46 * @param {BigNumber} a
47 * @param {BigNumber} b
48 * @return {BigNumber[]} result
49 * @private
50 */
51
52 function _xgcdBigNumber(a, b) {
53 // source: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
54 var // used to swap two variables
55 t;
56 var // quotient
57 q;
58 var // remainder
59 r;
60 var zero = new BigNumber(0);
61 var one = new BigNumber(1);
62 var x = zero;
63 var lastx = one;
64 var y = one;
65 var lasty = zero;
66
67 if (!a.isInt() || !b.isInt()) {
68 throw new Error('Parameters in function xgcd must be integer numbers');
69 }
70
71 while (!b.isZero()) {
72 q = a.div(b).floor();
73 r = a.mod(b);
74 t = x;
75 x = lastx.minus(q.times(x));
76 lastx = t;
77 t = y;
78 y = lasty.minus(q.times(y));
79 lasty = t;
80 a = b;
81 b = r;
82 }
83
84 var res;
85
86 if (a.lt(zero)) {
87 res = [a.neg(), lastx.neg(), lasty.neg()];
88 } else {
89 res = [a, !a.isZero() ? lastx : 0, lasty];
90 }
91
92 return config.matrix === 'Array' ? res : matrix(res);
93 }
94});
\No newline at end of file