@@ -18,11 +18,12 @@ export class SparseMatrix {
18
18
19
19
if ( Array . isArray ( rows ) ) {
20
20
const matrix = rows ;
21
- rows = matrix . length ;
22
- options = columns || { } ;
21
+ const nbRows = matrix . length ;
22
+ const nbColmuns = matrix [ 0 ] . length ;
23
+ options = columns || { initialCapacity : nbRows * nbColmuns } ;
23
24
columns = matrix [ 0 ] . length ;
24
- this . _init ( rows , columns , new HashTable ( options ) , options . threshold ) ;
25
- for ( let i = 0 ; i < rows ; i ++ ) {
25
+ this . _init ( nbRows , columns , new HashTable ( options ) , options . threshold ) ;
26
+ for ( let i = 0 ; i < nbRows ; i ++ ) {
26
27
for ( let j = 0 ; j < columns ; j ++ ) {
27
28
let value = matrix [ i ] [ j ] ;
28
29
if ( this . threshold && Math . abs ( value ) < this . threshold ) value = 0 ;
@@ -31,6 +32,7 @@ export class SparseMatrix {
31
32
}
32
33
}
33
34
}
35
+ this . elements . maybeShrinkCapacity ( ) ;
34
36
} else {
35
37
this . _init ( rows , columns , new HashTable ( options ) , options . threshold ) ;
36
38
}
@@ -169,14 +171,12 @@ export class SparseMatrix {
169
171
const p = other . columns ;
170
172
171
173
const result = new SparseMatrix ( m , p ) ;
172
- this . forEachNonZero ( ( i , j , v1 ) => {
173
- other . forEachNonZero ( ( k , l , v2 ) => {
174
+ this . withEachNonZero ( ( i , j , v1 ) => {
175
+ other . withEachNonZero ( ( k , l , v2 ) => {
174
176
if ( j === k ) {
175
177
result . set ( i , l , result . get ( i , l ) + v1 * v2 ) ;
176
178
}
177
- return v2 ;
178
179
} ) ;
179
- return v1 ;
180
180
} ) ;
181
181
return result ;
182
182
}
@@ -194,16 +194,31 @@ export class SparseMatrix {
194
194
const result = new SparseMatrix ( m * p , n * q , {
195
195
initialCapacity : this . cardinality * other . cardinality ,
196
196
} ) ;
197
- this . forEachNonZero ( ( i , j , v1 ) => {
198
- other . forEachNonZero ( ( k , l , v2 ) => {
199
- result . set ( p * i + k , q * j + l , v1 * v2 ) ;
200
- return v2 ;
197
+
198
+ this . withEachNonZero ( ( i , j , v1 ) => {
199
+ const pi = p * i ;
200
+ const qj = q * j ;
201
+ other . withEachNonZero ( ( k , l , v2 ) => {
202
+ result . set ( pi + k , qj + l , v1 * v2 ) ;
201
203
} ) ;
202
- return v1 ;
203
204
} ) ;
204
205
return result ;
205
206
}
206
207
208
+ withEachNonZero ( callback ) {
209
+ const { state, table, values } = this . elements ;
210
+ const nbStates = state . length ;
211
+ const activeIndex = [ ] ;
212
+ for ( let i = 0 ; i < nbStates ; i ++ ) {
213
+ if ( state [ i ] === 1 ) activeIndex . push ( i ) ;
214
+ }
215
+ const columns = this . columns ;
216
+ for ( const i of activeIndex ) {
217
+ const key = table [ i ] ;
218
+ callback ( ( key / columns ) | 0 , key % columns , values [ i ] ) ;
219
+ }
220
+ }
221
+
207
222
/**
208
223
* Calls `callback` for each value in the matrix that is not zero.
209
224
* The callback can return:
0 commit comments