@smockle/matrix 3.0.6 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/.github/CODEOWNERS +1 -0
  2. package/.github/workflows/publish.yml +33 -0
  3. package/.github/workflows/test.yml +30 -0
  4. package/LICENSE +21 -13
  5. package/README.md +97 -82
  6. package/package.json +28 -39
  7. package/src/__tests__/index.test.ts +540 -0
  8. package/src/index.ts +290 -0
  9. package/tsconfig.json +17 -0
  10. package/.editorconfig +0 -7
  11. package/.eslintignore +0 -1
  12. package/.eslintrc.json +0 -6
  13. package/.flowconfig +0 -27
  14. package/.prettierignore +0 -1
  15. package/.travis.yml +0 -19
  16. package/appveyor.yml +0 -21
  17. package/flow-typed/npm/@std/esm_vx.x.x.js +0 -33
  18. package/flow-typed/npm/codecov_vx.x.x.js +0 -276
  19. package/flow-typed/npm/colortape_vx.x.x.js +0 -80
  20. package/flow-typed/npm/eslint-config-standard_vx.x.x.js +0 -45
  21. package/flow-typed/npm/eslint-plugin-import_vx.x.x.js +0 -333
  22. package/flow-typed/npm/eslint-plugin-node_vx.x.x.js +0 -249
  23. package/flow-typed/npm/eslint-plugin-promise_vx.x.x.js +0 -150
  24. package/flow-typed/npm/eslint-plugin-standard_vx.x.x.js +0 -87
  25. package/flow-typed/npm/eslint_vx.x.x.js +0 -2363
  26. package/flow-typed/npm/flow-bin_v0.x.x.js +0 -6
  27. package/flow-typed/npm/flow-typed_vx.x.x.js +0 -193
  28. package/flow-typed/npm/husky_vx.x.x.js +0 -88
  29. package/flow-typed/npm/jsdoc-to-markdown_vx.x.x.js +0 -95
  30. package/flow-typed/npm/lint-staged_vx.x.x.js +0 -143
  31. package/flow-typed/npm/lodash_v4.x.x.js +0 -530
  32. package/flow-typed/npm/mathjs_vx.x.x.js +0 -5561
  33. package/flow-typed/npm/nyc_vx.x.x.js +0 -108
  34. package/flow-typed/npm/prettier-eslint-cli_vx.x.x.js +0 -74
  35. package/jsdoc.json +0 -6
  36. package/jsdoc2md/README.hbs +0 -41
  37. package/lib/matrix.js +0 -4
  38. package/lib/matrix.mjs +0 -312
  39. package/test/matrix.mjs +0 -243
package/src/index.ts ADDED
@@ -0,0 +1,290 @@
1
+ import { fill, flattenDeep, invert, padStart, unzip } from "lodash";
2
+ import { inv } from "mathjs";
3
+
4
+ type Matrix = {
5
+ __value: number | (number | number[])[];
6
+ countRows: () => number;
7
+ countColumns: () => number;
8
+ addable: (y: Matrix) => boolean;
9
+ add: (y: Matrix) => Matrix;
10
+ multipliable: (y: Matrix) => boolean;
11
+ multiply: (y: Matrix) => Matrix;
12
+ transpose: () => Matrix;
13
+ invert: () => Matrix;
14
+ map: (x: any) => Matrix;
15
+ valueOf: () => number | (number | number[])[];
16
+ };
17
+
18
+ /**
19
+ * Creates a Matrix
20
+ * @constructor
21
+ * @alias module:matrix
22
+ * @param {number|(number | number[])[]} x - Values to store in matrix
23
+ * @throws {TypeError} Argument x must be a number or number array
24
+ * @return {Matrix} Single or multi dimensional matrix
25
+ */
26
+ function Matrix(x: number | (number | number[])[]): Matrix {
27
+ // extra nesting
28
+ if (Array.isArray(x) && Array.isArray(x[0]) && x.length === 1) {
29
+ throw new TypeError("Matrix must be a number or array of numbers");
30
+ }
31
+
32
+ // uneven rows
33
+ if (
34
+ Array.isArray(x) &&
35
+ Array.isArray(x[0]) &&
36
+ x.some(
37
+ (row) => Array.isArray(row) && row.length !== (x[0] as number[]).length
38
+ )
39
+ ) {
40
+ throw new TypeError("Matrix must be a number or array of numbers");
41
+ }
42
+
43
+ /* Single or multi dimensional matrix */
44
+ const matrix = Object.create(Matrix.prototype);
45
+ matrix.__value = x;
46
+ return matrix;
47
+ }
48
+
49
+ /**
50
+ * Determines whether two matrices can be summed
51
+ * @alias module:matrix.addable
52
+ * @param {Matrix} x - Matrix to check
53
+ * @param {Matrix} y - Matrix to check
54
+ * @return {boolean} Whether two matrices can be summed (using matrix addition)
55
+ */
56
+ Matrix.addable = function (x: Matrix, y: Matrix): boolean {
57
+ return (
58
+ x.countRows() === y.countRows() && x.countColumns() === y.countColumns()
59
+ );
60
+ };
61
+
62
+ /**
63
+ * Adds two matrices using matrix addition
64
+ * @alias module:matrix.add
65
+ * @param {Matrix} x - Matrix to add
66
+ * @param {Matrix} y - Matrix to add
67
+ * @throws {TypeError} Matrices are not addable
68
+ * @return {Matrix} New matrix with the summation
69
+ */
70
+ Matrix.add = function (x: Matrix, y: Matrix): Matrix {
71
+ if (!Matrix.addable(x, y)) throw new TypeError("Matrices are not addable");
72
+ return x.map((row: number[], i: number): number[] =>
73
+ row.map(
74
+ (column: number, j: number): number =>
75
+ column + (y.__value as number[][])[i][j]
76
+ )
77
+ );
78
+ };
79
+
80
+ /**
81
+ * Determines whether two matrices can be multiplied
82
+ * @alias module:matrix.multipliable
83
+ * @param {Matrix} x - Matrix to check
84
+ * @param {Matrix} y - Matrix to check
85
+ * @return {boolean} Whether two matrices can be summed (using matrix multiplication)
86
+ */
87
+ Matrix.multipliable = function (x: Matrix, y: Matrix): boolean {
88
+ return x.countColumns() === y.countRows();
89
+ };
90
+
91
+ /**
92
+ * Calculates the inner product of two matrices
93
+ * @param {Matrix} x - Matrix to multiply
94
+ * @param {Matrix} y - Matrix to multiply
95
+ * @param {number} i - Column in matrix y to multiply
96
+ * @return {number} Inner product of matrices
97
+ */
98
+ function innerproduct(x: Matrix, y: Matrix, i: number): number {
99
+ const _x: number[] = x.__value as number[];
100
+ const _y: number[] =
101
+ Array.isArray(unzip<number>(y.__value as number[][])) &&
102
+ unzip<number>(y.__value as number[][]).length === 0
103
+ ? unzip([y.__value as number[]])[i]
104
+ : unzip(y.__value as number[][])[i];
105
+ return ([] as number[])
106
+ .concat(_x)
107
+ .reduce((z: number, _z: number, j: number): number => z + _z * _y[j], 0);
108
+ }
109
+
110
+ /**
111
+ * Calculates the dot product of two matrices
112
+ * @alias module:matrix.multiply
113
+ * @param {Matrix} x - Matrix to multiply
114
+ * @param {Matrix} y - Matrix to multiply
115
+ * @return {Matrix} New matrix with the dot product
116
+ */
117
+ Matrix.multiply = function (x: Matrix, y: Matrix): Matrix {
118
+ if (!Matrix.multipliable(x, y)) {
119
+ throw new TypeError("Matrices are not multipliable");
120
+ }
121
+
122
+ if (x.countColumns() === 0 && y.countRows() === 0) {
123
+ return Matrix((x.__value as number) * (y.__value as number));
124
+ }
125
+
126
+ /* New matrix with the dot product */
127
+ const z: Matrix = Matrix(
128
+ fill(
129
+ Array(x.countRows()),
130
+ x.countRows() !== 1 ? fill(Array(y.countColumns()), 0) : 0
131
+ )
132
+ );
133
+ return z.map((_z: number | number[], i: number): number | number[] => {
134
+ if (typeof _z === "number") return innerproduct(x, y, i);
135
+ return _z.map((_, j) =>
136
+ innerproduct(Matrix((x.__value as number[])[i]), y, j)
137
+ );
138
+ });
139
+ };
140
+
141
+ /**
142
+ * Inverts a matrix
143
+ * @alias module:matrix.invert
144
+ * @param {x} Matrix to invert
145
+ * @return {Matrix} Matrix inverse
146
+ */
147
+ Matrix.invert = function (x: Matrix): Matrix {
148
+ return Matrix(inv<any>(x instanceof Matrix ? x.__value : x));
149
+ };
150
+
151
+ /**
152
+ * Counts rows in this matrix
153
+ * @alias module:matrix#countRows
154
+ * @return {number} Number of rows
155
+ */
156
+ Matrix.prototype.countRows = function (this: Matrix): number {
157
+ if (typeof this.__value === "number") return 0;
158
+ if (typeof this.__value[0] === "number") return 1;
159
+ return this.__value.length;
160
+ };
161
+
162
+ /**
163
+ * Counts columns in this matrix
164
+ * @alias module:matrix#countColumns
165
+ * @return {number} Number of columns
166
+ */
167
+ Matrix.prototype.countColumns = function (this: Matrix): number {
168
+ if (typeof this.__value === "number") return 0;
169
+ if (typeof this.__value[0] === "number") return this.__value.length;
170
+ return this.__value[0].length;
171
+ };
172
+
173
+ /**
174
+ * Determines whether this matrix can be summed
175
+ * @alias module:matrix#addable
176
+ * @param {Matrix} y - Matrix to check
177
+ * @return {boolean} Whether this matrix can be summed (using matrix addition)
178
+ */
179
+ Matrix.prototype.addable = function (this: Matrix, y: Matrix): boolean {
180
+ return Matrix.addable(this, y);
181
+ };
182
+
183
+ /**
184
+ * Adds this matrix using matrix addition
185
+ * @alias module:matrix#add
186
+ * @param {Matrix} y - Matrix to add
187
+ * @return {Matrix} New matrix with the summation
188
+ */
189
+ Matrix.prototype.add = function (this: Matrix, y: Matrix): Matrix {
190
+ return Matrix.add(this, y);
191
+ };
192
+
193
+ /**
194
+ * Determines whether this matrix can be multiplied
195
+ * @alias module:matrix#multipliable
196
+ * @param {Matrix} y - Matrix to check
197
+ * @return {boolean} Whether two matrices can be summed (using matrix multiplication)
198
+ */
199
+ Matrix.prototype.multipliable = function (this: Matrix, y: Matrix): boolean {
200
+ return Matrix.multipliable(this, y);
201
+ };
202
+
203
+ /**
204
+ * Calculates the dot product of this matrix
205
+ * @alias module:matrix#multiply
206
+ * @param {Matrix} y - Matrix to multiply
207
+ * @return {Matrix} New matrix with the dot product
208
+ */
209
+ Matrix.prototype.multiply = function (this: Matrix, y: Matrix): Matrix {
210
+ return Matrix.multiply(this, y);
211
+ };
212
+
213
+ /**
214
+ * Calculates the transpose of this matrix
215
+ * @alias module:matrix#transpose
216
+ * @return {Matrix} New matrix with the transpose
217
+ */
218
+ Matrix.prototype.transpose = function (this: Matrix): Matrix {
219
+ switch (this.countRows()) {
220
+ case 0:
221
+ return Matrix(this.__value as number);
222
+ case 1:
223
+ return Matrix(unzip([this.__value as number[]]));
224
+ default:
225
+ return Matrix(unzip(this.__value as number[][]));
226
+ }
227
+ };
228
+
229
+ /**
230
+ * Inverts this matrix
231
+ * @alias module:matrix#invert
232
+ * @return {Matrix} Matrix inverse
233
+ */
234
+ Matrix.prototype.invert = function (this: Matrix): Matrix {
235
+ return Matrix.invert(this);
236
+ };
237
+
238
+ /**
239
+ * Maps over this matrix
240
+ * @alias module:matrix#map
241
+ * @return {Matrix} Matrix inverse
242
+ */
243
+ Matrix.prototype.map = function (this: Matrix, x: any): Matrix {
244
+ if (typeof this.__value === "number") return Matrix(x(this.__value));
245
+ return Matrix(this.__value.map(x));
246
+ };
247
+
248
+ /**
249
+ * Returns the number or number array value
250
+ * @alias module:matrix#valueOf
251
+ * @return {number|number[]} Number of number array value
252
+ */
253
+ Matrix.prototype.valueOf = function (
254
+ this: Matrix
255
+ ): number | (number | number[])[] {
256
+ return this.__value;
257
+ };
258
+
259
+ /**
260
+ * Formats and prints the matrix value
261
+ * @alias module:matrix#inspect
262
+ * @return {string} Formatted matrix value
263
+ */
264
+ Matrix.prototype[Symbol.for("nodejs.util.inspect.custom")] = function (
265
+ this: Matrix
266
+ ): string {
267
+ switch (this.countRows()) {
268
+ case 0:
269
+ return `${this.__value}`;
270
+ case 1:
271
+ return `[ ${(this.__value as number[]).join(" ")} ]`;
272
+ default:
273
+ /* Output array filled with zeroes */
274
+ const padding: number[] = unzip(this.__value as number[][]).map(
275
+ (column: number[]) =>
276
+ column.reduce((length, x) => Math.max(`${x}`.length, length), 0)
277
+ );
278
+ return (this.__value as number[][])
279
+ .reduce(
280
+ (output, row) =>
281
+ `${output}[ ${row
282
+ .map((x, i) => padStart(`${x}`, padding[i]))
283
+ .join(" ")} ]`,
284
+ ""
285
+ )
286
+ .replace(/]\[/g, "]\n[");
287
+ }
288
+ };
289
+
290
+ export default Matrix;
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "module": "nodenext",
5
+ "moduleResolution": "nodenext",
6
+ "esModuleInterop": true,
7
+ "strict": true,
8
+ "rootDir": "src",
9
+ "outDir": "dist",
10
+ "composite": true,
11
+ "incremental": true
12
+ },
13
+ "include": ["src/**/*.ts"],
14
+ "ts-node": {
15
+ "esm": true
16
+ }
17
+ }
package/.editorconfig DELETED
@@ -1,7 +0,0 @@
1
- # top-most EditorConfig file
2
- root = true
3
-
4
- # Unix-style newlines with a newline ending every file
5
- [*]
6
- end_of_line = lf
7
- insert_final_newline = true
package/.eslintignore DELETED
@@ -1 +0,0 @@
1
- flow-typed/*
package/.eslintrc.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "standard",
3
- "rules": {
4
- "no-global-assign": ["error", { "exceptions": ["require"] }]
5
- }
6
- }
package/.flowconfig DELETED
@@ -1,27 +0,0 @@
1
- [ignore]
2
-
3
- [include]
4
-
5
- [libs]
6
-
7
- [options]
8
- # Run Flow on .js, .mjs, .jsx, .json files
9
- module.file_ext=.js
10
- module.file_ext=.mjs
11
- module.file_ext=.jsx
12
- module.file_ext=.json
13
-
14
- # Use the Node.js module system to resolve `import` and `require`
15
- module.system=node
16
-
17
- # Allow static class fields
18
- esproposal.class_static_fields=enable
19
-
20
- # Allow instance class fields
21
- esproposal.class_instance_fields=enable
22
-
23
- # Treat underscore-prefixed class properties and methods as private
24
- munge_underscores=true
25
-
26
- # Ignore next line with /* @flow disable */ magic comment
27
- suppress_comment= \\(.\\|\n\\)*\\@flow disable
package/.prettierignore DELETED
@@ -1 +0,0 @@
1
- package.json
package/.travis.yml DELETED
@@ -1,19 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - '8'
4
- - '6'
5
- notifications:
6
- email:
7
- on_success: change
8
- on_failure: always
9
- before_install:
10
- - npm install -g greenkeeper-lockfile@1
11
- before_script:
12
- - greenkeeper-lockfile-update
13
- after_script:
14
- - greenkeeper-lockfile-upload
15
- - npm run coverage
16
- - codecov
17
- env:
18
- global:
19
- - secure: NWsEQyPx6mgrl+Q6k9iYd8V+xUSuzYJLi5nN8K3YNjx5/lzxNliCY89dGQ/sUZy3I2dtiQb61Cno6Ki7de2Q2yWSCZJK7w1x0B8zk2tb1J/Gyy4G4HFhjeWPyJQ61BiH+vu3zpA+Ad+/faR/pBegPd43gQ7qGbOldj2jikQ4T3qo+0c0yAcu0lveEmgB6CrvFf/TojI2BTPD9ez8rlJlTVUMhqm8j0Kly48mdchx08E8BTTHDx0I9UceuTxuy8HyKbL0wOARf6tsTiBVbKdie/qDwu3NUP0mGJ7Xt0C9/YLfuhP7e+cORzT+JWQuRREZys/x+xX43ckDS5HLq09Aeodc85toSD3CIWjNNE9hKr91EjmysIqvzFmZ0ElyDXjHKLrmfcedI2TAajuY0pycDD6zC/eddDIl8jhsbYKEZfArO763aM5hXHdxviJpmsdIBU2A297MrG4LzRZW6kUkO8rUaXqBzNiafICrOskF6hE91qIiJGd8an4i7zeBfnb3q1S4BVBzBj7DiH6p+Ud5PJkASOhj/7O5Qamg6LSDaEkzaYN4QL+z8rvCVthaWtJFpxVAa8RL7xrfMY9nwtPClbgwz28RS7dHrqZiDZA8a6UPbkGLLo9w2Gmlti0I5XJtc5gkWOQU9pVKYwXpEKi0rWNtFTbAmh++NSn+Givtsrs=
package/appveyor.yml DELETED
@@ -1,21 +0,0 @@
1
- # scripts that are called at very beginning, before repo cloning
2
- init:
3
- - git config --global core.autocrlf input
4
-
5
- # scripts that run after cloning repository
6
- install:
7
- # Install node 8
8
- - ps: Install-Product node 8
9
- # install modules
10
- - npm install
11
-
12
- # to run your custom scripts instead of automatic tests
13
- test_script:
14
- # Output useful info for debugging.
15
- - node --version
16
- - npm --version
17
- # run tests
18
- - npm test
19
-
20
- # Don't build with msbuild.
21
- build: off
@@ -1,33 +0,0 @@
1
- // flow-typed signature: 1a1a5f7378a3eb94c91b140831760eab
2
- // flow-typed version: <<STUB>>/@std/esm_v^0.5.1/flow_v0.53.1
3
-
4
- /**
5
- * This is an autogenerated libdef stub for:
6
- *
7
- * '@std/esm'
8
- *
9
- * Fill this stub out by replacing all the `any` types.
10
- *
11
- * Once filled out, we encourage you to share your work with the
12
- * community by sending a pull request to:
13
- * https://github.com/flowtype/flow-typed
14
- */
15
-
16
- declare module '@std/esm' {
17
- declare module.exports: any;
18
- }
19
-
20
- /**
21
- * We include stubs for each file inside this npm package in case you need to
22
- * require those files directly. Feel free to delete any files that aren't
23
- * needed.
24
- */
25
-
26
-
27
- // Filename aliases
28
- declare module '@std/esm/index' {
29
- declare module.exports: $Exports<'@std/esm'>;
30
- }
31
- declare module '@std/esm/index.js' {
32
- declare module.exports: $Exports<'@std/esm'>;
33
- }