Skip to content

Commit 78e9c0d

Browse files
committed
Armington case for mobile labour.
1 parent 4e046f6 commit 78e9c0d

2 files changed

Lines changed: 85 additions & 2 deletions

File tree

src/main/optimal_network.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,13 @@ function optimal_network(param, graph; I0=nothing, Il=nothing, Iu=nothing, verbo
8787
recover_allocation = recover_allocation_fixed_cgc
8888
end
8989
elseif param.mobility == 1 && !param.cong
90-
model = model_mobility(optimizer, auxdata)
91-
recover_allocation = recover_allocation_mobility
90+
if all(sum(param.Zjn .> 0, dims = 2) .<= 1) # Armington case
91+
model = model_mobility_armington(optimizer, auxdata)
92+
recover_allocation = recover_allocation_mobility_armington
93+
else
94+
model = model_mobility(optimizer, auxdata)
95+
recover_allocation = recover_allocation_mobility
96+
end
9297
elseif param.mobility == 0.5 && !param.cong
9398
model = model_partial_mobility(optimizer, auxdata)
9499
recover_allocation = recover_allocation_partial_mobility
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# The primal case, with labor mobility, no cross-good congestion, and an Armington (1969) world where each location produces only one good
2+
3+
function model_mobility_armington(optimizer, auxdata)
4+
5+
# Parameters and data
6+
param = auxdata.param
7+
graph = auxdata.graph
8+
kappa_ex_init = auxdata.kappa_ex
9+
A = auxdata.edges.A
10+
Apos = auxdata.edges.Apos
11+
Aneg = auxdata.edges.Aneg
12+
psigma = (param.sigma - 1) / param.sigma
13+
Hj = param.Hj
14+
15+
# Model
16+
model = Model(optimizer)
17+
set_string_names_on_creation(model, false)
18+
19+
# Variables + bounds
20+
@variable(model, u, start = 0.0) # Overall utility
21+
@variable(model, Cjn[1:graph.J, 1:param.N] >= 1e-8, container=Array, start = 1e-6) # Good specific consumption
22+
@variable(model, Qin[1:graph.ndeg, 1:param.N], container=Array, start = 0.0) # Good specific flow
23+
@variable(model, 1e-8 <= Lj[1:graph.J] <= 1, container=Array, start = 1 / graph.J) # Total labour
24+
25+
# Parameters: to be updated between solves
26+
@variable(model, kappa_ex[i = 1:graph.ndeg] in Parameter(i), container=Array)
27+
set_parameter_value.(kappa_ex, kappa_ex_init)
28+
29+
# Objective
30+
@objective(model, Max, u)
31+
32+
# Utility constraint (Lj*u <= ... )
33+
for j in 1:graph.J
34+
Cj = sum(Cjn[j, n]^psigma for n in 1:param.N)^(1 / psigma)
35+
@constraint(model, Lj[j] * u - (Cj / param.alpha)^param.alpha * (Hj[j] / (1 - param.alpha))^(1 - param.alpha) <= -1e-8)
36+
end
37+
38+
# balanced flow constraints
39+
@expression(model, Yjn[j=1:graph.J, n=1:param.N], param.Zjn[j, n] * Lj[j]^param.a)
40+
@constraint(model, Pjn[j in 1:param.J, n in 1:param.N],
41+
Cjn[j, n] + sum(A[j, i] * Qin[i, n] for i in 1:graph.ndeg) -
42+
Yjn[j, n] + sum(
43+
ifelse(Qin[i, n] > 0, Apos[j, i], Aneg[j, i]) *
44+
abs(Qin[i, n])^(1 + param.beta) / kappa_ex[i]
45+
for i in 1:graph.ndeg
46+
) <= -1e-8
47+
)
48+
49+
# Labor resource constraint
50+
@constraint(model, -1e-8 <= sum(Lj) - 1 <= 1e-8)
51+
52+
return model
53+
end
54+
55+
function recover_allocation_mobility_armington(model, auxdata)
56+
param = auxdata.param
57+
graph = auxdata.graph
58+
model_dict = model.obj_dict
59+
results = Dict()
60+
61+
results[:welfare] = value(model_dict[:u])
62+
results[:Yjn] = value.(model_dict[:Yjn])
63+
results[:Yj] = dropdims(sum(results[:Yjn], dims=2), dims = 2)
64+
results[:Cjn] = value.(model_dict[:Cjn])
65+
results[:Cj] = dropdims(sum(results[:Cjn] .^ ((param.sigma-1)/param.sigma), dims=2), dims = 2) .^ (param.sigma/(param.sigma-1))
66+
results[:Lj] = value.(model_dict[:Lj])
67+
results[:Ljn] = (param.Zjn .> 0) .* results[:Lj]
68+
results[:cj] = ifelse.(results[:Lj] .== 0, 0.0, results[:Cj] ./ results[:Lj])
69+
results[:hj] = ifelse.(results[:Lj] .== 0, 0.0, param.Hj ./ results[:Lj])
70+
results[:uj] = param.u.(results[:cj], results[:hj])
71+
# Prices
72+
results[:Pjn] = shadow_price.(model_dict[:Pjn])
73+
results[:PCj] = dropdims(sum(results[:Pjn] .^ (1-param.sigma), dims=2), dims=2) .^ (1/(1-param.sigma))
74+
# Network flows
75+
results[:Qin] = value.(model_dict[:Qin])
76+
results[:Qjkn] = gen_network_flows(results[:Qin], graph, param.N)
77+
return results
78+
end

0 commit comments

Comments
 (0)