1 | import { isMatrix } from '../../utils/is';
|
2 | import { arraySize } from '../../utils/array';
|
3 | import { factory } from '../../utils/factory';
|
4 | import { format } from '../../utils/string';
|
5 | var name = 'inv';
|
6 | var dependencies = ['typed', 'matrix', 'divideScalar', 'addScalar', 'multiply', 'unaryMinus', 'det', 'identity', 'abs'];
|
7 | export var createInv = factory(name, dependencies, function (_ref) {
|
8 | var typed = _ref.typed,
|
9 | matrix = _ref.matrix,
|
10 | divideScalar = _ref.divideScalar,
|
11 | addScalar = _ref.addScalar,
|
12 | multiply = _ref.multiply,
|
13 | unaryMinus = _ref.unaryMinus,
|
14 | det = _ref.det,
|
15 | identity = _ref.identity,
|
16 | abs = _ref.abs;
|
17 |
|
18 | |
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | return typed(name, {
|
39 | 'Array | Matrix': function ArrayMatrix(x) {
|
40 | var size = isMatrix(x) ? x.size() : arraySize(x);
|
41 |
|
42 | switch (size.length) {
|
43 | case 1:
|
44 |
|
45 | if (size[0] === 1) {
|
46 | if (isMatrix(x)) {
|
47 | return matrix([divideScalar(1, x.valueOf()[0])]);
|
48 | } else {
|
49 | return [divideScalar(1, x[0])];
|
50 | }
|
51 | } else {
|
52 | throw new RangeError('Matrix must be square ' + '(size: ' + format(size) + ')');
|
53 | }
|
54 |
|
55 | case 2:
|
56 |
|
57 | {
|
58 | var rows = size[0];
|
59 | var cols = size[1];
|
60 |
|
61 | if (rows === cols) {
|
62 | if (isMatrix(x)) {
|
63 | return matrix(_inv(x.valueOf(), rows, cols), x.storage());
|
64 | } else {
|
65 |
|
66 | return _inv(x, rows, cols);
|
67 | }
|
68 | } else {
|
69 | throw new RangeError('Matrix must be square ' + '(size: ' + format(size) + ')');
|
70 | }
|
71 | }
|
72 |
|
73 | default:
|
74 |
|
75 | throw new RangeError('Matrix must be two dimensional ' + '(size: ' + format(size) + ')');
|
76 | }
|
77 | },
|
78 | any: function any(x) {
|
79 |
|
80 | return divideScalar(1, x);
|
81 | }
|
82 | });
|
83 | |
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 | function _inv(mat, rows, cols) {
|
93 | var r, s, f, value, temp;
|
94 |
|
95 | if (rows === 1) {
|
96 |
|
97 | value = mat[0][0];
|
98 |
|
99 | if (value === 0) {
|
100 | throw Error('Cannot calculate inverse, determinant is zero');
|
101 | }
|
102 |
|
103 | return [[divideScalar(1, value)]];
|
104 | } else if (rows === 2) {
|
105 |
|
106 | var d = det(mat);
|
107 |
|
108 | if (d === 0) {
|
109 | throw Error('Cannot calculate inverse, determinant is zero');
|
110 | }
|
111 |
|
112 | return [[divideScalar(mat[1][1], d), divideScalar(unaryMinus(mat[0][1]), d)], [divideScalar(unaryMinus(mat[1][0]), d), divideScalar(mat[0][0], d)]];
|
113 | } else {
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | var A = mat.concat();
|
121 |
|
122 | for (r = 0; r < rows; r++) {
|
123 | A[r] = A[r].concat();
|
124 | }
|
125 |
|
126 |
|
127 |
|
128 | var B = identity(rows).valueOf();
|
129 |
|
130 | for (var c = 0; c < cols; c++) {
|
131 |
|
132 | var ABig = abs(A[c][c]);
|
133 | var rBig = c;
|
134 | r = c + 1;
|
135 |
|
136 | while (r < rows) {
|
137 | if (abs(A[r][c]) > ABig) {
|
138 | ABig = abs(A[r][c]);
|
139 | rBig = r;
|
140 | }
|
141 |
|
142 | r++;
|
143 | }
|
144 |
|
145 | if (ABig === 0) {
|
146 | throw Error('Cannot calculate inverse, determinant is zero');
|
147 | }
|
148 |
|
149 | r = rBig;
|
150 |
|
151 | if (r !== c) {
|
152 | temp = A[c];
|
153 | A[c] = A[r];
|
154 | A[r] = temp;
|
155 | temp = B[c];
|
156 | B[c] = B[r];
|
157 | B[r] = temp;
|
158 | }
|
159 |
|
160 |
|
161 | var Ac = A[c];
|
162 | var Bc = B[c];
|
163 |
|
164 | for (r = 0; r < rows; r++) {
|
165 | var Ar = A[r];
|
166 | var Br = B[r];
|
167 |
|
168 | if (r !== c) {
|
169 |
|
170 | if (Ar[c] !== 0) {
|
171 | f = divideScalar(unaryMinus(Ar[c]), Ac[c]);
|
172 |
|
173 |
|
174 | for (s = c; s < cols; s++) {
|
175 | Ar[s] = addScalar(Ar[s], multiply(f, Ac[s]));
|
176 | }
|
177 |
|
178 | for (s = 0; s < cols; s++) {
|
179 | Br[s] = addScalar(Br[s], multiply(f, Bc[s]));
|
180 | }
|
181 | }
|
182 | } else {
|
183 |
|
184 |
|
185 | f = Ac[c];
|
186 |
|
187 | for (s = c; s < cols; s++) {
|
188 | Ar[s] = divideScalar(Ar[s], f);
|
189 | }
|
190 |
|
191 | for (s = 0; s < cols; s++) {
|
192 | Br[s] = divideScalar(Br[s], f);
|
193 | }
|
194 | }
|
195 | }
|
196 | }
|
197 |
|
198 | return B;
|
199 | }
|
200 | }
|
201 | }); |
\ | No newline at end of file |