Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fixing issue 7936 #542

Closed
wants to merge 2 commits into from

3 participants

Jernej Krempuš Joseph Rushton Wakeling Jonathan M Davis
Jernej Krempuš
jerro commented April 17, 2012

This fixes the issue 7936. When the user passed a random generator to randomSample, gen was assinged after prime() was first called, so I moved gen assignment into the RandomSample constructor.

std/random.d
((9 lines not shown))
1506 1501
 
1507  
-    this(R input, size_t howMany, size_t total)
1508  
-    {
1509  
-        _input = input;
1510  
-        _available = total;
1511  
-        _toSelect = howMany;
1512  
-        enforce(_toSelect <= _available);
1513  
-        // we should skip some elements initially so we don't always
1514  
-        // start with the first
1515  
-        prime();
1516  
-    }
  1502
+	private void init(R input, size_t howMany, size_t total)
2
Jonathan M Davis Collaborator
jmdavis added a note May 03, 2012

Never create a function named init. It probably shouldn't even be legal. It will cause problems with the type's init property.

Also, thish should just stay as a constructor. One constructor can call another. The new constructor would then be something like

this(R input, size_t howMany, size_t total, Random gen)
{
    this.gen = gen;
    this(input, throwMany, total);
}
Jernej Krempuš
jerro added a note May 04, 2012

I forgot about the init property, thanks. I've renamed init to initialize now. It should certainly not stay a constructor. When Random is not void, using such a constructor to construct a RandomSample instance would always result in a bug that this pull request fixes. If a function can not safely construct an instance of a type, it should not be a constructor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
std/random.d
((37 lines not shown))
  1519
+			}
  1520
+
  1521
+		this(R input, size_t howMany, size_t total)
  1522
+		{
  1523
+			init(input, howMany, total);
  1524
+		}
  1525
+	}
  1526
+	else
  1527
+	{
  1528
+		static if (hasLength!R)
  1529
+			this(R input, size_t howMany, Random _gen)
  1530
+			{
  1531
+				this(input, howMany, input.length, _gen);
  1532
+			}
  1533
+
  1534
+		this(R input, size_t howMany, size_t total, Random _gen)
2
Jonathan M Davis Collaborator
jmdavis added a note May 03, 2012

Please do not prepend _ to a variable name if it's not a member variable. You can just leave it as gen and do this.gen = gen;.

Jernej Krempuš
jerro added a note May 04, 2012

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Joseph Rushton Wakeling

I've uploaded an alternative fix as part of my pull request implementing the Vitter sampling algorithm. I think this provides a better solution as it also handles the case where the user doesn't pass a random number generator at all.

Jernej Krempuš
jerro commented May 09, 2012

Oh, I never thought about a problem with copying a RandomSample that uses the global rng. It looks like your fix is the only way to fix that. I'm closing this pull request.

Jernej Krempuš jerro closed this May 09, 2012
Joseph Rushton Wakeling

My fault -- I didn't raise it in the bug report. I only noted the case where the sampler is passed a URNG with different seeds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Apr 18, 2012
Jernej Krempuš Fixed bug 7936 36c6b32
May 04, 2012
Jernej Krempuš Renamed _gen and init and replaced tabs with spaces. 3608d74
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 31 additions and 10 deletions. Show diff stats Hide diff stats

  1. 41  std/random.d
41  std/random.d
@@ -1498,13 +1498,8 @@ struct RandomSample(R, Random = void)
1498 1498
 /**
1499 1499
 Constructor.
1500 1500
 */
1501  
-    static if (hasLength!R)
1502  
-        this(R input, size_t howMany)
1503  
-        {
1504  
-            this(input, howMany, input.length);
1505  
-        }
1506 1501
 
1507  
-    this(R input, size_t howMany, size_t total)
  1502
+    private void initialize(R input, size_t howMany, size_t total)
1508 1503
     {
1509 1504
         _input = input;
1510 1505
         _available = total;
@@ -1515,6 +1510,34 @@ Constructor.
1515 1510
         prime();
1516 1511
     }
1517 1512
 
  1513
+    static if(is(Random == void))
  1514
+    {
  1515
+        static if (hasLength!R)
  1516
+            this(R input, size_t howMany)
  1517
+            {
  1518
+                this(input, howMany, input.length);
  1519
+            }
  1520
+
  1521
+        this(R input, size_t howMany, size_t total)
  1522
+        {
  1523
+            initialize(input, howMany, total);
  1524
+        }
  1525
+    }
  1526
+    else
  1527
+    {
  1528
+        static if (hasLength!R)
  1529
+            this(R input, size_t howMany, Random gen)
  1530
+            {
  1531
+                this(input, howMany, input.length, gen);
  1532
+            }
  1533
+
  1534
+        this(R input, size_t howMany, size_t total, Random gen)
  1535
+        {
  1536
+            this.gen = gen;
  1537
+            initialize(input, howMany, total);
  1538
+        }
  1539
+    }
  1540
+
1518 1541
 /**
1519 1542
    Range primitives.
1520 1543
 */
@@ -1608,8 +1631,7 @@ auto randomSample(R)(R r, size_t n) if (hasLength!R)
1608 1631
 auto randomSample(R, Random)(R r, size_t n, size_t total, Random gen)
1609 1632
 if(isInputRange!R && isUniformRNG!Random)
1610 1633
 {
1611  
-    auto ret = RandomSample!(R, Random)(r, n, total);
1612  
-    ret.gen = gen;
  1634
+    auto ret = RandomSample!(R, Random)(r, n, total, gen);
1613 1635
     return ret;
1614 1636
 }
1615 1637
 
@@ -1617,8 +1639,7 @@ if(isInputRange!R && isUniformRNG!Random)
1617 1639
 auto randomSample(R, Random)(R r, size_t n, Random gen)
1618 1640
 if (isInputRange!R && hasLength!R && isUniformRNG!Random)
1619 1641
 {
1620  
-    auto ret = RandomSample!(R, Random)(r, n, r.length);
1621  
-    ret.gen = gen;
  1642
+    auto ret = RandomSample!(R, Random)(r, n, r.length, gen);
1622 1643
     return ret;
1623 1644
 }
1624 1645
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.