Replies: 7 comments 2 replies
-
Also I attempted to solve an infinite horizon version using methods you proposed here. # CASE: Infinite Horizon
using InfiniteOpt, Ipopt, Plots
δ=0.10; # capital depreciation
ρ=0.05; # discount rate
#T = 90.0 # life horizon
k0 = 1.0 # endowment
#
z= ρ + δ +0.10
z > ρ + δ # Need: z > ρ + δ
I_SS = (z-ρ-δ)/(ρ+δ);
K_SS = I_SS/δ;
# Closed Form Solution:
ii(t) = I_SS
kk(t) = K_SS + exp(-(δ)*t)*(k0 - K_SS);
#
u(k,i;z=z) = z*k -i -(1/2)*(i)^2 # utility function
discount(t; ρ=ρ) = exp(-ρ*t) # discount function
int_discount(t; ρ=ρ) = exp((1-ρ)*t)
# additional weight function for the integral (will be multiplied by e^-t by Gauss Laguerre)
BC(k, i; δ=δ) = i - δ*k # LOM
opt = Ipopt.Optimizer # desired solver
ns = 10_000; # number of gridpoints
m = InfiniteModel(opt)
@infinite_parameter(m, t in [0, Inf])
#@infinite_parameter(m, t ∈ [0, T], num_supports = ns)
@variable(m, k, Infinite(t)) ## state variables
@variable(m, i, Infinite(t)) ## control variables
@parameter_function(m, dis == discount(t))
@objective(m, Max, integral(u(k,i), t, eval_method = GaussLaguerre(), num_nodes = 100, weight_func = int_discount))
@constraint(m, k == k0, DomainRestrictions(t => 0))
@constraint(m, dis * (1+i) * k == 0, DomainRestrictions(t => supports(t)[end]))
# not sure what u'(c_t) is...
@constraint(m, c1, deriv(k, t) == BC(k, i; δ=δ))
#@constraint(m, c2, i >= -(1-δ)*k)
optimize!(m)
termination_status(m)
opt_obj = objective_value(m) #
i_opt, k_opt = value(i), value(k)
ts = supports(t)
ix = 2:(length(ts)-1) # index for plotting
#
plot(legend=:bottomleft);
plot!(ts[ix], i_opt[ix], color = 1, lab = "i: InfiniteOpt")
plot!(ts[ix], ii, color = 1, linestyle=:dash, lab = "i: closed form")
plot!(ts[ix], k_opt[ix], color = 4, lab = "k: InfiniteOpt");
plot!(ts[ix], kk, color = 4, linestyle=:dash, lab = "k: closed form")
plot!([0.0], seriestype = :hline, lab="", color="red")
plot!(ts[ix], -(1-δ)*k_opt[ix], lab = "i>-(1-δ)*k", color="black", l=:dash)
plot!([-1], seriestype = :hline, lab="-1", color="black", l=:dash) |
Beta Was this translation helpful? Give feedback.
-
Hi there! First, good catch on the Second, the "kink" behavior occurs because Third, the behavior of the infinite horizon case isn't surprising since simultaneous approximation methods (which is currently what I have implemented) tend toward higher accuracy in the early times infinite horizon problems, but exhibit drift afterward because of the small weights you get in the integral (since the additional discount factor decreases the accuracy of the quadrature). More sophisticated solution methods are needed for infinite horizon problems, see #190. Fourth, instead of using DomainRestrictions at particular points, you can use our restricted variable syntax. @constraint(m, i >=-(1-δ)*k, DomainRestrictions(t => T))
@constraint(m, i(T) >=-(1-δ)*k(T)) # this is the same but will be more computationally efficient |
Beta Was this translation helpful? Give feedback.
-
Hmm, I might be making a math mistake moving from discrete time to continuous time in the kink example. In discrete time: In continuous time: Perhaps the terminal condition in continuous time should instead be: |
Beta Was this translation helpful? Give feedback.
-
I think I figured out the problem in the case where all capital is liquidated. in discrete time the terminal condition is: k_T+1 =0 continuous time analog: k_T=0 either way, economists typically only solve infinite horizon firm investment models… |
Beta Was this translation helpful? Give feedback.
-
Here is the final answer to the finite-horizon firm investment problem. The constrained optimization problem: The technology threshold at which both terminal conditions bind: Case 1: z = 0.30 > z̄ (burn capital) using InfiniteOpt, Ipopt, Plots
δ=0.10; # capital depreciation
ρ=0.05; # discount rate
T = 90.0 # life horizon
k0 = 1.0 # endowment
z=0.3
z > ρ + δ # Need: z > ρ + δ
I_SS = (z-ρ-δ)/(ρ+δ);
K_SS = I_SS/δ;
# Closed Form Solution if `z ≥ zqot` or `i[T]=-1`:
ii(t) = I_SS - (1+I_SS)*exp(-(ρ+δ)*(T-t))
kk(t) = K_SS -
((1+I_SS)/(ρ+2*δ))*exp(-(ρ+δ)*(T-t)) +
(((1+I_SS)/(ρ+2*δ))*exp(-(ρ+δ)*T) + k0 - K_SS)*exp(-(δ)*t);
#
u(k,i;z=z) = z*k -i -(1/2)*(i)^2 # utility function
discount(t; ρ=ρ) = exp(-ρ*t) # discount function
BC(k, i; δ=δ) = i - δ*k # LOM
opt = Ipopt.Optimizer # desired solver
ns = 10_000; # number of gridpoints
m = InfiniteModel(opt)
@infinite_parameter(m, t ∈ [0, T], num_supports = ns)
@variable(m, k, Infinite(t)) ## state variables
@variable(m, i, Infinite(t)) ## control variables
@objective(m, Max, integral(u(k,i), t, weight_func = discount))
@constraint(m, c1, deriv(k, t) == BC(k, i; δ=δ))
@constraint(m, c2, k >= 0) # Can't sell more than all your capital.
@constraint(m, k == k0, DomainRestrictions(t => 0))
@constraint(m, i(T) >=-1)
@constraint(m, k(T) >=0)
optimize!(m)
termination_status(m)
i_opt = value(i)
k_opt = value(k)
ts = supports(t)
opt_obj = objective_value(m) # V(k0, 0)
ix = 2:(length(ts)-1) # index for plotting
#
plot(legend=:topleft);
plot!(ts[ix], i_opt[ix], color = 1, lab = "i: InfiniteOpt")
plot!(ts[ix], ii, color = 1, linestyle=:dash, lab = "i: closed form")
plot!([-1], seriestype = :hline, lab="i>=-1, binds", color=1, l=:dash)
plot!(ts[ix], k_opt[ix], color = 4, lab = "k: InfiniteOpt");
plot!(ts[ix], kk, color = 4, linestyle=:dash, lab = "k: closed form")
plot!([0.0], seriestype = :hline, lab="k>=0, slack", color=4) Case 2: z = 0.20 < z̄ (sell all capital at the end) using InfiniteOpt, Ipopt, Plots
δ=0.10; # capital depreciation
ρ=0.05; # discount rate
T = 90.0 # life horizon
k0 = 1.0 # endowment
z=0.2
z > ρ + δ # Need: z > ρ + δ
I_SS = (z-ρ-δ)/(ρ+δ);
K_SS = I_SS/δ;
u(k,i;z=z) = z*k -i -(1/2)*(i)^2 # utility function
discount(t; ρ=ρ) = exp(-ρ*t) # discount function
BC(k, i; δ=δ) = i - δ*k # LOM
opt = Ipopt.Optimizer # desired solver
ns = 10_000; # number of gridpoints
m = InfiniteModel(opt)
@infinite_parameter(m, t ∈ [0, T], num_supports = ns)
@variable(m, k, Infinite(t)) ## state variables
@variable(m, i, Infinite(t)) ## control variables
@objective(m, Max, integral(u(k,i), t, weight_func = discount))
@constraint(m, c1, deriv(k, t) == BC(k, i; δ=δ))
@constraint(m, c2, k >= 0) # Can't sell more than all your capital.
@constraint(m, k == k0, DomainRestrictions(t => 0))
@constraint(m, i(T) >=-1)
@constraint(m, k(T) >=0)
optimize!(m)
termination_status(m)
i_opt = value(i)
k_opt = value(k)
ts = supports(t)
opt_obj = objective_value(m) # V(k0, 0)
ix = 2:(length(ts)-1) # index for plotting
#
plot(legend=:topleft);
plot!(ts[ix], i_opt[ix], color = 1, lab = "i: InfiniteOpt")
plot!([-1], seriestype = :hline, lab="i>=-1, slack", color=1, l=:dash)
plot!(ts[ix], k_opt[ix], color = 4, lab = "k: InfiniteOpt");
plot!([0.0], seriestype = :hline, lab="k>=0, binds", color=4) PS: I don't know how to solve the infinite horizon version in your package. At some point this can make for another nice example for the docs. |
Beta Was this translation helpful? Give feedback.
-
Here are some codes that solve the infinite horizon problem in continuous time |
Beta Was this translation helpful? Give feedback.
-
Thanks for the info. The challenge here will be developing a solution method that can handle general infinite-dimensional optimization problems (not just time ones) with general differential algebraic equations and path/point constraints. Moreover, traditional ODE solvers are not typically amendable to optimization problems (due to the presence of decision variables), though they can be used with multiple shooting methods (which don't scale well unfortunately). This is why we currently implement simultaneous approaches to handle general DAEs. This works well for domains with finite bounds (e.g., finite time horizons), but extending it to domains with infinite bounds is nontrivial in general. |
Beta Was this translation helpful? Give feedback.
-
(This is an edited/corrected version of my original post!)
I would like to contribute this example (once I confirm it works).
Consider a firm endowed with initial capital K0, that chooses investment to maximize the present value of its future dividends.
The firm terminates production at time T and sells its remaining undepreciated capital (or scraps it if its cheaper) .
The appropriate terminal condition for
i[T]
depends on the technology parameterz
:In principle, the terminal conditions can be combined into one:
@constraint(m, i == max(-1, -(1-δ)*k), DomainRestrictions(t => T))
This currently gives an error.
Consider the closed form for the case
z≥z̄
ori[T]=-1
:Now w/
InfiniteOpt.jl
The solution in this case is very very accurate!
Now solve the case
z<z̄
ori[T]=-(1-δ)*k[T]>-1
:Now the solution (for investment) has a weird unexpected kink:
Now plot it w/ the "i>-(1-δ)*k" constraint:
Compare this to the closed form solution in Mathematica (no kink & the expected constraint binds at "T"):
Do you know what I might be doing wrong?
My guess is I need to tune one of the optimization options...
Beta Was this translation helpful? Give feedback.
All reactions