Root Finding¶
Root finding means finding the zero of a function, i.e., find \(x^*\) such that \(f(x^*) = 0\).
For this type of problem, we use code packaged into reusable libraries, called "packages". See the Section on Packages.
In this case, we will use Roots.jl.
Before we can use Roots
, we need to add it as a dependency to the current environment:
julia> cd("/Users/lutz/Documents/data/web/professional/docs/econ890/julia/")
(@v1.5) pkg> activate .
Activating new environment at `~/Documents/data/web/professional/docs/econ890/julia/Project.toml`
We have now activated the environment described by Project.toml
in this directory.
To get the Pkg
commands to work, type ]
and the pkg>
prompt appears. Backspace backs out of the Pkg
mode in the REPL.
To see which packages are already contained in the enviroment:
(julia) pkg> st
Status `~/Documents/data/web/professional/docs/econ890/julia/Project.toml` (empty project)
This makes sense; we have not added any packages yet. But keep in mind that everything we activated before (including all packages in your v1.5
environment are still available). Let's add Roots
:
(julia) pkg> add Roots
Updating registry at `~/.julia/registries/General`
######################################################################## 100.0%
Updating registry at `~/.julia/registries/registryLH`
Updating git-repo `https://github.com/hendri54/registryLH`
Resolving package versions...
Updating `~/Documents/data/web/professional/docs/econ890/julia/Project.toml`
[f2b01f46] + Roots v1.0.8
Updating `~/Documents/data/web/professional/docs/econ890/julia/Manifest.toml`
[f2b01f46] + Roots v1.0.8
[de0858da] + Printf
[4ec0a83e] + Unicode
(julia) pkg> st
Status `~/Documents/data/web/professional/docs/econ890/julia/Project.toml`
[f2b01f46] Roots v1.0.8
Now using Roots
works.
Roots
is a registered package, so it can be installed with pkg> add Roots
. The package manager looks up where to find the files for Roots
in the General Registry and downloads them.
The code for Roots
now resides in a subdirectory of .julia/packages
. Each version of Roots
gets its own subdirectory. So you can have several versions installed at the same time.
But: Only one version of a package can be loaded at any given time. This can lead to interesting problems...
Note that all of the dependencies of Roots
were also installed automatically (in this case, Printf
and Unicode
).
Now we can use all functions that were exported by Roots.jl
. For example:
help?> find_zero
search: find_zero find_zeros find_zero!
find_zero(fs, x0, M, [N::AbstractBracketing]; kwargs...)
Interface to one of several methods for find zeros of a univariate function.
[...]
julia> f(x) = exp(x) - x^4;
julia> find_zero(f, (8, 9), Bisection())
8.6131694564414
Closures¶
We encounter a common problem: find_zero
expects a one-argument function f(x)
. But the function that we use takes 2 arguments: a model and \(c_T\). This type of problem is solved using a closure.
A closure is a function that "captures" some of the variables in the calling namespace. Example:
julia> function foo()
x = 1;
g(y) = x + y;
@show g(2)
x = 2;
@show g(2)
end
foo (generic function with 1 method)
julia> foo()
g(2) = 3
g(2) = 4
Note that g
has "captured" the variable x
from foo
. g
behaves as if there were an implicit second argument.
Anonymous functions¶
When closures are used, they often remain unnamed. Example:
julia> findfirst(x -> x > 2, 1:10)
3
# This is the same as
julia> f(x) = x > 2;
julia> findfirst(f, 1:10)
3
But note:
julia> [x -> x^2 for x in (1,2,3)]
3-element Array{var"#9#11",1}:
#9 (generic function with 1 method)
#9 (generic function with 1 method)
#9 (generic function with 1 method)