It's running too long

There are a number of performance issues here, first among them your use of global variables - see the Performance Tips section of the manual. You’ll need to either wrap the whole thing in a function (including your parameter definitions in the beginning), or pass the parameters as arguments to your functions. Parameters.jl helps with parameter-handling

When trying to tune performance, it’s best to trim down the problem as much as possible so you can iterate quickly - for example, replace for i in 1:50 with for i in 1:1, and reduce the length of your grids drastically. It helps to set the grid lengths using a variable so it only needs to be modified in one place, e.g. N = 1000; c_choice1 = zeros(N), k_choice1 = zeros(N), which can be quickly changed to N = 10. Once you have a functional ‘diet’ version of your code, you can use Julia’s profiling tools (mentioned in the Performance Tips) to find the slow spots. Pay special attention to memory allocation and type instability.

Try to avoid writing functions inside the inner loops of your code - this is sometimes necessary, but it’s often more ergonomic to move the function to the outermost level and pass any necessary data as function arguments.

You use this pattern several times:

function t1(x)                      
    w_func = LinearInterpolation(grid_b, w,extrapolation_bc=Line())
    return w_func(x)
end

Are you trying to create an interpolation and evaluate it at one point, or create a function that can be passed to the optimizer? In either case, you should only need to create the interpolator once (not once per function call!), e.g.

w_func = LinearInterpolation(grid_b, w,extrapolation_bc=Line())
t1 = x -> w_func(x)

You may also be able to use Interpolations.gradient to calculate the derivative, which will likely be faster than :autodiff.

6 Likes