ml-matrix 6.10.7 → 6.11.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.
- package/matrix.d.ts +267 -3
- package/matrix.js +458 -19
- package/matrix.mjs +4 -2
- package/matrix.umd.js +1 -1
- package/package.json +1 -1
- package/src/distanceMatrix.js +121 -0
- package/src/index.js +2 -0
- package/src/matrix.js +86 -19
- package/src/symmetricMatrix.js +248 -0
package/matrix.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
var isAnyArray = require('is-any-array');
|
|
4
6
|
var rescale = require('ml-array-rescale');
|
|
5
7
|
|
|
@@ -1470,6 +1472,16 @@ class AbstractMatrix {
|
|
|
1470
1472
|
return false;
|
|
1471
1473
|
}
|
|
1472
1474
|
|
|
1475
|
+
isDistance() {
|
|
1476
|
+
if (!this.isSymmetric()) return false;
|
|
1477
|
+
|
|
1478
|
+
for (let i = 0; i < this.rows; i++) {
|
|
1479
|
+
if (this.get(i, i) !== 0) return false;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
return true;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1473
1485
|
isEchelonForm() {
|
|
1474
1486
|
let i = 0;
|
|
1475
1487
|
let j = 0;
|
|
@@ -2544,13 +2556,21 @@ class AbstractMatrix {
|
|
|
2544
2556
|
}
|
|
2545
2557
|
|
|
2546
2558
|
clone() {
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2559
|
+
return this.constructor.copy(this, new Matrix(this.rows, this.columns));
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
/**
|
|
2563
|
+
* @template {AbstractMatrix} M
|
|
2564
|
+
* @param {AbstractMatrix} from
|
|
2565
|
+
* @param {M} to
|
|
2566
|
+
* @return {M}
|
|
2567
|
+
*/
|
|
2568
|
+
static copy(from, to) {
|
|
2569
|
+
for (const [row, column, value] of from.entries()) {
|
|
2570
|
+
to.set(row, column, value);
|
|
2552
2571
|
}
|
|
2553
|
-
|
|
2572
|
+
|
|
2573
|
+
return to;
|
|
2554
2574
|
}
|
|
2555
2575
|
|
|
2556
2576
|
sum(by) {
|
|
@@ -2734,6 +2754,36 @@ class AbstractMatrix {
|
|
|
2734
2754
|
toString(options) {
|
|
2735
2755
|
return inspectMatrixWithOptions(this, options);
|
|
2736
2756
|
}
|
|
2757
|
+
|
|
2758
|
+
[Symbol.iterator]() {
|
|
2759
|
+
return this.entries();
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
/**
|
|
2763
|
+
* iterator from left to right, from top to bottom
|
|
2764
|
+
* yield [row, column, value]
|
|
2765
|
+
* @returns {Generator<[number, number, number], void, *>}
|
|
2766
|
+
*/
|
|
2767
|
+
*entries() {
|
|
2768
|
+
for (let row = 0; row < this.rows; row++) {
|
|
2769
|
+
for (let col = 0; col < this.columns; col++) {
|
|
2770
|
+
yield [row, col, this.get(row, col)];
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
/**
|
|
2776
|
+
* iterator from left to right, from top to bottom
|
|
2777
|
+
* yield value
|
|
2778
|
+
* @returns {Generator<number, void, *>}
|
|
2779
|
+
*/
|
|
2780
|
+
*values() {
|
|
2781
|
+
for (let row = 0; row < this.rows; row++) {
|
|
2782
|
+
for (let col = 0; col < this.columns; col++) {
|
|
2783
|
+
yield this.get(row, col);
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2737
2787
|
}
|
|
2738
2788
|
|
|
2739
2789
|
AbstractMatrix.prototype.klass = 'Matrix';
|
|
@@ -2763,21 +2813,38 @@ AbstractMatrix.prototype.tensorProduct =
|
|
|
2763
2813
|
AbstractMatrix.prototype.kroneckerProduct;
|
|
2764
2814
|
|
|
2765
2815
|
class Matrix extends AbstractMatrix {
|
|
2816
|
+
/**
|
|
2817
|
+
* @type {Float64Array[]}
|
|
2818
|
+
*/
|
|
2819
|
+
data;
|
|
2820
|
+
|
|
2821
|
+
/**
|
|
2822
|
+
* Init an empty matrix
|
|
2823
|
+
* @param {number} nRows
|
|
2824
|
+
* @param {number} nColumns
|
|
2825
|
+
*/
|
|
2826
|
+
#initData(nRows, nColumns) {
|
|
2827
|
+
this.data = [];
|
|
2828
|
+
|
|
2829
|
+
if (Number.isInteger(nColumns) && nColumns >= 0) {
|
|
2830
|
+
for (let i = 0; i < nRows; i++) {
|
|
2831
|
+
this.data.push(new Float64Array(nColumns));
|
|
2832
|
+
}
|
|
2833
|
+
} else {
|
|
2834
|
+
throw new TypeError('nColumns must be a positive integer');
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
this.rows = nRows;
|
|
2838
|
+
this.columns = nColumns;
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2766
2841
|
constructor(nRows, nColumns) {
|
|
2767
2842
|
super();
|
|
2768
2843
|
if (Matrix.isMatrix(nRows)) {
|
|
2769
|
-
|
|
2770
|
-
|
|
2844
|
+
this.#initData(nRows.rows, nRows.columns);
|
|
2845
|
+
Matrix.copy(nRows, this);
|
|
2771
2846
|
} else if (Number.isInteger(nRows) && nRows >= 0) {
|
|
2772
|
-
|
|
2773
|
-
this.data = [];
|
|
2774
|
-
if (Number.isInteger(nColumns) && nColumns >= 0) {
|
|
2775
|
-
for (let i = 0; i < nRows; i++) {
|
|
2776
|
-
this.data.push(new Float64Array(nColumns));
|
|
2777
|
-
}
|
|
2778
|
-
} else {
|
|
2779
|
-
throw new TypeError('nColumns must be a positive integer');
|
|
2780
|
-
}
|
|
2847
|
+
this.#initData(nRows, nColumns);
|
|
2781
2848
|
} else if (isAnyArray.isAnyArray(nRows)) {
|
|
2782
2849
|
// Copy the values from the 2D array
|
|
2783
2850
|
const arrayData = nRows;
|
|
@@ -2789,6 +2856,7 @@ class Matrix extends AbstractMatrix {
|
|
|
2789
2856
|
);
|
|
2790
2857
|
}
|
|
2791
2858
|
this.data = [];
|
|
2859
|
+
|
|
2792
2860
|
for (let i = 0; i < nRows; i++) {
|
|
2793
2861
|
if (arrayData[i].length !== nColumns) {
|
|
2794
2862
|
throw new RangeError('Inconsistent array dimensions');
|
|
@@ -2798,13 +2866,14 @@ class Matrix extends AbstractMatrix {
|
|
|
2798
2866
|
}
|
|
2799
2867
|
this.data.push(Float64Array.from(arrayData[i]));
|
|
2800
2868
|
}
|
|
2869
|
+
|
|
2870
|
+
this.rows = nRows;
|
|
2871
|
+
this.columns = nColumns;
|
|
2801
2872
|
} else {
|
|
2802
2873
|
throw new TypeError(
|
|
2803
2874
|
'First argument must be a positive number or an array',
|
|
2804
2875
|
);
|
|
2805
2876
|
}
|
|
2806
|
-
this.rows = nRows;
|
|
2807
|
-
this.columns = nColumns;
|
|
2808
2877
|
}
|
|
2809
2878
|
|
|
2810
2879
|
set(rowIndex, columnIndex, value) {
|
|
@@ -2877,6 +2946,374 @@ class Matrix extends AbstractMatrix {
|
|
|
2877
2946
|
|
|
2878
2947
|
installMathOperations(AbstractMatrix, Matrix);
|
|
2879
2948
|
|
|
2949
|
+
/**
|
|
2950
|
+
* @typedef {0 | 1 | number | boolean} Mask
|
|
2951
|
+
*/
|
|
2952
|
+
|
|
2953
|
+
class SymmetricMatrix extends AbstractMatrix {
|
|
2954
|
+
/** @type {Matrix} */
|
|
2955
|
+
#matrix;
|
|
2956
|
+
|
|
2957
|
+
get size() {
|
|
2958
|
+
return this.#matrix.size;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
get rows() {
|
|
2962
|
+
return this.#matrix.rows;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
get columns() {
|
|
2966
|
+
return this.#matrix.columns;
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
get diagonalSize() {
|
|
2970
|
+
return this.rows;
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
/**
|
|
2974
|
+
* not the same as matrix.isSymmetric()
|
|
2975
|
+
* Here is to check if it's instanceof SymmetricMatrix without bundling issues
|
|
2976
|
+
*
|
|
2977
|
+
* @param value
|
|
2978
|
+
* @returns {boolean}
|
|
2979
|
+
*/
|
|
2980
|
+
static isSymmetricMatrix(value) {
|
|
2981
|
+
return Matrix.isMatrix(value) && value.klassType === 'SymmetricMatrix';
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2984
|
+
/**
|
|
2985
|
+
* @param diagonalSize
|
|
2986
|
+
* @return {SymmetricMatrix}
|
|
2987
|
+
*/
|
|
2988
|
+
static zeros(diagonalSize) {
|
|
2989
|
+
return new this(diagonalSize);
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
/**
|
|
2993
|
+
* @param diagonalSize
|
|
2994
|
+
* @return {SymmetricMatrix}
|
|
2995
|
+
*/
|
|
2996
|
+
static ones(diagonalSize) {
|
|
2997
|
+
return new this(diagonalSize).fill(1);
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
/**
|
|
3001
|
+
* @param {number | AbstractMatrix | ArrayLike<ArrayLike<number>>} diagonalSize
|
|
3002
|
+
* @return {this}
|
|
3003
|
+
*/
|
|
3004
|
+
constructor(diagonalSize) {
|
|
3005
|
+
super();
|
|
3006
|
+
|
|
3007
|
+
if (Matrix.isMatrix(diagonalSize)) {
|
|
3008
|
+
if (!diagonalSize.isSymmetric()) {
|
|
3009
|
+
throw new TypeError('not symmetric data');
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
this.#matrix = Matrix.copy(
|
|
3013
|
+
diagonalSize,
|
|
3014
|
+
new Matrix(diagonalSize.rows, diagonalSize.rows),
|
|
3015
|
+
);
|
|
3016
|
+
} else if (Number.isInteger(diagonalSize) && diagonalSize >= 0) {
|
|
3017
|
+
this.#matrix = new Matrix(diagonalSize, diagonalSize);
|
|
3018
|
+
} else {
|
|
3019
|
+
this.#matrix = new Matrix(diagonalSize);
|
|
3020
|
+
|
|
3021
|
+
if (!this.isSymmetric()) {
|
|
3022
|
+
throw new TypeError('not symmetric data');
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
clone() {
|
|
3028
|
+
const matrix = new SymmetricMatrix(this.diagonalSize);
|
|
3029
|
+
|
|
3030
|
+
for (const [row, col, value] of this.upperRightEntries()) {
|
|
3031
|
+
matrix.set(row, col, value);
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
return matrix;
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
toMatrix() {
|
|
3038
|
+
return new Matrix(this);
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
get(rowIndex, columnIndex) {
|
|
3042
|
+
return this.#matrix.get(rowIndex, columnIndex);
|
|
3043
|
+
}
|
|
3044
|
+
set(rowIndex, columnIndex, value) {
|
|
3045
|
+
// symmetric set
|
|
3046
|
+
this.#matrix.set(rowIndex, columnIndex, value);
|
|
3047
|
+
this.#matrix.set(columnIndex, rowIndex, value);
|
|
3048
|
+
|
|
3049
|
+
return this;
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
removeCross(index) {
|
|
3053
|
+
// symmetric remove side
|
|
3054
|
+
this.#matrix.removeRow(index);
|
|
3055
|
+
this.#matrix.removeColumn(index);
|
|
3056
|
+
|
|
3057
|
+
return this;
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
addCross(index, array) {
|
|
3061
|
+
if (array === undefined) {
|
|
3062
|
+
array = index;
|
|
3063
|
+
index = this.diagonalSize;
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
const row = array.slice();
|
|
3067
|
+
row.splice(index, 1);
|
|
3068
|
+
|
|
3069
|
+
this.#matrix.addRow(index, row);
|
|
3070
|
+
this.#matrix.addColumn(index, array);
|
|
3071
|
+
|
|
3072
|
+
return this;
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
/**
|
|
3076
|
+
* @param {Mask[]} mask
|
|
3077
|
+
*/
|
|
3078
|
+
applyMask(mask) {
|
|
3079
|
+
if (mask.length !== this.diagonalSize) {
|
|
3080
|
+
throw new RangeError('Mask size do not match with matrix size');
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
// prepare sides to remove from matrix from mask
|
|
3084
|
+
/** @type {number[]} */
|
|
3085
|
+
const sidesToRemove = [];
|
|
3086
|
+
for (const [index, passthroughs] of mask.entries()) {
|
|
3087
|
+
if (passthroughs) continue;
|
|
3088
|
+
sidesToRemove.push(index);
|
|
3089
|
+
}
|
|
3090
|
+
// to remove from highest to lowest for no mutation shifting
|
|
3091
|
+
sidesToRemove.reverse();
|
|
3092
|
+
|
|
3093
|
+
// remove sides
|
|
3094
|
+
for (const sideIndex of sidesToRemove) {
|
|
3095
|
+
this.removeCross(sideIndex);
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
return this;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
/**
|
|
3102
|
+
* Compact format upper-right corner of matrix
|
|
3103
|
+
* iterate from left to right, from top to bottom.
|
|
3104
|
+
*
|
|
3105
|
+
* ```
|
|
3106
|
+
* A B C D
|
|
3107
|
+
* A 1 2 3 4
|
|
3108
|
+
* B 2 5 6 7
|
|
3109
|
+
* C 3 6 8 9
|
|
3110
|
+
* D 4 7 9 10
|
|
3111
|
+
* ```
|
|
3112
|
+
*
|
|
3113
|
+
* will return compact 1D array `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]`
|
|
3114
|
+
*
|
|
3115
|
+
* length is S(i=0, n=sideSize) => 10 for a 4 sideSized matrix
|
|
3116
|
+
*
|
|
3117
|
+
* @returns {number[]}
|
|
3118
|
+
*/
|
|
3119
|
+
toCompact() {
|
|
3120
|
+
const { diagonalSize } = this;
|
|
3121
|
+
|
|
3122
|
+
/** @type {number[]} */
|
|
3123
|
+
const compact = new Array((diagonalSize * (diagonalSize + 1)) / 2);
|
|
3124
|
+
for (let col = 0, row = 0, index = 0; index < compact.length; index++) {
|
|
3125
|
+
compact[index] = this.get(row, col);
|
|
3126
|
+
|
|
3127
|
+
if (++col >= diagonalSize) col = ++row;
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
return compact;
|
|
3131
|
+
}
|
|
3132
|
+
|
|
3133
|
+
/**
|
|
3134
|
+
* @param {number[]} compact
|
|
3135
|
+
* @return {SymmetricMatrix}
|
|
3136
|
+
*/
|
|
3137
|
+
static fromCompact(compact) {
|
|
3138
|
+
const compactSize = compact.length;
|
|
3139
|
+
// compactSize = (sideSize * (sideSize + 1)) / 2
|
|
3140
|
+
// https://mathsolver.microsoft.com/fr/solve-problem/y%20%3D%20%20x%20%60cdot%20%20%20%60frac%7B%20%20%60left(%20x%2B1%20%20%60right)%20%20%20%20%7D%7B%202%20%20%7D
|
|
3141
|
+
// sideSize = (Sqrt(8 × compactSize + 1) - 1) / 2
|
|
3142
|
+
const diagonalSize = (Math.sqrt(8 * compactSize + 1) - 1) / 2;
|
|
3143
|
+
|
|
3144
|
+
if (!Number.isInteger(diagonalSize)) {
|
|
3145
|
+
throw new TypeError(
|
|
3146
|
+
`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(
|
|
3147
|
+
compact,
|
|
3148
|
+
)}`,
|
|
3149
|
+
);
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
const matrix = new SymmetricMatrix(diagonalSize);
|
|
3153
|
+
for (let col = 0, row = 0, index = 0; index < compactSize; index++) {
|
|
3154
|
+
matrix.set(col, row, compact[index]);
|
|
3155
|
+
if (++col >= diagonalSize) col = ++row;
|
|
3156
|
+
}
|
|
3157
|
+
|
|
3158
|
+
return matrix;
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
/**
|
|
3162
|
+
* half iterator upper-right-corner from left to right, from top to bottom
|
|
3163
|
+
* yield [row, column, value]
|
|
3164
|
+
*
|
|
3165
|
+
* @returns {Generator<[number, number, number], void, *>}
|
|
3166
|
+
*/
|
|
3167
|
+
*upperRightEntries() {
|
|
3168
|
+
for (let row = 0, col = 0; row < this.diagonalSize; void 0) {
|
|
3169
|
+
const value = this.get(row, col);
|
|
3170
|
+
|
|
3171
|
+
yield [row, col, value];
|
|
3172
|
+
|
|
3173
|
+
// at the end of row, move cursor to next row at diagonal position
|
|
3174
|
+
if (++col >= this.diagonalSize) col = ++row;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
/**
|
|
3179
|
+
* half iterator upper-right-corner from left to right, from top to bottom
|
|
3180
|
+
* yield value
|
|
3181
|
+
*
|
|
3182
|
+
* @returns {Generator<[number, number, number], void, *>}
|
|
3183
|
+
*/
|
|
3184
|
+
*upperRightValues() {
|
|
3185
|
+
for (let row = 0, col = 0; row < this.diagonalSize; void 0) {
|
|
3186
|
+
const value = this.get(row, col);
|
|
3187
|
+
|
|
3188
|
+
yield value;
|
|
3189
|
+
|
|
3190
|
+
// at the end of row, move cursor to next row at diagonal position
|
|
3191
|
+
if (++col >= this.diagonalSize) col = ++row;
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
SymmetricMatrix.prototype.klassType = 'SymmetricMatrix';
|
|
3196
|
+
|
|
3197
|
+
class DistanceMatrix extends SymmetricMatrix {
|
|
3198
|
+
/**
|
|
3199
|
+
* not the same as matrix.isSymmetric()
|
|
3200
|
+
* Here is to check if it's instanceof SymmetricMatrix without bundling issues
|
|
3201
|
+
*
|
|
3202
|
+
* @param value
|
|
3203
|
+
* @returns {boolean}
|
|
3204
|
+
*/
|
|
3205
|
+
static isDistanceMatrix(value) {
|
|
3206
|
+
return (
|
|
3207
|
+
SymmetricMatrix.isSymmetricMatrix(value) &&
|
|
3208
|
+
value.klassSubType === 'DistanceMatrix'
|
|
3209
|
+
);
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
constructor(sideSize) {
|
|
3213
|
+
super(sideSize);
|
|
3214
|
+
|
|
3215
|
+
if (!this.isDistance()) {
|
|
3216
|
+
throw new TypeError('Provided arguments do no produce a distance matrix');
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
set(rowIndex, columnIndex, value) {
|
|
3221
|
+
// distance matrix diagonal is 0
|
|
3222
|
+
if (rowIndex === columnIndex) value = 0;
|
|
3223
|
+
|
|
3224
|
+
return super.set(rowIndex, columnIndex, value);
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
addCross(index, array) {
|
|
3228
|
+
if (array === undefined) {
|
|
3229
|
+
array = index;
|
|
3230
|
+
index = this.diagonalSize;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
// ensure distance
|
|
3234
|
+
array = array.slice();
|
|
3235
|
+
array[index] = 0;
|
|
3236
|
+
|
|
3237
|
+
return super.addCross(index, array);
|
|
3238
|
+
}
|
|
3239
|
+
|
|
3240
|
+
toSymmetricMatrix() {
|
|
3241
|
+
return new SymmetricMatrix(this);
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
clone() {
|
|
3245
|
+
const matrix = new DistanceMatrix(this.diagonalSize);
|
|
3246
|
+
|
|
3247
|
+
for (const [row, col, value] of this.upperRightEntries()) {
|
|
3248
|
+
if (row === col) continue;
|
|
3249
|
+
matrix.set(row, col, value);
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3252
|
+
return matrix;
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
/**
|
|
3256
|
+
* Compact format upper-right corner of matrix
|
|
3257
|
+
* no diagonal (only zeros)
|
|
3258
|
+
* iterable from left to right, from top to bottom.
|
|
3259
|
+
*
|
|
3260
|
+
* ```
|
|
3261
|
+
* A B C D
|
|
3262
|
+
* A 0 1 2 3
|
|
3263
|
+
* B 1 0 4 5
|
|
3264
|
+
* C 2 4 0 6
|
|
3265
|
+
* D 3 5 6 0
|
|
3266
|
+
* ```
|
|
3267
|
+
*
|
|
3268
|
+
* will return compact 1D array `[1, 2, 3, 4, 5, 6]`
|
|
3269
|
+
*
|
|
3270
|
+
* length is S(i=0, n=sideSize-1) => 6 for a 4 side sized matrix
|
|
3271
|
+
*
|
|
3272
|
+
* @returns {number[]}
|
|
3273
|
+
*/
|
|
3274
|
+
toCompact() {
|
|
3275
|
+
const { diagonalSize } = this;
|
|
3276
|
+
const compactLength = ((diagonalSize - 1) * diagonalSize) / 2;
|
|
3277
|
+
|
|
3278
|
+
/** @type {number[]} */
|
|
3279
|
+
const compact = new Array(compactLength);
|
|
3280
|
+
for (let col = 1, row = 0, index = 0; index < compact.length; index++) {
|
|
3281
|
+
compact[index] = this.get(row, col);
|
|
3282
|
+
|
|
3283
|
+
if (++col >= diagonalSize) col = ++row + 1;
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
return compact;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
/**
|
|
3290
|
+
* @param {number[]} compact
|
|
3291
|
+
*/
|
|
3292
|
+
static fromCompact(compact) {
|
|
3293
|
+
const compactSize = compact.length;
|
|
3294
|
+
// compactSize = (sideSize * (sideSize - 1)) / 2
|
|
3295
|
+
// sideSize = (Sqrt(8 × compactSize + 1) + 1) / 2
|
|
3296
|
+
const diagonalSize = (Math.sqrt(8 * compactSize + 1) + 1) / 2;
|
|
3297
|
+
|
|
3298
|
+
if (!Number.isInteger(diagonalSize)) {
|
|
3299
|
+
throw new TypeError(
|
|
3300
|
+
`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(
|
|
3301
|
+
compact,
|
|
3302
|
+
)}`,
|
|
3303
|
+
);
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3306
|
+
const matrix = new this(diagonalSize);
|
|
3307
|
+
for (let col = 1, row = 0, index = 0; index < compactSize; index++) {
|
|
3308
|
+
matrix.set(col, row, compact[index]);
|
|
3309
|
+
if (++col >= diagonalSize) col = ++row + 1;
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
return matrix;
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
DistanceMatrix.prototype.klassSubType = 'DistanceMatrix';
|
|
3316
|
+
|
|
2880
3317
|
class BaseView extends AbstractMatrix {
|
|
2881
3318
|
constructor(matrix, rows, columns) {
|
|
2882
3319
|
super();
|
|
@@ -5145,6 +5582,7 @@ class nipals {
|
|
|
5145
5582
|
exports.AbstractMatrix = AbstractMatrix;
|
|
5146
5583
|
exports.CHO = CholeskyDecomposition;
|
|
5147
5584
|
exports.CholeskyDecomposition = CholeskyDecomposition;
|
|
5585
|
+
exports.DistanceMatrix = DistanceMatrix;
|
|
5148
5586
|
exports.EVD = EigenvalueDecomposition;
|
|
5149
5587
|
exports.EigenvalueDecomposition = EigenvalueDecomposition;
|
|
5150
5588
|
exports.LU = LuDecomposition;
|
|
@@ -5165,6 +5603,7 @@ exports.QR = QrDecomposition;
|
|
|
5165
5603
|
exports.QrDecomposition = QrDecomposition;
|
|
5166
5604
|
exports.SVD = SingularValueDecomposition;
|
|
5167
5605
|
exports.SingularValueDecomposition = SingularValueDecomposition;
|
|
5606
|
+
exports.SymmetricMatrix = SymmetricMatrix;
|
|
5168
5607
|
exports.WrapperMatrix1D = WrapperMatrix1D;
|
|
5169
5608
|
exports.WrapperMatrix2D = WrapperMatrix2D;
|
|
5170
5609
|
exports.correlation = correlation;
|
package/matrix.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import matrix from './matrix.js';
|
|
1
|
+
import * as matrix from './matrix.js';
|
|
2
2
|
|
|
3
3
|
export const AbstractMatrix = matrix.AbstractMatrix;
|
|
4
4
|
export const CHO = matrix.CHO;
|
|
5
5
|
export const CholeskyDecomposition = matrix.CholeskyDecomposition;
|
|
6
|
+
export const DistanceMatrix = matrix.DistanceMatrix;
|
|
6
7
|
export const EVD = matrix.EVD;
|
|
7
8
|
export const EigenvalueDecomposition = matrix.EigenvalueDecomposition;
|
|
8
9
|
export const LU = matrix.LU;
|
|
@@ -23,11 +24,12 @@ export const QR = matrix.QR;
|
|
|
23
24
|
export const QrDecomposition = matrix.QrDecomposition;
|
|
24
25
|
export const SVD = matrix.SVD;
|
|
25
26
|
export const SingularValueDecomposition = matrix.SingularValueDecomposition;
|
|
27
|
+
export const SymmetricMatrix = matrix.SymmetricMatrix;
|
|
26
28
|
export const WrapperMatrix1D = matrix.WrapperMatrix1D;
|
|
27
29
|
export const WrapperMatrix2D = matrix.WrapperMatrix2D;
|
|
28
30
|
export const correlation = matrix.correlation;
|
|
29
31
|
export const covariance = matrix.covariance;
|
|
30
|
-
export default matrix.default;
|
|
32
|
+
export default matrix.default.Matrix ? matrix.default.Matrix : matrix.Matrix;
|
|
31
33
|
export const determinant = matrix.determinant;
|
|
32
34
|
export const inverse = matrix.inverse;
|
|
33
35
|
export const linearDependencies = matrix.linearDependencies;
|