@@ -29,6 +29,7 @@ var isUint32Array = require( '@stdlib/assert/is-uint32array' );
29
29
var Uint32Array = require ( '@stdlib/array/uint32' ) ;
30
30
var kstest = require ( '@stdlib/stats/kstest' ) ;
31
31
var minstd = require ( '@stdlib/random/base/minstd-shuffle' ) ;
32
+ var gcopy = require ( '@stdlib/blas/base/gcopy' ) ;
32
33
var factory = require ( './../lib/factory.js' ) ;
33
34
34
35
@@ -349,7 +350,7 @@ tape( 'if provided a `state` option containing an unsupported section length, th
349
350
values = [ ] ;
350
351
351
352
v = new Uint32Array ( 632 ) ; // >624+7
352
- v [ 0 ] = 0 ; // version
353
+ v [ 0 ] = 1 ; // version
353
354
v [ 1 ] = 3 ; // number of sections
354
355
v [ 2 ] = 624 ; // state length
355
356
v [ 627 ] = 2 ; // other length
@@ -358,7 +359,7 @@ tape( 'if provided a `state` option containing an unsupported section length, th
358
359
values . push ( v ) ;
359
360
360
361
v = new Uint32Array ( 633 ) ; // >624+7
361
- v [ 0 ] = 0 ; // version
362
+ v [ 0 ] = 1 ; // version
362
363
v [ 1 ] = 3 ; // number of sections
363
364
v [ 2 ] = 624 ; // state length
364
365
v [ 627 ] = 2 ; // other length
@@ -388,7 +389,7 @@ tape( 'if provided a `state` option containing an incompatible seed length, the
388
389
values = [ ] ;
389
390
390
391
v = new Uint32Array ( 631 ) ; // 624+7
391
- v [ 0 ] = 0 ; // version
392
+ v [ 0 ] = 1 ; // version
392
393
v [ 1 ] = 3 ; // number of sections
393
394
v [ 2 ] = 624 ; // state length
394
395
v [ 627 ] = 1 ; // other length
@@ -397,7 +398,7 @@ tape( 'if provided a `state` option containing an incompatible seed length, the
397
398
values . push ( v ) ;
398
399
399
400
v = new Uint32Array ( 632 ) ; // >624+7
400
- v [ 0 ] = 0 ; // version
401
+ v [ 0 ] = 1 ; // version
401
402
v [ 1 ] = 3 ; // number of sections
402
403
v [ 2 ] = 624 ; // state length
403
404
v [ 627 ] = 1 ; // other length
@@ -1387,24 +1388,6 @@ tape( 'the function supports specifying a shared generator state', function test
1387
1388
'copy' : false
1388
1389
} ) ;
1389
1390
1390
- // Replay previously generated values...
1391
- j = 0 ;
1392
- for ( i = 0 ; i < 50 ; i ++ ) {
1393
- v1 = rand1 ( ) ;
1394
- v2 = rand2 ( ) ;
1395
- t . equal ( v1 , arr [ j ] , 'returns expected value. i: ' + j + '.' ) ;
1396
- t . equal ( v2 , arr [ j + 1 ] , 'returns expected value. i: ' + ( j + 1 ) + '.' ) ;
1397
- j += 2 ; // stride
1398
- }
1399
-
1400
- // Move to a future state...
1401
- for ( i = 0 ; i < 100 ; i ++ ) {
1402
- v2 = rand2 ( ) ;
1403
- }
1404
-
1405
- // Reset the (shared) state:
1406
- rand1 . state = new Uint32Array ( state ) ;
1407
-
1408
1391
// Replay previously generated values...
1409
1392
j = 0 ;
1410
1393
for ( i = 0 ; i < 50 ; i ++ ) {
@@ -1506,3 +1489,152 @@ tape( 'the returned function supports setting the generator state (normalized)',
1506
1489
}
1507
1490
t . end ( ) ;
1508
1491
} ) ;
1492
+
1493
+ tape ( 'the returned function supports setting a compatible shared generator state' , function test ( t ) {
1494
+ var mt19937 ;
1495
+ var shared ;
1496
+ var state ;
1497
+ var rand1 ;
1498
+ var rand2 ;
1499
+ var arr ;
1500
+ var v1 ;
1501
+ var v2 ;
1502
+ var i ;
1503
+ var j ;
1504
+
1505
+ mt19937 = factory ( ) ;
1506
+
1507
+ // Move to a future state...
1508
+ for ( i = 0 ; i < 100 ; i ++ ) {
1509
+ mt19937 ( ) ;
1510
+ }
1511
+ // Capture the current state:
1512
+ state = mt19937 . state ;
1513
+
1514
+ // Move to a future state...
1515
+ arr = [ ] ;
1516
+ for ( i = 0 ; i < 100 ; i ++ ) {
1517
+ arr . push ( mt19937 ( ) ) ;
1518
+ }
1519
+
1520
+ // Create a copy of the state (to prevent mutation) which will be shared by more than one PRNG:
1521
+ shared = new Uint32Array ( state ) ;
1522
+
1523
+ // Create PRNGs using the captured state:
1524
+ rand1 = factory ( {
1525
+ 'state' : shared ,
1526
+ 'copy' : false
1527
+ } ) ;
1528
+ rand2 = factory ( {
1529
+ 'state' : shared ,
1530
+ 'copy' : false
1531
+ } ) ;
1532
+
1533
+ // Replay previously generated values...
1534
+ j = 0 ;
1535
+ for ( i = 0 ; i < 50 ; i ++ ) {
1536
+ v1 = rand1 ( ) ;
1537
+ v2 = rand2 ( ) ;
1538
+ t . equal ( v1 , arr [ j ] , 'returns expected value. i: ' + j + '.' ) ;
1539
+ t . equal ( v2 , arr [ j + 1 ] , 'returns expected value. i: ' + ( j + 1 ) + '.' ) ;
1540
+ j += 2 ; // stride
1541
+ }
1542
+
1543
+ // Move to a future state...
1544
+ for ( i = 0 ; i < 100 ; i ++ ) {
1545
+ v2 = rand2 ( ) ;
1546
+ }
1547
+
1548
+ // Reset the (shared) state:
1549
+ rand1 . state = new Uint32Array ( state ) ;
1550
+
1551
+ // Replay previously generated values...
1552
+ j = 0 ;
1553
+ for ( i = 0 ; i < 50 ; i ++ ) {
1554
+ v1 = rand1 ( ) ;
1555
+ v2 = rand2 ( ) ;
1556
+ t . equal ( v1 , arr [ j ] , 'returns expected value. i: ' + j + '.' ) ;
1557
+ t . equal ( v2 , arr [ j + 1 ] , 'returns expected value. i: ' + ( j + 1 ) + '.' ) ;
1558
+ j += 2 ; // stride
1559
+ }
1560
+ t . end ( ) ;
1561
+ } ) ;
1562
+
1563
+ tape ( 'the returned function does not support setting an incompatible shared generator state' , function test ( t ) {
1564
+ var mt19937 ;
1565
+ var shared ;
1566
+ var state ;
1567
+ var rand1 ;
1568
+ var rand2 ;
1569
+ var arr ;
1570
+ var v1 ;
1571
+ var v2 ;
1572
+ var s ;
1573
+ var i ;
1574
+ var j ;
1575
+
1576
+ mt19937 = factory ( ) ;
1577
+
1578
+ // Move to a future state...
1579
+ for ( i = 0 ; i < 100 ; i ++ ) {
1580
+ mt19937 ( ) ;
1581
+ }
1582
+ // Capture the current state:
1583
+ state = mt19937 . state ;
1584
+
1585
+ // Move to a future state...
1586
+ arr = [ ] ;
1587
+ for ( i = 0 ; i < 100 ; i ++ ) {
1588
+ arr . push ( mt19937 ( ) ) ;
1589
+ }
1590
+
1591
+ // Create a copy of the state (to prevent mutation) which will be shared by more than one PRNG:
1592
+ shared = new Uint32Array ( state ) ;
1593
+
1594
+ // Create PRNGs using the captured state:
1595
+ rand1 = factory ( {
1596
+ 'state' : shared ,
1597
+ 'copy' : false
1598
+ } ) ;
1599
+ rand2 = factory ( {
1600
+ 'state' : shared ,
1601
+ 'copy' : false
1602
+ } ) ;
1603
+
1604
+ // Replay previously generated values...
1605
+ j = 0 ;
1606
+ for ( i = 0 ; i < 50 ; i ++ ) {
1607
+ v1 = rand1 ( ) ;
1608
+ v2 = rand2 ( ) ;
1609
+ t . equal ( v1 , arr [ j ] , 'returns expected value. i: ' + j + '.' ) ;
1610
+ t . equal ( v2 , arr [ j + 1 ] , 'returns expected value. i: ' + ( j + 1 ) + '.' ) ;
1611
+ j += 2 ; // stride
1612
+ }
1613
+
1614
+ // Move to a future state...
1615
+ for ( i = 0 ; i < 100 ; i ++ ) {
1616
+ v2 = rand2 ( ) ;
1617
+ }
1618
+
1619
+ // Reset the (*previously* shared) state:
1620
+ s = new Uint32Array ( state . length + 1 ) ;
1621
+ gcopy ( state . length , state , 1 , s , 1 ) ;
1622
+ s [ s . length - 3 ] = 2 ;
1623
+ s [ s . length - 1 ] = 1234 ;
1624
+ rand1 . state = s ;
1625
+
1626
+ // Attempt to replay previously generated values...
1627
+ j = 0 ;
1628
+ for ( i = 0 ; i < 50 ; i ++ ) {
1629
+ v1 = rand1 ( ) ;
1630
+ v2 = rand2 ( ) ;
1631
+
1632
+ // `rand1()` state is not affected by `rand2()`:
1633
+ t . equal ( v1 , arr [ i ] , 'returns expected value. i: ' + i + '.' ) ;
1634
+
1635
+ // `rand2()` state was never reset:
1636
+ t . notEqual ( v2 , arr [ j + 1 ] , 'does not return expected value. i: ' + ( j + 1 ) + '.' ) ;
1637
+ j += 2 ; // stride
1638
+ }
1639
+ t . end ( ) ;
1640
+ } ) ;
0 commit comments