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/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 (typeof rowIndices !== 'object') {
964
- throw new TypeError('unexpected type for row indices');
957
+ if (!isAnyArray.isAnyArray(rowIndices)) {
958
+ throw new TypeError('row indices must be an array');
965
959
  }
966
960
 
967
- let rowOut = rowIndices.some((r) => {
968
- return r < 0 || r >= matrix.rows;
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 (typeof columnIndices !== 'object') {
982
- throw new TypeError('unexpected type for column indices');
969
+ if (!isAnyArray.isAnyArray(columnIndices)) {
970
+ throw new TypeError('column indices must be an array');
983
971
  }
984
972
 
985
- let columnOut = columnIndices.some((c) => {
986
- return c < 0 || c >= matrix.columns;
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
- let v = this.get(0, 0);
1785
- for (let i = 0; i < this.rows; i++) {
1786
- for (let j = 0; j < this.columns; j++) {
1787
- if (this.get(i, j) > v) {
1788
- v = this.get(i, j);
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
- let v = this.get(0, 0);
1816
- for (let i = 0; i < this.rows; i++) {
1817
- for (let j = 0; j < this.columns; j++) {
1818
- if (this.get(i, j) < v) {
1819
- v = this.get(i, j);
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
- let indices = checkIndices(this, rowIndices, columnIndices);
2497
+ checkRowIndices(this, rowIndices);
2498
+ checkColumnIndices(this, columnIndices);
2458
2499
  let newMatrix = new Matrix(rowIndices.length, columnIndices.length);
2459
- for (let i = 0; i < indices.row.length; i++) {
2460
- let rowIndex = indices.row[i];
2461
- for (let j = 0; j < indices.column.length; j++) {
2462
- let columnIndex = indices.column[j];
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 (!Array.isArray(mean)) {
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 (!Array.isArray(mean)) {
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 (!Array.isArray(center)) {
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 (!Array.isArray(center)) {
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 (!Array.isArray(scale)) {
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 (!Array.isArray(scale)) {
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 (Array.isArray(nRows)) {
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
- columnIndices = checkColumnIndices(matrix, columnIndices);
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
- rowIndices = checkRowIndices(matrix, rowIndices);
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
- let indices = checkIndices(matrix, rowIndices, columnIndices);
2913
- super(matrix, indices.row.length, indices.column.length);
2914
- this.rowIndices = indices.row;
2915
- this.columnIndices = indices.column;
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 (Array.isArray(array)) {
3024
- if (array[0] && Array.isArray(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
- !Array.isArray(yMatrix)
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
- !Array.isArray(yMatrix)
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 (Array.isArray(Y) && typeof Y[0] === 'number') {
5044
+ if (isAnyArray.isAnyArray(Y) && typeof Y[0] === 'number') {
4994
5045
  Y = Matrix.columnVector(Y);
4995
5046
  } else {
4996
5047
  Y = WrapperMatrix2D.checkMatrix(Y);