Skip to content

Commit

Permalink
Improve speed of simulations (#18)
Browse files Browse the repository at this point in the history
* Improve speed of simulations

* Some more improvements

* Update search_and_matching_credit.jl

* Update search_and_matching.jl

* Update BeforeIT.jl

* Update search_and_matching.jl
  • Loading branch information
Tortar authored Nov 1, 2024
1 parent b2a0adc commit eb8d22e
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 72 deletions.
1 change: 1 addition & 0 deletions src/BeforeIT.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module BeforeIT

using LinearAlgebra
using Random
using StatsBase
import Base: length
Expand Down
128 changes: 57 additions & 71 deletions src/markets/search_and_matching.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,22 @@ function update_aggregate_variables!(
gov.P_j = sum(P_j_g)
rotw.P_l = sum(P_l_g)

P_CF_i[I_i .> 0] .= P_CF_i[I_i .> 0] ./ I_i[I_i .> 0]
P_bar_i[DM_i .> 0] .= P_bar_i[DM_i .> 0] ./ DM_i[DM_i .> 0]
P_CF_i[I_i .> 0] .= @view(P_CF_i[I_i .> 0]) ./ @view(I_i[I_i .> 0])
P_bar_i[DM_i .> 0] .= @view(P_bar_i[DM_i .> 0]) ./ @view(DM_i[DM_i .> 0])

agg.P_bar_h = sum(C_h) / agg.P_bar_h
agg.P_bar_CF_h = sum(I_h) / agg.P_bar_CF_h
gov.P_j = gov.C_j / gov.P_j
rotw.P_l = rotw.C_l / rotw.P_l

w_act.C_h .= C_h[1:H_W]
w_inact.C_h .= C_h[(H_W + 1):(H_W + H_inact)]
firms.C_h .= C_h[(H_W + H_inact + 1):(H_W + H_inact + I)]
w_act.C_h .= @view(C_h[1:H_W])
w_inact.C_h .= @view(C_h[(H_W + 1):(H_W + H_inact)])
firms.C_h .= @view(C_h[(H_W + H_inact + 1):(H_W + H_inact + I)])
bank.C_h = C_h[H]

w_act.I_h .= I_h[1:H_W]
w_inact.I_h .= I_h[(H_W + 1):(H_W + H_inact)]
firms.I_h .= I_h[(H_W + H_inact + 1):(H_W + H_inact + I)]
w_act.I_h .= @view(I_h[1:H_W])
w_inact.I_h .= @view(I_h[(H_W + 1):(H_W + H_inact)])
firms.I_h .= @view(I_h[(H_W + H_inact + 1):(H_W + H_inact + I)])
bank.I_h = I_h[H]

rotw.Q_d_m .= Q_d_m
Expand Down Expand Up @@ -345,31 +345,30 @@ function perform_firms_market!(
##############################
######## FIRMS MARKET ########
##############################

DM_d_ig = a_sg[g, firms.G_i] .* firms.DM_d_i + b_CF_g[g] .* firms.I_d_i
DM_d_ig = @view(a_sg[g, firms.G_i]) .* firms.DM_d_i + b_CF_g[g] .* firms.I_d_i
DM_nominal_ig = zeros(size(DM_d_ig))

# firms that have demand for good "g" participate as buyers
I_g = findall(DM_d_ig .> 0)

# remove firms that have no stock of good "g"
#F_g[S_fg[F_g] .<= 0] .= []
to_delete = findall(S_fg[F_g] .<= 0)
to_delete = findall(@view(S_fg[F_g]) .<= 0)
deleteat!(F_g, to_delete)

# continue exchanges until either demand or supply terminates

while length(I_g) != 0 && length(F_g) != 0

# price probability of being selected
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))

# size probability of being selected
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
# total probabilities of being selected
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))

# total probabilities of being selected
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)
#pr_cum_f = [0; cumsum(pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)]

# select buyers at random
shuffle!(I_g)
Expand All @@ -378,47 +377,40 @@ function perform_firms_market!(

# select a random firm according to the probabilities
e = wsample(1:length(F_g), pr_cum_f_)
#e = randf(pr_cum_f)
f = F_g[e]

# selected firm has sufficient stock
if S_fg[f] > DM_d_ig[i]
S_fg[f] -= DM_d_ig[i]
DM_nominal_ig[i] += DM_d_ig[i] .* P_f[f]
DM_nominal_ig[i] += DM_d_ig[i] .* @view(P_f[f])
DM_d_ig[i] = 0

else
DM_d_ig[i] -= S_fg[f]
DM_nominal_ig[i] += S_fg[f] .* P_f[f]
DM_nominal_ig[i] += @view(S_fg[f]) .* @view(P_f[f])
S_fg[f] = 0
F_g = deleteat!(F_g, e)

if isempty(F_g)
break
end
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
deleteat!(F_g, e)
isempty(F_g) && break
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)
end
end
I_g = findall(DM_d_ig .> 0)
end


if !isempty(I_g)
DM_d_ig_ = copy(DM_d_ig)
I_g = findall(DM_d_ig_ .> 0)
F_g = findall(G_f .== g)

to_delete = findall((S_fg_[F_g] .<= 0.0) .|| (S_f[F_g] .<= 0.0))
to_delete = findall((@view(S_fg_[F_g]) .<= 0.0) .|| (@view(S_f[F_g]) .<= 0.0))
deleteat!(F_g, to_delete)

while !isempty(I_g) && !isempty(F_g)
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)

# I_g = I_g[randperm(length(I_g))]
shuffle!(I_g)
for j in eachindex(I_g)
i = I_g[j]
Expand All @@ -435,30 +427,28 @@ function perform_firms_market!(
S_fg[f] -= S_fg_[f]
S_fg_[f] = 0
deleteat!(F_g, e)
if isempty(F_g)
break
end
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
isempty(F_g) && break
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)
end
end
I_g = findall(DM_d_ig_ .> 0)
end
end

DM_i_g[g, :] .= a_sg[g, firms.G_i] .* firms.DM_d_i .- pos(DM_d_ig .- b_CF_g[g] .* firms.I_d_i)
DM_i_g[g, :] .= @view(a_sg[g, firms.G_i]) .* firms.DM_d_i .- pos(DM_d_ig .- b_CF_g[g] .* firms.I_d_i)

I_i_g[g, :] .= pos(b_CF_g[g] .* firms.I_d_i .- DM_d_ig)

P_bar_i_g[g, :] .= pos(
DM_nominal_ig .* (a_sg[g, firms.G_i] .* firms.DM_d_i .- pos(DM_d_ig .- b_CF_g[g] .* firms.I_d_i)) ./
(a_sg[g, firms.G_i] .* firms.DM_d_i .+ b_CF_g[g] .* firms.I_d_i .- DM_d_ig),
DM_nominal_ig .* (@view(a_sg[g, firms.G_i]) .* firms.DM_d_i .- pos(DM_d_ig .- b_CF_g[g] .* firms.I_d_i)) ./
(@view(a_sg[g, firms.G_i]) .* firms.DM_d_i .+ b_CF_g[g] .* firms.I_d_i .- DM_d_ig),
)

P_CF_i_g[g, :] .= pos(
DM_nominal_ig .* pos(b_CF_g[g] .* firms.I_d_i .- DM_d_ig) ./
(a_sg[g, firms.G_i] .* firms.DM_d_i .+ b_CF_g[g] .* firms.I_d_i .- DM_d_ig),
(@view(a_sg[g, firms.G_i]) .* firms.DM_d_i .+ b_CF_g[g] .* firms.I_d_i .- DM_d_ig),
)

end
Expand Down Expand Up @@ -508,13 +498,13 @@ function perform_retail_market!(
C_real_hg = zeros(size(C_d_hg))
H_g = findall(C_d_hg .> 0.0)

to_delete = findall(S_fg[F_g] .<= 0)
to_delete = findall(@view(S_fg[F_g]) .<= 0)
deleteat!(F_g, to_delete)


while !isempty(H_g) && !isempty(F_g)
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)

shuffle!(H_g)
Expand All @@ -532,12 +522,10 @@ function perform_retail_market!(
C_d_hg[h] -= S_fg[f] * P_f[f]
C_real_hg[h] += S_fg[f]
S_fg[f] = 0
F_g = F_g[setdiff(1:end, e)]
if isempty(F_g)
break
end
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
deleteat!(F_g, e)
isempty(F_g) && break
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)
end
end
Expand All @@ -548,10 +536,10 @@ function perform_retail_market!(
C_d_hg_ = copy(C_d_hg)
H_g = findall(C_d_hg_ .> 0)
F_g = findall(G_f .== g)
F_g = F_g[(S_fg_[F_g] .> 0) .& (S_f[F_g] .> 0)]
F_g = F_g[(@view(S_fg_[F_g]) .> 0) .& (@view(S_f[F_g]) .> 0)]
while !isempty(H_g) && !isempty(F_g)
pr_price_f = pos(exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
pr_price_f = pos(exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)

H_g = shuffle(H_g)
Expand All @@ -568,13 +556,11 @@ function perform_retail_market!(
C_d_hg_[h] -= S_fg_[f] * P_f[f]
S_fg[f] -= S_fg_[f]
S_fg_[f] = 0
F_g = deleteat!(F_g, e)
if isempty(F_g)
break
end
pr_price_f = max.(0, exp.(-2 .* P_f[F_g]) ./ sum(exp.(-2 .* P_f[F_g])))
deleteat!(F_g, e)
isempty(F_g) && break
pr_price_f = max.(0, exp.(-2 .* @view(P_f[F_g])) ./ sum(exp.(-2 .* @view(P_f[F_g]))))
pr_price_f[isnan.(pr_price_f)] .= 0.0
pr_size_f = S_f[F_g] ./ sum(S_f[F_g])
pr_size_f = @view(S_f[F_g]) ./ sum(@view(S_f[F_g]))
pr_cum_f_ = (pr_price_f + pr_size_f) ./ sum(pr_price_f + pr_size_f)

end
Expand All @@ -583,27 +569,27 @@ function perform_retail_market!(
end
end

Q_d_i_g[g, :] .= S_f[1:I] .- S_fg[1:I]
Q_d_m_g[g, :] .= S_f[(I + 1):end] .- S_fg[(I + 1):end]
Q_d_i_g[g, :] .= @view(S_f[1:I]) .- @view(S_fg[1:I])
Q_d_m_g[g, :] .= @view(S_f[(I + 1):end]) .- @view(S_fg[(I + 1):end])

C_h_g[g, :] .= b_HH_g[g] .* C_d_h .- pos(C_d_hg[1:H] .- b_CFH_g[g] .* I_d_h)
I_h_g[g, :] .= pos(b_CFH_g[g] .* I_d_h .- view(C_d_hg, 1:H)) #I_h_g[g, :] .= pos(b_CFH_g[g] .* I_d_h .- C_d_hg[1:H])
C_h_g[g, :] .= b_HH_g[g] .* C_d_h .- pos(@view(C_d_hg[1:H]) .- b_CFH_g[g] .* I_d_h)
I_h_g[g, :] .= pos(b_CFH_g[g] .* I_d_h .- @view(C_d_hg[1:H]))

C_j_g[g] = sum(c_G_g[g] .* gov.C_d_j) - sum(C_d_hg[(H + L + 1):(H + L + J)])
C_l_g[g] = sum(c_E_g[g] .* rotw.C_d_l) - sum(C_d_hg[(H + 1):(H + L)])
C_j_g[g] = sum(c_G_g[g] .* gov.C_d_j) - sum(@view(C_d_hg[(H + L + 1):(H + L + J)]))
C_l_g[g] = sum(c_E_g[g] .* rotw.C_d_l) - sum(@view(C_d_hg[(H + 1):(H + L)]))

a = sum(C_real_hg[1:H])
b = sum(C_d_h .* b_HH_g[g] .- pos(view(C_d_hg, 1:H) .- b_CFH_g[g] .* I_d_h)) # b = sum(C_d_h .* b_HH_g[g] .- pos(C_d_hg[1:H] .- b_CFH_g[g] .* I_d_h)) # OLD
c = sum((C_d_h .* b_HH_g[g] .+ b_CFH_g[g] .* I_d_h .- C_d_hg[1:H]))
a = sum(@view(C_real_hg[1:H]))
b = sum(C_d_h .* b_HH_g[g] .- pos(@view(C_d_hg[1:H]) .- b_CFH_g[g] .* I_d_h))
c = sum((C_d_h .* b_HH_g[g] .+ b_CFH_g[g] .* I_d_h .- @view(C_d_hg[1:H])))

P_bar_h_g[g] = pos(a * b / c)

P_bar_CF_h_g[g] = pos(
sum(C_real_hg[1:H]) * sum(pos(b_CFH_g[g] .* I_d_h .- C_d_hg[1:H])) /
sum((C_d_h .* b_HH_g[g] .+ b_CFH_g[g] .* I_d_h .- C_d_hg[1:H])),
sum(@view(C_real_hg[1:H])) * sum(pos(b_CFH_g[g] .* I_d_h .- @view(C_d_hg[1:H]))) /
sum((C_d_h .* b_HH_g[g] .+ b_CFH_g[g] .* I_d_h .- @view(C_d_hg[1:H]))),
)

P_j_g[g] = sum(C_real_hg[(H + L + 1):(H + L + J)])
P_l_g[g] = sum(C_real_hg[(H + 1):(H + L)])
P_j_g[g] = sum(@view(C_real_hg[(H + L + 1):(H + L + J)]))
P_l_g[g] = sum(@view(C_real_hg[(H + 1):(H + L)]))

end
2 changes: 1 addition & 1 deletion src/markets/search_and_matching_credit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function search_and_matching_credit(firms::AbstractFirms, model)
shuffle!(I_FG)
for f in eachindex(I_FG)
i = I_FG[f]
DL_i[i] = max(0, min(min(DL_d_i[i], zeta_LTV * K_e_i[i] - L_e_i[i]), E_k / zeta - sum(L_e_i .+ DL_i)))
DL_i[i] = max(0, min(min(DL_d_i[i], zeta_LTV * K_e_i[i] - L_e_i[i]), E_k / zeta - (sum(L_e_i) + sum(DL_i))))
end
return DL_i
end

0 comments on commit eb8d22e

Please sign in to comment.