@smockle/matrix 4.0.3 → 5.0.1

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.
package/README.md CHANGED
@@ -15,7 +15,7 @@ Run `npm install --save @smockle/matrix` to add `matrix` to your project.
15
15
  import Matrix from '@smockle/matrix'
16
16
 
17
17
  // 1x1 Matrix
18
- const m11 = Matrix(3)
18
+ const m11 = Matrix([3])
19
19
 
20
20
  // 1x3 Matrix
21
21
  const m13 = Matrix([1, 2, 3])
package/dist/index.d.ts CHANGED
@@ -1,30 +1,59 @@
1
- type Matrix = {
2
- __value: number | (number | number[])[];
1
+ interface IMatrix {
3
2
  countRows: () => number;
4
3
  countColumns: () => number;
5
4
  addable: (y: Matrix) => boolean;
6
- add: (y: Matrix) => Matrix;
7
5
  multipliable: (y: Matrix) => boolean;
8
6
  multiply: (y: Matrix) => Matrix;
9
- transpose: () => Matrix;
10
- invert: () => Matrix;
7
+ transpose: () => Matrix2D;
11
8
  map: (x: any) => Matrix;
12
- valueOf: () => number | (number | number[])[];
13
- };
9
+ }
10
+ export interface Matrix1D extends IMatrix {
11
+ __value: number[];
12
+ add: (y: Matrix1D) => Matrix1D;
13
+ invert: () => Matrix1D;
14
+ valueOf: () => number[];
15
+ }
16
+ export interface Matrix2D extends IMatrix {
17
+ __value: number[][];
18
+ add: (y: Matrix2D) => Matrix2D;
19
+ invert: () => Matrix2D;
20
+ valueOf: () => number[][];
21
+ }
22
+ type Matrix = Matrix1D | Matrix2D;
23
+ export declare function isMatrix1D(matrix: Matrix): matrix is Matrix1D;
14
24
  /**
15
25
  * Creates a Matrix
16
26
  * @constructor
17
27
  * @alias module:matrix
18
- * @param {number|(number | number[])[]} x - Values to store in matrix
28
+ * @param {number[] | number[][]} x - Values to store in matrix
19
29
  * @throws {TypeError} Argument x must be a number or number array
20
30
  * @return {Matrix} Single or multi dimensional matrix
21
31
  */
22
- declare function Matrix(x: number | (number | number[])[]): Matrix;
32
+ declare function Matrix(x: number[]): Matrix1D;
33
+ declare function Matrix(x: number[][]): Matrix2D;
23
34
  declare namespace Matrix {
24
35
  var addable: (x: Matrix, y: Matrix) => boolean;
25
- var add: (x: Matrix, y: Matrix) => Matrix;
36
+ var add: typeof Add;
26
37
  var multipliable: (x: Matrix, y: Matrix) => boolean;
27
38
  var multiply: (x: Matrix, y: Matrix) => Matrix;
28
- var invert: (x: Matrix) => Matrix;
39
+ var invert: typeof Invert;
29
40
  }
41
+ /**
42
+ * Adds two matrices using matrix addition
43
+ * @alias module:matrix.add
44
+ * @param {Matrix} x - Matrix to add
45
+ * @param {Matrix} y - Matrix to add
46
+ * @throws {TypeError} Matrices are not addable
47
+ * @return {Matrix} New matrix with the summation
48
+ */
49
+ declare function Add(x: Matrix1D, y: Matrix1D): Matrix1D;
50
+ declare function Add(x: Matrix2D, y: Matrix2D): Matrix2D;
51
+ /**
52
+ * Inverts a matrix. Matrix must be a square (e.g. 1x1 or 2x2)
53
+ * @alias module:matrix.invert
54
+ * @param {x} Matrix to invert
55
+ * @return {Matrix} Matrix inverse
56
+ */
57
+ declare function Invert(x: Matrix1D): Matrix1D;
58
+ declare function Invert(x: Matrix2D): Matrix2D;
30
59
  export default Matrix;
package/dist/index.js CHANGED
@@ -1,22 +1,17 @@
1
1
  import { fill, padStart, unzip } from "lodash-es";
2
2
  import { inv } from "mathjs";
3
- /**
4
- * Creates a Matrix
5
- * @constructor
6
- * @alias module:matrix
7
- * @param {number|(number | number[])[]} x - Values to store in matrix
8
- * @throws {TypeError} Argument x must be a number or number array
9
- * @return {Matrix} Single or multi dimensional matrix
10
- */
3
+ export function isMatrix1D(matrix) {
4
+ return matrix.countRows() === 1;
5
+ }
11
6
  function Matrix(x) {
12
7
  // extra nesting
13
- if (Array.isArray(x) && Array.isArray(x[0]) && x.length === 1) {
8
+ if (Array.isArray(x[0]) && x.length === 1) {
14
9
  throw new TypeError("Matrix must be a number or array of numbers");
15
10
  }
16
11
  // uneven rows
17
- if (Array.isArray(x) &&
18
- Array.isArray(x[0]) &&
19
- x.some((row) => Array.isArray(row) && row.length !== x[0].length)) {
12
+ const firstRowLength = Array.isArray(x[0]) ? x[0].length : 0;
13
+ if (firstRowLength > 0 &&
14
+ x.some((row) => Array.isArray(row) && row.length !== firstRowLength)) {
20
15
  throw new TypeError("Matrix must be a number or array of numbers");
21
16
  }
22
17
  /* Single or multi dimensional matrix */
@@ -34,25 +29,20 @@ function Matrix(x) {
34
29
  Matrix.addable = function (x, y) {
35
30
  return (x.countRows() === y.countRows() && x.countColumns() === y.countColumns());
36
31
  };
37
- /**
38
- * Adds two matrices using matrix addition
39
- * @alias module:matrix.add
40
- * @param {Matrix} x - Matrix to add
41
- * @param {Matrix} y - Matrix to add
42
- * @throws {TypeError} Matrices are not addable
43
- * @return {Matrix} New matrix with the summation
44
- */
45
- Matrix.add = function (x, y) {
32
+ function Add(x, y) {
46
33
  if (!Matrix.addable(x, y))
47
34
  throw new TypeError("Matrices are not addable");
48
- return x.map((row, i) => row.map((column, j) => column + y.__value[i][j]));
49
- };
35
+ return x.map((row, i) => row.map((column, j) => {
36
+ return column + (Array.isArray(y.__value[i]) ? y.__value[i][j] : 0);
37
+ }));
38
+ }
39
+ Matrix.add = Add;
50
40
  /**
51
41
  * Determines whether two matrices can be multiplied
52
42
  * @alias module:matrix.multipliable
53
43
  * @param {Matrix} x - Matrix to check
54
44
  * @param {Matrix} y - Matrix to check
55
- * @return {boolean} Whether two matrices can be summed (using matrix multiplication)
45
+ * @return {boolean} Whether two matrices can be multiplied (using matrix multiplication)
56
46
  */
57
47
  Matrix.multipliable = function (x, y) {
58
48
  return x.countColumns() === y.countRows();
@@ -66,13 +56,14 @@ Matrix.multipliable = function (x, y) {
66
56
  */
67
57
  function innerproduct(x, y, i) {
68
58
  const _x = x.__value;
69
- const _y = Array.isArray(unzip(y.__value)) &&
70
- unzip(y.__value).length === 0
71
- ? unzip([y.__value])[i]
72
- : unzip(y.__value)[i];
73
- return []
74
- .concat(_x)
75
- .reduce((z, _z, j) => z + _z * _y[j], 0);
59
+ let _y;
60
+ if (isMatrix1D(y)) {
61
+ _y = unzip([y.__value])[i];
62
+ }
63
+ else {
64
+ _y = unzip(y.__value)[i];
65
+ }
66
+ return [..._x].reduce((z, _z, j) => z + _z * _y[j], 0);
76
67
  }
77
68
  /**
78
69
  * Calculates the dot product of two matrices
@@ -85,34 +76,29 @@ Matrix.multiply = function (x, y) {
85
76
  if (!Matrix.multipliable(x, y)) {
86
77
  throw new TypeError("Matrices are not multipliable");
87
78
  }
88
- if (x.countColumns() === 0 && y.countRows() === 0) {
89
- return Matrix(x.__value * y.__value);
90
- }
91
79
  /* New matrix with the dot product */
92
- const z = Matrix(fill(Array(x.countRows()), x.countRows() !== 1 ? fill(Array(y.countColumns()), 0) : 0));
93
- return z.map((_z, i) => {
94
- if (typeof _z === "number")
95
- return innerproduct(x, y, i);
96
- return _z.map((_, j) => innerproduct(Matrix(x.__value[i]), y, j));
97
- });
98
- };
99
- /**
100
- * Inverts a matrix
101
- * @alias module:matrix.invert
102
- * @param {x} Matrix to invert
103
- * @return {Matrix} Matrix inverse
104
- */
105
- Matrix.invert = function (x) {
106
- return Matrix(inv(x instanceof Matrix ? x.__value : x));
80
+ if (isMatrix1D(x)) {
81
+ return Matrix([0]).map((_z, i) => innerproduct(x, y, i));
82
+ }
83
+ else {
84
+ return Matrix(fill(Array(x.countRows()), fill(Array(y.countColumns()), 0))).map((_z, i) => {
85
+ const _x = Matrix(x.__value[i]);
86
+ if (isMatrix1D(_x)) {
87
+ return _z.map((_, j) => innerproduct(_x, y, j));
88
+ }
89
+ });
90
+ }
107
91
  };
92
+ function Invert(x) {
93
+ return Matrix(inv(x.__value));
94
+ }
95
+ Matrix.invert = Invert;
108
96
  /**
109
97
  * Counts rows in this matrix
110
98
  * @alias module:matrix#countRows
111
99
  * @return {number} Number of rows
112
100
  */
113
101
  Matrix.prototype.countRows = function () {
114
- if (typeof this.__value === "number")
115
- return 0;
116
102
  if (typeof this.__value[0] === "number")
117
103
  return 1;
118
104
  return this.__value.length;
@@ -123,8 +109,6 @@ Matrix.prototype.countRows = function () {
123
109
  * @return {number} Number of columns
124
110
  */
125
111
  Matrix.prototype.countColumns = function () {
126
- if (typeof this.__value === "number")
127
- return 0;
128
112
  if (typeof this.__value[0] === "number")
129
113
  return this.__value.length;
130
114
  return this.__value[0].length;
@@ -138,15 +122,10 @@ Matrix.prototype.countColumns = function () {
138
122
  Matrix.prototype.addable = function (y) {
139
123
  return Matrix.addable(this, y);
140
124
  };
141
- /**
142
- * Adds this matrix using matrix addition
143
- * @alias module:matrix#add
144
- * @param {Matrix} y - Matrix to add
145
- * @return {Matrix} New matrix with the summation
146
- */
147
- Matrix.prototype.add = function (y) {
125
+ function add(y) {
148
126
  return Matrix.add(this, y);
149
- };
127
+ }
128
+ Matrix.prototype.add = add;
150
129
  /**
151
130
  * Determines whether this matrix can be multiplied
152
131
  * @alias module:matrix#multipliable
@@ -171,37 +150,34 @@ Matrix.prototype.multiply = function (y) {
171
150
  * @return {Matrix} New matrix with the transpose
172
151
  */
173
152
  Matrix.prototype.transpose = function () {
174
- switch (this.countRows()) {
175
- case 0:
176
- return Matrix(this.__value);
177
- case 1:
178
- return Matrix(unzip([this.__value]));
179
- default:
180
- return Matrix(unzip(this.__value));
153
+ if (isMatrix1D(this)) {
154
+ return Matrix(unzip([this.__value]));
155
+ }
156
+ else {
157
+ return Matrix(unzip(this.__value));
181
158
  }
182
159
  };
183
- /**
184
- * Inverts this matrix
185
- * @alias module:matrix#invert
186
- * @return {Matrix} Matrix inverse
187
- */
188
- Matrix.prototype.invert = function () {
160
+ function invert() {
189
161
  return Matrix.invert(this);
190
- };
162
+ }
163
+ Matrix.prototype.invert = invert;
191
164
  /**
192
165
  * Maps over this matrix
193
166
  * @alias module:matrix#map
194
167
  * @return {Matrix} Matrix inverse
195
168
  */
196
169
  Matrix.prototype.map = function (x) {
197
- if (typeof this.__value === "number")
198
- return Matrix(x(this.__value));
199
- return Matrix(this.__value.map(x));
170
+ if (isMatrix1D(this)) {
171
+ return Matrix(this.__value.map((x)));
172
+ }
173
+ else {
174
+ return Matrix(this.__value.map((x)));
175
+ }
200
176
  };
201
177
  /**
202
178
  * Returns the number or number array value
203
179
  * @alias module:matrix#valueOf
204
- * @return {number|number[]} Number of number array value
180
+ * @return {number[]|number[][]} Number of number array value
205
181
  */
206
182
  Matrix.prototype.valueOf = function () {
207
183
  return this.__value;
@@ -212,19 +188,17 @@ Matrix.prototype.valueOf = function () {
212
188
  * @return {string} Formatted matrix value
213
189
  */
214
190
  Matrix.prototype[Symbol.for("nodejs.util.inspect.custom")] = function () {
215
- switch (this.countRows()) {
216
- case 0:
217
- return `${this.__value}`;
218
- case 1:
219
- return `[ ${this.__value.join(" ")} ]`;
220
- default:
221
- /* Output array filled with zeroes */
222
- const padding = unzip(this.__value).map((column) => column.reduce((length, x) => Math.max(`${x}`.length, length), 0));
223
- return this.__value
224
- .reduce((output, row) => `${output}[ ${row
225
- .map((x, i) => padStart(`${x}`, padding[i]))
226
- .join(" ")} ]`, "")
227
- .replace(/]\[/g, "]\n[");
191
+ if (isMatrix1D(this)) {
192
+ return `[ ${this.__value.join(" ")} ]`;
193
+ }
194
+ else {
195
+ /* Output array filled with zeroes */
196
+ const padding = unzip(this.__value).map((column) => column.reduce((length, x) => Math.max(`${x}`.length, length), 0));
197
+ return this.__value
198
+ .reduce((output, row) => `${output}[ ${row
199
+ .map((x, i) => padStart(`${x}`, padding[i]))
200
+ .join(" ")} ]`, "")
201
+ .replace(/]\[/g, "]\n[");
228
202
  }
229
203
  };
230
204
  export default Matrix;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smockle/matrix",
3
- "version": "4.0.3",
3
+ "version": "5.0.1",
4
4
  "description": "Single and multi dimensional matrices and matrix functions.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",