how do we represent the model?

use a vector (closest to numpy arrays)

  • homeogenous containers
[2,3,24.0] 
3-element Vector{Float64}:
  2.0
  3.0
 24.0
[3,23, "ji"] # avoid vectors of any type
3-element Vector{Any}:
  3
 23
   "ji"
model = [0.3, 0.96, 4, 0.1, 0.4]
5-element Vector{Float64}:
 0.3
 0.96
 4.0
 0.1
 0.4
# to access variables I need to remembeer the positions
I_alpha = 1
model[I_alpha] 
0.3
# a tuple 
# positional container that is immutable
model = (0.3, 0.96, 4, 0.1, 0.4)
(0.3, 0.96, 4, 0.1, 0.4)
model[1]
0.3
model[2] = 43
MethodError: MethodError: no method matching setindex!(::Tuple{Float64, Float64, Int64, Float64, Float64}, ::Int64, ::Int64)
The function `setindex!` exists, but no method is defined for this combination of argument types.
MethodError: no method matching setindex!(::Tuple{Float64, Float64, Int64, Float64, Float64}, ::Int64, ::Int64)

The function `setindex!` exists, but no method is defined for this combination of argument types.



Stacktrace:

 [1] top-level scope

   @ ~/Teaching/econobits/eco309/corrections/jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X12sZmlsZQ==.jl:1
numbers = [1.0, 2.0, 4.0, 8.0]
4-element Vector{Float64}:
 1.0
 2.0
 4.0
 8.0
[x^2 for x in numbers if x<5]
3-element Vector{Float64}:
  1.0
  4.0
 16.0
it = (x^2 for x in numbers)
Base.Generator{Vector{Float64}, var"#50#51"}(var"#50#51"(), [1.0, 2.0, 4.0, 8.0])
sum(it)
85.0
# tuples a more memory efficient than vectors
numbers = [1.0, 2.0, 4.0, 8.0]
function fun1(x, numbers)
    res = sum( (x^2 for x in numbers) )
    return res
end
fun1 (generic function with 2 methods)
@time fun1(2, numbers)
  0.000006 seconds (1 allocation: 16 bytes)
85.0
# tuples a more memory efficient than vectors
numbers = (1.0, 2.0, 4.0, 8.0)
function fun2(x, numbers)
    res = sum( (x^2 for x in numbers) )
    return res
end
fun2 (generic function with 1 method)
@time fun2(2, numbers)
  0.000007 seconds (1 allocation: 16 bytes)
85.0
# tuples share the same issues as vecotrs
# position sensitive
# a dictionary (list of pairs)

# d = Dict(
#     "α"=>0.3,
#     "β"=>0.96,
#     "γ"=>4.0,
#     "δ"=>0.1
# )

# d["α"]

# use small-strings (symbols) that are optimized

d = Dict(
    :α=>0.3,
    :β=>0.96,
    :γ=>4.0,
    :δ=>0.1
)

d[:α]
0.3
# idctionaries are not memory efficient
# they can grow, contain any kind of data...

define your own structure

struct Model{T}
    α::Float64
    β::Float64
    γ::Float64
    δ::Float64
end
# instantiate
m = Model(0.3, 0.96, 4.0, 0.1)
Model(0.3, 0.96, 4.0, 0.1)
sizeof(m)
32
# advantages
# - memorey efficeint
# - easy to acces fields

m.α
0.3
# problems:
# - still need to remember the positions when creating the object
#      # workaround @kwdef
# - can't change easily the structure definition

Namedtuples

m = (; α=0.3, β=0.97, γ=4.0, δ=0.1, s=0.2)   # ; is followed by keywords
(α = 0.3, β = 0.97, γ = 4.0, δ = 0.1, s = 0.2)
m[1] # behaves like a tuple (is memory efficient)
0.3
m.α
0.3
range(1,10 ;  length=100)
1.0:0.09090909090909091:10.0
# named unpacking

(;α, δ, s) = m
(α = 0.3, β = 0.97, γ = 4.0, δ = 0.1, s = 0.2)

Functions

#matlab-like

function  fun(a,b)
    x = (a+b)
    return x
end

function  fun(a)
    return fun(a,a)
end

# you can specialize based on argument types
# multiple dispatch
function  fun(a,b::String)
    if b=="double"
        return a*2
    elseif b=="triple"
        return a*3
    else
        throw(error("Unkonwn string"))
    end
end
fun (generic function with 3 methods)
fun([1,2], [3,4])
2-element Vector{Int64}:
 4
 6
fun(1,"hundred")
ErrorException: Unkonwn string
Unkonwn string



Stacktrace:

 [1] error(s::String)

   @ Base ./error.jl:44

 [2] fun(a::Int64, b::String)

   @ Main ~/Teaching/econobits/eco309/corrections/jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X52sZmlsZQ==.jl:19

 [3] top-level scope

   @ ~/Teaching/econobits/eco309/corrections/jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X53sZmlsZQ==.jl:1
function fun2(a,b; l=1.0)
    return a+b*l
end
fun2 (generic function with 1 method)
fun2(1,3; l=2)
7
# one liners (equivalent but shorter)
fun3(a,b;l=1.0) = a+b*l
fun3 (generic function with 1 method)
# anonymous 

(a,b)->a^b
#65 (generic function with 1 method)
((a,b)->a^b)(2.0, 2.0)
4.0
maximum(u->u^2, 1:10)
100

control flow

for el  1:10 # all values from 1 to 10 included
end
v = [3.0]
1-element Vector{Float64}:
 3.0
# grow a vector with push!
push!(v, 4.0)
2-element Vector{Float64}:
 3.0
 4.0