Solving differential equations with state variables and co-states
30 views (last 30 days)
Show older comments
The problem is quite straightforward in terms of max present value of the the sum of discounted utilities. Social discount rate is \rho. Utility function is given by log (c).
There are two equations of motion:
capital accumulation or investment = production - consumption
resource stock accumulation = - extraction of resources (there is a negative sign)
so there are two associated co-states.
production function is standard Cobb-Douglas with capital and non-renewable resource.
There are two controls, consumption and flow of resource extraction (call c and r) and two states, capital and stock of the non-renewable resource ( call k and s). The initial and final values of the states k and s are given. And the initial values of the co-states lambdas need to be found optimally. The graphs of the states, the co-states and the controls would be helpful.
It gives a system of differential equations and we need to find the optimal values of the initial values of lambdas.
%% Title: Solving Hamiltonian Objective Function using system of Differential Equations
% 1. Parameter Setup
clear; clc;
%%
% Preferences
rho = 0.05; % Discount rate
%sigma = 2; % Inverse of elasticity of intertemporal substitution (for CRRA)
u = @(c) log (c); % Utility function
%%
% Technology
%delta = 0.05; % Capital depreciation rate
alpha = 0.90; % Capital share in production
beta = 1-alpha; % Resource share in production
A = 3.968; % TFP
f = @(k, r) A * k.^alpha .* r.^beta; % Cobb-Douglas production function
% Initial conditions
%K0 = 100; % Initial capital stock
%S0 = 1000; % Initial resource stock
K0 = 4.913; % Initial capital stock
S0 = 11.5; % Initial resource stock
KT = 0; % final capital stock
ST = 0; % final resource stock
% Time setup
T = 100; % Time horizon
% dt = 0.1; % Time step
dt = 10; % Time step
time_periods = 0:dt:T;
N = length(time_periods);
%%
% Upon solving the Hamiltonian maximization with constraints, we get the
% following foc's
% 2. Define the System of ODEs (based on First-Order Conditions)
function d_vars = ode_system(t, vars, params)
% Unpack variables and parameters
k = vars(1);
s = vars(2);
lambda_k = vars(3);
lambda_s = vars(4);
params.rho = rho;
params.alpha = alpha;
params.beta = beta;
params.A = A;
% Optimal controls (consumption and resource extraction)
c = (lambda_k).^(-1);
r = (lambda_s / (lambda_k * A * beta * k^alpha)).^(1/(beta-1));
% System of ODEs
dk_dt = A * k^alpha * r^beta - c;
ds_dt = -r;
d_lambda_k_dt = lambda_k * (rho - A * alpha * k^(alpha-1) * r^beta);
d_lambda_s_dt = lambda_s * rho;
d_vars = [dk_dt; ds_dt; d_lambda_k_dt; d_lambda_s_dt];
end
%%
% 3. Solve using a Shooting Method
% Define terminal conditions
% S(T) = 0 and K(T) = 0 (transversality condition)
final_cond = @(vars_T) [vars_T(1); vars_T(2)];
% Define the function to find the initial shadow prices
find_initial_lambda = @(lambda0) (final_cond(ode_solver(lambda0)))';
% ODE solver setup
ode_solver = @(lambda0) solve_ode(lambda0, K0, S0, T, dt, @ode_system, params);
% Use fsolve to find the initial shadow prices (lambda_k0, lambda_s0)
x0 = [1; 1]; % Initial guess for lambda_k0 and lambda_s0
initial_lambdas = fsolve(find_initial_lambda, x0);
% Final run with optimal initial values
[~, vars] = ode_solver(initial_lambdas);
% Extract optimal paths
k_optimal = vars(:, 1);
s_optimal = vars(:, 2);
lambda_k_optimal = vars(:, 3);
lambda_s_optimal = vars(:, 4);
c_optimal = (lambda_k_optimal).^(-1/sigma);
r_optimal = (lambda_s_optimal ./ (lambda_k_optimal .* A .* k_optimal.^alpha)).^(1/(beta-1));
%%
% 4. Auxiliary function to solve ODE
function [t_out, vars_out] = solve_ode(lambda0, k0, s0, T, dt, ode_func, params)
y0 = [k0; s0; lambda0(1); lambda0(2)];
t_span = [0 T];
[t_out, vars_out] = ode45(@(t, y) ode_func(t, y, params), t_span, y0);
end
0 Comments
Answers (1)
Torsten
on 22 Oct 2025 at 15:05
Edited: Torsten
about 23 hours ago
This code works, but gives no solution for the parameters given.
%% Title: Solving Hamiltonian Objective Function using system of Differential Equations
% 1. Parameter Setup
% Preferences
rho = 0.05; % Discount rate
%%
% Technology
alpha = 0.90; % Capital share in production
beta = 1-alpha; % Resource share in production
A = 3.968; % TFP
% Initial conditions
k0 = 4.913; % Initial capital stock
s0 = 11.5; % Initial resource stock
% Final conditions
kT = 0; % final capital stock
sT = 0; % final resource stock
% Time setup
T = 100; % Time horizon
params.rho = rho;
params.alpha = alpha;
params.beta = beta;
params.A = A;
params.k0 = k0;
params.s0 = s0;
params.kT = kT;
params.sT = sT;
params.T = T;
% Use fsolve to find the initial shadow prices (lambda_k0, lambda_s0)
lambda0 = [1; 1]; % Initial guess for lambda_k0 and lambda_s0
initial_lambdas = fsolve(@(lambda)find_initial_lambda(lambda,params), lambda0)
% Final run with optimal initial values
[~, t, vars] = find_initial_lambda(initial_lambdas,params);
% Extract optimal paths
k_optimal = vars(:, 1);
s_optimal = vars(:, 2);
lambda_k_optimal = vars(:, 3);
lambda_s_optimal = vars(:, 4);
c_optimal = (lambda_k_optimal).^(-1);
r_optimal = (lambda_s_optimal ./ (lambda_k_optimal .* A .* k_optimal.^alpha)).^(1/(beta-1));
% Now plot what you like
figure(1)
plot(t,k_optimal)
figure(2)
plot(t,s_optimal)
figure(3)
plot(t,lambda_k_optimal)
figure(4)
plot(t,lambda_s_optimal)
figure(5)
plot(t,c_optimal)
figure(6)
plot(t,r_optimal)
function [res,t_out,vars_out] = find_initial_lambda(lambda,params)
k0 = params.k0;
s0 = params.s0;
kT = params.kT;
sT = params.sT;
T = params.T;
y0 = [k0; s0; lambda(1); lambda(2)];
t_span = [0 T];
[t_out, vars_out] = ode45(@(t, y) ode_func(t, y, params), t_span, y0);
res = [vars_out(end,1)-kT ; vars_out(end,2)-sT];
end
function d_vars = ode_func(t,vars,params)
k = vars(1);
s = vars(2);
lambda_k = vars(3);
lambda_s = vars(4);
rho = params.rho;
alpha = params.alpha;
beta = params.beta;
A = params.A;
% Optimal controls (consumption and resource extraction)
c = (lambda_k).^(-1);
r = (lambda_s / (lambda_k * A * beta * k^alpha)).^(1/(beta-1));
% System of ODEs
dk_dt = A * k^alpha * r^beta - c;
ds_dt = -r;
d_lambda_k_dt = lambda_k * (rho - A * alpha * k^(alpha-1) * r^beta);
d_lambda_s_dt = lambda_s * rho;
d_vars = [dk_dt; ds_dt; d_lambda_k_dt; d_lambda_s_dt];
end
See Also
Categories
Find more on Financial Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!