You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Update to julia by examples to make 1.7 oriented and fix plotting
* Added 1.7 material for the essentials
* Updates on style guides
* Added additional kwarg trick
* Cleanup on geometric series
Co-authored-by: James Yu <[email protected]>
We can explore taking expectations over this distribution
@@ -367,22 +369,22 @@ One approach to solving the model is to directly implement this sort of iteratio
367
369
between successive iterates is below tol
368
370
369
371
```{code-cell} julia
370
-
function compute_reservation_wage_direct(params; v_iv = collect(w ./(1-β)), max_iter = 500,
371
-
tol = 1e-6)
372
+
function compute_reservation_wage_direct(params; v_iv = collect(w ./(1-β)),
373
+
max_iter = 500, tol = 1e-6)
372
374
(;c, β, w) = params
373
375
374
376
# create a closure for the T operator
375
377
T(v) = max.(w/(1 - β), c + β * E*v) # (5) fixing the parameter values
376
378
377
-
v = copy(v_iv) # start at initial value. copy to prevent v_iv modification
379
+
v = copy(v_iv) # copy to prevent v_iv modification
378
380
v_next = similar(v)
379
381
i = 0
380
382
error = Inf
381
383
while i < max_iter && error > tol
382
384
v_next .= T(v) # (4)
383
385
error = norm(v_next - v)
384
386
i += 1
385
-
v .= v_next # copy contents into v. Also could have used v[:] = v_next
387
+
v .= v_next # copy contents into v
386
388
end
387
389
# now compute the reservation wage
388
390
return (1 - β) * (c + β * E*v) # (2)
@@ -406,17 +408,22 @@ As usual, we are better off using a package, which may give a better algorithm a
406
408
In this case, we can use the `fixedpoint` algorithm discussed in {doc}`our Julia by Example lecture <../getting_started_julia/julia_by_example>` to find the fixed point of the $T$ operator. Note that below we set the parameter `m=1` for Anderson iteration rather than leaving as the default value - which fails to converge in this case. This is still almost 10x faster than the `m=0` case, which corresponds to naive fixed-point iteration.
407
409
408
410
```{code-cell} julia
409
-
function compute_reservation_wage(params; v_iv = collect(w ./(1-β)), iterations = 500,
410
-
ftol = 1e-6, m = 6)
411
+
function compute_reservation_wage(params; v_iv = collect(w ./(1-β)),
412
+
iterations = 500, ftol = 1e-6, m = 1)
411
413
(;c, β, w) = params
412
414
T(v) = max.(w/(1 - β), c + β * E*v) # (5) fixing the parameter values
sol = fixedpoint(T, v_iv; iterations, ftol, m) # (5)
417
+
sol.f_converged || error("Failed to converge")
418
+
v_star = sol.zero
416
419
return (1 - β) * (c + β * E*v_star) # (3)
417
420
end
418
421
```
419
422
423
+
Note that this checks the convergence (i.e, the `sol.f_converged`) from the fixedpoint iteration and throws an error if it fails.
424
+
425
+
This coding pattern, where `expression || error("failure)` first checks the expression is true and then moves to the right hand side of the `||` or operator if it is false, is a common pattern in Julia.
426
+
420
427
Let's compute the reservation wage at the default parameters
421
428
422
429
```{code-cell} julia
@@ -430,8 +437,8 @@ compute_reservation_wage(mcm()) # call with default parameters
Note the above is setting the `m` parameter to `0` to use naive fixed-point iteration. This is because the Anderson iteration fails to converge in a 2 of the 25^2 cases.
468
+
469
+
This demonstrates care must be used with advanced algorithms, and checking the return type (i.e., the `sol.f_converged` field) is important.
@@ -999,6 +1033,15 @@ paramgen = @with_kw (α = 0.1, β = 0.2) # create named tuples with defaults
999
1033
@show paramgen(α = 0.2, β = 0.5);
1000
1034
```
1001
1035
1036
+
Or create a function which returns the named tuple with defaults, which can also do intermediate calculations
1037
+
```{code-cell} julia
1038
+
function paramgen2(;α = 0.1, β = 0.2)
1039
+
return (;α, β)
1040
+
end
1041
+
@show paramgen2()
1042
+
@show paramgen2(;α = 0.2)
1043
+
```
1044
+
1002
1045
An alternative approach, defining a new type using `struct` tends to be more prone to accidental misuse, and leads to a great deal of boilerplate code.
1003
1046
1004
1047
For that, and other reasons of generality, we will use named tuples for collections of parameters where possible.
Now why would we emphasize naming and style as a crucial part of the lectures?
678
677
@@ -693,6 +692,9 @@ Some helpful ways to think about this are
693
692
For example, if you change notation in your model, then immediately update
694
693
all variables in the code to reflect it.
695
694
695
+
696
+
While variable naming takes discipline, code formatting for a specific style guide can be automated using [JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl) which is built into the Julia VS Code extension.
697
+
696
698
#### Commenting Code
697
699
698
700
One common mistake people make when trying to apply these goals is to add in a large number of comments.
0 commit comments