changeset 3236:98e15955107e

[project @ 1999-03-05 07:17:10 by jwe]
author jwe
date Fri, 05 Mar 1999 07:19:35 +0000
parents 41602f25d19f
children 737b219ab65a
files scripts/control/DEMOcontrol.m scripts/control/abcddim.m scripts/control/abcddims.m scripts/control/analdemo.m scripts/control/are.m scripts/control/bddemo.m scripts/control/bode.m scripts/control/bode_bounds.m scripts/control/buildssic.m scripts/control/c2d.m scripts/control/com2str.m scripts/control/controldemo.m scripts/control/ctrb.m scripts/control/d2c.m scripts/control/damp.m scripts/control/dare.m scripts/control/dcgain.m scripts/control/dezero.m scripts/control/dgkfdemo.m scripts/control/dgram.m scripts/control/dhinfdemo.m scripts/control/dlqe.m scripts/control/dlqg.m scripts/control/dlqr.m scripts/control/dlyap.m scripts/control/dre.m scripts/control/fir2sys.m scripts/control/frdemo.m scripts/control/freqchkw.m scripts/control/freqresp.m scripts/control/gram.m scripts/control/h2norm.m scripts/control/h2syn.m scripts/control/hinf_ctr.m scripts/control/hinfdemo.m scripts/control/hinfnorm.m scripts/control/hinfsyn.m scripts/control/hinfsyn_chk.m scripts/control/hinfsyn_ric.m scripts/control/impulse.m scripts/control/is_abcd.m scripts/control/is_controllable.m scripts/control/is_detectable.m scripts/control/is_dgkf.m scripts/control/is_digital.m scripts/control/is_observable.m scripts/control/is_sample.m scripts/control/is_signal_list.m scripts/control/is_siso.m scripts/control/is_stabilizable.m scripts/control/is_stable.m scripts/control/jet707.m scripts/control/lqe.m scripts/control/lqg.m scripts/control/lqr.m scripts/control/lsim.m scripts/control/ltifr.m scripts/control/mb.m scripts/control/minfo.m scripts/control/moddemo.m scripts/control/nichols.m scripts/control/obsv.m scripts/control/ord2.m scripts/control/outlist.m scripts/control/packedform.m scripts/control/packsys.m scripts/control/parallel.m scripts/control/pinv.m scripts/control/place.m scripts/control/polyout.m scripts/control/prompt.m scripts/control/rldemo.m scripts/control/rlocus.m scripts/control/rotg.m scripts/control/run_cmd.m scripts/control/series.m scripts/control/sortcom.m scripts/control/ss2sys.m scripts/control/ss2tf.m scripts/control/ss2zp.m scripts/control/starp.m scripts/control/step.m scripts/control/stepimp.m scripts/control/swap.m scripts/control/swapcols.m scripts/control/swaprows.m scripts/control/sys2fir.m scripts/control/sys2ss.m scripts/control/sys2tf.m scripts/control/sys2zp.m scripts/control/sysadd.m scripts/control/sysappend.m scripts/control/syschnames.m scripts/control/syschtsam.m scripts/control/sysconnect.m scripts/control/syscont.m scripts/control/sysdefstname.m scripts/control/sysdisc.m scripts/control/sysdup.m scripts/control/sysgettsam.m scripts/control/sysgroup.m scripts/control/sysgroupn.m scripts/control/sysidx.m scripts/control/sysmult.m scripts/control/sysout.m scripts/control/sysprune.m scripts/control/sysreorder.m scripts/control/sysrepdemo.m scripts/control/sysscale.m scripts/control/syssetsignals.m scripts/control/syssub.m scripts/control/sysupdate.m scripts/control/tf2ss.m scripts/control/tf2sys.m scripts/control/tf2sysl.m scripts/control/tf2zp.m scripts/control/tfout.m scripts/control/tzero.m scripts/control/tzero2.m scripts/control/ugain.m scripts/control/unpacksys.m scripts/control/wgt1o.m scripts/control/zgfmul.m scripts/control/zgfslv.m scripts/control/zginit.m scripts/control/zgpbal.m scripts/control/zgreduce.m scripts/control/zgrownorm.m scripts/control/zgscal.m scripts/control/zgsgiv.m scripts/control/zgshsr.m scripts/control/zp2ss.m scripts/control/zp2ssg2.m scripts/control/zp2sys.m scripts/control/zp2tf.m
diffstat 135 files changed, 859 insertions(+), 480 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/control/DEMOcontrol.m
+++ b/scripts/control/DEMOcontrol.m
@@ -21,7 +21,6 @@
 # Demo programs: bddemo.m, frdemo.m, analdemo.m, moddmeo.m, rldemo.m
 #  
 # Written by David Clem August 15, 1994
-# $Revision: 2.0.0.2 $    
 
   disp(' O C T A V E    C O N T R O L   S Y S T E M S   T O O L B O X')
 
--- a/scripts/control/abcddim.m
+++ b/scripts/control/abcddim.m
@@ -35,54 +35,6 @@
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
 # a s hodel: modified to accept pure-gain systems aug 1996
-# $Revision: 1.17 $
-# $Log: abcddim.m,v $
-# Revision 1.17  1998-12-10 03:06:31  jwe
-# *** empty log message ***
-#
-# Revision 2.0.0.2  1998/12/08  23:29:21  hodel
-# Octave-Marsyas Interface updated for signals-as-lists
-#
-# Revision 2.0.0.1  1998/12/08  21:40:44  hodel
-# Dummy version to match ftp.eng.auburn.edu version number
-#
-# Revision 2.0.0.0  1998/12/08  21:36:51  hodel
-# Branch for beta release patches
-#
-# Revision 2.0  1998/12/08  21:34:56  hodel
-# Initial beta release of signals-as-lists rewrite;
-# sysdimensions now takes opt as an argument
-#
-# Revision 2.0.0.1  1998/12/08  20:54:18  hodel
-# sysdimensions takes opt parameter now
-#
-# Revision 2.0.0.0  1998/12/08  20:30:08  hodel
-# beta release revision
-#
-# Revision 2.0  1998/12/08  20:27:55  hodel
-# Initial list rewrite of OCST
-#
-# Revision 1.2  1998/10/05 17:12:56  hodelas
-# various bug changes
-#
-# Revision 1.1.1.1  1998/05/19 20:24:05  jwe
-#
-# Revision 1.4  1997/12/01 16:44:22  scotte
-# *** empty log message ***
-#
-# Revision 1.3  1997/02/12 15:38:14  hodel
-# *** empty log message ***
-#
-#
-# fixed typo
-#
-# Revision 1.1  1997/02/12 11:34:53  hodel
-# Initial revision
-#
-# Revision 1.7  1997/02/07 15:29:56  scotte
-# fixed is_square check to allow for empty a matrix
-# (this allows for pure gain blocks)
-#
 
   if (nargin != 4)
     error ("abcddim: four arguments required");
--- a/scripts/control/abcddims.m
+++ b/scripts/control/abcddims.m
@@ -24,7 +24,6 @@
 # get set to 0.  my and ny are the row and column dimensions of the result.
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) Feb 1997
-# $Revision: 2.0.0.2 $
 
   y = x;
   if(isempty(y))
--- a/scripts/control/analdemo.m
+++ b/scripts/control/analdemo.m
@@ -20,7 +20,6 @@
 # Octave Controls toolbox demo: State Space analysis demo
 # Written by David Clem August 15, 1994
 # Updated by John Ingram December 1996
-# $Revision: 2.0.0.2 $
   
   while (1)
     clc
--- a/scripts/control/are.m
+++ b/scripts/control/are.m
@@ -35,7 +35,6 @@
 # See also: balance
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
-# $Revision: 1.20 $
 
   if (nargin == 3 || nargin == 4)
     if (nargin == 4)
--- a/scripts/control/bddemo.m
+++ b/scripts/control/bddemo.m
@@ -21,17 +21,6 @@
 # Written by David Clem August 15, 1994
 # Modified by A S Hodel Summer-Fall 1996
 
-# Revision 1.6  1998/05/05 17:02:45  scotte
-# updated May 5 by Kai Meuller
-#
-# Revision 1.2  1998/05/05  13:21:51  mueller
-# buildssic command description
-# buildssic example added
-#
-# Revision 1.1  1998/05/05  13:20:26  mueller
-# Initial revision
-#
- 
   str_sav = implicit_str_to_num_ok;
   sav_page = page_screen_output;
   implicit_str_to_num_ok = 1;
--- a/scripts/control/bode.m
+++ b/scripts/control/bode.m
@@ -57,64 +57,6 @@
 # Modified by David Clem November 13, 1994
 # again by A. S. Hodel July 1995 (smart plot range, etc.)
 # Modified by Kai P. Mueller September 28, 1997 (multiplot mode)
-# $Revision: 2.0.0.2 $
-# $Log: bode.m,v $
-# Revision 2.0.0.2  1998/12/08  23:29:23  hodel
-# Octave-Marsyas Interface updated for signals-as-lists
-#
-# Revision 2.0.0.1  1998/12/08  21:40:45  hodel
-# Dummy version to match ftp.eng.auburn.edu version number
-#
-# Revision 2.0.0.0  1998/12/08  21:36:52  hodel
-# Branch for beta release patches
-#
-# Revision 2.0  1998/12/08  21:34:57  hodel
-# Initial beta release of signals-as-lists rewrite;
-# sysdimensions now takes opt as an argument
-#
-# Revision 2.0.0.1  1998/12/08  20:54:19  hodel
-# sysdimensions takes opt parameter now
-#
-# Revision 2.0.0.0  1998/12/08  20:30:09  hodel
-# beta release revision
-#
-# Revision 2.0  1998/12/08  20:27:56  hodel
-# Initial list rewrite of OCST
-#
-# Revision 1.7  1998/10/21 12:46:59  hodelas
-# moved grid command so that grid appears in plots
-#
-# Revision 1.6  1998/09/04 20:57:18  hodelas
-# fixed bodquist bug (use reshape instead of  transpose); removed extraneous
-# output from bode.
-#
-# Bodquist is now much faster
-#
-# Revision 1.4  1998/08/24 15:50:03  hodelas
-# updated documentation
-#
-# Revision 1.3  1998/08/13 20:11:27  hodelas
-# Added calls to axis2dlim for flat-plots
-#
-# Revision 1.2  1998/07/24 18:16:51  hodelas
-# rewrote bodquist as a function call.  nyquist interactive plot now optional
-#
-# Revision 1.1.1.1  1998/05/19 20:24:05  jwe
-#
-# Revision 1.7  1998/02/09 13:04:11  scotte
-# fixed oneplot/gset nokey to function only if gnuplot_has_multiplot
-#
-# Revision 1.6  1997/12/01 16:51:50  scotte
-# updated by Mueller 27 Nov 97
-#
-# Revision 1.2  1997/11/24  18:53:01  mueller
-# gset autoscale prevents the following error message:
-#    line 0: x range must be greater than 0 for log scale!
-# gset nokey and call to oneplot() added
-#
-# Revision 1.1  1997/11/11  17:31:27  mueller
-# Initial revision
-#
 
   # check number of input arguments given
   if (nargin < 1 | nargin > 4)
@@ -158,7 +100,6 @@
       tistr = "(jw)";
     endif
     xlabel(xlstr);
-    ylabel("Gain in dB");
     if(is_siso(sys))
       if (gnuplot_has_multiplot)
         subplot(2,1,1);
@@ -172,7 +113,13 @@
       disp(outlist(outname,"	"));
     endif
     wv = [min(w), max(w)];
-    md = 20*log10(mag);
+    if(max(mag) > 0)
+      ylabel("Gain in dB");
+      md = 20*log10(mag);
+    else
+      ylabel("Gain |Y/U|")
+      md = mag;
+    endif
 
     axvec = axis2dlim([vec(w),vec(md)]);
     axvec(1:2) = wv;
--- a/scripts/control/bode_bounds.m
+++ b/scripts/control/bode_bounds.m
@@ -24,8 +24,6 @@
 #
 # used internally in freqresp
 
-# $Revision: 2.0.0.2 $
-
   # make sure zer,pol are row vectors
   if(!isempty(pol)) pol = reshape(pol,1,length(pol)); endif
   if(!isempty(zer)) zer = reshape(zer,1,length(zer)); endif
--- a/scripts/control/buildssic.m
+++ b/scripts/control/buildssic.m
@@ -108,7 +108,6 @@
 #
 
 # Written by Kai Mueller April 1998
-# $Revision: 2.0.0.2 $
 
   if((nargin < 5) || (nargin > 12))
     usage("[sys] = buildssic(Clst,Ulst,Olst,Ilst,s1,s2,s3,s4,s5,s6,s7,s8)");
--- a/scripts/control/c2d.m
+++ b/scripts/control/c2d.m
@@ -49,7 +49,6 @@
 # Written by R.B. Tenison (btenison@eng.auburn.edu)
 # October 1993
 # Updated by John Ingram for system data structure August 1996
-# $Revision: 1.15 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/com2str.m
+++ b/scripts/control/com2str.m
@@ -25,7 +25,6 @@
 #      0 (default):            -1, 0, 1,   1i,   1 + 0.5i
 #      1 (for use with zpout): -1, 0, + 1, + 1i, + 1 + 0.5i
 #
-# $Revision: 2.0.0.2 $
 
   if (nargin < 1 | nargin > 2)
     usage("com2str(zz{,flg})");
--- a/scripts/control/controldemo.m
+++ b/scripts/control/controldemo.m
@@ -21,7 +21,6 @@
 # Demo programs: bddemo.m, frdemo.m, analdemo.m, moddmeo.m, rldemo.m
 #  
 # Written by David Clem August 15, 1994
-# $Revision: 2.0.0.2 $    
 
   disp(' O C T A V E    C O N T R O L   S Y S T E M S   T O O L B O X')
 
--- a/scripts/control/ctrb.m
+++ b/scripts/control/ctrb.m
@@ -35,7 +35,6 @@
   # Written by Kai P. Mueller November 4, 1997
   # based on is_controllable.m of Scottedward Hodel
   # modified by
-  # $Revision: 2.0.0.2 $
 
   if (nargin == 2)
     a = sys;
--- a/scripts/control/d2c.m
+++ b/scripts/control/d2c.m
@@ -53,7 +53,6 @@
 # Written by R. Bruce Tenison August 23, 1994
 # Updated by John Ingram for system data structure  August 1996
 # SYS_INTERNAL accesses members of system data structure
-# $Revision: 2.0.0.2 $ 
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/damp.m
+++ b/scripts/control/damp.m
@@ -29,7 +29,6 @@
 
 # Written by Kai P. Mueller September 29, 1997.
 # Update
-# $Revision: 2.0.0.2 $
 
   # assume a continuous system
   DIGITAL = 0;
--- a/scripts/control/dare.m
+++ b/scripts/control/dare.m
@@ -47,7 +47,6 @@
 ## Author: A. S. Hodel <scotte@eng.auburn.edu>
 ## Created: August 1993
 ## Adapted-By: jwe
-## $Revision: 1.17 $
 
 function x = dare (a, b, c, r, opt)
 
--- a/scripts/control/dcgain.m
+++ b/scripts/control/dcgain.m
@@ -26,7 +26,6 @@
 #
 
 # Written by Kai P Mueller (mueller@ifr.ing.tu-bs.de) October 1, 1997
-# $Revision: 2.0.0.2 $
 
   if((nargin < 1) || (nargin > 2) || (nargout > 1))
     usage("[gm, ok] = dcgain(sys[, tol])");
--- a/scripts/control/dezero.m
+++ b/scripts/control/dezero.m
@@ -26,7 +26,6 @@
 ## Adapted from deblank by A. S. Hodel (a.s.hodel@eng.auburn.edu)
 ## 	(the name dezero is a reference to the Fermilab D0 experiment,
 ##      where my sister did her PhD research) 
-## $Revision: 2.0.0.2 $
 
 function t = dezero (s)
 
--- a/scripts/control/dgkfdemo.m
+++ b/scripts/control/dgkfdemo.m
@@ -19,7 +19,6 @@
 function dgkfdemo()
 # Octave Controls toolbox demo: H2/Hinfinity options demos
 # Written by A. S. Hodel June 1995
-# $Revision: 2.0.0.2 $
  
   save_val = page_screen_output;
   page_screen_output = 1;
--- a/scripts/control/dgram.m
+++ b/scripts/control/dgram.m
@@ -25,7 +25,6 @@
   # a m a' - m + b*b' = 0 
 
   # Written by A. S. Hodel July 1995
-  # $Revision: 1.13 $
 
   # let dlyap do the error checking...
   m = dlyap(a,b*b');
--- a/scripts/control/dhinfdemo.m
+++ b/scripts/control/dhinfdemo.m
@@ -1,3 +1,21 @@
+# Copyright (C) 1996,1998 Kai Mueller
+#
+# 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.
+
 # ------------------------------------------------------------
 # dhinfdemo   Design of a discrete H_infinity controller.
 #             This is not a true discrete design. The design
@@ -40,8 +58,6 @@
 
 # K. Mueller, <mueller@ifr.ing.tu-bs.de>
 # Technical University of Braunschweig, IfR
-# $Revision: 2.0.0.2 $  $Date: 1998/12/08 23:29:27 $
-#
 
 echo off
 disp(" ");
--- a/scripts/control/dlqe.m
+++ b/scripts/control/dlqe.m
@@ -45,8 +45,6 @@
 # Modified for discrete time by R. Bruce Tenison (btenison@eng.auburn.edu)
 # October, 1993
 
-# $Revision: 1.16 $
-
   if (nargin != 5 && nargin != 6)
     error ("dlqe: invalid number of arguments");
   endif
--- a/scripts/control/dlqg.m
+++ b/scripts/control/dlqg.m
@@ -47,7 +47,6 @@
 # See also: lqg, dlqe, dlqr
 
 # Written by A. S. Hodel August 1995
-# $Revision: 2.0.0.2 $
 
 warning("dlqg: obsolete. use lqg instead (system data structure format)");
 
--- a/scripts/control/dlqr.m
+++ b/scripts/control/dlqr.m
@@ -46,7 +46,6 @@
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
 # Converted to discrete time by R. B. Tenison
 # (btenison@eng.auburn.edu) October 1993
-# $Revision: 1.17 $
 
   if (nargin != 4 && nargin != 5)
     error ("dlqr: invalid number of arguments");
--- a/scripts/control/dlyap.m
+++ b/scripts/control/dlyap.m
@@ -34,7 +34,6 @@
 # (1977).
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
-# $Revision: 1.15 $
 
   if ((n = is_square (a)) == 0)
     warning ("dlyap: a must be square");
new file mode 100644
--- /dev/null
+++ b/scripts/control/dre.m
@@ -0,0 +1,126 @@
+# Copyright (C) 1998 A. Scottedward Hodel
+#
+# 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 [tvals,Plist] = dre(sys,Q,R,Qf,t0,tf,Ptol,maxits)
+# [tvals,Plist] = dre(sys,Q,R,Qf,t0,tf{,Ptol,maxits});
+# Solve the differential Riccati equation
+#   -d P/dt = A'P + P A - P B inv(R) B' P + Q
+#   P(tf) = Qf
+# for the LTI system sys.  Solution of standard LTI
+# state feedback optimization
+#   min \int_{t_0}^{t_f} x' Q x + u' R u dt + x(t_f)' Qf x(t_f)
+# optimal input is
+#   u = - inv(R) B' P(t) x
+# inputs:
+#   sys: continuous time system data structure
+#   Q: state integral penalty
+#   R: input integral penalty
+#   Qf: state terminal penalty
+#   t0,tf: limits on the integral
+#   Ptol: tolerance (used to select time samples; see below); default = 0.1
+#   max number of refinement iterations (default=10)
+# outputs:
+#   tvals: time values at which P(t) is computed
+#   Plist: list values of P(t); nth(Plist,ii) is P(tvals(ii)).
+#
+#   tvals is selected so that || nth(Plist,ii) - nth(Plist,ii-1) || < Ptol
+#     for ii=2:length(tvals)
+#
+# Reference:
+
+if(nargin < 6 | nargin > 8 | nargout != 2)
+  usage("[tvals,Plist] = dre(sys,Q,R,Qf,t0,tf{,Ptol})");
+elseif(!is_struct(sys))
+  error("sys must be a system data structure")
+elseif(is_digital(sys))
+  error("sys must be a continuous time system")
+elseif(!is_matrix(Q) | !is_matrix(R) | !is_matrix(Qf))
+  error("Q, R, and Qf must be matrices.");
+elseif(!is_scalar(t0) | !is_scalar(tf))
+  error("t0 and tf must be scalars")
+elseif(t0 >= tf)		error("t0=%e >= tf=%e",t0,tf);
+elseif(nargin == 6)		Ptol = 0.1;
+elseif(!is_scalar(Ptol))	error("Ptol must be a scalar");
+elseif(Ptol <= 0)		error("Ptol must be positive");
+endif
+
+if(nargin < 8) maxits = 10;
+elseif(!is_scalar(maxits))	error("maxits must be a scalar");
+elseif(maxits <= 0)		error("maxits must be positive");
+endif
+maxits = ceil(maxits);
+
+[aa,bb] = sys2ss(sys);
+nn = sysdimensions(sys,"cst");
+mm = sysdimensions(sys,"in");
+pp = sysdimensions(sys,"out");
+
+if(size(Q) != [nn nn])
+  error("Q(%dx%d); sys has %d states",rows(Q),columns(Q),nn);
+elseif(size(Qf) != [nn nn])
+  error("Qf(%dx%d); sys has %d states",rows(Qf),columns(Qf),nn);
+elseif(size(R) != [mm mm])
+  error("R(%dx%d); sys has %d inputs",rows(R),columns(R),mm);
+endif
+
+# construct Hamiltonian matrix
+H = [aa , -(bb/R)*bb' ; -Q, -aa'];
+
+# select time step to avoid numerical overflow
+fast_eig = max(abs(eig(H)));
+tc = log(10)/fast_eig;
+nst = ceil((tf-t0)/tc);
+tvals = -linspace(-tf,-t0,nst);
+Plist = list(Qf);
+In = eye(nn);
+n1 = nn+1;
+n2 = nn+nn;
+done = 0;
+while(!done)
+  done = 1;      # assume this pass will do the job
+  # sort time values in reverse order
+  tvals = -sort(-tvals);
+  tvlen = length(tvals);
+  maxerr = 0;
+  # compute new values of P(t); recompute old values just in case
+  for ii=2:tvlen
+    uv_i_minus_1 = [ In ; nth(Plist,ii-1) ];
+    delta_t = tvals(ii-1) - tvals(ii);
+    uv = expm(-H*delta_t)*uv_i_minus_1;
+    Qi = uv(n1:n2,1:nn)/uv(1:nn,1:nn);
+    Plist(ii) = (Qi+Qi')/2;
+    # check error
+    Perr = norm(nth(Plist,ii) - nth(Plist,ii-1))/norm(nth(Plist,ii));
+    maxerr = max(maxerr,Perr);
+    if(Perr > Ptol)
+      new_t = mean(tvals([ii,ii-1]));
+      tvals = [tvals new_t];
+      done = 0;
+    endif
+  endfor
+
+  # check number of iterations
+  maxits = maxits - 1;
+  done = done+(maxits==0);
+endwhile
+if(maxerr > Ptol)
+  warning("dre: \n\texiting with%4d points, max rel chg. =%e, Ptol=%e\n", ...
+	tvlen,maxerr,Ptol);
+  tvals = tvals(1:length(Plist));
+endif
+endfunction
--- a/scripts/control/fir2sys.m
+++ b/scripts/control/fir2sys.m
@@ -32,7 +32,6 @@
   #  Name changed to TF2SYS July 1995
   #  updated for new system data structure format July 1996
   # adapted from tf2sys july 1996
-  # $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;
   implicit_str_to_num_ok = 1;
--- a/scripts/control/frdemo.m
+++ b/scripts/control/frdemo.m
@@ -20,7 +20,6 @@
 # Octave Controls toolbox demo: Frequency Response demo
 # Written by David Clem August 15, 1994 
 
-# $Revision: 2.0.0.2 $
 # a s hodel: updated to match new order of ss2zp outputs
 # J Ingram:  updated for system data structure format August 1996
 
--- a/scripts/control/freqchkw.m
+++ b/scripts/control/freqchkw.m
@@ -21,7 +21,6 @@
   # used by freqresp to check that input frequency vector is legal
 
   # A S Hodel July 1996
-  # $Revision: 2.0.0.2 $
 
   if(isempty(w))
     USEW = 0;
--- a/scripts/control/freqresp.m
+++ b/scripts/control/freqresp.m
@@ -28,7 +28,6 @@
   #      ff and w are both returned as row vectors
 
   #  Written by: R. Bruce Tenison July 11, 1994
-  # $Revision: 2.0.0.2 $
   # SYS_INTERNAL accesses members of system data structure
 
   save_val = empty_list_elements_ok;
--- a/scripts/control/gram.m
+++ b/scripts/control/gram.m
@@ -25,7 +25,6 @@
   # a m + a' + b*b' = 0 
 
   # Written by A. S. Hodel 
-  # $Revision: 2.0.0.2 $
 
   # let lyap do the error checking...
   m = lyap(a,b*b');
--- a/scripts/control/h2norm.m
+++ b/scripts/control/h2norm.m
@@ -30,7 +30,6 @@
 
   # A. S. Hodel Aug 1995
   # updated for system data structure by John Ingram November 1996
-  # $Revision: 2.0.0.2 $
 
   if((nargin != 1))
     usage("h2gain = h2norm(sys)");
--- a/scripts/control/h2syn.m
+++ b/scripts/control/h2syn.m
@@ -42,7 +42,6 @@
   #    Pf: ARE solution matrix for filter subproblem
 
   # Updated for System structure December 1996 by John Ingram
-  # $Revision: 2.0.0.2 $
 
   if ((nargin < 3) | (nargin > 4))
     usage("[K,gain, Kc, Kf, Pc, Pf] = h2syn(Asys,nu,ny[,tol])");
--- a/scripts/control/hinf_ctr.m
+++ b/scripts/control/hinf_ctr.m
@@ -31,11 +31,9 @@
   # Do not attempt to use this at home; no argument checking performed.
 
   # A. S. Hodel August 1995
-  # $Revision: 2.0.0.2 $
   # Revised by Kai P Mueller April 1998 to solve the general H_infinity
   # problem using unitary transformations Q (on w and z)
   # and non-singular transformations R (on u and y).
-  # $Revision: 2.0.0.2 $
 
   nw = dgs.nw;
   nu = dgs.nu;
--- a/scripts/control/hinfdemo.m
+++ b/scripts/control/hinfdemo.m
@@ -1,3 +1,21 @@
+# Copyright (C) 1996,1998 Kai Mueller
+#
+# 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.
+
 # hinfdemo  H_infinity design demos for continuous SISO and MIMO
 #           systems and a discrete system.
 #           The SISO system is difficult to control because
@@ -99,7 +117,6 @@
 
 
 # Kai P. Mueller 30-APR-1998 <mueller@ifr.ing.tu-bs.de
-# $Revision: 2.0.0.2 $
 
 yn = [];
 while (length(yn) < 1)
--- a/scripts/control/hinfnorm.m
+++ b/scripts/control/hinfnorm.m
@@ -39,7 +39,6 @@
   # Iglesias and Glover, "State-Space approach to discrete-time Hinf control,"
   #    Int. J. Control, vol 54, #5, 1991
   # Zhou, Doyle, Glover, "Robust and Optimal Control," Prentice-Hall, 1996
-  # $Revision: 2.0.0.2 $
 
   if((nargin == 0) || (nargin > 4))
     usage("[g gmin gmax] = hinfnorm(sys[,tol,gmin,gmax,ptol])");
--- a/scripts/control/hinfsyn.m
+++ b/scripts/control/hinfsyn.m
@@ -1,4 +1,4 @@
-# Copyright (C) 1996 A. Scottedward Hodel 
+# Copyright (C) 1996,1998 A. Scottedward Hodel 
 #
 # This file is part of Octave. 
 #
@@ -56,15 +56,10 @@
 
   # A. S. Hodel August 1995
   # Updated for Packed system structures December 1996 by John Ingram
-  # $Revision: 2.0.0.2 $
   #
   # Revised by Kai P Mueller April 1998 to solve the general H_infinity
   # problem using unitary transformations Q (on w and z)
   # and non-singular transformations R (on u and y).
-  # $Revision: 2.0.0.2 $
-
-  old_page_val = page_screen_output;
-  page_screen_output = 0;
 
   if( (nargin < 1) | (nargin > 8) )
     usage("[K,g,GW,Xinf,Yinf] = hinfsyn(Asys,nu,ny,gmin,gmax,gtol,ptol,tol)");
@@ -151,17 +146,38 @@
     printf("----------------------------------------");
     printf("--------------------------------------\n");
 
+    # set up error messages
+    errmesg = list(" o   o   o   o   o  ", ...
+	" #   -   -   -   -  ", ...
+	" o   #   -   -   -  ", ...
+	" o   o   #   -   -  ", ...
+	" o   o   o   #   -  ", ...
+	" o   o   o   o   #  ", ...
+	" -   -   -   -   -  ");
+    errdesx = list("", ...
+	"X im eig.", ...
+	"Hx not Ham.", ...
+	"X inf.eig", ...
+	"X not symm.", ...
+	"X not pos", ...
+	"R singular");
+
+    errdesy = list(" ", ...
+	"Y im eig.", ...
+	"Hy not Ham.", ...
+	"Y inf.eig", ...
+	"Y not symm.", ...
+	"Y not pos", ...
+	"Rtilde singular");
+
+
     # now do the search
     while (!iteration_finished)
       switch (search_state)
-        case (0)
-	  g = ghi;
-        case (1)
-	  g = glo;
-        case (2)
-	  g = 0.5 * (ghi + glo);
-        otherwise
-	  error(" *** This should never happen!");
+        case (0) 	g = ghi;
+        case (1) 	g = glo;
+        case (2) 	g = 0.5 * (ghi + glo);
+        otherwise 	error(" *** This should never happen!");
       endswitch
       printf("%10.4f ", g);
 
@@ -175,128 +191,39 @@
       Rtilde(1:nz,1:nz) = -g*g*eye(nz);
       Rtilde = Rtilde + ddot1 * ddot1';
 
-      # build hamiltonian Ha for X_inf
-      xx = ([BB; -C1'*d1dot]/R) * [d1dot'*C1 BB'];
-      Ha = [A 0*A; -C1'*C1 -A'] - xx;
-      x_ha_err = 0;
-      # copied from from are(...)...
-      [d, Ha] = balance(Ha);
-      [u, s] = schur(Ha, "A");
-      rev = real(eig(s));
-      if (any(abs(rev) <= ptol))
-        # eigenvalues near the imaginary axis
-        x_ha_err = 1;
-      elseif (sum(rev > 0) != sum(rev < 0))
-        # unequal number of positive and negative eigenvalues
-	x_ha_err = 2;
-      else
-	# compute positive Riccati equation solution
-      	u = d * u;
-      	Xinf = u(n+1:2*n,1:n) / u(1:n,1:n);
-	if (!all(all(finite(Xinf))))
-	  x_ha_err = 3;
-	elseif (norm(Xinf-Xinf') >= 10*ptol)
-	  # solution not symmetric
-	  x_ha_err = 4;
-	else
-	  # positive semidefinite?
-	  rev = eig(Xinf);
-	  if (any(rev <= -ptol))
-	    x_ha_err = 5;
-	  endif
-	endif
-      endif
-      
-      # build hamiltonian Ha for Y_inf
-      xx = ([CC'; -B1*ddot1']/Rtilde) * [ddot1*B1' CC];
-      Ha = [A' 0*A; -B1*B1' -A] - xx;
-      y_ha_err = 0;
-      # copied from from are(...)...
-      [d, Ha] = balance(Ha);
-      [u, s] = schur(Ha, "A");
-      rev = real(eig(s));
-      if (any(abs(rev) <= ptol))
-        # eigenvalues near the imaginary axis
-        y_ha_err = 1;
-      elseif (sum(rev > 0) != sum(rev < 0))
-        # unequal number of positive and negative eigenvalues
-	y_ha_err = 2;
-      else
-	# compute positive Riccati equation solution
-      	u = d * u;
-      	Yinf = u(n+1:2*n,1:n) / u(1:n,1:n);
-	if (!all(all(finite(Yinf))))
-	  y_ha_err = 3;
-	elseif (norm(Yinf-Yinf') >= 10*ptol)
-	  # solution not symmetric
-	  x_ha_err = 4;
-     	else
-	  # positive semidefinite?
-	  rev = eig(Yinf);
-	  if (any(rev <= -ptol))
-	    y_ha_err = 5;
-	  endif
-	endif
-      endif
+      [Xinf,x_ha_err] = hinfsyn_ric(A,BB,C1,d1dot,R,ptol);
+      [Yinf,y_ha_err] = hinfsyn_ric(A',CC',B1',ddot1',Rtilde,ptol);
 
       # assume failure for this gamma
       passed = 0;
+      rerr="";
       if (!x_ha_err && !y_ha_err)
 	# test spectral radius condition
 	rho = max(abs(eig(Xinf * Yinf)));
 	if (rho < g*g)
 	  # spectral radius condition passed
 	  passed = 1;
+        else
+          rerr = sprintf("rho=%f",rho);
 	endif
       endif
 
-      switch (x_ha_err)
-	case (0)
-	  #       iax nev ene sym pos
-	  printf(" o   o   o   o   o  ");
-          xerr = " ";
-	case (1)
-	  printf(" #   -   -   -   -  ");
-          xerr = "X im.eig.";
-	case (2)
-	  printf(" o   #   -   -   -  ");
-          xerr = "Hx not Ham.";
-	case (3)
-	  printf(" o   o   #   -   -  ");
-          xerr = "X inf.eig.";
-	case (4)
-	  printf(" o   o   o   #   -  ");
-          xerr = "X not symm.";
-	case (5)
-	  printf(" o   o   o   o   #  ");
-          xerr = "X not pos.";
-	otherwise
-	  error(" *** Xinf fail: this should never happen!");
-      endswitch
-      switch (y_ha_err)
-	case (0)
-	  #       iax nev ene sym pos rho
-	  if (passed)
-	    printf(" o   o   o   o   o   o    y  all tests passed.\n");
-	  elseif (x_ha_err)
-	    printf(" o   o   o   o   o   -    n  %s\n", xerr);
-	  else
-	    printf(" o   o   o   o   o   #    n  rho=%f.\n", rho);
-	  endif
-	case (1)
-	  printf(" #   -   -   -   -   -    n  %s/Y im. eig.", xerr);
-	case (2)
-	  printf(" o   #   -   -   -   -    n  %s/Hy not Ham.", xerr);
-	case (3)
-	  printf(" o   o   #   -   -   -    n  %s/Y inf.eig.", xerr);
-	case (4)
-	  printf(" o   o   o   #   -   -    n  %s/Y not symm.", xerr);
-	case (5)
-	  printf(" o   o   o   o   #   -    n  %s/Y not pos.", xerr);
-	otherwise
-	  error(" *** Yinf fail: this should never happen!");
-      endswitch
+      if(x_ha_err >= 0 & x_ha_err <= 6)
+        printf("%s",nth(errmesg,x_ha_err+1));
+        xerr = nth(errdesx,x_ha_err+1);
+      else
+        error(" *** Xinf fail: this should never happen!");
+      endif
 
+      if(y_ha_err >= 0 & y_ha_err <= 6)
+        printf("%s",nth(errmesg,y_ha_err+1));
+        yerr = nth(errdesy,y_ha_err+1);
+      else
+        error(" *** Yinf fail: this should never happen!");
+      endif
+
+      if(passed)  printf("  y all tests passed.\n");
+      else        printf("  n %s/%s%s\n",xerr,yerr,rerr);          endif
 
       if (passed && (de/g < gtol))
 	search_state = 3;
@@ -312,25 +239,19 @@
             search_state = 1;
 	  endif
         case (1)
-	  if (!passed)
-            search_state = 2;
+	  if (!passed)      search_state = 2;
 	  else
 	    # lower bound must not pass but passed
 	    fprintf(" *** the lower bound of gamma (%f) passed.\n", g);
 	    iteration_finished = 3;
 	  endif
         case (2)
-	  if (!passed)
-	    glo = g;
-	  else
-	    ghi = g;
-	  endif
-	    de = ghi - glo;
-        case (3)
-	  # done
-	  iteration_finished = 1;
-        otherwise
-	  error(" *** This should never happen!");
+          # Normal case; must check that singular R, Rtilde wasn't the problem.
+	  if ((!passed) & (x_ha_err != 6) & (y_ha_err != 6) ) glo = g;
+	  else         ghi = g;        endif
+	  de = ghi - glo;
+        case (3)       iteration_finished = 1;        # done
+        otherwise      error(" *** This should never happen!");
       endswitch
     endwhile
 
@@ -366,5 +287,4 @@
 
   endif
 
-  page_screen_output = old_page_val;
 endfunction
--- a/scripts/control/hinfsyn_chk.m
+++ b/scripts/control/hinfsyn_chk.m
@@ -35,7 +35,6 @@
   # Do not attempt to use this at home; no argument checking performed.
 
   # A. S. Hodel August 1995
-  # $Revision: 2.0.0.2 $
 
   Pc = Pf = [];
 
new file mode 100644
--- /dev/null
+++ b/scripts/control/hinfsyn_ric.m
@@ -0,0 +1,72 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel
+#
+# 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 [Xinf,x_ha_err] = hinfsyn_ric(A,BB,C1,d1dot,R,ptol)
+#
+# forms
+#        xx = ([BB; -C1'*d1dot]/R) * [d1dot'*C1 BB'];
+#        Ha = [A 0*A; -C1'*C1 -A'] - xx;
+# and solves associated Riccati equation
+# returns error code
+#  x_ha_err:
+#    0: successful
+#    1: Xinf has imaginary eigenvalues
+#    2: Hx not Hamiltonian
+#    3: Xinf has inf. eigenvalues (numerical overflow)
+#    4: Xinf not symmetric
+#    5: Xinf not positive definite
+#    6: R is singular
+
+x_ha_err = 0;        # assume success
+Xinf = [];		     # default return value
+n = is_square(A);
+nw = is_square(R);
+if(rank(R) != nw)    x_ha_err = 6;
+else                 # build hamiltonian Ha for X_inf
+  xx = ([BB; -C1'*d1dot]/R) * [d1dot'*C1 BB'];
+  Ha = [A 0*A; -C1'*C1 -A'] - xx;
+  x_ha_err = 0;
+  [d, Ha] = balance(Ha);
+  [u, s] = schur(Ha, "A");
+  rev = real(eig(s));
+
+  if (any(abs(rev) <= ptol))	# eigenvalues near the imaginary axis
+    x_ha_err = 1;
+  elseif (sum(rev > 0) != sum(rev < 0))
+    # unequal number of positive and negative eigenvalues
+    x_ha_err = 2;
+  else
+    # compute positive Riccati equation solution
+    u = d * u;
+    Xinf = u(n+1:2*n,1:n) / u(1:n,1:n);
+    if (!all(all(finite(Xinf))))
+      x_ha_err = 3;
+    elseif (norm(Xinf-Xinf') >= 10*ptol)
+      # solution not symmetric
+      x_ha_err = 4;
+    else
+      # positive semidefinite?
+      # force symmetry (faster, avoids some convergence problems)
+      Xinf = (Xinf + Xinf')/2;
+      rev = eig(Xinf);
+      if (any(rev <= -ptol))
+        x_ha_err = 5;
+      endif
+    endif
+  endif
+endif
--- a/scripts/control/impulse.m
+++ b/scripts/control/impulse.m
@@ -36,7 +36,6 @@
 # Written by Kai P. Mueller October 2, 1997
 # based on lsim.m of Scottedward Hodel
 # modified by
-# $Revision: 2.0.0.2 $
 
   if((nargin < 1) || (nargin > 4))
     usage("[y, u] = impulse(sys[, inp, tstop, n])");
--- a/scripts/control/is_abcd.m
+++ b/scripts/control/is_abcd.m
@@ -29,7 +29,6 @@
   # Written by Kai P. Mueller November 4, 1997
   # based on is_controllable.m of Scottedward Hodel
   # modified by
-  # $Revision: 2.0.0.2 $
 
   retval = 0;
   switch (nargin)
--- a/scripts/control/is_controllable.m
+++ b/scripts/control/is_controllable.m
@@ -37,7 +37,6 @@
 # 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 for packed systems
-# $Revision: 1.16 $
 
   deftol = 1;    # assume default tolerance
   if(nargin < 1 | nargin > 3)
--- a/scripts/control/is_detectable.m
+++ b/scripts/control/is_detectable.m
@@ -31,7 +31,6 @@
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
 # Updated by John Ingram (ingraje@eng.auburn.edu) July 1996.
-# $Revision: 2.0.0.2 $ 
 
   if( nargin < 1) 
     usage("[retval,U] = is_detectable(a , c {, tol})");
--- a/scripts/control/is_dgkf.m
+++ b/scripts/control/is_dgkf.m
@@ -70,7 +70,6 @@
   
   #  Written by A. S. Hodel
   #  Updated by John Ingram July 1996 to accept structured systems
-  #  $Revision: 2.0.0.2 $
   #
   # Revised by Kai P Mueller April 1998 to solve the general H_infinity
   # problem using unitary transformations Q (on w and z)
@@ -92,7 +91,6 @@
   #
   # This transformation together with the algorithm in [1] solves
   # the general problem (see [2] for example). 
-  # $Revision: 2.0.0.2 $
 
   if (nargin < 3) | (nargin > 4)
     usage("[retval,dgkf_struct] = is_dgkf(Asys,nu,ny{,tol})");
--- a/scripts/control/is_digital.m
+++ b/scripts/control/is_digital.m
@@ -22,7 +22,6 @@
 # exits with an error of sys is a mixed (continuous and discrete) system
 
 # a s hodel July 1996
-# $Revision: 2.0.0.2 $
 # SYS_INTERNAL accesses members of system structure
 
   # checked for sampled data system (mixed)
--- a/scripts/control/is_observable.m
+++ b/scripts/control/is_observable.m
@@ -31,7 +31,6 @@
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
 # Updated by John Ingram (ingraje@eng.auburn.edu) July 1996.
-# $Revision: 1.16 $ 
 
   if( nargin < 1) 
     usage("[retval,U] = is_observable(a , c {, tol})");
--- a/scripts/control/is_sample.m
+++ b/scripts/control/is_sample.m
@@ -22,7 +22,6 @@
 # (real,scalar, > 0)
 
 # A. S. Hodel July 1995
-# $Revision: 2.0.0.2 $
 
 out = (is_scalar(Ts) && (Ts == abs(Ts)) && (Ts != 0) );
 
new file mode 100644
--- /dev/null
+++ b/scripts/control/is_signal_list.m
@@ -0,0 +1,33 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel
+#
+# 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 flg = is_signal_list(mylist)
+# function flg = is_signal_list(mylist)
+# returns true if mylist is a list of individual strings.
+# 
+
+flg = is_list(mylist);
+if(flg)
+  for ii=1:length(mylist)
+    if(!(isstr(nth(mylist,ii)) & rows(nth(mylist,ii)) ==1) )
+      flg = 0;
+    endif
+  endfor
+endif
+
+endfunction
--- a/scripts/control/is_siso.m
+++ b/scripts/control/is_siso.m
@@ -21,8 +21,6 @@
 # return nonzero if the system sys is single-input, single-output.
 
 # a s hodel July 1996, 1998
-# $Revision: 2.0.0.2 $
-# SYS_INTERNAL accesses members of system structure
 
   if(nargin != 1)
     usage("SISO = is_siso(sys)");
--- a/scripts/control/is_stabilizable.m
+++ b/scripts/control/is_stabilizable.m
@@ -38,7 +38,6 @@
 # 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
-# $Revision: 2.0.0.2 $
 
   if(nargin < 1)        usage("[retval,U] = is_stabilizable(a {, b ,tol})");
   elseif(is_struct(a))
--- a/scripts/control/is_stable.m
+++ b/scripts/control/is_stable.m
@@ -33,7 +33,6 @@
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August, 1993.
 # Updated by John Ingram (ingraje@eng.auburn.edu) July, 1996 for systems
 # Updated to simpler form by a.s.hodel 1998
-# $Revision: 2.0.0.2 $
 
   if( (nargin < 1) | (nargin > 3) )   usage("is_stable(a {,tol,disc})");
   elseif(is_struct(a))
--- a/scripts/control/jet707.m
+++ b/scripts/control/jet707.m
@@ -28,7 +28,6 @@
 
   # Written by Kai P. Mueller September 28, 1997
   # Updates
-  # $Revision: 2.0.0.2 $
 
   if (nargin != 0)
     usage("outsys = jet707()")
--- a/scripts/control/lqe.m
+++ b/scripts/control/lqe.m
@@ -40,7 +40,6 @@
 #   e = closed loop poles of (A - K C)
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August, 1993.
-# $Revision: 1.16 $
 
   if ( (nargin != 5) && (nargin != 6))
     error ("lqe: invalid number of arguments");
--- a/scripts/control/lqg.m
+++ b/scripts/control/lqg.m
@@ -48,7 +48,6 @@
 
 # Written by A. S. Hodel August 1995; revised for new system format
 # August 1996
-# $Revision: 2.0.0.2 $
 
 sav_val = implicit_str_to_num_ok;
 implicit_str_to_num_ok = 1;
--- a/scripts/control/lqr.m
+++ b/scripts/control/lqr.m
@@ -47,7 +47,6 @@
 # reference: Anderson and Moore, OPTIMAL CONTROL: LINEAR QUADRATIC METHODS,
 # Prentice-Hall, 1990, pp. 56-58
 
-# $Revision: 1.15 $
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
 
--- a/scripts/control/lsim.m
+++ b/scripts/control/lsim.m
@@ -35,7 +35,6 @@
 
 # Written by David Clem, A. S. Hodel July 1995
 # modified by John Ingram for system format August 1996
-# $Revision: 2.0.0.2 $
 
 
   if((nargin < 3)||(nargin > 4))
--- a/scripts/control/ltifr.m
+++ b/scripts/control/ltifr.m
@@ -32,7 +32,6 @@
 
   # R. B. Tenison, D. Clem, A. S. Hodel, July 1995
   # updated by John Ingram August 1996 for system format
-  # $Revision: 2.0.0.2 $
   
   if ((nargin < 2) || (nargin > 3))
     error("incorrect number of input arguments");
--- a/scripts/control/mb.m
+++ b/scripts/control/mb.m
@@ -1,8 +1,24 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel
+#
+# 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.
+
 # I think that this m-file can be deleted
 # a.s.hodel@eng.auburn.edu - 4 Dec. 1998
 
-# $Revision: 2.0.0.2 $
-
 Ap = [0 1;1960 0];
 Bp = [0;-6261];
 Cp = [1 0];
--- a/scripts/control/minfo.m
+++ b/scripts/control/minfo.m
@@ -33,7 +33,6 @@
   # Written by R. Bruce Tenison July 29, 1994
   # Modified by David Clem November 13, 1994
   # Modified by A. S. Hodel July 1995
-  # $Revision: 2.0.0.2 $
 
   warning("minfo: obsolete.  Use sys2ss, sys2tf, or sys2zp.");
     
--- a/scripts/control/moddemo.m
+++ b/scripts/control/moddemo.m
@@ -20,7 +20,6 @@
 # Octave Controls toolbox demo: Model Manipulations demo
 # Written by David Clem August 15, 1994
 
-# $Revision: 2.0.0.2 $
 # a s hodel: updated to reflect updated output order in ss2zp
 
   while (1)
--- a/scripts/control/nichols.m
+++ b/scripts/control/nichols.m
@@ -92,7 +92,6 @@
       tistr = "(jw)";
     endif
     xlabel("Phase (deg)");
-    ylabel("Gain in dB");
     if(is_siso(sys))
       title(["Nichols plot of |[Y/U]",tistr,"|, u=", ...
 	sysgetsignals(sys,"in",1,1), ", y=",sysgetsignals(sys,"out",1,1)]);
@@ -101,7 +100,14 @@
       printf("MIMO plot from\n%s\nto\n%s\n",outlist(inname,"	"), ...
         outlist(outname,"	"));
     endif
-    md = 20*log10(mag);
+    if(max(mag) > 0)
+      ylabel("Gain in dB");
+      md = 20*log10(mag);
+    else
+      ylabel("Gain |Y/U|")
+      md = mag;
+    endif
+
     axvec = axis2dlim([vec(phase),vec(md)]);
     axis(axvec);
     plot(phase,md);
--- a/scripts/control/obsv.m
+++ b/scripts/control/obsv.m
@@ -39,7 +39,6 @@
 
   # Written by Kai P. Mueller November 4, 1997
   # modified by
-  # $Revision: 2.0.0.2 $
 
   if (nargin == 2)
     a = sys;
--- a/scripts/control/ord2.m
+++ b/scripts/control/ord2.m
@@ -38,7 +38,6 @@
 
   # Written by Kai P. Mueller September 28, 1997
   # Updates
-  # $Revision: 2.0.0.2 $
 
   if(nargin != 2 & nargin != 3)
     usage("outsys = ord2(nfreq, damp[, gain])")
--- a/scripts/control/outlist.m
+++ b/scripts/control/outlist.m
@@ -34,7 +34,6 @@
 #   prints the list to the screen, numbering each string in order.
 
 # A. S. Hodel Dec. 1995, 1998
-# $Revision: 2.0.0.2 $
 
 #save for restore later
 save_empty = empty_list_elements_ok;
--- a/scripts/control/packedform.m
+++ b/scripts/control/packedform.m
@@ -16,7 +16,6 @@
 # along with Octave; see the file COPYING.  If not, write to the Free 
 # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  
-# $Revision#
 save_var = page_screen_output;
 page_screen_output = 1;
 disp("Description of system data structure:")
--- a/scripts/control/packsys.m
+++ b/scripts/control/packsys.m
@@ -32,7 +32,6 @@
   # Written by R. Bruce Tenison  July 29, 1994
   # Modified by David Clem November 13, 1994
   # Modified by A. S. Hodel April 1995
-  # $Revision: 2.0.0.2 $
 
   warning("packsys is obsolete!  Use ss2sys instead.");
   
--- a/scripts/control/parallel.m
+++ b/scripts/control/parallel.m
@@ -33,7 +33,6 @@
 # Written by David Clem August 15, 1994
 # completely rewritten Oct 1996 a s hodel
 # SYS_INTERNAL accesses members of system structure
-# $Revision: 2.0.0.2 $
 
   if(nargin != 2)
     usage("sysp = parallel(Asys,Bsys)");
@@ -48,10 +47,18 @@
   if(mA != mB)
     error(["Asys has ",num2str(mA)," inputs, Bsys has ",num2str(mB)," inputs"]);
   endif
+
+  # save signal names
+  Ain = sysgetsignals(Asys,"in");
+
+  # change signal names to avoid warning messages from sysgroup
+  Asys = syssetsignals(Asys,"in",sysdefioname(length(Ain),"Ain_u"));
+  Bsys = syssetsignals(Bsys,"in",sysdefioname(length(Ain),"Bin_u"));
+
   sysp = sysgroup(Asys,Bsys);
   sysD = ss2sys([],[],[],[eye(mA);eye(mA)]);
   
   sysp = sysmult(sysp,sysD);
-  sysp = syssetsignals(sysp,"in",sysgetsignals(Asys,"in"));
+  sysp = syssetsignals(sysp,"in",Ain);
   
 endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/control/pinv.m
@@ -0,0 +1,54 @@
+# Copyright (C) 1994 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 = pinv (X, tol)
+
+# usage: pinv (X, tol)
+#
+# Returns the pseudoinverse of X; singular values less than tol are
+# ignored.
+#
+# If the second argument is omitted, it is assumed that
+#
+#   tol = max (size (X)) * sigma_max (X) * eps,
+#
+# where sigma_max(X) is the maximal singular value of X.
+
+# Written by Kurt Hornik (hornik@neuro.tuwien.ac.at) March 1993.
+# Dept of Probability Theory and Statistics TU Wien, Austria.
+
+  if (nargin < 1 || nargin > 2)
+    error ("usage: pinv (X [, tol])");
+  endif
+
+  [U, S, V] = svd(X);
+  s = diag(S);
+
+  if (nargin == 1)
+    tol = max (size (X)) * s (1) * eps;
+  endif
+
+  r = sum (s > tol);
+  if (r == 0)
+    retval = zeros (X');
+  else
+    D = diag (ones (r, 1) ./ s (1:r));
+    retval = V (:, 1:r) * D * U (:, 1:r)';
+  endif
+
+endfunction
--- a/scripts/control/place.m
+++ b/scripts/control/place.m
@@ -40,7 +40,6 @@
 #
 # code adaped by A.S.Hodel (a.s.hodel@eng.auburn.edu) for use in controls
 # toolbox
-# $Revision: 2.0.0.2 $
 
   sav_val = empty_list_elements_ok;
   empty_list_elements_ok = 1;
--- a/scripts/control/polyout.m
+++ b/scripts/control/polyout.m
@@ -30,7 +30,6 @@
 
 # Written by A. Scottedward Hodel (scotte@eng.auburn.edu) May 1995)
 # Nov 1998: Correctly handles complex coefficients
-# $Revision: 2.0.0.2 $ 
   
   if (nargin < 1 ) || (nargin > 2) || (nargout < 0 ) || (nargout > 1)
     usage("[y = ] polyout(c,[x])");
--- a/scripts/control/prompt.m
+++ b/scripts/control/prompt.m
@@ -23,7 +23,6 @@
 # Written by David Clem August 15, 1994
 # Modified A. S. Hodel June 1995
 
-# $Revision: 2.0.0.2 $
 
 if(nargin > 1)
   usage("prompt([str])");
--- a/scripts/control/rldemo.m
+++ b/scripts/control/rldemo.m
@@ -20,7 +20,6 @@
 # Octave Controls toolbox demo: Root Locus demo
 # Written by David Clem August 15, 1994
 # Updated by John Ingram December 1996
-# $Revision: 2.0.0.2 $
 
   while (1)
     clc
--- a/scripts/control/rlocus.m
+++ b/scripts/control/rlocus.m
@@ -42,7 +42,6 @@
   # Written by Clem and Tenison
   # Updated by Kristi McGowan July 1996 for intelligent gain selection
   # Updated by John Ingram July 1996 for systems
-  # $Revision: 2.0.0.2 $
   
   if (nargin < 1) | (nargin > 4)
     usage("rlocus(sys[,inc,mink,maxk])");
--- a/scripts/control/rotg.m
+++ b/scripts/control/rotg.m
@@ -22,7 +22,5 @@
   #
   # NOTE: Use [c,s] = givens(a,b) instead.
 
-  # $Revision: 2.0.0.2 $
-
   [c,s] = givens(a,b);
 endfunction
--- a/scripts/control/run_cmd.m
+++ b/scripts/control/run_cmd.m
@@ -1,8 +1,24 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel
+#
+# 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.
+
 # run_cmd: short script used in demos
 # prints string cmd to the screen, then executes after a pause
 
-# $Revision: 2.0.0.2 $
-
 disp(["Command: ",cmd])
 puts("Press a key to execute command");
 fflush(stdout);
--- a/scripts/control/series.m
+++ b/scripts/control/series.m
@@ -38,7 +38,6 @@
 # Written by David Clem August 15, 1994
 
 # If two arguments input, take care of mu system case
-# $Revision: 2.0.0.2 $
 
   warning("series is superseded by sysmult; use sysmult instead.")
 
--- a/scripts/control/sortcom.m
+++ b/scripts/control/sortcom.m
@@ -32,7 +32,6 @@
 # idx: permutation vector: yy = xx(idx)
 
 # Written by A. S. Hodel June 1995
-# $Revision: 2.0.0.2 $
 
   if( nargin < 1 | nargin > 2 )
      usage("yy = sortcom(xx[,opt]");
@@ -46,34 +45,35 @@
       error("sortcom: second argument must be a string");
     endif
   endif
-
-  if(strcmp(opt,"re"))        datavec = real(xx);
-  elseif(strcmp(opt,"im"))    datavec = imag(xx);
-  elseif(strcmp(opt,"mag"))   datavec = abs(xx);
+ 
+  if(isempty(xx))
+    yy = idx = [];
   else
-    error(["sortcom: illegal option = ", opt])
-  endif
-
-  [datavec,idx] = sort(datavec);
-  yy= xx(idx);
+    if(strcmp(opt,"re"))        datavec = real(xx);
+    elseif(strcmp(opt,"im"))    datavec = imag(xx);
+    elseif(strcmp(opt,"mag"))   datavec = abs(xx);
+    else                        error(["sortcom: illegal option = ", opt])
+    endif
   
-  if(strcmp(opt,"re") | strcmp(opt,"mag"))
-    # sort so that complex conjugate pairs appear together
+    [datavec,idx] = sort(datavec);
+    yy= xx(idx);
     
-    ddiff = diff(datavec);
-    zidx = find(ddiff == 0);
-
-    # sort common datavec values
-    if(!isempty(zidx))
-      for iv=create_set(datavec(zidx))
-        vidx = find(datavec == iv);
-        [vals,imidx] = sort(imag(yy(vidx)));
-        yy(vidx)  = yy(vidx(imidx));
-        idx(vidx) = idx(vidx(imidx));
-      endfor
+    if(strcmp(opt,"re") | strcmp(opt,"mag"))
+      # sort so that complex conjugate pairs appear together
+      
+      ddiff = diff(datavec);
+      zidx = find(ddiff == 0);
+  
+      # sort common datavec values
+      if(!isempty(zidx))
+        for iv=create_set(datavec(zidx))
+          vidx = find(datavec == iv);
+          [vals,imidx] = sort(imag(yy(vidx)));
+          yy(vidx)  = yy(vidx(imidx));
+          idx(vidx) = idx(vidx(imidx));
+        endfor
+      endif
     endif
-
-  endif
-
+  endif  
 endfunction
-
+  
--- a/scripts/control/ss2sys.m
+++ b/scripts/control/ss2sys.m
@@ -72,7 +72,6 @@
   #
 
   #  Written by John Ingram (ingraje@eng.auburn.edu)  July 20, 1996
-  # $Revision: 1.6 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/ss2tf.m
+++ b/scripts/control/ss2tf.m
@@ -34,7 +34,6 @@
 
 # Written by R. Bruce Tenison (June 24, 1994) btenison@eng.auburn.edu
 # a s hodel: modified to allow for pure gain blocks Aug 1996
-# $Revision: 2.0.0.2 $
 
 # Check args
   [n,m,p] = abcddim(a,b,c,d);
--- a/scripts/control/ss2zp.m
+++ b/scripts/control/ss2zp.m
@@ -27,7 +27,6 @@
 # Written by David Clem August 15, 1994
 # Hodel: changed order of output arguments to zer, pol, k. July 1996
 # a s hodel: added argument checking, allow for pure gain blocks aug 1996
-# $Revision: 2.0.0.2 $
 
   if(nargin != 4)
     usage("[zer,pol,k] = ss2zp(a,b,c,d)");
--- a/scripts/control/starp.m
+++ b/scripts/control/starp.m
@@ -46,7 +46,6 @@
 # ny and/or nu may be negative (= negative feedback)
 
 # Written by Kai Mueller May 1998
-# $Revision: 2.0.0.2 $
 
   if((nargin != 2) && (nargin != 4))
     usage("[sys] = starp(P, K, ny, nu)");
--- a/scripts/control/step.m
+++ b/scripts/control/step.m
@@ -36,7 +36,6 @@
 # Written by Kai P. Mueller September 30, 1997
 # based on lsim.m of Scottedward Hodel
 # modified by
-# $Revision: 2.0.0.2 $
 
   if((nargin < 1) || (nargin > 4))
     usage("[y, u] = step(sys[, inp, tstop, n])");
--- a/scripts/control/stepimp.m
+++ b/scripts/control/stepimp.m
@@ -31,7 +31,6 @@
 
 # Written by Kai P. Mueller October 2, 1997
 # based on lsim.m of Scottedward Hodel
-# $Revision: 2.0.0.2 $
 
   if (sitype == 1)         IMPULSE = 0;
   elseif (sitype == 2)     IMPULSE = 1;
--- a/scripts/control/swap.m
+++ b/scripts/control/swap.m
@@ -22,7 +22,6 @@
 
   # A. S. Hodel July 24 1992
   # Conversion to Octave R. Bruce Tenison July 4, 1994
-  # $Revision: 2.0.0.2 $
 
   a1 = b;
   b1 = a;
--- a/scripts/control/swapcols.m
+++ b/scripts/control/swapcols.m
@@ -22,7 +22,6 @@
   
   # A. S. Hodel July 23, 1992
   # Conversion to Octave R. Bruce Tenison July 4, 1994
-  # $Revision: 2.0.0.2 $
 
   m = length(A(1,:));
   idx = m:-1:1;
--- a/scripts/control/swaprows.m
+++ b/scripts/control/swaprows.m
@@ -22,7 +22,6 @@
 
   # A. S. Hodel July 23, 1992
   # Conversion to Octave R. Bruce Tenison July 4, 1994
-  # $Revision: 2.0.0.2 $
   
   m = rows(A);
   idx = m:-1:1;
--- a/scripts/control/sys2fir.m
+++ b/scripts/control/sys2fir.m
@@ -20,7 +20,6 @@
 # function [c,tsam,inname,outname] = sys2fir(sys)
 # extract fir system from system data structure
 
-# $Revision: 2.0.0.2 $
 # a s hodel July 1996
 
   # let sys2tf do most of the work
--- a/scripts/control/sys2ss.m
+++ b/scripts/control/sys2ss.m
@@ -41,7 +41,6 @@
 
   # Written by David Clem August 19, 1994
   # Updates by John Ingram July 14, 1996
-  # $Revision: 2.0.0.2 $
 
   if(nargin != 1)
     usage("[a,b,c,d,tsam,n,nz,stname,inname,outname,yd] = sys2ss(sys)")
--- a/scripts/control/sys2tf.m
+++ b/scripts/control/sys2tf.m
@@ -31,7 +31,6 @@
 # Written by R. Bruce Tenison (June 24, 1994) btenison@eng.auburn.edu
 # modified to make sys2tf by A. S. Hodel Aug 1995
 # modified again for updated system format by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   if(nargin != 1)
     usage("[num,den,tsam,inname,outname] = sys2tf(Asys)");
--- a/scripts/control/sys2zp.m
+++ b/scripts/control/sys2zp.m
@@ -29,7 +29,6 @@
 #   inname, outname: input/output signal names (strings)
 
 # Created by John Ingram July 15 1996
-# $Revision: 2.0.0.2 $
 
   if(nargin != 1)
     usage("[zer,pol,k,tsam,inname,outname] = sys2zp(sys)");
--- a/scripts/control/sysadd.m
+++ b/scripts/control/sysadd.m
@@ -36,7 +36,6 @@
 #                  --------
 
 # Written by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
@@ -82,15 +81,17 @@
   Gsys = sysupdate(Gsys,"ss");
   Hsys = sysupdate(Hsys,"ss");
 
+  # change signal names to avoid warning messages from sysgroup
+  Gsys = syssetsignals(Gsys,"in",sysdefioname(length(Gin),"Gin_u"));
+  Gsys = syssetsignals(Gsys,"out",sysdefioname(length(Gout),"Gout_u"));
+  Hsys = syssetsignals(Hsys,"in",sysdefioname(length(Hin),"Hin_u"));
+  Hsys = syssetsignals(Hsys,"out",sysdefioname(length(Hout),"Hout_u"));
+  
   sys = sysgroup(Gsys,Hsys);
 
   eyin = eye(mg);
   eyout = eye(pg);
 
-
-  inname = Gin;
-  outname = Gout;
-
-  sys = sysscale(sys,[eyout eyout],[eyin;eyin],outname,inname);
+  sys = sysscale(sys,[eyout eyout],[eyin;eyin],Gout,Gin);
 
 endfunction
--- a/scripts/control/sysappend.m
+++ b/scripts/control/sysappend.m
@@ -48,7 +48,6 @@
   #     sys = discrete:            yd = ones(1,rows(c))
   
   # written by John Ingram August 1996
-  # $Revision: 2.0.0.2 $
   
   sav_implicit_str_to_num_ok = implicit_str_to_num_ok;	# save for later
   sav_empty_list_elements_ok = empty_list_elements_ok;
--- a/scripts/control/syschnames.m
+++ b/scripts/control/syschnames.m
@@ -40,7 +40,6 @@
 #            (or yd values, where appropriate)
 
 # Written by John Ingram August 1996; updated by A. S. Hodel 1998
-# $Revision: 2.0.0.2 $
 
   retsys = syssetsignals(sys,opt,names,list);
 
--- a/scripts/control/syschtsam.m
+++ b/scripts/control/syschtsam.m
@@ -23,7 +23,6 @@
 # This function changes the sampling time (tsam) of the system.
 
 # Written by John Ingram August 1996
-# $Revision: 2.0.0.2 $
 
   if (nargin != 2)
     usage("retsys = syschtsam(sys,tsam)");
--- a/scripts/control/sysconnect.m
+++ b/scripts/control/sysconnect.m
@@ -50,7 +50,6 @@
 
 # A. S. Hodel August 1995
 # modified by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/syscont.m
+++ b/scripts/control/syscont.m
@@ -29,7 +29,6 @@
 # returns csys empty if no continuous/continous path exists
 
 # Written by John Ingram August 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   save_empty = empty_list_elements_ok;
--- a/scripts/control/sysdefstname.m
+++ b/scripts/control/sysdefstname.m
@@ -21,8 +21,6 @@
 # return default state names given n, nz
 # used internally, minimal argument checking
 
-# $Revision: 2.0.0.2 $
-
   stname = list();
   if(n > 0)
     for ii = 1:n
--- a/scripts/control/sysdisc.m
+++ b/scripts/control/sysdisc.m
@@ -26,8 +26,6 @@
 #    outputs, respectively.
 #
 
-# $Revision: 2.0.0.2 $
-
   save_val = implicit_str_to_num_ok;	# save for later
   save_empty = empty_list_elements_ok;
   empty_list_elements_ok = implicit_str_to_num_ok = 1;
--- a/scripts/control/sysdup.m
+++ b/scripts/control/sysdup.m
@@ -43,7 +43,6 @@
 
 # A. S. Hodel August 1995
 # modified by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/sysgettsam.m
+++ b/scripts/control/sysgettsam.m
@@ -1,9 +1,25 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel
+#
+# 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 T = sysgettsam(sys)
 # T = sysgettsam(sys)
 # return the sampling time of the system
 
-# $Revision: 2.0.0.2 $
-
 if(!is_struct(sys))
   usage("T = sysgettsam(sys)");
 endif
--- a/scripts/control/sysgroup.m
+++ b/scripts/control/sysgroup.m
@@ -40,7 +40,6 @@
 
 # A. S. Hodel August 1995
 # modified by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/sysgroupn.m
+++ b/scripts/control/sysgroupn.m
@@ -28,22 +28,21 @@
 #
 #  used internally in sysgroup
 
-# $Revision: 2.0.0.2 $
-
   # check for duplicate names
   l = length(names);
   ii = 1;
-  while(ii < l-1)
+  while(ii <= l-1)
     st1 = nth(names,ii);
     jj = ii+1;
-    while ( jj < l)
+    while ( jj <= l)
       st2 = nth(names,jj);
       if(strcmp(st1,st2))
         suffix = ["_",num2str(jj)];
-        warning("sysgroup: %s name(%d) = %s name(%d); appending suffix %s to %d", ...
-		kind,ii,kind,jj,suffix,jj);
+        warning("sysgroup: %s name(%d) = %s name(%d) = %s", ...
+	  kind,ii,kind,jj,st1);
         strval = sprintf("%s%s",st2,suffix);
         names(jj) = strval;
+        warning("sysgroup:     changed %s name %d to %s",kind,jj,strval);
         # restart the check (just to be sure there's no further duplications)
         ii = 0; jj = l;
       endif
new file mode 100644
--- /dev/null
+++ b/scripts/control/sysidx.m
@@ -0,0 +1,50 @@
+function idxvec = sysidx(sys,sigtype,signamelist)
+# idxvec = sysidx(sys,sigtype,signamelist)
+# return indices of signals with specified signal names
+# inputs:
+#   sys:         OCST system data structure
+#   sigtype:     signal type to be selected: "in", "out", "st"
+#   signamelist: list of desired signal names
+# outputs:
+#   idxvec: vector of signal indices (appropriate for use with sysprune)
+
+if(nargin != 3)         usage("idxvec = sysidx(sys,sigtype,signamelist)");
+elseif(!is_struct(sys)) error("sys must be a system data structure");
+elseif(!isstr(sigtype)) error("sigtype must be a string");
+elseif(rows(sigtype) != 1) 
+                        error("sigtype (%d x %d) must be a single string", ...
+	                  rows(sigtype),columns(sigtype));
+elseif(!is_signal_list(signamelist)) 
+                        error("signamelist must be a list of strings");
+endif
+
+sigtype_list = list("input","output","state");
+sigtnum = 0;
+for idx = 1:length(sigtype_list)
+  thistype = nth(sigtype_list,idx);
+  if(strcmp(sigtype, thistype(1:length(sigtype)) )) sigtnum = idx; endif
+endfor
+if(sigtnum == 0)  error("Illegal sigtype value = %s\n",sigtype); endif
+
+syssiglist = sysgetsignals(sys,sigtype);
+
+for idx = 1:length(signamelist)
+  signame = nth(signamelist,idx);
+  idxvec(idx) = 0;
+  for jdx = 1:sysdimensions(sys,sigtype)
+    if(strcmp(signame,sysgetsignals(sys,sigtype,jdx,1)))
+      if(idxvec(idx) != 0)
+        warning("Duplicate system input %s (%d,%d)\n", ...
+          sysgetsignals(sys,sigtype,jdx,1),jdx,idxvec(idx));
+      else
+        idxvec(idx) = jdx;
+      endif
+    endif
+  endfor
+  if(idxvec(idx) == 0)
+    error("Did not find %s %s",nth(sigtype_list,sigtnum),signame);
+  endif
+endfor
+
+
+endfunction
--- a/scripts/control/sysmult.m
+++ b/scripts/control/sysmult.m
@@ -36,7 +36,6 @@
 # does not recognize discrete inputs)
 
 # Written by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
@@ -79,6 +78,10 @@
     endif
   endif
 
+  # change signal names to avoid spurious warnings from sysgroup
+  Asys = syssetsignals(Asys,"in",sysdefioname(Am,"A_sysmult_tmp_name"));
+  Bsys = syssetsignals(Bsys,"out",sysdefioname(Bp,"B_sysmult_tmp_name"));
+
   sys = sysgroup(Asys,Bsys);
 
   # connect outputs of B to inputs of A
--- a/scripts/control/sysout.m
+++ b/scripts/control/sysout.m
@@ -28,7 +28,6 @@
 #      "all": all of the above
 
 # Written by A S Hodel: 1995-1996
-# $Revision: 2.0.0.2 $
 
 # save for restoring at end of routine
 save_val = implicit_str_to_num_ok;
--- a/scripts/control/sysprune.m
+++ b/scripts/control/sysprune.m
@@ -1,4 +1,4 @@
-# Copyright (C) 1996 A. Scottedward Hodel 
+# Copyright (C) 1996,1998 A. Scottedward Hodel 
 #
 # This file is part of Octave. 
 #
@@ -16,21 +16,24 @@
 # along with Octave; see the file COPYING.  If not, write to the Free 
 # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  
-function sys = sysprune(sys,output_list,input_list)
-# function retsys = sysprune(Asys,output_list,input_list)
-# Extract specified inputs/outputs from a system
+function sys = sysprune(sys,output_idx,input_idx,state_idx)
+# function retsys = sysprune(Asys,output_idx,input_idx{,state_idx})
+# Extract/permute specified inputs, outputs, and/or states of a system.
 #
 # inputs:
 #   Asys: system data structure 
-#   output_list,input_list: list of connections indices; the new
-#       system has outputs y(output_list(ii)) and inputs u(input_list(ii)).
+#   output_idx,input_idx: list of connections indices; the new
+#       system has outputs y(output_idx(ii)) and inputs u(input_idx(ii)).
 #       May select as [] (empty matrix) to specify all outputs/inputs.
+#   state_idx: optional argument; list of indices of states to keep
+#       in the reduced model.  May omit this argument or pass [] (empty 
+#       matrix) to keep all states in the returned model
 #
 # output: retsys: resulting system:
 #                      ____________________
 #                      |                  |
 #     u1         ----->|                  |----> y1
-#    (input_list)      |       Asys       | (output_list)
+#    (input_idx)       |       Asys       | (output_idx)
 #                      |                  |
 #   u2 (deleted) |---->|                  |----| y2  (deleted)
 #                      |                  |    
@@ -38,58 +41,109 @@
 
 # A. S. Hodel August 1995
 # Updated by John Ingram 7-15-96
-# $Revision: 2.0.0.2 $
 
-  if( nargin != 3  )
-    usage("retsys = sysprune(sys,output_list,input_list)");
+  if( nargin < 3 | nargin > 4  )
+    usage("retsys = sysprune(sys,output_idx,input_idx{,state_idx})");
+  elseif(nargin < 4)
+    state_idx = [];
   endif
 
   # default: no action
   [nn,nz,mm,pp] = sysdimensions(sys);
-  if(isempty(output_list))
-    outputlist = 1:pp;
-  endif
-  if(isempty(input_list))
-    input_list = 1:mm;
-  endif
+  if(isempty(output_idx)) output_idx = 1:pp; endif
+  if(isempty(input_idx)) input_idx = 1:mm; endif
+  if(isempty(state_idx)) state_idx = 1:(nn+nz); endif
 
   # check dimensions
-  if( !(
-	(is_vector(output_list) | isempty(output_list)) 
-	& (is_vector(input_list) | isempty(input_list)) 
-  ))
-    error("sysprune: output_list and input_list must be vectors");
-  else
-    lo = length(output_list);
-    li = length(input_list);
-    
-    if(is_duplicate_entry(output_list) || is_duplicate_entry(input_list) )
-      error("sysprune: duplicate entry in input and/or output list");
+  if( !(is_vector(output_idx) | isempty(output_idx) )  )
+    if(!is_matrix(output_idx)) 
+      error("sysprune: bad argument passed for output_idx");
+    else 
+      error("sysprune: output_idx (%d x %d) must be a vector or empty", ...
+        rows(output_idx),columns(output_idx));
+    endif
+  elseif(is_duplicate_entry(output_idx))
+     error("sysprune: duplicate entries found in output_idx");
+  endif
+
+  if( !(is_vector(input_idx) | isempty(input_idx) )  )
+    if(!is_matrix(input_idx)) 
+      error("sysprune: bad argument passed for input_idx");
+    else 
+      error("sysprune: input_idx (%d x %d) must be a vector or empty", ...
+        rows(input_idx),columns(input_idx));
+    endif
+  elseif(is_duplicate_entry(input_idx))
+     error("sysprune: duplicate entries found in input_idx");
+  endif
+
+  if( !(is_vector(state_idx) | isempty(state_idx) )  )
+    if(!is_matrix(state_idx)) 
+      error("sysprune: bad argument passed for state_idx");
+    else 
+      error("sysprune: state_idx (%d x %d) must be a vector or empty", ...
+        rows(state_idx),columns(state_idx));
+    endif
+  elseif(nn+nz > 0)
+    if(is_duplicate_entry(state_idx))
+      error("sysprune: duplicate entries found in state_idx");
     endif
   endif
+
+  lo = length(output_idx);
+  li = length(input_idx);
+  lst = length(state_idx);
   
-  m = mm;
-  p = pp;
-
   if( !is_struct(sys))
     error("Asys must be a system data structure (see ss2sys, tf2sys, or zp2sys)")
-  elseif(p < lo)
-    error([num2str(lo)," output_list entries, system has only ", ...
-	num2str(p)," outputs"]);
-  elseif(m < li)
-    error([num2str(li)," input_list entries, system has only ", ...
-	num2str(m)," inputs"]);
+  elseif(pp < lo)
+    error([num2str(lo)," output_idx entries, system has only ", ...
+	num2str(pp)," outputs"]);
+  elseif(mm < li)
+    error([num2str(li)," input_idx entries, system has only ", ...
+	num2str(mm)," inputs"]);
+  elseif(nn+nz < lst)
+    error([num2str(lst)," state_idx entries, system has only ", ...
+	num2str(nn+nz)," states"]);
   endif
 
   [aa,bb,cc,dd,tsam,nn,nz,stnam,innam,outnam,yd] = sys2ss(sys);
-  bb = bb(:,input_list);
-  cc = cc(output_list,:);
-  dd = dd(output_list,input_list);
-  yd = yd(output_list); 
+
+  # check for legal state permutation
+  if(nn & nz)
+    c_idx = find(state_idx <= nn);
+    if(!isempty(c_idx)) max_c = max(c_idx);
+    else	        max_c = 0;            endif
+    d_idx = find(state_idx > nn);
+    if(!isempty(d_idx)) min_d = min(d_idx);
+    else	        min_d = nn+nz;            endif
+    if(max_c > min_d)
+      warning("sysprune: state_idx(%d)=%d (discrete) preceeds", ...
+	min_d,state_idx(min_d));
+      warning("          state_idx(%d)=%d (continuous)",...
+	max_c,state_idx(max_c));
+      warning("sysprune: sys has %d continuous states, %d discrete states", ...
+	nn,nz);
+      error("continuous/discrete state partition not preserved ; see ss2sys");
+    endif
+  endif
 
-  # this part needs rewritten for the list structure of signal names
-  innam  = innam(input_list);
-  outnam = outnam(output_list); 
-  
-  sys = ss2sys(aa,bb,cc,dd,tsam,nn,nz,stnam,innam,outnam,find(yd));
+  idx = input_idx;
+  odx = output_idx;
+  if(isempty(state_idx))
+    idx = [];
+    odx = [];
+  endif
+  aa = aa(state_idx,state_idx);
+  bb = bb(state_idx,idx);
+  cc = cc(odx,state_idx);
+  dd = dd(output_idx,input_idx);
+  yd = yd(output_idx); 
+
+  innam  = innam(input_idx);
+  outnam = outnam(output_idx); 
+  stnam = stnam(state_idx);
+  nn1 = length(find(state_idx <= nn));
+  nz1 = length(find(state_idx > nn));
+  sys = ss2sys(aa,bb,cc,dd,tsam,nn1,nz1,stnam,innam,outnam,find(yd));
 endfunction
--- a/scripts/control/sysreorder.m
+++ b/scripts/control/sysreorder.m
@@ -28,7 +28,6 @@
 # to use this at home!
 
 # A. S. Hodel, Aug 1995
-# $Revision: 2.0.0.2 $
   
   #disp('sysreorder: entry')
   
--- a/scripts/control/sysrepdemo.m
+++ b/scripts/control/sysrepdemo.m
@@ -23,8 +23,6 @@
 # Written by A. S. Hodel June 1995
 # Revised Aug 1995 for system data structure format
 
-# $Revision: 2.0.0.2 $
-
   save_val = page_screen_output;
   page_screen_output = 1;
 
--- a/scripts/control/sysscale.m
+++ b/scripts/control/sysscale.m
@@ -39,7 +39,6 @@
 
 # A. S. Hodel August 1995
 # modified by John Ingram 7-15-96
-# $Revision: 2.0.0.2 $
 
   if( (nargin < 3) || (nargin > 5)  )
     usage("retsys = sysscale(Asys,output_list,input_list{,inname,outname})");
new file mode 100644
--- /dev/null
+++ b/scripts/control/syssetsignals.m
@@ -0,0 +1,168 @@
+# Copyright (C) 1996,1998 A. Scottedward Hodel 
+#
+# 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 retsys = syssetsignals(sys,opt,names,sig_idx)
+# retsys = syssetsignals(sys,opt,names{,sig_idx})
+# change the names of selected inputs, outputs and states.
+# inputs:
+# 	sys: system data structure
+#	opt: []: change default name (output)
+#	     "out": change selected output names
+#	     "in": change selected input names
+#	     "st": change selected state names	 
+#	     "yd": change selected outputs from discrete to continuous or 
+#		   from continuous to discrete.
+#    	names: opt = "out", "in", or "st": string or or list of strings
+#              opt = "yd": desired output continuous/discrete flag.
+#                          names(ii) = 0: output ii is continuous
+#                          names(ii) = 1: output ii is discrete
+#     	list: vector of indices of outputs, yd, inputs, or
+#             states whose respective names should be changed.
+#             Default: replace entire signal list/vector value
+# outputs:
+#    retsys=sys with appropriate signal names changed 
+#            (or yd values, where appropriate)
+
+# Written by John Ingram August 1996
+
+  save_val = implicit_str_to_num_ok;	# save for later
+  implicit_str_to_num_ok = 1;
+
+  if (nargin < 3 | nargin > 4)
+    usage("retsys=syssetsignals(sys,opt,names{,sig_idx})");
+  elseif (!is_struct(sys))
+    error("sys must be a system data structure");
+  elseif (isempty(opt))
+    opt = "out";
+  elseif( ! isstr(opt)  )
+    error("opt must be a string");
+  elseif( ! (strcmp(opt,"out") + strcmp(opt,"yd") + ...
+    strcmp(opt,"in") + strcmp(opt,"st") ) )
+    error("opt must be one of [], ""out"", ""yd"", ""in"", or ""st""");
+  elseif(nargin == 4)
+    if(min(size(sig_idx)) > 1)
+      disp("syssetsignals: sig_idx=")
+      disp(sig_idx);
+      error("sig_idx must be a vector")
+    endif
+  endif
+
+  sig_vals = sysgetsignals(sys,opt);
+
+  # make sure it's in state space form if state names are given
+  if(strcmp(opt,"st"))    sys = sysupdate(sys,"ss");    endif
+
+  if(strcmp(opt,"yd") == 0)
+    # it's a signal name list we're changing
+    if(!is_list(names))
+      names = list(names);
+    endif
+    if(!is_signal_list(names))
+      if(isstr(nth(names,1)))
+        warning("syssetsignals(opt=%s): converting string matrix \"names\" to a list of strings",opt);
+        tmpstr = nth(names,1);
+        for ii=1:rows(tmpstr)
+          names(ii) = deblank(tmpstr(ii,:));
+        endfor
+      else
+        names
+        error("parameter \"names\" must be a list of strings");
+      endif
+    endif
+    nsigs = length(sig_vals);
+
+    if(nargin == 3)
+      # replace all signal names
+      if(length(names) != nsigs)
+        error("opt=%s, sig_idx omitted: names(len=%d) should have %d entries ", ...
+          opt,length(names),nsigs);
+      endif
+      sig_idx = 1:nsigs;
+    elseif(length(names) != length(sig_idx))
+      # replace specified signal names
+      error("opt=%s, sig_idx(len=%d), names(len=%d) mismatch",opt, ...
+        length(sig_idx), length(names));
+    endif
+
+    for ii=1:length(sig_idx)
+      jj = sig_idx(ii);
+      if(jj < 1 | jj > nsigs | jj != floor(jj+0.5))
+        error("opt=%s, sig_idx(%d)=%d, %e: must be an integer between 1 and %d", ...
+          opt, ii, jj, jj, nsigs);
+      endif
+      sig_vals(jj) = nth(names,ii);
+    endfor
+
+  else
+    nsigs = length(sig_vals);
+    if(!is_vector(names))
+      error("syssetsignals: opt=yd, names(%dx%d) must be a vector", ...
+        rows(names), columns(names));
+    endif
+    if(nargin == 3)
+      if(length(names) != nsigs)
+        error("opt=yd, sig_idx omitted: names(%d) should be length(%d)", ...
+          length(names), nsigs);
+      endif
+      sig_idx = 1:nsigs;
+    elseif(length(names) != length(sig_idx))
+      error("opt=yd: length(names)=%d, length(sig_idx)=%d",length(names), ...
+        length(sig_idx) );
+    endif
+
+    badidx = find(names != 0 & names != 1);
+    if(! isempty(badidx) )
+      for ii=1:length(badidx)
+        warning("syssetsignals: opt=yd: names(%d)=%e, must be 0 or 1", ...
+          badidx(ii), names(badidx(ii)) );
+      endfor
+      error("opt=yd: illegal values in names");
+    endif
+
+    for ii=1:length(sig_idx)
+      jj = sig_idx(ii);
+      if(jj < 1 | jj > nsigs | jj != floor(jj))
+        error("sig_idx(%d)=%d, %e: must be an integer between 1 and %d", ...
+          ii,jj, jj, nsigs);
+      endif
+      sig_vals(jj) = names(ii);
+    endfor
+    if(any(sig_vals == 1) & sysgettsam(sys) == 0)
+      warning("Setting system sampling time to 1");
+      printf("syssetsignals: original system sampling time=0 but output(s)\n");
+      disp(find(sig_vals==1))
+      printf("are digital\n");
+      sys = syschtsam(sys,1);
+    endif
+    
+  endif
+
+  if(strcmp(opt,"st"))
+    sys.stname = sig_vals;
+  elseif(strcmp(opt,"in"))
+    sys.inname = sig_vals;
+  elseif(strcmp(opt,"out"))
+    sys.outname = sig_vals;
+  elseif(strcmp(opt,"yd"))
+    sys.yd = sig_vals;
+  endif
+
+  retsys = sys;
+  implicit_str_to_num_ok = save_val;	# restore value
+
+endfunction
--- a/scripts/control/syssub.m
+++ b/scripts/control/syssub.m
@@ -36,7 +36,6 @@
 #                  --------
 
 # Written by John Ingram July 1996
-# $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for later
   implicit_str_to_num_ok = 1;
@@ -82,13 +81,16 @@
   Gsys = sysupdate(Gsys,"ss");
   Hsys = sysupdate(Hsys,"ss");
 
+  # change signal names to avoid warning messages from sysgroup
+  Gsys = syssetsignals(Gsys,"in",sysdefioname(length(Gin),"Gin_u"));
+  Gsys = syssetsignals(Gsys,"out",sysdefioname(length(Gout),"Gout_u"));
+  Hsys = syssetsignals(Hsys,"in",sysdefioname(length(Hin),"Hin_u"));
+  Hsys = syssetsignals(Hsys,"out",sysdefioname(length(Hout),"Hout_u"));
+  
   sys = sysgroup(Gsys,Hsys);
 
   eyin = eye(mg); eyout = eye(pg);
 
-  inname = Gin;
-  outname = Gout;
-
-  sys = sysscale(sys,[eyout -eyout],[eyin;eyin],outname,inname);
+  sys = sysscale(sys,[eyout -eyout],[eyin;eyin],Gout,Gin);
 
 endfunction
--- a/scripts/control/sysupdate.m
+++ b/scripts/control/sysupdate.m
@@ -34,7 +34,6 @@
 # see also: tf2sys, ss2sys, zp2sys, sysout, sys2ss, sys2tf, sys2zp
 
 # Written by John Ingram  7-9-96
-# $Revision: 2.0.0.2 $
 
   # check for correct number of inputs 
   if (nargin != 2)
--- a/scripts/control/tf2ss.m
+++ b/scripts/control/tf2ss.m
@@ -39,7 +39,6 @@
 
   # Written by R. Bruce Tenison (June 22, 1994) btenison@eng.auburn.edu
   # mod A S Hodel July, Aug  1995
-  # $Revision: 2.0.0.2 $
 
   if(nargin != 2)        error("tf2ss: wrong number of input arguments")
   elseif(isempty(num))   error("tf2ss: empty numerator");
--- a/scripts/control/tf2sys.m
+++ b/scripts/control/tf2sys.m
@@ -29,7 +29,6 @@
   #  Written by R. Bruce Tenison  July 29, 1994
   #  Name changed to TF2SYS July 1995
   #  updated for new system data structure format July 1996
-  # $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;
   implicit_str_to_num_ok = 1;
--- a/scripts/control/tf2sysl.m
+++ b/scripts/control/tf2sysl.m
@@ -22,7 +22,6 @@
 # used internally in tf2sys
 # strip leading zero coefficients to get the true polynomial length
 
-# $Revision: 2.0.0.2 $
 
 while( (length(vec) > 1) & (vec(1) == 0) )
   vec = vec(2:length(vec));
--- a/scripts/control/tf2zp.m
+++ b/scripts/control/tf2zp.m
@@ -23,7 +23,6 @@
 # defined by num/den.  K is a gain associated with the system zeros.
 
 # Written by A. S. Hodel, etc.
-# $Revision: 2.0.0.2 $
 
   if(nargin == 2)
     if(length(den) > 1)          pol = roots(den);
--- a/scripts/control/tfout.m
+++ b/scripts/control/tfout.m
@@ -28,7 +28,6 @@
 #	filter, polyderiv, polyinteg, polyout
 
 # Written by A. Scottedward Hodel (scotte@eng.auburn.edu) June 1995)
-# $Revision: 2.0.0.2 $
   
   save_val = implicit_str_to_num_ok;
   save_empty = empty_list_elements_ok;
--- a/scripts/control/tzero.m
+++ b/scripts/control/tzero.m
@@ -39,7 +39,6 @@
   
   # R. Bruce Tenison July 4, 1994
   # A. S. Hodel Aug 1995: allow for MIMO and system data structures
-  # $Revision: 1.18 $ 
 
   # get A,B,C,D and Asys variables, regardless of initial form
   if(nargin == 4)
--- a/scripts/control/tzero2.m
+++ b/scripts/control/tzero2.m
@@ -27,7 +27,6 @@
 # Needs to incorporate mvzero algorithm to isolate finite zeros.
 
 # Written by A. S. Hodel (scotte@eng.auburn.edu) August 1993.
-# $Revision: 2.0.0.2 $
 
   if (nargin == 4)
     bal = "B";
--- a/scripts/control/ugain.m
+++ b/scripts/control/ugain.m
@@ -28,7 +28,6 @@
 
   # Written by Kai P. Mueller April, 1998
   # Updates
-  # $Revision: 2.0.0.2 $
 
   if((nargin != 1) || (nargout > 1))
     usage("outsys = ugain(n)")
--- a/scripts/control/unpacksys.m
+++ b/scripts/control/unpacksys.m
@@ -21,7 +21,6 @@
   # Obsolete.  Use sys2ss instead.
 
   # Written by David Clem August 19, 1994
-  # $Revision: 2.0.0.2 $
 
   warning("unpacksys obsolete; calling sys2ss");
   [a,b,c,d] = sys2ss(syst);
--- a/scripts/control/wgt1o.m
+++ b/scripts/control/wgt1o.m
@@ -30,7 +30,6 @@
 # fc = Corner frequency (in Hz, *not* in rad/sec)
 
 # Written by Kai P. Mueller September 30, 1997
-# $Revision: 2.0.0.2 $
 
   if (nargin != 3)
     usage("wsys = wgt1o(vl, vh, fc)");
--- a/scripts/control/zgfmul.m
+++ b/scripts/control/zgfmul.m
@@ -30,7 +30,6 @@
   
   # A. S. Hodel July 24 1992
   # Conversion to Octave July 3, 1994
-  # $Revision: 2.0.0.2 $
   
   [n,m] = size(b);
   [p,m1] = size(c);
--- a/scripts/control/zgfslv.m
+++ b/scripts/control/zgfslv.m
@@ -22,7 +22,6 @@
   
   # Written by A. Scotte Hodel
   # Converted to Octave by R Bruce Tenison, July 3, 1994
-  # $Revision: 2.0.0.2 $
 
   nmp = n+m+p;
   gam1 = (2*n)+m+p;    gam2 = n+p;     gam3 = n+m;
--- a/scripts/control/zginit.m
+++ b/scripts/control/zginit.m
@@ -29,7 +29,6 @@
   
   # A. S. Hodel July 24 1992
   # Conversion to Octave by R. Bruce Tenison, July 3, 1994
-  # $Revision: 2.0.0.2 $
 
   [nn,mm] = size(b);
   [pp,mm] = size(d);
--- a/scripts/control/zgpbal.m
+++ b/scripts/control/zgpbal.m
@@ -38,7 +38,6 @@
   
   # A. S. Hodel July 24 1992
   # Conversion to Octave by R. Bruce Tenison July 3, 1994
-  # $Revision: 2.0.0.2 $
 
   if( (nargin != 1) | (!is_struct(Asys)))
     usage("retsys = zgpbal(Asys)");
--- a/scripts/control/zgreduce.m
+++ b/scripts/control/zgreduce.m
@@ -23,7 +23,6 @@
 #
 # used internally in tzero; minimal argument checking performed
 
-#$Revision: 2.0.0.2 $
 # SYS_INTERNAL accesses members of system data structure
 
 is_digital(Asys);		# make sure it's pure digital/continuous
--- a/scripts/control/zgrownorm.m
+++ b/scripts/control/zgrownorm.m
@@ -22,7 +22,6 @@
 # returns nonz = number of rows of mat whose two norm exceeds meps
 #         zer = number of rows of mat whose two norm is less than meps
 
-# $Revision: 2.0.0.2 $
 
   rownorm = [];
   for ii=1:rows(mat)
--- a/scripts/control/zgscal.m
+++ b/scripts/control/zgscal.m
@@ -28,7 +28,7 @@
   
   # A. S. Hodel July 24 1992
   # Conversion to Octave R. Bruce Tenison July 3, 1994
-  # $Revision: 2.0.0.2 $
+
 
   #**************************************************************************
   #initialize parameters:
@@ -43,6 +43,41 @@
   rk1 = z;
   k = 0;
 
+  # construct balancing least squares problem
+  F = eye(nmp);
+  for kk=1:nmp
+    F(1:nmp,kk) = zgfmul(a,b,c,d,F(:,kk));
+  endfor
+
+  [U,H,k1] = krylov(F,z,nmp,1e-12);
+  if(!is_square(H))
+    if(columns(H) != k1) 
+      error("zgscal(tzero): k1=%d, columns(H)=%d",k1,columns(H));
+    elseif(rows(H) != k1+1)
+      error("zgscal: k1=%d, rows(H) = %d",k1,rows(H));
+    elseif ( norm(H(k1+1,:)) > 1e-12*norm(H,"inf") )
+      zgscal_last_row_of_H = H(k1+1,:)
+      error("zgscal: last row of H nonzero (norm(H)=%e)",norm(H,"inf"))
+    endif
+    H = H(1:k1,1:k1);
+    U = U(:,1:k1);
+  endif
+
+  # tridiagonal H can still be rank deficient, so do permuted qr 
+  # factorization
+  [qq,rr,pp] = qr(H);	# H = qq*rr*pp'
+  nn = rank(rr);
+  qq = qq(:,1:nn);
+  rr = rr(1:nn,:);            # rr may not be square, but "\" does least
+  xx = U*pp*(rr\qq'*(U'*z));  # squares solution, so this works
+  #xx1 = pinv(F)*z;
+  #zgscal_x_xx1_err = [xx,xx1,xx-xx1]
+  return;
+
+  # the rest of this is left from the original zgscal;
+  # I've had some numerical problems with the GCG algorithm,
+  # so for now I'm solving it with the krylov routine.
+
   #initialize residual error norm
   rnorm = norm(rk1,1);
 
--- a/scripts/control/zgsgiv.m
+++ b/scripts/control/zgsgiv.m
@@ -23,7 +23,6 @@
   
   # A. S. Hodel July 29, 1992
   # Convertion to Octave by R. Bruce Tenison July 3, 1994
-  # $Revision: 2.0.0.2 $
 
   t1 = c*a + s*b;
   t2 = -s*a + c*b;
--- a/scripts/control/zgshsr.m
+++ b/scripts/control/zgshsr.m
@@ -24,7 +24,6 @@
 
   # A. S. Hodel July 24, 1992
   # Conversion to Octave by R. Bruce Tenison July 3, 1994
-  # $Revision: 2.0.0.2 $
 
   if(!is_vector(y))
     error(sprintf("y(%dx%d) must be a vector",rows(y),columns(y)));
--- a/scripts/control/zp2ss.m
+++ b/scripts/control/zp2ss.m
@@ -39,7 +39,6 @@
 # k is a gain that is associated with the zero vector.
 
 # Written by David Clem August 15, 1994
-# $Revision: 2.0.0.2 $
 
   sav_val = empty_list_elements_ok;
   empty_list_elements_ok = 1;
--- a/scripts/control/zp2ssg2.m
+++ b/scripts/control/zp2ssg2.m
@@ -23,7 +23,6 @@
 # extract 2 values from rvals (if possible) and construct
 # a polynomial with those roots.
 
-# $Revision: 2.0.0.2 $
 # A. S. Hodel Aug 1996
 
 # locate imaginary roots (if any)
--- a/scripts/control/zp2sys.m
+++ b/scripts/control/zp2sys.m
@@ -28,7 +28,6 @@
   # outputs: sys: system data structure
 
   #  Modified by John Ingram  July 20, 1996  
-  # $Revision: 2.0.0.2 $
 
   save_val = implicit_str_to_num_ok;	# save for restoring later
   implicit_str_to_num_ok = 1;
--- a/scripts/control/zp2tf.m
+++ b/scripts/control/zp2tf.m
@@ -32,7 +32,6 @@
 # convert to a column vector if necessary
 # Written by A. S. Hodel with help from students Ingram, McGowan.
 # a.s.hodel@eng.auburn.edu
-# $Revision: 2.0.0.2 $
 #
 
   [rp,cp] = size(pol);