I need to speed up this recursive system. Can anyone help?
I annotated all variables and only used Float64-consistent functions. I also tried using memoization (since the system is recursive) via Memoize.jl, but I have to compute U, V and Z thousands of times in an optimization algorithm and my computer quickly runs out of memory.
const Tage = 60.0
const initT = 1975.0
const Ttime = 1990.0
const K = 6.0
const β = 0.95
const s = 0.5
θ0 = [
0.0011
-0.0045
-0.0075
-0.0013
3.60
0.2587
-0.0026
-0.0528
0.0060
1.3772
0.2932
-0.0030
0.0021
0.0044
10.2593
0.7498
1.1765
]./10000
function wagem(t::Float64, agem::Float64, edum::Float64, θ::Vector{Float64})
θ[5] + θ[6]*agem + θ[7]*agem^2 + θ[8]*edum + θ[9]*edum^2
end
function wagef(t::Float64, agef::Float64, eduf::Float64, θ::Vector{Float64})
θ[10] + θ[11]*agef + θ[12]*agef^2 + θ[13]*eduf + θ[14]*eduf^2
end
function ζ(agem::Float64, edum::Float64, agef::Float64, eduf::Float64, θ::Vector{Float64})
θ[1]*agem*agef + θ[2]*agem*eduf + θ[3]*edum*agef + θ[4]*edum*eduf
end
function z(t::Float64, agem::Float64, edum::Float64, agef::Float64, eduf::Float64, θ::Vector{Float64})
ζ(agem, edum, agef, eduf, θ) + wagem(t, agem, edum, θ) + wagef(t, agef, eduf, θ)
end
function dc(θ::Vector{Float64})
ret::Float64 = 0.0
ret = θ[15]
return ret
end
function Z(t::Float64, agem::Float64, edum::Float64, agef::Float64, eduf::Float64, θ::Vector{Float64})
ret::Float64 = 0.0
if agem >= Tage || agef >= Tage # terminal age conditions
ret = 0.0
elseif t >= Ttime # terminal time condition
ret = 1.5
else
ret = log(
exp(z(t, agem, edum, agef, eduf, θ) + β*Z(t+1, agem+1, edum, agef+1, eduf, θ))
+ exp(-dc(θ) + β*(V(t+1, agem+1, edum, θ) + U(t+1, agef+1, eduf, θ)))
)
end
return ret
end
function V(t::Float64, agem::Float64, edum::Float64, θ::Vector{Float64})
ret::Float64 = 0.0
if agem >= Tage
ret = 0.0
elseif t >= Ttime
ret = 1.5
else
suma::Float64 = 0.0
for agef in 16.0:Tage-1, eduf in 1.0:K
suma += exp(s*z(t, agem, edum, agef, eduf, θ) + wagem(t, agem, edum, θ) + β*(s*(Z(t+1, agem+1, edum, agef+1, eduf, θ) - V(t+1, agem+1, edum, θ) - U(t+1, agef+1, eduf, θ)) + V(t+1, agem+1, edum, θ)))
end
ret = log(
exp(wagem(t, agem, edum, θ) + β*(V(t+1, agem+1, edum, θ))) + suma
)
end
return ret
end
function U(t::Float64, agef::Float64, eduf::Float64, θ::Vector{Float64})
ret::Float64 = 0.0
if agef >= Tage
ret = 0.0
elseif t >= Ttime
ret = 1.5
else
suma::Float64 = 0.0
for agem in 16.0:Tage-1, edum in 1.0:K
suma += exp((1-s)*z(t, agem, edum, agef, eduf, θ) + wagef(t, agef, eduf, θ) + β*((1-s)*(Z(t+1, agem+1, edum, agef+1, eduf, θ) - V(t+1, agem+1, edum, θ) - U(t+1, agef+1, eduf, θ)) + U(t+1, agef+1, eduf, θ)))
end
ret = log(
exp(wagef(t, agef, eduf, θ) + β*(U(t+1, agef+1, eduf, θ))) + suma
)
end
return ret
end
I want to be able to compute things like U(1984.0, 17.0, 3.0, θ0) or V(1975.0, 16.0, 1.0, θ0) very quickly.
Any help would be appreciated.