@@ -864,7 +864,8 @@ a
864864Mutability leads to the following behavior (which can be shocking to MATLAB programmers...)
865865866866```{code-cell} python3
867-a = np.random.randn(3)
867+rng = np.random.default_rng()
868+a = rng.standard_normal(3)
868869a
869870```
870871@@ -894,7 +895,7 @@ It is of course possible to make `b` an independent copy of `a` when required.
894895This can be done using `np.copy`
895896896897```{code-cell} python3
897-a = np.random.randn(3)
898+a = rng.standard_normal(3)
898899a
899900```
900901@@ -972,7 +973,7 @@ def f(x):
972973The NumPy function `np.where` provides a vectorized alternative:
973974974975```{code-cell} python3
975-x = np.random.randn(4)
976+x = rng.standard_normal(4)
976977x
977978```
978979@@ -1049,11 +1050,12 @@ z[z > 3]
10491050NumPy provides some additional functionality related to scientific programming
10501051through its sub-packages.
105110521052-We've already seen how we can generate random variables using np.random
1053+We've already seen how we can generate random variables using NumPy's
1054+[random `Generator`](https://numpy.org/doc/stable/reference/random/generator.html#random-generator).
1053105510541056```{code-cell} python3
1055-z = np.random.randn(10000) # Generate standard normals
1056-y = np.random.binomial(10, 0.5, size=1000) # 1,000 draws from Bin(10, 0.5)
1057+z = rng.standard_normal(10000) # Generate standard normals
1058+y = rng.binomial(10, 0.5, size=1000) # 1,000 draws from Bin(10, 0.5)
10571059y.mean()
10581060```
10591061@@ -1099,7 +1101,7 @@ It takes a few seconds to run.
10991101n = 20
11001102m = 1000
11011103for i in range(n):
1102- X = np.random.randn(m, m)
1104+ X = rng.standard_normal((m, m))
11031105 λ = np.linalg.eigvals(X)
11041106```
11051107@@ -1240,28 +1242,28 @@ Here's our first pass at a solution:
1240124212411243```{code-cell} python3
12421244from numpy import cumsum
1243-from numpy.random import uniform
1244124512451246class DiscreteRV:
12461247 """
12471248 Generates an array of draws from a discrete random variable with vector of
12481249 probabilities given by q.
12491250 """
125012511251- def __init__(self, q):
1252+ def __init__(self, q, seed=None):
12521253 """
12531254 The argument q is a NumPy array, or array like, nonnegative and sums
12541255 to 1
12551256 """
12561257 self.q = q
12571258 self.Q = cumsum(q)
1259+ self.rng = np.random.default_rng(seed)
1258126012591261 def draw(self, k=1):
12601262 """
12611263 Returns k draws from q. For each such draw, the value i is returned
12621264 with probability q[i].
12631265 """
1264- return self.Q.searchsorted(uniform(0, 1, size=k))
1266+ return self.Q.searchsorted(self.rng.uniform(0, 1, size=k))
12651267```
1266126812671269The logic is not obvious, but if you take your time and read it slowly,
@@ -1390,7 +1392,8 @@ Here's an example of usage
1390139213911393```{code-cell} python3
13921394fig, ax = plt.subplots()
1393-X = np.random.randn(1000)
1395+rng = np.random.default_rng()
1396+X = rng.standard_normal(1000)
13941397F = ECDF(X)
13951398F.plot(ax)
13961399```
@@ -1411,9 +1414,9 @@ In this exercise, try to use `for` loops to replicate the result of the followin
1411141414121415```{code-cell} python3
141314161414-np.random.seed(123)
1415-x = np.random.randn(4, 4)
1416-y = np.random.randn(4)
1417+rng = np.random.default_rng(123)
1418+x = rng.standard_normal((4, 4))
1419+y = rng.standard_normal(4)
14171420A = x / y
14181421```
14191422@@ -1441,9 +1444,9 @@ Now we can import the quantecon package.
1441144414421445```{code-cell} python3
144314461444-np.random.seed(123)
1445-x = np.random.randn(1000, 100, 100)
1446-y = np.random.randn(100)
1447+rng = np.random.default_rng(123)
1448+x = rng.standard_normal((1000, 100, 100))
1449+y = rng.standard_normal(100)
1447145014481451with qe.Timer("Broadcasting operation"):
14491452 B = x / y
@@ -1469,9 +1472,9 @@ print(B)
14691472**Part 1 Solution**
1470147314711474```{code-cell} python3
1472-np.random.seed(123)
1473-x = np.random.randn(4, 4)
1474-y = np.random.randn(4)
1475+rng = np.random.default_rng(123)
1476+x = rng.standard_normal((4, 4))
1477+y = rng.standard_normal(4)
1475147814761479C = np.empty_like(x)
14771480n = len(x)
@@ -1500,9 +1503,9 @@ print(np.array_equal(A, C))
1500150315011504```{code-cell} python3
150215051503-np.random.seed(123)
1504-x = np.random.randn(1000, 100, 100)
1505-y = np.random.randn(100)
1506+rng = np.random.default_rng(123)
1507+x = rng.standard_normal((1000, 100, 100))
1508+y = rng.standard_normal(100)
1506150915071510with qe.Timer("For loop operation"):
15081511 D = np.empty_like(x)