1
1
type MaybeMatrix = AbstractMatrix | ArrayLike < ArrayLike < number > > ;
2
2
type ScalarOrMatrix = number | MaybeMatrix ;
3
3
type MatrixDimension = 'row' | 'column' ;
4
+ type MaskValue = 0 | 1 | number | boolean ;
5
+ /**
6
+ * allow use of numbers (only 0 is considered false) and booleans
7
+ */
8
+ type Mask = MaskValue [ ] ;
4
9
5
10
export interface IRandomOptions {
6
11
/**
@@ -165,17 +170,24 @@ export abstract class AbstractMatrix {
165
170
* This is equivalent to calling the Matrix constructor.
166
171
* @param rows - Number of rows.
167
172
* @param columns - Number of columns.
173
+ * @template _M is private. Don't override it.
168
174
* @returns The new matrix.
169
175
*/
170
- static zeros ( rows : number , columns : number ) : Matrix ;
176
+ static zeros < _M extends AbstractMatrix = Matrix > (
177
+ rows : number ,
178
+ columns : number ,
179
+ ) : _M ;
171
180
172
181
/**
173
182
* Creates a matrix with the given dimensions. Values will be set to one.
174
183
* @param rows - Number of rows.
175
184
* @param columns - Number of columns.
176
185
* @returns The new matrix.
177
186
*/
178
- static ones ( rows : number , columns : number ) : Matrix ;
187
+ static ones < M extends AbstractMatrix = Matrix > (
188
+ rows : number ,
189
+ columns : number ,
190
+ ) : M ;
179
191
180
192
/**
181
193
* Creates a matrix with the given dimensions. Values will be randomly set.
@@ -195,6 +207,7 @@ export abstract class AbstractMatrix {
195
207
* Creates a matrix with the given dimensions. Values will be random integers.
196
208
* @param rows - Number of rows.
197
209
* @param columns - Number of columns.
210
+ * @param options
198
211
* @returns - The new matrix.
199
212
*/
200
213
static randInt (
@@ -313,6 +326,11 @@ export abstract class AbstractMatrix {
313
326
*/
314
327
isSquare ( ) : boolean ;
315
328
329
+ /**
330
+ * Returns whether the matrix is symmetric and diagonal values are equals to 0
331
+ */
332
+ isDistance ( ) : boolean ;
333
+
316
334
/**
317
335
* Returns whether the number of rows or columns (or both) is zero.
318
336
*/
@@ -728,7 +746,9 @@ export abstract class AbstractMatrix {
728
746
/**
729
747
* Creates an exact and independent copy of the matrix.
730
748
*/
731
- clone ( ) : Matrix ;
749
+ clone ( ) : this;
750
+
751
+ static copy < M extends AbstractMatrix > ( from : AbstractMatrix , to : M ) : M ;
732
752
733
753
/**
734
754
* Returns the sum of all elements of the matrix.
@@ -824,6 +844,34 @@ export abstract class AbstractMatrix {
824
844
825
845
toString ( options ?: IToStringOptions ) : string ;
826
846
847
+ // iterators methods
848
+
849
+ /**
850
+ * iterator from left to right, from top to bottom
851
+ * yield [row, column, value]
852
+ */
853
+ [ Symbol . iterator ] ( ) : Generator <
854
+ [ row : number , column : number , value : number ] ,
855
+ void ,
856
+ never
857
+ > ;
858
+
859
+ /**
860
+ * iterator from left to right, from top to bottom
861
+ * yield [row, column, value]
862
+ */
863
+ entries ( ) : Generator <
864
+ [ row : number , column : number , value : number ] ,
865
+ void ,
866
+ never
867
+ > ;
868
+
869
+ /**
870
+ * iterator from left to right, from top to bottom
871
+ * yield value
872
+ */
873
+ values ( ) : Generator < number , void , never > ;
874
+
827
875
// From here we document methods dynamically generated from operators
828
876
829
877
// Mathematical operators
@@ -960,17 +1008,233 @@ export class Matrix extends AbstractMatrix {
960
1008
* @param array - Column to add.
961
1009
*/
962
1010
addColumn ( index : number , array : ArrayLike < number > | AbstractMatrix ) : this;
1011
+ addColumn ( array : ArrayLike < number > | AbstractMatrix ) : this;
963
1012
964
1013
/**
965
1014
* Adds a new row to the matrix (in place).
966
1015
* @param index - Row index. Default: `this.rows`.
967
1016
* @param array - Row to add.
968
1017
*/
969
1018
addRow ( index : number , array : ArrayLike < number > | AbstractMatrix ) : this;
1019
+ addRow ( array : ArrayLike < number > | AbstractMatrix ) : this;
970
1020
}
971
1021
972
1022
export default Matrix ;
973
1023
1024
+ export class SymmetricMatrix extends AbstractMatrix {
1025
+ /**
1026
+ * alias for `rows` or `columns` (square matrix so equals)
1027
+ */
1028
+ readonly diagonalSize : number ;
1029
+
1030
+ /**
1031
+ * @throws TypeError if otherMatrix is not symmetric
1032
+ * @param otherMatrix
1033
+ */
1034
+ constructor ( otherMatrix : AbstractMatrix ) ;
1035
+ constructor ( diagonalSize : number ) ;
1036
+ /**
1037
+ * @throws TypeError if data are not symmetric
1038
+ * @param data
1039
+ */
1040
+ constructor ( data : ArrayLike < ArrayLike < number > > ) ;
1041
+
1042
+ get ( rowIndex : number , columnIndex : number ) : number ;
1043
+ set ( rowIndex : number , columnIndex : number , value : number ) : this;
1044
+
1045
+ /**
1046
+ * Creates a symmetric matrix with the given dimensions. Values will be set to zero.
1047
+ * This is equivalent to calling the Matrix constructor.
1048
+ *
1049
+ * @param diagonalSize - Number of rows or columns (square).
1050
+ * @template _M is private, do not override it.
1051
+ * @returns The new symmetric matrix.
1052
+ */
1053
+ static zeros < _M extends AbstractMatrix = SymmetricMatrix > (
1054
+ diagonalSize : number ,
1055
+ ) : _M ;
1056
+ /**
1057
+ * Creates a symmetric matrix with the given dimensions. Values will be set to one.
1058
+ * @param diagonalSize - Number of rows or columns (square).
1059
+ * @template _M is private, do not override it.
1060
+ * @returns The new symmetric matrix.
1061
+ */
1062
+ static ones < _M extends AbstractMatrix = SymmetricMatrix > (
1063
+ diagonalSize : number ,
1064
+ ) : _M ;
1065
+
1066
+ static isSymmetricMatrix ( value : unknown ) : value is SymmetricMatrix ;
1067
+
1068
+ /**
1069
+ * copy to a new matrix
1070
+ */
1071
+ toMatrix ( ) : Matrix ;
1072
+
1073
+ /**
1074
+ * Symmetric remove row / column
1075
+ * @param index
1076
+ */
1077
+ removeCross ( index : number ) : this;
1078
+
1079
+ /**
1080
+ * Symmetric add row / column
1081
+ * @param index
1082
+ * @param array
1083
+ */
1084
+ addCross ( index : number , array : ArrayLike < number > | AbstractMatrix ) : this;
1085
+ addCross ( array : ArrayLike < number > | AbstractMatrix ) : this;
1086
+
1087
+ /**
1088
+ * remove sides (rows / columns) with falsy value from mask.
1089
+ *
1090
+ * @example
1091
+ *
1092
+ * ```js
1093
+ * const matrix = new SymmetricMatrix([
1094
+ * [0,1,2,3],
1095
+ * [1,0,4,5],
1096
+ * [2,4,0,6],
1097
+ * [3,5,6,0],
1098
+ * ]);
1099
+ * matrix.applyMask([1,0,0,1]);
1100
+ * assert.deepEqual(matrix.toCompact(), new SymmetricMatrix([
1101
+ * [0,3],
1102
+ * [3,0],
1103
+ * ]).toCompact());
1104
+ * ```
1105
+ *
1106
+ * @throws RangeError if mask length is different of matrix sideSize
1107
+ *
1108
+ * @param mask
1109
+ */
1110
+ applyMask ( mask : Mask ) : this;
1111
+
1112
+ /**
1113
+ * Compact format upper-right corner of matrix
1114
+ * iterate from left to right, from top to bottom.
1115
+ *
1116
+ * ```
1117
+ * full view | usefull data
1118
+ * A B C D | A B C D
1119
+ * A 1 2 3 4 | A 1 2 3 4
1120
+ * B 2 5 6 7 | B · 5 6 7
1121
+ * C 3 6 8 9 | C · · 8 9
1122
+ * D 4 7 9 10 | D · · · 10
1123
+ * ```
1124
+ *
1125
+ * will return compact 1D array `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]`
1126
+ *
1127
+ * length is S(i=0, n=sideSize) => 10 for a 4 sideSized matrix
1128
+ */
1129
+ toCompact ( ) : number [ ] ;
1130
+
1131
+ /**
1132
+ * @throws TypeError if `compact` is not the compact form of a Symmetric Matrix
1133
+ * `(Math.sqrt(8 * compactLength + 1) - 1) / 2` must be an integer
1134
+ *
1135
+ * @param compact
1136
+ */
1137
+ static fromCompact ( compact : number [ ] ) : SymmetricMatrix ;
1138
+
1139
+ clone ( ) : this;
1140
+
1141
+ /**
1142
+ * half iterator upper-right-corner from left to right, from top to bottom
1143
+ * yield [row, column, value]
1144
+ */
1145
+ upperRightEntries ( ) : Generator <
1146
+ [ row : number , column : number , value : number ] ,
1147
+ void ,
1148
+ never
1149
+ > ;
1150
+
1151
+ /**
1152
+ * half iterator upper-right-corner from left to right, from top to bottom
1153
+ * yield value
1154
+ */
1155
+ upperRightValues ( ) : Generator < number , void , never > ;
1156
+ }
1157
+
1158
+ export class DistanceMatrix extends SymmetricMatrix {
1159
+ /**
1160
+ * Creates a distance matrix with the given dimensions. Values will be set to zero.
1161
+ * This is equivalent to calling the Matrix constructor.
1162
+ * @param sidesSize - Number of rows or columns (square).
1163
+ * @template _M is private, do not specify it
1164
+ * @returns The new symmetric matrix.
1165
+ */
1166
+ static zeros < _M extends AbstractMatrix = DistanceMatrix > (
1167
+ sidesSize : number ,
1168
+ ) : _M ;
1169
+
1170
+ /**
1171
+ * Creates a symmetric matrix with the given dimensions. Values will be set to one.
1172
+ * @param sidesSize - Number of rows or columns (square).
1173
+ * @template _M is private, do not specify it
1174
+ * @returns The new symmetric matrix.
1175
+ */
1176
+ static ones < _M extends AbstractMatrix = DistanceMatrix > (
1177
+ sidesSize : number ,
1178
+ ) : _M ;
1179
+
1180
+ static isDistanceMatrix ( value : unknown ) : value is DistanceMatrix ;
1181
+
1182
+ constructor ( sidesSize : number ) ;
1183
+ /**
1184
+ * @throws TypeError if data are not symmetric and diagonal is not 0
1185
+ * @param data
1186
+ */
1187
+ constructor ( data : ArrayLike < ArrayLike < number > > ) ;
1188
+ /**
1189
+ * @throws TypeError if otherMatrix is not symmetric and diagonal is not 0
1190
+ * @param otherMatrix
1191
+ */
1192
+ constructor ( otherMatrix : AbstractMatrix ) ;
1193
+
1194
+ /**
1195
+ * because it's a distance matrix, if rowIndex === columnIndex,
1196
+ * value will be set to 0
1197
+ *
1198
+ * @param rowIndex
1199
+ * @param columnIndex
1200
+ * @param value
1201
+ */
1202
+ set ( rowIndex : number , columnIndex : number , value : number ) : this;
1203
+
1204
+ toSymmetricMatrix ( ) : SymmetricMatrix ;
1205
+
1206
+ /**
1207
+ * Compact format upper-right corner of matrix
1208
+ * no diagonal (because only store zeros)
1209
+ * iterable from left to right, from top to bottom.
1210
+ *
1211
+ * ```
1212
+ * A B C D
1213
+ * A 0 1 2 3
1214
+ * B 1 0 4 5
1215
+ * C 2 4 0 6
1216
+ * D 3 5 6 0
1217
+ * ```
1218
+ *
1219
+ * will return compact 1D array `[1, 2, 3, 4, 5, 6]`
1220
+ *
1221
+ * length is S(i=0, n=sideSize-1) => 6 for a 4 side sized matrix
1222
+ *
1223
+ * @returns {number[] }
1224
+ */
1225
+ toCompact ( ) : number [ ] ;
1226
+
1227
+ /**
1228
+ * @throws TypeError if `compact` is not the compact form of a Distance Matrix
1229
+ * `(Math.sqrt(8 * compactSize + 1) + 1) / 2` must be an integer
1230
+ *
1231
+ * @param compact
1232
+ */
1233
+ static fromCompact ( compact : number [ ] ) : DistanceMatrix ;
1234
+
1235
+ clone ( ) : this;
1236
+ }
1237
+
974
1238
export class MatrixColumnView extends AbstractMatrix {
975
1239
constructor ( matrix : AbstractMatrix , column : number ) ;
976
1240
set ( rowIndex : number , columnIndex : number , value : number ) : this;
0 commit comments