@@ -5405,6 +5405,82 @@ describe('Matrix', () => {
5405
5405
} )
5406
5406
} )
5407
5407
5408
+ describe ( 'balancing' , ( ) => {
5409
+ test . each ( [ 1 , 2 , 3 , 4 ] ) ( 'square %d' , n => {
5410
+ const mat = Matrix . random ( n , n , 0.1 , 10 )
5411
+ const [ d1 , a , d2 ] = mat . balancing ( )
5412
+
5413
+ expect ( a . sizes ) . toEqual ( [ n , n ] )
5414
+ expect ( d1 ) . toHaveLength ( n )
5415
+ expect ( d2 ) . toHaveLength ( n )
5416
+ const s0 = a . sum ( 0 ) . value
5417
+ const s1 = a . sum ( 1 ) . value
5418
+ for ( let i = 0 ; i < n ; i ++ ) {
5419
+ expect ( s0 [ i ] ) . toBeCloseTo ( 1 )
5420
+ expect ( s1 [ i ] ) . toBeCloseTo ( 1 )
5421
+ }
5422
+
5423
+ const dad = Matrix . diag ( d1 ) . dot ( a ) . dot ( Matrix . diag ( d2 ) )
5424
+ for ( let i = 0 ; i < n ; i ++ ) {
5425
+ for ( let j = 0 ; j < n ; j ++ ) {
5426
+ expect ( dad . at ( i , j ) ) . toBeCloseTo ( mat . at ( i , j ) )
5427
+ }
5428
+ }
5429
+ } )
5430
+
5431
+ test ( 'fail neg value' , ( ) => {
5432
+ const mat = Matrix . randn ( 3 , 3 )
5433
+ mat . set ( 0 , 0 , - 0.1 )
5434
+ expect ( ( ) => mat . balancing ( ) ) . toThrow ( 'Doubly stochastic matrix only calculate for non negative matrix.' )
5435
+ } )
5436
+
5437
+ test . each ( [
5438
+ [ 2 , 3 ] ,
5439
+ [ 3 , 2 ] ,
5440
+ ] ) ( 'fail(%i, %i)' , ( r , c ) => {
5441
+ const mat = Matrix . randn ( r , c )
5442
+ expect ( ( ) => mat . balancing ( ) ) . toThrow ( 'Doubly stochastic matrix only defined for square matrix.' )
5443
+ } )
5444
+ } )
5445
+
5446
+ describe ( 'balancingSinkhornKnopp' , ( ) => {
5447
+ test . each ( [ 1 , 2 , 3 , 4 ] ) ( 'square %d' , n => {
5448
+ const mat = Matrix . random ( n , n , 0.1 , 10 )
5449
+ const [ d1 , a , d2 ] = mat . balancingSinkhornKnopp ( )
5450
+
5451
+ expect ( a . sizes ) . toEqual ( [ n , n ] )
5452
+ expect ( d1 ) . toHaveLength ( n )
5453
+ expect ( d2 ) . toHaveLength ( n )
5454
+ const s0 = a . sum ( 0 ) . value
5455
+ const s1 = a . sum ( 1 ) . value
5456
+ for ( let i = 0 ; i < n ; i ++ ) {
5457
+ expect ( s0 [ i ] ) . toBeCloseTo ( 1 )
5458
+ expect ( s1 [ i ] ) . toBeCloseTo ( 1 )
5459
+ }
5460
+
5461
+ const dad = Matrix . diag ( d1 ) . dot ( a ) . dot ( Matrix . diag ( d2 ) )
5462
+ for ( let i = 0 ; i < n ; i ++ ) {
5463
+ for ( let j = 0 ; j < n ; j ++ ) {
5464
+ expect ( dad . at ( i , j ) ) . toBeCloseTo ( mat . at ( i , j ) )
5465
+ }
5466
+ }
5467
+ } )
5468
+
5469
+ test ( 'fail neg value' , ( ) => {
5470
+ const mat = Matrix . randn ( 3 , 3 )
5471
+ mat . set ( 0 , 0 , - 0.1 )
5472
+ expect ( ( ) => mat . balancingSinkhornKnopp ( ) ) . toThrow ( 'Doubly stochastic matrix only calculate for non negative matrix.' )
5473
+ } )
5474
+
5475
+ test . each ( [
5476
+ [ 2 , 3 ] ,
5477
+ [ 3 , 2 ] ,
5478
+ ] ) ( 'fail(%i, %i)' , ( r , c ) => {
5479
+ const mat = Matrix . randn ( r , c )
5480
+ expect ( ( ) => mat . balancingSinkhornKnopp ( ) ) . toThrow ( 'Doubly stochastic matrix only defined for square matrix.' )
5481
+ } )
5482
+ } )
5483
+
5408
5484
describe ( 'lu' , ( ) => {
5409
5485
test . each ( [ 0 , 1 , 2 , 3 , 5 ] ) ( 'success %i' , n => {
5410
5486
const mat = Matrix . randn ( n , n )
@@ -6577,7 +6653,7 @@ describe('Matrix', () => {
6577
6653
expect ( ( ) => mat . eigenValuesQR ( ) ) . toThrow ( 'Eigen values only define square matrix.' )
6578
6654
} )
6579
6655
6580
- test ( 'iteration not converged' , ( ) => {
6656
+ test . only ( 'iteration not converged' , ( ) => {
6581
6657
const mat = new Matrix ( 3 , 3 , [
6582
6658
[ - 0.3 , - 0.4 , 1.7 ] ,
6583
6659
[ - 0.2 , - 1.8 , - 0.8 ] ,
0 commit comments