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.
 
     
    