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

时间:2019-11-15 21:10:16

标签: matlab recursion

user12339314帮助我,他帮助我解决了MATLAB中的递归差分方程。我已经尝试将该方法应用于稍微复杂的递归方程,并且它也可以工作。这次,我在左侧有x(t + 1),在右边有x(t)和x(t-1),即3阶差分方程。该方法有效,但是我有点困惑为什么我要得到一个复数,而真正的部分是解决方案。我知道xt的动态是振荡的,它收敛到0.0480162880552655,但是在我运行下面的代码并单击x之后,我看到它收敛到0.0480162880552655 + 1.55851090378119e-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

1 个答案:

答案 0 :(得分:0)

基本上,您得到的是一个非线性递归方程。 为了获得from adder import ffi, lib print(lib.add(2,6)) ,必须(以数值方式)求解递归方程式。

user12339314给出的想法是找到fixed point of your equation的简单重复。这是一种简单的寻根算法。

由于现在您的递归方程具有3个项,即x(t+1)x(t+1)x(t),因此必须使用这3个值来找到根x(t-1)。更改一些代码,以使代码的“寻路部分”更清晰,我们可以编写:

x(t+1)

注意几件事:

  • 我们必须提供2个初始条件。因此,我们定义了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 x(1) = 12200;
  • 鉴于您提供的方程式,您在递归方程式x(2) = 12200;中命名了三个变量:recEqp=x(t)q=x(t+1)。由于您要查找根z=x(t-1),因此必须将其定义为未知变量x(t+1)kp是已知的(从先前的迭代或从第一次迭代的初始条件开始)。

运行此代码,不会引入舍入错误。复数很可能会出现在幂运算中,并且z中的p,q,z分配错误(在您的代码中)。请注意与我的代码的区别。

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

k = recEq(x(t), kold,kold);

使用fzerofsolve内置函数。您将获得相同的结果(对于这种特定情况,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快得多)。 如果您还有其他方程式(甚至更难求解),只需使用内置函数,就可以了。