ml-matrix 6.8.2 → 6.10.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 +68 -19
- package/matrix.d.ts +56 -37
- package/matrix.js +118 -67
- package/matrix.umd.js +1 -1
- package/package.json +13 -15
- package/src/correlation.js +3 -1
- package/src/covariance.js +3 -1
- package/src/dc/nipals.js +3 -1
- package/src/matrix.js +96 -27
- package/src/util.js +14 -30
- package/src/views/columnSelection.js +1 -1
- package/src/views/rowSelection.js +1 -1
- package/src/views/selection.js +6 -5
- package/src/wrap/wrap.js +4 -2
package/matrix.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var isAnyArray = require('is-any-array');
|
|
5
6
|
var rescale = require('ml-array-rescale');
|
|
6
7
|
|
|
7
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -952,46 +953,28 @@ function checkColumnVector(matrix, vector) {
|
|
|
952
953
|
return vector;
|
|
953
954
|
}
|
|
954
955
|
|
|
955
|
-
function checkIndices(matrix, rowIndices, columnIndices) {
|
|
956
|
-
return {
|
|
957
|
-
row: checkRowIndices(matrix, rowIndices),
|
|
958
|
-
column: checkColumnIndices(matrix, columnIndices),
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
|
|
962
956
|
function checkRowIndices(matrix, rowIndices) {
|
|
963
|
-
if (
|
|
964
|
-
throw new TypeError('
|
|
957
|
+
if (!isAnyArray.isAnyArray(rowIndices)) {
|
|
958
|
+
throw new TypeError('row indices must be an array');
|
|
965
959
|
}
|
|
966
960
|
|
|
967
|
-
let
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
if (rowOut) {
|
|
972
|
-
throw new RangeError('row indices are out of range');
|
|
961
|
+
for (let i = 0; i < rowIndices.length; i++) {
|
|
962
|
+
if (rowIndices[i] < 0 || rowIndices[i] >= matrix.rows) {
|
|
963
|
+
throw new RangeError('row indices are out of range');
|
|
964
|
+
}
|
|
973
965
|
}
|
|
974
|
-
|
|
975
|
-
if (!Array.isArray(rowIndices)) rowIndices = Array.from(rowIndices);
|
|
976
|
-
|
|
977
|
-
return rowIndices;
|
|
978
966
|
}
|
|
979
967
|
|
|
980
968
|
function checkColumnIndices(matrix, columnIndices) {
|
|
981
|
-
if (
|
|
982
|
-
throw new TypeError('
|
|
969
|
+
if (!isAnyArray.isAnyArray(columnIndices)) {
|
|
970
|
+
throw new TypeError('column indices must be an array');
|
|
983
971
|
}
|
|
984
972
|
|
|
985
|
-
let
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (columnOut) {
|
|
990
|
-
throw new RangeError('column indices are out of range');
|
|
973
|
+
for (let i = 0; i < columnIndices.length; i++) {
|
|
974
|
+
if (columnIndices[i] < 0 || columnIndices[i] >= matrix.columns) {
|
|
975
|
+
throw new RangeError('column indices are out of range');
|
|
976
|
+
}
|
|
991
977
|
}
|
|
992
|
-
if (!Array.isArray(columnIndices)) columnIndices = Array.from(columnIndices);
|
|
993
|
-
|
|
994
|
-
return columnIndices;
|
|
995
978
|
}
|
|
996
979
|
|
|
997
980
|
function checkRange(matrix, startRow, endRow, startColumn, endColumn) {
|
|
@@ -1777,19 +1760,47 @@ class AbstractMatrix {
|
|
|
1777
1760
|
return this;
|
|
1778
1761
|
}
|
|
1779
1762
|
|
|
1780
|
-
max() {
|
|
1763
|
+
max(by) {
|
|
1781
1764
|
if (this.isEmpty()) {
|
|
1782
1765
|
return NaN;
|
|
1783
1766
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1767
|
+
switch (by) {
|
|
1768
|
+
case 'row': {
|
|
1769
|
+
const max = new Array(this.rows).fill(Number.NEGATIVE_INFINITY);
|
|
1770
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1771
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1772
|
+
if (this.get(row, column) > max[row]) {
|
|
1773
|
+
max[row] = this.get(row, column);
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
return max;
|
|
1778
|
+
}
|
|
1779
|
+
case 'column': {
|
|
1780
|
+
const max = new Array(this.columns).fill(Number.NEGATIVE_INFINITY);
|
|
1781
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1782
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1783
|
+
if (this.get(row, column) > max[column]) {
|
|
1784
|
+
max[column] = this.get(row, column);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
return max;
|
|
1789
|
+
}
|
|
1790
|
+
case undefined: {
|
|
1791
|
+
let max = this.get(0, 0);
|
|
1792
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1793
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1794
|
+
if (this.get(row, column) > max) {
|
|
1795
|
+
max = this.get(row, column);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1789
1798
|
}
|
|
1799
|
+
return max;
|
|
1790
1800
|
}
|
|
1801
|
+
default:
|
|
1802
|
+
throw new Error(`invalid option: ${by}`);
|
|
1791
1803
|
}
|
|
1792
|
-
return v;
|
|
1793
1804
|
}
|
|
1794
1805
|
|
|
1795
1806
|
maxIndex() {
|
|
@@ -1808,19 +1819,48 @@ class AbstractMatrix {
|
|
|
1808
1819
|
return idx;
|
|
1809
1820
|
}
|
|
1810
1821
|
|
|
1811
|
-
min() {
|
|
1822
|
+
min(by) {
|
|
1812
1823
|
if (this.isEmpty()) {
|
|
1813
1824
|
return NaN;
|
|
1814
1825
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1826
|
+
|
|
1827
|
+
switch (by) {
|
|
1828
|
+
case 'row': {
|
|
1829
|
+
const min = new Array(this.rows).fill(Number.POSITIVE_INFINITY);
|
|
1830
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1831
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1832
|
+
if (this.get(row, column) < min[row]) {
|
|
1833
|
+
min[row] = this.get(row, column);
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1820
1836
|
}
|
|
1837
|
+
return min;
|
|
1821
1838
|
}
|
|
1839
|
+
case 'column': {
|
|
1840
|
+
const min = new Array(this.columns).fill(Number.POSITIVE_INFINITY);
|
|
1841
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1842
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1843
|
+
if (this.get(row, column) < min[column]) {
|
|
1844
|
+
min[column] = this.get(row, column);
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
return min;
|
|
1849
|
+
}
|
|
1850
|
+
case undefined: {
|
|
1851
|
+
let min = this.get(0, 0);
|
|
1852
|
+
for (let row = 0; row < this.rows; row++) {
|
|
1853
|
+
for (let column = 0; column < this.columns; column++) {
|
|
1854
|
+
if (this.get(row, column) < min) {
|
|
1855
|
+
min = this.get(row, column);
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
return min;
|
|
1860
|
+
}
|
|
1861
|
+
default:
|
|
1862
|
+
throw new Error(`invalid option: ${by}`);
|
|
1822
1863
|
}
|
|
1823
|
-
return v;
|
|
1824
1864
|
}
|
|
1825
1865
|
|
|
1826
1866
|
minIndex() {
|
|
@@ -2454,12 +2494,13 @@ class AbstractMatrix {
|
|
|
2454
2494
|
}
|
|
2455
2495
|
|
|
2456
2496
|
selection(rowIndices, columnIndices) {
|
|
2457
|
-
|
|
2497
|
+
checkRowIndices(this, rowIndices);
|
|
2498
|
+
checkColumnIndices(this, columnIndices);
|
|
2458
2499
|
let newMatrix = new Matrix(rowIndices.length, columnIndices.length);
|
|
2459
|
-
for (let i = 0; i <
|
|
2460
|
-
let rowIndex =
|
|
2461
|
-
for (let j = 0; j <
|
|
2462
|
-
let columnIndex =
|
|
2500
|
+
for (let i = 0; i < rowIndices.length; i++) {
|
|
2501
|
+
let rowIndex = rowIndices[i];
|
|
2502
|
+
for (let j = 0; j < columnIndices.length; j++) {
|
|
2503
|
+
let columnIndex = columnIndices[j];
|
|
2463
2504
|
newMatrix.set(i, j, this.get(rowIndex, columnIndex));
|
|
2464
2505
|
}
|
|
2465
2506
|
}
|
|
@@ -2547,13 +2588,13 @@ class AbstractMatrix {
|
|
|
2547
2588
|
}
|
|
2548
2589
|
switch (by) {
|
|
2549
2590
|
case 'row': {
|
|
2550
|
-
if (!
|
|
2591
|
+
if (!isAnyArray.isAnyArray(mean)) {
|
|
2551
2592
|
throw new TypeError('mean must be an array');
|
|
2552
2593
|
}
|
|
2553
2594
|
return varianceByRow(this, unbiased, mean);
|
|
2554
2595
|
}
|
|
2555
2596
|
case 'column': {
|
|
2556
|
-
if (!
|
|
2597
|
+
if (!isAnyArray.isAnyArray(mean)) {
|
|
2557
2598
|
throw new TypeError('mean must be an array');
|
|
2558
2599
|
}
|
|
2559
2600
|
return varianceByColumn(this, unbiased, mean);
|
|
@@ -2596,14 +2637,14 @@ class AbstractMatrix {
|
|
|
2596
2637
|
const { center = this.mean(by) } = options;
|
|
2597
2638
|
switch (by) {
|
|
2598
2639
|
case 'row': {
|
|
2599
|
-
if (!
|
|
2640
|
+
if (!isAnyArray.isAnyArray(center)) {
|
|
2600
2641
|
throw new TypeError('center must be an array');
|
|
2601
2642
|
}
|
|
2602
2643
|
centerByRow(this, center);
|
|
2603
2644
|
return this;
|
|
2604
2645
|
}
|
|
2605
2646
|
case 'column': {
|
|
2606
|
-
if (!
|
|
2647
|
+
if (!isAnyArray.isAnyArray(center)) {
|
|
2607
2648
|
throw new TypeError('center must be an array');
|
|
2608
2649
|
}
|
|
2609
2650
|
centerByColumn(this, center);
|
|
@@ -2634,7 +2675,7 @@ class AbstractMatrix {
|
|
|
2634
2675
|
case 'row': {
|
|
2635
2676
|
if (scale === undefined) {
|
|
2636
2677
|
scale = getScaleByRow(this);
|
|
2637
|
-
} else if (!
|
|
2678
|
+
} else if (!isAnyArray.isAnyArray(scale)) {
|
|
2638
2679
|
throw new TypeError('scale must be an array');
|
|
2639
2680
|
}
|
|
2640
2681
|
scaleByRow(this, scale);
|
|
@@ -2643,7 +2684,7 @@ class AbstractMatrix {
|
|
|
2643
2684
|
case 'column': {
|
|
2644
2685
|
if (scale === undefined) {
|
|
2645
2686
|
scale = getScaleByColumn(this);
|
|
2646
|
-
} else if (!
|
|
2687
|
+
} else if (!isAnyArray.isAnyArray(scale)) {
|
|
2647
2688
|
throw new TypeError('scale must be an array');
|
|
2648
2689
|
}
|
|
2649
2690
|
scaleByColumn(this, scale);
|
|
@@ -2678,6 +2719,12 @@ function compareNumbers(a, b) {
|
|
|
2678
2719
|
return a - b;
|
|
2679
2720
|
}
|
|
2680
2721
|
|
|
2722
|
+
function isArrayOfNumbers(array) {
|
|
2723
|
+
return array.every((element) => {
|
|
2724
|
+
return typeof element === 'number';
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2681
2728
|
// Synonyms
|
|
2682
2729
|
AbstractMatrix.random = AbstractMatrix.rand;
|
|
2683
2730
|
AbstractMatrix.randomInt = AbstractMatrix.randInt;
|
|
@@ -2704,7 +2751,7 @@ class Matrix extends AbstractMatrix {
|
|
|
2704
2751
|
} else {
|
|
2705
2752
|
throw new TypeError('nColumns must be a positive integer');
|
|
2706
2753
|
}
|
|
2707
|
-
} else if (
|
|
2754
|
+
} else if (isAnyArray.isAnyArray(nRows)) {
|
|
2708
2755
|
// Copy the values from the 2D array
|
|
2709
2756
|
const arrayData = nRows;
|
|
2710
2757
|
nRows = arrayData.length;
|
|
@@ -2719,6 +2766,9 @@ class Matrix extends AbstractMatrix {
|
|
|
2719
2766
|
if (arrayData[i].length !== nColumns) {
|
|
2720
2767
|
throw new RangeError('Inconsistent array dimensions');
|
|
2721
2768
|
}
|
|
2769
|
+
if (!isArrayOfNumbers(arrayData[i])) {
|
|
2770
|
+
throw new TypeError('Input data contains non-numeric values');
|
|
2771
|
+
}
|
|
2722
2772
|
this.data.push(Float64Array.from(arrayData[i]));
|
|
2723
2773
|
}
|
|
2724
2774
|
} else {
|
|
@@ -2828,7 +2878,7 @@ class MatrixColumnView extends BaseView {
|
|
|
2828
2878
|
|
|
2829
2879
|
class MatrixColumnSelectionView extends BaseView {
|
|
2830
2880
|
constructor(matrix, columnIndices) {
|
|
2831
|
-
|
|
2881
|
+
checkColumnIndices(matrix, columnIndices);
|
|
2832
2882
|
super(matrix, matrix.rows, columnIndices.length);
|
|
2833
2883
|
this.columnIndices = columnIndices;
|
|
2834
2884
|
}
|
|
@@ -2892,7 +2942,7 @@ class MatrixRowView extends BaseView {
|
|
|
2892
2942
|
|
|
2893
2943
|
class MatrixRowSelectionView extends BaseView {
|
|
2894
2944
|
constructor(matrix, rowIndices) {
|
|
2895
|
-
|
|
2945
|
+
checkRowIndices(matrix, rowIndices);
|
|
2896
2946
|
super(matrix, rowIndices.length, matrix.columns);
|
|
2897
2947
|
this.rowIndices = rowIndices;
|
|
2898
2948
|
}
|
|
@@ -2909,10 +2959,11 @@ class MatrixRowSelectionView extends BaseView {
|
|
|
2909
2959
|
|
|
2910
2960
|
class MatrixSelectionView extends BaseView {
|
|
2911
2961
|
constructor(matrix, rowIndices, columnIndices) {
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
this.
|
|
2962
|
+
checkRowIndices(matrix, rowIndices);
|
|
2963
|
+
checkColumnIndices(matrix, columnIndices);
|
|
2964
|
+
super(matrix, rowIndices.length, columnIndices.length);
|
|
2965
|
+
this.rowIndices = rowIndices;
|
|
2966
|
+
this.columnIndices = columnIndices;
|
|
2916
2967
|
}
|
|
2917
2968
|
|
|
2918
2969
|
set(rowIndex, columnIndex, value) {
|
|
@@ -3020,8 +3071,8 @@ class WrapperMatrix2D extends AbstractMatrix {
|
|
|
3020
3071
|
}
|
|
3021
3072
|
|
|
3022
3073
|
function wrap(array, options) {
|
|
3023
|
-
if (
|
|
3024
|
-
if (array[0] &&
|
|
3074
|
+
if (isAnyArray.isAnyArray(array)) {
|
|
3075
|
+
if (array[0] && isAnyArray.isAnyArray(array[0])) {
|
|
3025
3076
|
return new WrapperMatrix2D(array);
|
|
3026
3077
|
} else {
|
|
3027
3078
|
return new WrapperMatrix1D(array, options);
|
|
@@ -4021,7 +4072,7 @@ function covariance(xMatrix, yMatrix = xMatrix, options = {}) {
|
|
|
4021
4072
|
if (
|
|
4022
4073
|
typeof yMatrix === 'object' &&
|
|
4023
4074
|
!Matrix.isMatrix(yMatrix) &&
|
|
4024
|
-
!
|
|
4075
|
+
!isAnyArray.isAnyArray(yMatrix)
|
|
4025
4076
|
) {
|
|
4026
4077
|
options = yMatrix;
|
|
4027
4078
|
yMatrix = xMatrix;
|
|
@@ -4054,7 +4105,7 @@ function correlation(xMatrix, yMatrix = xMatrix, options = {}) {
|
|
|
4054
4105
|
if (
|
|
4055
4106
|
typeof yMatrix === 'object' &&
|
|
4056
4107
|
!Matrix.isMatrix(yMatrix) &&
|
|
4057
|
-
!
|
|
4108
|
+
!isAnyArray.isAnyArray(yMatrix)
|
|
4058
4109
|
) {
|
|
4059
4110
|
options = yMatrix;
|
|
4060
4111
|
yMatrix = xMatrix;
|
|
@@ -4990,7 +5041,7 @@ class nipals {
|
|
|
4990
5041
|
|
|
4991
5042
|
let u;
|
|
4992
5043
|
if (Y) {
|
|
4993
|
-
if (
|
|
5044
|
+
if (isAnyArray.isAnyArray(Y) && typeof Y[0] === 'number') {
|
|
4994
5045
|
Y = Matrix.columnVector(Y);
|
|
4995
5046
|
} else {
|
|
4996
5047
|
Y = WrapperMatrix2D.checkMatrix(Y);
|