@@ -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?
9798end
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