Skip to content

Instantly share code, notes, and snippets.

@tyleransom
Last active June 22, 2018 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tyleransom/3549a1f9156591491f649ec37f3d29e7 to your computer and use it in GitHub Desktop.
Save tyleransom/3549a1f9156591491f649ec37f3d29e7 to your computer and use it in GitHub Desktop.
Optimize memory usage in Julia
using Optim, NLSolversBase
function datagen(n=5500,k=13)
b = rand(k)
l = rand(2)
x = randn(n,k)
abil = randn(n,1)
vabil = randn(n,1)
sector = 1.0.*(rand(n,1).>0.8)
weight = rand(n,1)
y = l[1] .+ l[2].*(x*b .+ abil .+ vabil.^2)
return y,x,abil,vabil,sector,weight
end
# Objective function A
function wolslambdaNoAssignCorrFusion(b::Vector,y::Array,x::Array,abil::Array,vabil::Array,sector::Array,weight::Array)
# λ0 = b[end-1]
# λ1 = b[end]
# β = b[1:end-2]
# sector=1 corresponds to subset of observations that get hit by lambda
# sector=0 corresponds to all other observations
if ~isequal(size(y),size(sector))
error("sector variable is wrong")
end
SSE = sum(weight.*(vabil.*(((sector.==0).*1).+((sector.==1).*b[end-1])).^2 .+ (y.-((sector.==0).*0).-((sector.==1).*b[end-1]).-(((sector.==0).*1).+((sector.==1).*b[end])).*(x*b[1:end-2].+abil)).^2))
return SSE
end
# Objective function B
function wolslambdaNoAssign(b::Vector,y::Array,x::Array,abil::Array,vabil::Array,sector::Array,weight::Array)
# λ0 = b[end-1]
# λ1 = b[end]
# β = b[1:end-2]
# sector=1 corresponds to subset of observations that get hit by lambda
# sector=0 corresponds to all other observations
if ~isequal(size(y),size(sector))
error("sector variable is wrong")
end
SSE = sum(weight.*(vabil.*(((sector.==0)*1).+((sector.==1)*b[end-1])).^2 .+ (y.-((sector.==0)*0).-((sector.==1)*b[end-1]).-(((sector.==0)*1).+((sector.==1)*b[end])).*(x*b[1:end-2].+abil)).^2))
return SSE
end
# Objective function C
function wolslambda(b::Vector,y::Array,x::Array,abil::Array,vabil::Array,sector::Array,weight::Array)
λ0 = b[end-1]
λ1 = b[end]
β = b[1:end-2]
# sector=1 corresponds to subset of observations that get hit by lambda
# sector=0 corresponds to all other observations
if ~isequal(size(y),size(sector))
error("sector variable is wrong")
end
SSE = sum(weight.*(vabil.*(((sector.==0)*1).+((sector.==1)*λ1)).^2 .+ (y.-((sector.==0)*0).-((sector.==1)*λ0).-(((sector.==0)*1).+((sector.==1)*λ1)).*(x*β.+abil)).^2))
return SSE
end
# Objective function D
function wolslambdaNoAssignLooping(b::Vector,y::Array,x::Array,abil::Array,vabil::Array,sector::Array,weight::Array)
# λ0 = b[end-1]
# λ1 = b[end]
# β = b[1:end-2]
# sector=1 corresponds to subset of observations that get hit by lambda
# sector=0 corresponds to all other observations
if ~isequal(size(y),size(sector))
error("sector variable is wrong")
end
SSE = 0.0
for i=1:size(y,1)
SSE+=weight[i]*(vabil[i]*(((sector[i]==0)*1)+((sector[i]==1)*b[end-1]))^2 + (y[i]-((sector[i]==0)*0)-((sector[i]==1)*b[end-1])-(((sector[i]==0)*1)+((sector[i]==1)*b[end]))*(dot(x[i,:],b[1:end-2])+abil[i]))^2)
end
return SSE
end
# data (arrays):
wageg,xg,abilg,vabilg,gflg,qg = datagen()
bstartg = rand(size(xg,2))
lambdag0start = 0.5
lambdag1start = 0.75
# starting value
x0 = vec([bstartg;lambdag0start;lambdag1start])
fung = TwiceDifferentiable((arg)->wolslambda(arg,wageg,xg,abilg,vabilg,gflg,qg), x0; autodiff = :forward);
println("\n original")
@time res = optimize(fung, x0, LBFGS(), Optim.Options(show_trace=false,iterations=100_000,g_tol=1e-6,f_tol=1e-20))
println(res.minimizer)
fung = TwiceDifferentiable((arg)->wolslambdaNoAssign(arg,wageg,xg,abilg,vabilg,gflg,qg), x0; autodiff = :forward);
println("\n get rid of mutliple copying")
@time res = optimize(fung, x0, LBFGS(), Optim.Options(show_trace=false,iterations=100_000,g_tol=1e-6,f_tol=1e-20))
println(res.minimizer)
fung = TwiceDifferentiable((arg)->wolslambdaNoAssignCorrFusion(arg,wageg,xg,abilg,vabilg,gflg,qg), x0; autodiff = :forward);
println("\n get rid of multiple copying and use correct fusion operators")
@time res = optimize(fung, x0, LBFGS(), Optim.Options(show_trace=false,iterations=100_000,g_tol=1e-6,f_tol=1e-20))
println(res.minimizer)
fung = TwiceDifferentiable((arg)->wolslambdaNoAssignLooping(arg,wageg,xg,abilg,vabilg,gflg,qg), x0; autodiff = :forward);
println("\n loop over observations")
@time res = optimize(fung, x0, LBFGS(), Optim.Options(show_trace=false,iterations=100_000,g_tol=1e-6,f_tol=1e-20))
println(res.minimizer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment