MATLAB中递归差分方程的非实根



用户12339314帮助我在MATLAB中求解递归差分方程。我曾尝试将该方法应用于稍微复杂一点的递归方程,它也很有效。这一次,我在左手边有x(t+1(,在右手边我有x(t(和x(t-1(,即3阶差分方程。这个方法是有效的,但我有点困惑,为什么我要得到一个复数,它的实数部分是解。我知道xt的动力学是振荡的,它收敛到0.0480162880552655,但在我运行下面的代码并点击x后,我看到它收敛到了0.0480162880352655+1.558510090378119e-67i。我不知道为什么会发生这种情况。我尝试了不同的最初猜测,但问题并没有消失。下面是代码。谢谢你的帮助。

tic
clear
clc
format long;
time = 0:1:100;
A = 1.00;
h = 0.90;
beta  = 0.40;
alpha = 0.36;
n = 0.10;
xstar = 0.3581201041248495;
kstartheir = (alpha*A*xstar/h)^(1/(1-alpha));
zeta1 = 1/(1+beta+beta^2);
a = (1-zeta1+zeta1*beta^2*h/(1+n))/(zeta1+(1+h+n)*alpha/(h*(1-alpha)));
b = (zeta1*beta^2*h/(1+n))/(zeta1+(1+h+n)*alpha/(h*(1-alpha)));
recEq = @(p,q,z) ((1-alpha)*A*p^alpha/(1+h+n))*(1-zeta1*(1+h*q/(A*alpha*p^alpha))+(zeta1*beta^2*h/(1+n))*((1+h*p/(A*alpha*z^alpha))/(h*p/(A*alpha*z^alpha))));
x = nan(1, 100);
x(1) = 12200;
for t = 1:100
kold = x(t);
k = recEq(x(t),kold,kold);
while abs(k-kold) > 1e-8
kold = k;
k = recEq(x(t), kold,kold);
end
x(t+1) = k;
end
toc

本质上,你得到的是一个非线性递推方程。为了得到x(t+1),必须(数值(求解递推方程才能得到它

用户12339314给出的想法是一个简单的递归,以找到方程的不动点。这是一个简单的寻根算法。

因为现在递归方程有三个项,即x(t+1)x(t)x(t-1),所以必须使用这三个值来求根x(t+1)。稍微更改一下你的代码,为了让它更清楚地显示你代码的"rood finding part",我们可以写:

tic;clear;clc;format long;
time = 0:1:100;
A = 1.00;
h = 0.90;
beta  = 0.40;
alpha = 0.36;
n = 0.10;
xstar = 0.3581201041248495;
kstartheir = (alpha*A*xstar/h)^(1/(1-alpha));
zeta1 = 1/(1+beta+beta^2);
a = (1-zeta1+zeta1*beta^2*h/(1+n))/(zeta1+(1+h+n)*alpha/(h*(1-alpha)));
b = (zeta1*beta^2*h/(1+n))/(zeta1+(1+h+n)*alpha/(h*(1-alpha)));
recEq = @(p,q,z) ((1-alpha)*A*p^alpha/(1+h+n))*(1-zeta1*(1+h*q/(A*alpha*p^alpha))+(zeta1*beta^2*h/(1+n))*((1+h*p/(A*alpha*z^alpha))/(h*p/(A*alpha*z^alpha))));
x = nan(1, 100);
x(1) = 12200;
x(2) = 12200; % notice we must provide now 2 guesses, because we need 2 initial conditions
for t = 2:100
k = x(t);
kold = x(t);
kold2 = x(t-1);
% root finding algorithm to obtain x(t+1)
converged = false;
while ~converged
kk = k;
k = recEq(kold, kk, kold2);
if(abs(k-kk)<1e-8)
converged = true;
end
end
x(t+1) = k;
end
toc

注意几件事:

  • 我们必须提供2个初始条件。所以我们定义了x(1) = 12200;x(2) = 12200;
  • 给定您提供的方程,您在递归方程recEq中命名了三个变量:p=x(t)q=x(t+1)z=x(t-1)。由于您正在查找根x(t+1),因此这是必须定义为未知的变量k。CCD_ 14和CCD_

运行此代码时,不会引入舍入错误。复数很可能出现在求幂中,k = recEq(x(t), kold,kold);中的p,q,z赋值错误(在代码中(。请注意与我的代码之间的差异。

最后一点是,在等式中,您可以使用任何寻根算法。这非常有趣,因为知道这一点,您可以使用任何内置函数来查找根。优点是MATLAB的内置函数比您编写的任何简单代码都要好得多。我们可以更改循环,将其写成:

for t = 2:100
fun = @(k) recEq(x(t),k,x(t-1))-k;
x(t+1) = fzero(fun,x(t));
% x(t+1) = fsolve(fun,x(t));
end

使用fzero或fsolve内置函数。您将得到相同的结果(对于这种特殊情况,fzero的运行速度将比fsolve快得多(。如果你有任何其他方程(甚至更难求解(,只需使用内置函数,你就可以了。

最新更新