diff scripts/control/is_stabilizable.m @ 3213:ba1c7cdc6090

[project @ 1998-11-06 16:15:36 by jwe]
author jwe
date Fri, 06 Nov 1998 16:16:31 +0000
parents
children dbcc24961c44
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/scripts/control/is_stabilizable.m
@@ -0,0 +1,96 @@
+# Copyright (C) 1993, 1994, 1995 John W. Eaton
+# 
+# This file is part of Octave.
+# 
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, write to the Free
+# Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+function [retval,U] = is_stabilizable (a, b, tol)
+
+# Usage: [retval,U] = is_stabilizable (a {, b, tol})
+#
+# Returns retval = 1 if the system, a, is stabilizable, if the pair (a, b) is 
+# stabilizable, or 0 if not.
+#         U = orthogonal basis of controllable subspace.
+#
+# Controllable subspace is determined by applying Arnoldi iteration with
+# complete re-orthogonalization to obtain an orthogonal basis of the
+# Krylov subspace.
+#
+#   span ([b,a*b,...,a^   b]).
+#
+# tol is a roundoff paramter, set to 200*eps if omitted.
+#
+# See also: size, rows, columns, length, is_matrix, is_scalar, is_vector
+#     is_observable, is_stabilizable, is_detectable, krylov, krylovb
+
+# Written by A. S. Hodel (scotte@eng.auburn.edu) August, 1993.
+# Updated by A. S. Hodel (scotte@eng.auburn.edu) Aubust, 1995 to use krylovb 
+# Updated by John Ingram (ingraje@eng.auburn.edu) July, 1996 to accept systems
+# SYS_INTERNAL accesses members of system structure
+# $Revision: 1.1.1.1 $
+
+  if(nargin < 1)
+    usage("[retval,U] = is_stabilizable(a {, b ,tol})");
+  elseif(is_struct(a))
+    # sustem passed.
+    if(nargin == 2)
+      tol = b;          % get tolerance
+    elseif(nargin > 2)
+      usage("[retval,U] = is_stabilizable(sys{,tol})");
+    endif
+    sys = sysupdate(a,"ss");
+    a = sys.a;
+    b = sys.b;
+  else
+    # a,b arguments sent directly.
+    if(nargin > 3)
+      usage("[retval,U] = is_stabilizable(a {, b ,tol})");
+    endif
+  endif
+
+  if(exist("tol"))
+    [retval,U] = is_controllable(a,b,tol);
+  else
+    [retval,U] = is_controllable(a,b);
+    tol = 1e2*rows(b)*eps;
+  endif
+  
+  #disp("is_stabilzable: is_controllable returns")
+  #retval
+  #U
+  #disp("/is_stabilzable: is_controllable returns")
+
+  if( !retval & columns(U) > 0)
+    # now use an ordered Schur decomposition to get an orthogonal
+    # basis of the unstable subspace...
+    n = rows(a);
+    [ua,s] = schur(-(a+eye(n)*tol),'A');
+    k = sum( real(eig(a)) >= 0 );	# count unstable poles 
+
+    #disp("is_stabilizable: unstable poles found:")
+    #k
+    #s
+    #disp("/is_stabilizable: unstable poles found:")
+    
+    if( k > 0 )
+      ua = ua(:,1:k);
+      # now see if span(ua) is contained in span(U)
+      retval = (norm(ua - U*U'*ua) < tol);
+    else
+      retval = 1;			# all poles stable
+    endif
+  endif
+
+endfunction