Home > matlab > lyapunov_symm.m

lyapunov_symm

PURPOSE ^

Solves the Lyapunov equation x-a*x*a' = b, for b and x symmetric matrices.

SYNOPSIS ^

function [x,u] = lyapunov_symm(a,b,third_argument,lyapunov_complex_threshold,method, R)

DESCRIPTION ^

 Solves the Lyapunov equation x-a*x*a' = b, for b and x symmetric matrices.
 If a has some unit roots, the function computes only the solution of the stable subsystem.
  
 INPUTS:
   a                           [double]    n*n matrix.
   b                           [double]    n*n matrix.
   third_argument              [double]    scalar, if method <= 2 :
                                                      qz_criterium = third_argument unit root threshold for eigenvalues in a,
                                                    elseif method = 3 :
                                                      tol =third_argument the convergence criteria for fixed_point algorithm.
   lyapunov_complex_threshold  [double]    scalar, complex block threshold for the upper triangular matrix T.
   method                      [integer]   Scalar, if method=0 [default] then U, T, n and k are not persistent.  
                                                      method=1 then U, T, n and k are declared as persistent 
                                                               variables and the schur decomposition is triggered.    
                                                      method=2 then U, T, n and k are declared as persistent 
                                                               variables and the schur decomposition is not performed.
                                                      method=3 fixed point method
 OUTPUTS
   x:      [double]    m*m solution matrix of the lyapunov equation, where m is the dimension of the stable subsystem.
   u:      [double]    Schur vectors associated with unit roots  

 ALGORITHM
   Uses reordered Schur decomposition

 SPECIAL REQUIREMENTS
   None

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [x,u] = lyapunov_symm(a,b,third_argument,lyapunov_complex_threshold,method, R)
0002 % Solves the Lyapunov equation x-a*x*a' = b, for b and x symmetric matrices.
0003 % If a has some unit roots, the function computes only the solution of the stable subsystem.
0004 %
0005 % INPUTS:
0006 %   a                           [double]    n*n matrix.
0007 %   b                           [double]    n*n matrix.
0008 %   third_argument              [double]    scalar, if method <= 2 :
0009 %                                                      qz_criterium = third_argument unit root threshold for eigenvalues in a,
0010 %                                                    elseif method = 3 :
0011 %                                                      tol =third_argument the convergence criteria for fixed_point algorithm.
0012 %   lyapunov_complex_threshold  [double]    scalar, complex block threshold for the upper triangular matrix T.
0013 %   method                      [integer]   Scalar, if method=0 [default] then U, T, n and k are not persistent.
0014 %                                                      method=1 then U, T, n and k are declared as persistent
0015 %                                                               variables and the schur decomposition is triggered.
0016 %                                                      method=2 then U, T, n and k are declared as persistent
0017 %                                                               variables and the schur decomposition is not performed.
0018 %                                                      method=3 fixed point method
0019 % OUTPUTS
0020 %   x:      [double]    m*m solution matrix of the lyapunov equation, where m is the dimension of the stable subsystem.
0021 %   u:      [double]    Schur vectors associated with unit roots
0022 %
0023 % ALGORITHM
0024 %   Uses reordered Schur decomposition
0025 %
0026 % SPECIAL REQUIREMENTS
0027 %   None
0028 
0029 % Copyright (C) 2006-2010 Dynare Team
0030 %
0031 % This file is part of Dynare.
0032 %
0033 % Dynare is free software: you can redistribute it and/or modify
0034 % it under the terms of the GNU General Public License as published by
0035 % the Free Software Foundation, either version 3 of the License, or
0036 % (at your option) any later version.
0037 %
0038 % Dynare is distributed in the hope that it will be useful,
0039 % but WITHOUT ANY WARRANTY; without even the implied warranty of
0040 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0041 % GNU General Public License for more details.
0042 %
0043 % You should have received a copy of the GNU General Public License
0044 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
0045 if nargin<5
0046     method = 0;
0047 end
0048 
0049 if method == 3
0050     persistent X method1;
0051     if ~isempty(method1)
0052         method = method1;
0053     end;
0054     tol = third_argument;
0055     fprintf(' [methode=%d] ',method);
0056     if method == 3
0057         %tol = 1e-10;
0058         it_fp = 0;
0059         evol = 100;
0060         if isempty(X)
0061             X = b;
0062             max_it_fp = 2000;
0063         else
0064             max_it_fp = 300;
0065         end;
0066         at = a';
0067         %fixed point iterations
0068         while evol > tol && it_fp < max_it_fp;
0069             X_old = X;
0070             X = a * X * at + b;
0071             evol = max(sum(abs(X - X_old))); %norm_1
0072             %evol = max(sum(abs(X - X_old)')); %norm_inf
0073             it_fp = it_fp + 1;
0074         end;
0075         fprintf('lyapunov it_fp=%d evol=%g\n',it_fp,evol);
0076         if it_fp >= max_it_fp
0077             disp(['convergence not achieved in solution of Lyapunov equation after ' int2str(it_fp) ' iterations, switching method from 3 to 0']);
0078             method1 = 0;
0079             method = 0;
0080         else
0081             method1 = 3;
0082             x = X;
0083             return;
0084         end;
0085     end;
0086 elseif method == 4
0087     % works only with Matlab System Control toolbox or octave the control package,
0088     if exist('OCTAVE_VERSION')
0089         if ~user_has_octave_forge_package('control')
0090             error('lyapunov=square_root_solver not available; you must install the control package from Octave Forge')
0091         end
0092     else
0093         if ~user_has_matlab_license('control_toolbox')
0094             error('lyapunov=square_root_solver not available; you must install the control system toolbox')
0095         end
0096     end
0097     chol_b = R*chol(b,'lower');
0098     Rx = dlyapchol(a,chol_b);
0099     x = Rx' * Rx;
0100     return;
0101 end;
0102 
0103 qz_criterium = third_argument;
0104 if method
0105     persistent U T k n
0106 else
0107     if exist('U','var')
0108         clear('U','T','k','n')
0109     end
0110 end
0111 
0112 u = [];
0113 
0114 if size(a,1) == 1
0115     x=b/(1-a*a);
0116     return
0117 end
0118 
0119 if method<2
0120     [U,T] = schur(a);
0121     e1 = abs(ordeig(T)) > 2-qz_criterium;
0122     k = sum(e1);       % Number of unit roots.
0123     n = length(e1)-k;  % Number of stationary variables.
0124     if k > 0
0125         % Selects stable roots
0126         [U,T] = ordschur(U,T,e1);
0127         T = T(k+1:end,k+1:end);
0128     end
0129 end
0130 
0131 B = U(:,k+1:end)'*b*U(:,k+1:end);
0132 
0133 x = zeros(n,n);
0134 i = n;
0135 
0136 while i >= 2
0137     if abs(T(i,i-1))<lyapunov_complex_threshold
0138         if i == n
0139             c = zeros(n,1);
0140         else
0141             c = T(1:i,:)*(x(:,i+1:end)*T(i,i+1:end)') + ...
0142                 T(i,i)*T(1:i,i+1:end)*x(i+1:end,i);
0143         end
0144         q = eye(i)-T(1:i,1:i)*T(i,i);
0145         x(1:i,i) = q\(B(1:i,i)+c);
0146         x(i,1:i-1) = x(1:i-1,i)';
0147         i = i - 1;
0148     else
0149         if i == n
0150             c = zeros(n,1);
0151             c1 = zeros(n,1);
0152         else
0153             c = T(1:i,:)*(x(:,i+1:end)*T(i,i+1:end)') + ...
0154                 T(i,i)*T(1:i,i+1:end)*x(i+1:end,i) + ...
0155                 T(i,i-1)*T(1:i,i+1:end)*x(i+1:end,i-1);
0156             c1 = T(1:i,:)*(x(:,i+1:end)*T(i-1,i+1:end)') + ...
0157                  T(i-1,i-1)*T(1:i,i+1:end)*x(i+1:end,i-1) + ...
0158                  T(i-1,i)*T(1:i,i+1:end)*x(i+1:end,i);
0159         end
0160         q = [  eye(i)-T(1:i,1:i)*T(i,i) ,  -T(1:i,1:i)*T(i,i-1) ; ...
0161                -T(1:i,1:i)*T(i-1,i)     ,   eye(i)-T(1:i,1:i)*T(i-1,i-1) ];
0162         z =  q\[ B(1:i,i)+c ; B(1:i,i-1) + c1 ];
0163         x(1:i,i) = z(1:i);
0164         x(1:i,i-1) = z(i+1:end);
0165         x(i,1:i-1) = x(1:i-1,i)';
0166         x(i-1,1:i-2) = x(1:i-2,i-1)';
0167         i = i - 2;
0168     end
0169 end
0170 if i == 1
0171     c = T(1,:)*(x(:,2:end)*T(1,2:end)') + T(1,1)*T(1,2:end)*x(2:end,1);
0172     x(1,1) = (B(1,1)+c)/(1-T(1,1)*T(1,1));
0173 end
0174 x = U(:,k+1:end)*x*U(:,k+1:end)';
0175 u = U(:,1:k);

Generated on Mon 21-May-2012 02:42:43 by m2html © 2005