Skip to content

Commit 3a01636

Browse files
committed
Enforcing non-negative flows.
1 parent 72ebe6e commit 3a01636

1 file changed

Lines changed: 74 additions & 71 deletions

File tree

src/models/solve_allocation_by_duality_cgc.jl

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ function objective_duality_cgc(x, auxdata)
9393

9494
# Compute objective value
9595
f = sum(graph.omegaj .* graph.Lj .* auxdata.param.u.(res.cj, graph.hj)) - sum(cons)
96+
9697
return f # Negative objective because Ipopt minimizes?
9798
end
9899

@@ -152,12 +153,13 @@ function hessian_duality_cgc(
152153

153154
# Prepare computation of production function
154155
if a != 1
155-
Psi = sum((Pjn .* Zjn) .^ (1 / (1 - a)), dims=2)
156156
psi = (Pjn .* Zjn) .^ (1 / (1 - a))
157+
Psi = sum(psi, dims=2)
157158
end
158159

159160
# Now the big loop over the hessian terms to compute
160161
ind = 0
162+
161163
# https://stackoverflow.com/questions/38901275/inbounds-propagation-rules-in-julia
162164
for (jdnd, jn) in zip(hess_str[1], hess_str[2])
163165
ind += 1
@@ -184,8 +186,8 @@ function hessian_duality_cgc(
184186
for k in neighbors # TODO: add to loop below ??
185187
T += res.Qjk[j, k]^(1+beta) / kappa[j, k]
186188
end
187-
Cprime = 1/omegaj[j] * Pjn[j, nd]^(-sigma) * PDj[j]^sigma * param.uprimeinvprime(PDj[j]/omegaj[j], graph.hj[j])
188-
Gprime = sigma * Pjn[j, n] * Pjn[j, nd]^(-sigma) * PDj[j]^(sigma-2) * G^((sigma+1)/sigma)
189+
Cprime = Lj[j]/omegaj[j] * (PDj[j] / Pjn[j, nd])^sigma * param.uprimeinvprime(PDj[j]/omegaj[j], graph.hj[j])
190+
Gprime = sigma * (Pjn[j, n] * Pjn[j, nd])^(-sigma) * PDj[j]^(2*sigma-1)
189191
if nd == n
190192
Gprime -= sigma / PDj[j] * G^((sigma+1)/sigma)
191193
end
@@ -199,75 +201,77 @@ function hessian_duality_cgc(
199201

200202
# Now terms sum_k(Q^n_{jk} - Q^n_{kj}) as well as T'_2 G
201203
for k in neighbors
202-
# Constant Terms
203-
K0 = (1 + beta) / kappa[j, k]
204-
PK0 = PDj[j] * K0
205-
K = K0^m1dbeta
206-
207-
# Terms with Derivatives
208-
A = ((Pjn[k, nd] - Pjn[j, nd])/m[nd])^(1/(nu-1)) # 0 for n' != n
209-
B = (res.Qjk[j, k] * PK0^m1dbeta)^(numbetam1/(nu-1))
210-
211-
# Computing the right derivative: Q^n_{jk}
212-
if jd == j # P^x_j
213-
Bprime = cons2 * A * B^((numbetam1 - nu*beta)/numbetam1)
214-
if nd == n # P^n_j
215-
Aprime = -n1dnum1 / m[n] * A^(2-nu)
216-
term += K * (Pprime*A*B + P*Aprime*B + P*A*Bprime)
217-
else # P^n'_j (A' is zero)
218-
term += K * (Pprime*A*B + P*A*Bprime)
219-
end
220-
# This computes the remaining derivative of D^n_j (T'_2 G)
221-
term += cons * K / (1+beta) * Bprime * B^(-nu*beta/(numbetam1+nu*beta))
222-
elseif jd == k # P^x_k (P' is zero)
223-
Bprime = -cons2 * A * B^((numbetam1 - nu*beta)/numbetam1) # simply the negative
224-
if nd == n # P^n_k
225-
Aprime = n1dnum1 / m[n] * A^(2-nu) # Simply the negative
226-
term += K * (P*Aprime*B + P*A*Bprime)
227-
else # # P^n'_k (A' is zero)
228-
term += K * P*A*Bprime
204+
205+
# Terms with Derivative
206+
diff = Pjn[k, nd] - Pjn[j, nd]
207+
if diff >= 0
208+
A = (diff/m[nd])^(1/(nu-1)) # 0 for n' != n
209+
# Constant Terms
210+
K0 = (1 + beta) / kappa[j, k]
211+
PK0 = PDj[j] * K0
212+
K = K0^m1dbeta
213+
214+
# Terms with Derivatives..continued
215+
B = (res.Qjk[j, k] * PK0^m1dbeta)^(numbetam1/(nu-1))
216+
217+
# Computing the right derivative: Q^n_{jk}
218+
if jd == j # P^x_j
219+
Bprime = cons2 * A * B^((numbetam1 - nu*beta)/numbetam1)
220+
if nd == n # P^n_j
221+
Aprime = -n1dnum1 / m[n] * A^(2-nu)
222+
term += K * (Pprime*A*B + P*Aprime*B + P*A*Bprime)
223+
else # P^n'_j (A' is zero)
224+
term += K * (Pprime*A*B + P*A*Bprime)
225+
end
226+
# This computes the remaining derivative of D^n_j (T'_2 G)
227+
term += cons * K / (1+beta) * Bprime * B^(-nu*beta/(numbetam1+nu*beta))
228+
elseif jd == k # P^x_k (P' is zero)
229+
Bprime = -cons2 * A * B^((numbetam1 - nu*beta)/numbetam1) # simply the negative
230+
if nd == n # P^n_k
231+
Aprime = n1dnum1 / m[n] * A^(2-nu) # Simply the negative
232+
term += K * (P*Aprime*B + P*A*Bprime)
233+
else # # P^n'_k (A' is zero)
234+
term += K * P*A*Bprime
235+
end
236+
# This computes the remaining derivative of D^n_j (T'_2 G)
237+
term += cons * K / (1+beta) * Bprime * B^(-nu*beta/(numbetam1+nu*beta))
229238
end
230-
# This computes the remaining derivative of D^n_j (T'_2 G)
231-
term += cons * K / (1+beta) * Bprime * B^(-nu*beta/(numbetam1+nu*beta))
232-
# else
233-
# error("This should not occur, jd != j and jd != k")
234239
end
235240

236241
# Computing the right derivative: Q^n_{kj} (other direction -> needs to be subtracted)
237-
# TODO: are therse terms already negative??
238-
239-
# Also need prices here
240-
Pk = PDj[k]^m1dbeta
241-
Pkprime = m1dbeta * Pjn[k, nd]^(-sigma) * Pk^(1+beta - beta*sigma)
242-
243-
# Constant Terms
244-
K0 = (1 + beta) / kappa[k, j]
245-
PK0 = PDj[k] * K0
246-
K = K0^m1dbeta
247-
242+
248243
# Terms with Derivatives
249-
A = ((Pjn[j, nd] - Pjn[k, nd])/m[nd])^(1/(nu-1)) # 0 for n' != n
250-
B = (res.Qjk[k, j] * PK0^m1dbeta)^(numbetam1/(nu-1))
251-
252-
# Computing the right derivative: Q^n_{kj}
253-
if jd == k # P^x_k
254-
Bprime = cons2 * A * B^((numbetam1 - nu*beta)/numbetam1)
255-
if nd == n # P^n_k
256-
Aprime = -n1dnum1 / m[n] * A^(2-nu)
257-
term -= K * (Pkprime*A*B + Pk*Aprime*B + Pk*A*Bprime)
258-
else # P^n'_k (A' is zero)
259-
term -= K * (Pkprime*A*B + Pk*A*Bprime)
260-
end
261-
elseif jd == j # P^x_j (P' is zero)
262-
Bprime = -cons2 * A * B^((numbetam1 - nu*beta)/numbetam1) # simply the negative
263-
if nd == n # P^n_j
264-
Aprime = n1dnum1 / m[n] * A^(2-nu) # Simply the negative
265-
term -= K * (Pk*Aprime*B + Pk*A*Bprime)
266-
else # # P^n'_j (A' is zero)
267-
term -= K * Pk*A*Bprime
244+
if diff < 0
245+
A = (-diff/m[nd])^(1/(nu-1)) # 0 for n' != n
246+
# Also need prices here
247+
Pk = PDj[k]^m1dbeta
248+
Pkprime = m1dbeta * Pjn[k, nd]^(-sigma) * Pk^(1+beta - beta*sigma)
249+
250+
# Constant Terms
251+
K0 = (1 + beta) / kappa[k, j]
252+
PK0 = PDj[k] * K0
253+
K = K0^m1dbeta
254+
255+
# Terms with Derivatives..continued
256+
B = (res.Qjk[k, j] * PK0^m1dbeta)^(numbetam1/(nu-1))
257+
# Computing the right derivative: Q^n_{kj}
258+
if jd == k # P^x_k
259+
Bprime = cons2 * A * B^((numbetam1 - nu*beta)/numbetam1)
260+
if nd == n # P^n_k
261+
Aprime = -n1dnum1 / m[n] * A^(2-nu)
262+
term -= K * (Pkprime*A*B + Pk*Aprime*B + Pk*A*Bprime)
263+
else # P^n'_k (A' is zero)
264+
term -= K * (Pkprime*A*B + Pk*A*Bprime)
265+
end
266+
elseif jd == j # P^x_j (P' is zero)
267+
Bprime = -cons2 * A * B^((numbetam1 - nu*beta)/numbetam1) # simply the negative
268+
if nd == n # P^n_j
269+
Aprime = n1dnum1 / m[n] * A^(2-nu) # Simply the negative
270+
term -= K * (Pk*Aprime*B + Pk*A*Bprime)
271+
else # # P^n'_j (A' is zero)
272+
term -= K * Pk*A*Bprime
273+
end
268274
end
269-
# else
270-
# error("This should not occur, jd != k and jd != j")
271275
end
272276
end # End of k loop
273277

@@ -277,7 +281,7 @@ function hessian_duality_cgc(
277281
if nd == n
278282
X *= 1 - Psi[j] / psi[j, n]
279283
end
280-
term += X
284+
term -= X
281285
end
282286

283287
# Assign result
@@ -327,21 +331,20 @@ function recover_allocation_duality_cgc(x, auxdata)
327331
temp[nadj] .= 0
328332
for n in 1:param.N
329333
Lambda = repeat(Pjn[:, n], 1, graph.J)
330-
LL = Lambda' - Lambda # P^n_k - P^n_j
334+
LL = max.(Lambda' - Lambda, 0) # P^n_k - P^n_j (non-negative flows)
331335
Qjk += m[n] * (LL / m[n]) .^ (nu/(nu-1))
332336
end
333337
Qjk = (Qjk .* temp) .^ (nu-1)/(nu*param.beta)
334338

335339
# Calculate the flows Qjkn
336340
Qjkn = zeros(graph.J, graph.J, param.N)
337341
temp = kappa ./ ((1 + param.beta) * PDj .* Qjk .^ (1+param.beta-nu))
338-
temp[nadj] .= 0
342+
temp[nadj .| isinf.(temp)] .= 0 # Because of the max() clause, Qjk may be zero
339343
for n in 1:param.N
340344
Lambda = repeat(Pjn[:, n], 1, graph.J)
341-
LL = Lambda' - Lambda # P^n_k - P^n_j
345+
LL = max.(Lambda' - Lambda, 0) # P^n_k - P^n_j (non-negative flows)
342346
Qjkn[:, :, n] = ((LL .* temp) / m[n]) .^ (1/(nu-1))
343347
end
344-
345348
# Now calculating consumption bundle pre-transport cost
346349
temp = Qjk .^ (1+param.beta) ./ kappa
347350
temp[nadj] .= 0

0 commit comments

Comments
 (0)