GitHub

@@ -864,7 +864,8 @@ a

864864

Mutability 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)

868869

a

869870

```

870871

@@ -894,7 +895,7 @@ It is of course possible to make `b` an independent copy of `a` when required.

894895

This can be done using `np.copy`

895896896897

```{code-cell} python3

897-

a = np.random.randn(3)

898+

a = rng.standard_normal(3)

898899

a

899900

```

900901

@@ -972,7 +973,7 @@ def f(x):

972973

The NumPy function `np.where` provides a vectorized alternative:

973974974975

```{code-cell} python3

975-

x = np.random.randn(4)

976+

x = rng.standard_normal(4)

976977

x

977978

```

978979

@@ -1049,11 +1050,12 @@ z[z > 3]

10491050

NumPy provides some additional functionality related to scientific programming

10501051

through 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)

10571059

y.mean()

10581060

```

10591061

@@ -1099,7 +1101,7 @@ It takes a few seconds to run.

10991101

n = 20

11001102

m = 1000

11011103

for 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

12421244

from numpy import cumsum

1243-

from numpy.random import uniform

1244124512451246

class 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

```

1266126812671269

The 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

13921394

fig, ax = plt.subplots()

1393-

X = np.random.randn(1000)

1395+

rng = np.random.default_rng()

1396+

X = rng.standard_normal(1000)

13941397

F = ECDF(X)

13951398

F.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)

14171420

A = 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)

1447145014481451

with 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)

1475147814761479

C = np.empty_like(x)

14771480

n = 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)

1506150915071510

with qe.Timer("For loop operation"):

15081511

D = np.empty_like(x)

Read the original on github.com ↗