changeset 4460:cef48c4b902d

[project @ 2003-07-11 18:37:48 by jwe]
author jwe
date Fri, 11 Jul 2003 18:37:48 +0000
parents 75ee1995d2b4
children af308ca1a354
files ChangeLog doc/interpreter/numbers.txi doc/interpreter/var.txi emacs/octave-mod.el scripts/ChangeLog scripts/control/base/__freqresp__.m scripts/control/base/place.m scripts/control/base/pzmap.m scripts/control/system/sysappend.m scripts/control/system/syscont.m scripts/control/system/sysdisc.m scripts/control/system/sysgroup.m scripts/control/system/tfout.m scripts/control/system/zp2ss.m scripts/control/system/zpout.m scripts/control/util/__outlist__.m scripts/general/shift.m scripts/miscellaneous/dump_prefs.m scripts/signal/arma_rnd.m scripts/strings/strcat.m src/ChangeLog src/pt-mat.cc
diffstat 22 files changed, 746 insertions(+), 720 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jul 11 17:46:41 2003 +0000
+++ b/ChangeLog	Fri Jul 11 18:37:48 2003 +0000
@@ -1,3 +1,9 @@
+2003-07-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* emacs/octave-mod.el (octave-variables): Add
+	warn_empty_list_elements to the list.
+	Delete empty_list_elements_ok from the list.
+
 2003-07-10  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* emacs/octave-mod.el (octave-variables): Add warn_neg_dim_as_zero
--- a/doc/interpreter/numbers.txi	Fri Jul 11 17:46:41 2003 +0000
+++ b/doc/interpreter/numbers.txi	Fri Jul 11 18:37:48 2003 +0000
@@ -314,12 +314,7 @@
 way to delete rows or columns of matrices.
 @xref{Assignment Ops, ,Assignment Expressions}.
 
-Octave will normally issue a warning if it finds an empty matrix in the
-list of elements that make up another matrix.  You can use the variable
-@code{empty_list_elements_ok} to suppress the warning or to treat it as
-an error.
-
-@DOCSTRING(empty_list_elements_ok)
+@DOCSTRING(warn_empty_list_elements)
 
 When Octave parses a matrix expression, it examines the elements of the
 list to determine whether they are all constants.  If they are, it
--- a/doc/interpreter/var.txi	Fri Jul 11 17:46:41 2003 +0000
+++ b/doc/interpreter/var.txi	Fri Jul 11 18:37:48 2003 +0000
@@ -266,11 +266,6 @@
 
 Default value: 0.
 
-@item empty_list_elements_ok
-@xref{Empty Matrices}.
-
-Default value: @code{"warn"}.
-
 @item fixed_point_format
 @xref{Matrices}.
 
@@ -391,6 +386,11 @@
 
 Default value: 1.
 
+@item warn_empty_list_elements
+@xref{Empty Matrices}.
+
+Default value: 0.
+
 @item warn_fortran_indexing
 @xref{Index Expressions}.
 
--- a/emacs/octave-mod.el	Fri Jul 11 17:46:41 2003 +0000
+++ b/emacs/octave-mod.el	Fri Jul 11 18:37:48 2003 +0000
@@ -140,14 +140,11 @@
     "__program_invocation_name__" "__program_name__" "__realmax__"
     "__realmin__" "__stderr__" "__stdin__" "__stdout__" "ans" "argv"
     "automatic_replot" "beep_on_error" "completion_append_char"
-    "crash_dumps_octave_core"
-    "default_return_value" "default_save_format"
-    "define_all_return_values" "e"
-    "echo_executing_commands" "empty_list_elements_ok" "eps"
+    "crash_dumps_octave_core" "default_return_value" "default_save_format"
+    "define_all_return_values" "e" "echo_executing_commands" "eps"
     "error_text" "gnuplot_binary" "history_file"
     "history_size" "ignore_function_time_stamp"
-    "inf" "nan" "nargin"
-    "output_max_field_width" "output_precision"
+    "inf" "nan" "nargin" "output_max_field_width" "output_precision"
     "page_output_immediately" "page_screen_output" "pi"
     "print_answer_id_name" "print_empty_dimensions"
     "program_invocation_name" "program_name" "propagate_empty_matrices"
@@ -158,8 +155,9 @@
     "string_fill_char" "struct_levels_to_print"
     "suppress_verbose_help_message" "warn_assign_as_truth_value"
     "warn_comma_in_global_decl" "warn_divide_by_zero"
-    "warn_fortran_indexing" "warn_function_name_clash"
-    "warn_imag_to_real" "warn_missing_semicolon" "warn_neg_dim_as_zero"
+    "warn_empty_list_elements" "warn_fortran_indexing"
+    "warn_function_name_clash" "warn_imag_to_real"
+    "warn_missing_semicolon" "warn_neg_dim_as_zero"
     "warn_num_to_str" "warn_str_to_num" "whitespace_in_literal_matrix")
   "Builtin variables in Octave.")
 
--- a/scripts/ChangeLog	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/ChangeLog	Fri Jul 11 18:37:48 2003 +0000
@@ -1,3 +1,17 @@
+2003-07-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* control/base/pzmap.m, control/base/place.m,
+	control/base/__freqresp__.m, control/system/sysappend.m,
+	control/system/syscont.m, control/system/sysdisc.m,
+	control/system/sysgroup.m, control/system/tfout.m,
+	control/system/zp2ss.m, control/system/zpout.m,
+	control/util/__outlist__.m, signal/arma_rnd.m, general/shift.m,
+	strings/strcat.m: Save and restore warn_empty_list_elements, not
+	empty_list_elements_ok.
+
+	* miscellaneous/dump_prefs.m: Add warn_empty_list_elements to the list.
+	Delete empty_list_elements_ok from the list.
+
 2003-07-10  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* miscellaneous/dump_prefs.m: Include warn_neg_dim_as_zero in the
--- a/scripts/control/base/__freqresp__.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/base/__freqresp__.m	Fri Jul 11 18:37:48 2003 +0000
@@ -46,88 +46,91 @@
 
   ## SYS_INTERNAL accesses members of system data structure
 
-  save_val = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
+
+    ## Check Args
+    if ((nargin < 2) || (nargin > 4))
+      usage ("[ff, w] = __freqresp__ (sys, USEW, w)");
+    elseif (USEW & (nargin < 3) )
+      error ("USEW = 1 but w was not passed.");
+    elseif (USEW & isempty(w))
+      warning("USEW = 1 but w is empty; setting USEW=0");
+      USEW = 0;
+    endif
+
+    DIGITAL = is_digital(sys);
 
-  ## Check Args
-  if ((nargin < 2) || (nargin > 4))
-    usage ("[ff, w] = __freqresp__ (sys, USEW, w)");
-  elseif (USEW & (nargin < 3) )
-    error ("USEW = 1 but w was not passed.");
-  elseif (USEW & isempty(w))
-    warning("USEW = 1 but w is empty; setting USEW=0");
-    USEW = 0;
-  endif
+    ## compute default w if needed
+    if(!USEW)
+      if(is_siso(sys))
+	sys = sysupdate(sys,"zp");
+	[zer,pol] = sys2zp(sys);
+      else
+	zer = tzero(sys);
+	pol = eig(sys2ss(sys));
+      endif
 
-  DIGITAL = is_digital(sys);
+      ## get default frequency range
+      [wmin,wmax] = bode_bounds(zer,pol,DIGITAL,sysgettsam(sys));
+      w = logspace(wmin,wmax,50);
+    else
+      w = reshape(w,1,length(w));         # make sure it's a row vector
+    endif
 
-  ## compute default w if needed
-  if(!USEW)
-    if(is_siso(sys))
-      sys = sysupdate(sys,"zp");
-      [zer,pol] = sys2zp(sys);
+    ## now get complex values of s or z
+    if(DIGITAL)
+      jw = exp(i*w*sysgettsam(sys));
     else
-      zer = tzero(sys);
-      pol = eig(sys2ss(sys));
+      jw = i*w;
     endif
 
-    ## get default frequency range
-    [wmin,wmax] = bode_bounds(zer,pol,DIGITAL,sysgettsam(sys));
-    w = logspace(wmin,wmax,50);
-  else
-    w = reshape(w,1,length(w));         # make sure it's a row vector
-  endif
+    [nn,nz,mm,pp] = sysdimensions(sys);
 
-  ## now get complex values of s or z
-  if(DIGITAL)
-    jw = exp(i*w*sysgettsam(sys));
-  else
-    jw = i*w;
-  endif
-
-  [nn,nz,mm,pp] = sysdimensions(sys);
+    ## now compute the frequency response - divide by zero yields a warning
+    if (strcmp(sysgettype(sys),"zp"))
+      ## zero-pole form (preferred)
+      [zer,pol,sysk] = sys2zp(sys);
+      ff = ones(size(jw));
+      l1 = min(length(zer)*(1-isempty(zer)),length(pol)*(1-isempty(pol)));
+      for ii=1:l1
+	ff = ff .* (jw - zer(ii)) ./ (jw - pol(ii));
+      endfor
 
-  ## now compute the frequency response - divide by zero yields a warning
-  if (strcmp(sysgettype(sys),"zp"))
-    ## zero-pole form (preferred)
-    [zer,pol,sysk] = sys2zp(sys);
-    ff = ones(size(jw));
-    l1 = min(length(zer)*(1-isempty(zer)),length(pol)*(1-isempty(pol)));
-    for ii=1:l1
-      ff = ff .* (jw - zer(ii)) ./ (jw - pol(ii));
-    endfor
+      ## require proper  transfer function, so now just get poles.
+      for ii=(l1+1):length(pol)
+	ff = ff ./ (jw - pol(ii));
+      endfor
+      ff = ff*sysk;
 
-    ## require proper  transfer function, so now just get poles.
-    for ii=(l1+1):length(pol)
-      ff = ff ./ (jw - pol(ii));
-    endfor
-    ff = ff*sysk;
+    elseif (strcmp(sysgettype(sys),"tf"))
+      ## transfer function form
+      [num,den] = sys2tf(sys);
+      ff = polyval(num,jw)./polyval(den,jw);
+    elseif (mm==pp)
+      ## The system is square; do state-space form bode plot
+      [sysa,sysb,sysc,sysd,tsam,sysn,sysnz] = sys2ss(sys);
+      n = sysn + sysnz;
+      for ii=1:length(jw);
+	ff(ii) = det(sysc*((jw(ii).*eye(n)-sysa)\sysb)+sysd);
+      endfor;
+    else
+      ## Must be state space... bode
+      [sysa,sysb,sysc,sysd,tsam,sysn,sysnz] = sys2ss(sys);
+      n = sysn + sysnz;
+      for ii=1:length(jw);
+	ff(ii) = norm(sysc*((jw(ii)*eye(n)-sysa)\sysb)+sysd);
+      endfor
 
-  elseif (strcmp(sysgettype(sys),"tf"))
-    ## transfer function form
-    [num,den] = sys2tf(sys);
-    ff = polyval(num,jw)./polyval(den,jw);
-  elseif (mm==pp)
-    ## The system is square; do state-space form bode plot
-    [sysa,sysb,sysc,sysd,tsam,sysn,sysnz] = sys2ss(sys);
-    n = sysn + sysnz;
-    for ii=1:length(jw);
-      ff(ii) = det(sysc*((jw(ii).*eye(n)-sysa)\sysb)+sysd);
-    endfor;
-  else
-    ## Must be state space... bode
-    [sysa,sysb,sysc,sysd,tsam,sysn,sysnz] = sys2ss(sys);
-    n = sysn + sysnz;
-    for ii=1:length(jw);
-      ff(ii) = norm(sysc*((jw(ii)*eye(n)-sysa)\sysb)+sysd);
-    endfor
+    endif
+
+    w = reshape(w,1,length(w));
+    ff = reshape(ff,1,length(ff));
 
-  endif
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
-  w = reshape(w,1,length(w));
-  ff = reshape(ff,1,length(ff));
-
-  ## restore global variable
-  empty_list_elements_ok = save_val;
 endfunction
 
--- a/scripts/control/base/place.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/base/place.m	Fri Jul 11 18:37:48 2003 +0000
@@ -44,83 +44,87 @@
 
 function K = place (sys, P)
 
-  sav_val = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  ## check arguments
+    ## check arguments
 
-  if(!isstruct(sys))
-    error("sys must be in system data structure format (see ss2sys)");
-  endif
-  sys = sysupdate(sys,"ss");    # make sure it has state space form up to date
-  if(!is_controllable(sys))
-    error("sys is not controllable.");
-  elseif( min(size(P)) != 1)
-    error("P must be a vector")
-  else
-    P = reshape(P,length(P),1); # make P a column vector
-  endif
-  ## system must be purely continuous or discrete
-  is_digital(sys);
-  [n,nz,m,p] = sysdimensions(sys);
-  nx = n+nz;    # already checked that it's not a mixed system.
-  if(m != 1)
-    error(["sys has ", num2str(m)," inputs; need only 1"]);
-  endif
+    if(!isstruct(sys))
+      error("sys must be in system data structure format (see ss2sys)");
+    endif
+    sys = sysupdate(sys,"ss");    # make sure it has state space form up to date
+    if(!is_controllable(sys))
+      error("sys is not controllable.");
+    elseif( min(size(P)) != 1)
+      error("P must be a vector")
+    else
+      P = reshape(P,length(P),1); # make P a column vector
+    endif
+    ## system must be purely continuous or discrete
+    is_digital(sys);
+    [n,nz,m,p] = sysdimensions(sys);
+    nx = n+nz;    # already checked that it's not a mixed system.
+    if(m != 1)
+      error(["sys has ", num2str(m)," inputs; need only 1"]);
+    endif
 
-  ## takes the A and B matrix from the system representation
-  [A,B]=sys2ss(sys);
-  sp = length(P);
-  if(nx == 0)
-    error("place: A matrix is empty (0x0)");
-  elseif(nx != length(P))
-    error(["A=(",num2str(nx),"x",num2str(nx),", P has ", num2str(length(P)), ...
-        "entries."])
-  endif
+    ## takes the A and B matrix from the system representation
+    [A,B]=sys2ss(sys);
+    sp = length(P);
+    if(nx == 0)
+      error("place: A matrix is empty (0x0)");
+    elseif(nx != length(P))
+      error(["A=(",num2str(nx),"x",num2str(nx),", P has ", num2str(length(P)), ...
+	  "entries."])
+    endif
 
-  ## arguments appear to be compatible; let's give it a try!
-  ## The second step is the calculation of the characteristic polynomial ofA
-  PC=poly(A);
+    ## arguments appear to be compatible; let's give it a try!
+    ## The second step is the calculation of the characteristic polynomial ofA
+    PC=poly(A);
 
-  ## Third step: Calculate the transformation matrix T that transforms the state
-  ## equation in the controllable canonical form.
+    ## Third step: Calculate the transformation matrix T that transforms the state
+    ## equation in the controllable canonical form.
+
+    ## first we must calculate the controllability matrix M:
+    M=B;
+    AA=A;
+    for n = 2:nx
+      M(:,n)=AA*B;
+      AA=AA*A;
+    endfor
 
-  ## first we must calculate the controllability matrix M:
-  M=B;
-  AA=A;
-  for n = 2:nx
-    M(:,n)=AA*B;
-    AA=AA*A;
-  endfor
+    ## second, construct the matrix W
+    PCO=PC(nx:-1:1);
+    PC1=PCO;      # Matrix to shift and create W row by row
 
-  ## second, construct the matrix W
-  PCO=PC(nx:-1:1);
-  PC1=PCO;      # Matrix to shift and create W row by row
+    for n = 1:nx
+      W(n,:) = PC1;
+      PC1=[PCO(n+1:nx),zeros(1,n)];
+    endfor
 
-  for n = 1:nx
-    W(n,:) = PC1;
-    PC1=[PCO(n+1:nx),zeros(1,n)];
-  endfor
+    T=M*W;
 
-  T=M*W;
+    ## finaly the matrix K is calculated
+    PD = poly(P); # The desired characteristic polynomial
+    PD = PD(nx+1:-1:2);
+    PC = PC(nx+1:-1:2);
 
-  ## finaly the matrix K is calculated
-  PD = poly(P); # The desired characteristic polynomial
-  PD = PD(nx+1:-1:2);
-  PC = PC(nx+1:-1:2);
+    K = (PD-PC)/T;
 
-  K = (PD-PC)/T;
+    ## Check if the eigenvalues of (A-BK) are the same specified in P
+    Pcalc = eig(A-B*K);
 
-  ## Check if the eigenvalues of (A-BK) are the same specified in P
-  Pcalc = eig(A-B*K);
-
-  Pcalc = sortcom(Pcalc);
-  P = sortcom(P);
+    Pcalc = sortcom(Pcalc);
+    P = sortcom(P);
 
-  if(max( (abs(Pcalc)-abs(P))./abs(P) ) > 0.1)
-    disp("Place: Pole placed at more than 10% relative error from specified");
-  endif
+    if(max( (abs(Pcalc)-abs(P))./abs(P) ) > 0.1)
+      disp("Place: Pole placed at more than 10% relative error from specified");
+    endif
 
-  empty_list_elements_ok = sav_val;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
+
 endfunction
 
--- a/scripts/control/base/pzmap.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/base/pzmap.m	Fri Jul 11 18:37:48 2003 +0000
@@ -30,57 +30,59 @@
 
 function [zer, pol]=pzmap (sys)
 
-  save_emp = empty_list_elements_ok;
-
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if(nargin != 1)
-    usage("pzmap(sys) or [zer,pol] = pzmap(sys)");
-  elseif (!isstruct(sys));
-    error("sys must be in system format");
-  endif
+    if(nargin != 1)
+      usage("pzmap(sys) or [zer,pol] = pzmap(sys)");
+    elseif (!isstruct(sys));
+      error("sys must be in system format");
+    endif
+
+    [zer,pol] = sys2zp(sys);
 
-  [zer,pol] = sys2zp(sys);
+    ## force to column vectors, split into real, imaginary parts
+    zerdata = poldata = [];
+    if(length(zer))
+      zer = reshape(zer,length(zer),1);
+      zerdata = [real(zer(:,1)), imag(zer(:,1))];
+    endif
+    if(length(pol))
+      pol = reshape(pol,length(pol),1);
+      poldata = [real(pol(:,1)), imag(pol(:,1))];
+    endif
 
-  ## force to column vectors, split into real, imaginary parts
-  zerdata = poldata = [];
-  if(length(zer))
-    zer = reshape(zer,length(zer),1);
-    zerdata = [real(zer(:,1)), imag(zer(:,1))];
-  endif
-  if(length(pol))
-    pol = reshape(pol,length(pol),1);
-    poldata = [real(pol(:,1)), imag(pol(:,1))];
-  endif
+    ## determine continuous or discrete plane
+    vars = "sz";
+    varstr = vars(is_digital(sys) + 1);
 
-  ## determine continuous or discrete plane
-  vars = "sz";
-  varstr = vars(is_digital(sys) + 1);
-
-  ## Plot the data
-  gset nologscale xy;
-  if(is_siso(sys))
-    title(sprintf("Pole-zero map from %s to %s", ...
-       sysgetsignals(sys,"in",1,1), sysgetsignals(sys,"out",1,1) ));
-  endif
-  xlabel(["Re(",varstr,")"]);
-  ylabel(["Im(",varstr,")"]);
-  grid;
+    ## Plot the data
+    gset nologscale xy;
+    if(is_siso(sys))
+      title(sprintf("Pole-zero map from %s to %s", ...
+	 sysgetsignals(sys,"in",1,1), sysgetsignals(sys,"out",1,1) ));
+    endif
+    xlabel(["Re(",varstr,")"]);
+    ylabel(["Im(",varstr,")"]);
+    grid;
 
-  ## compute axis limits
-  axis(axis2dlim([zerdata;poldata]));
-  grid
-  ## finally, plot the data
-  if(length(zer) == 0)
-    plot(poldata(:,1), poldata(:,2),"@12 ;poles (no zeros);");
-  elseif(length(pol) == 0)
-    plot(zerdata(:,1), zerdata(:,2),"@31 ;zeros (no poles);");
-  else
-    plot(zerdata(:,1), zerdata(:,2),"@31 ;zeros;", ...
-      poldata(:,1), poldata(:,2),"@12 ;poles;");
-  endif
-  replot
+    ## compute axis limits
+    axis(axis2dlim([zerdata;poldata]));
+    grid
+    ## finally, plot the data
+    if(length(zer) == 0)
+      plot(poldata(:,1), poldata(:,2),"@12 ;poles (no zeros);");
+    elseif(length(pol) == 0)
+      plot(zerdata(:,1), zerdata(:,2),"@31 ;zeros (no poles);");
+    else
+      plot(zerdata(:,1), zerdata(:,2),"@31 ;zeros;", ...
+	poldata(:,1), poldata(:,2),"@12 ;poles;");
+    endif
+    replot
 
-  empty_list_elements_ok = save_emp;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/system/sysappend.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/sysappend.m	Fri Jul 11 18:37:48 2003 +0000
@@ -77,114 +77,116 @@
 
 function retsys = sysappend (sys, b, c, d, outname, inname, yd)
 
-  sav_empty_list_elements_ok = empty_list_elements_ok;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  empty_list_elements_ok = 1;
+    ## check input arguments
+    if ( (nargin < 2) | (nargin > 7) | (!isstruct(sys)))
+      usage("retsys = sysappend(sys,b,c[,d,outname,inname,yd]) ");
+    elseif(!isstruct(sys))
+      error("sys must be a system data structure");
+    endif
 
-  ## check input arguments
-  if ( (nargin < 2) | (nargin > 7) | (!isstruct(sys)))
-    usage("retsys = sysappend(sys,b,c[,d,outname,inname,yd]) ");
-  elseif(!isstruct(sys))
-    error("sys must be a system data structure");
-  endif
+    ## default system type must be state space form
+    [Aa,Ab,Ac,Ad,Ats,Ann,Anz,Ast,Ain,Aout,Ayd] = sys2ss(sys);
+    [Ann,Anz,Am,Ap] = sysdimensions(sys);
 
-  ## default system type must be state space form
-  [Aa,Ab,Ac,Ad,Ats,Ann,Anz,Ast,Ain,Aout,Ayd] = sys2ss(sys);
-  [Ann,Anz,Am,Ap] = sysdimensions(sys);
+    ## default c
+    if(nargin < 3)      c = [];                                endif
 
-  ## default c
-  if(nargin < 3)      c = [];                                endif
+    ## default d
+    if(nargin < 4)     make_d = 1;
+    elseif(isempty(d)) make_d = 1;
+    else               make_d = 0;                             endif
+    if(make_d)         d = zeros(rows(c)+Ap,columns(b) + Am);  endif
 
-  ## default d
-  if(nargin < 4)     make_d = 1;
-  elseif(isempty(d)) make_d = 1;
-  else               make_d = 0;                             endif
-  if(make_d)         d = zeros(rows(c)+Ap,columns(b) + Am);  endif
+    ## Append new input(s) if any
+    Bm = max(columns(d),columns(b)+Am);
+    if(Bm != Am)
+      ## construct new signal names
+      if(nargin >= 6)   # new names were passed
+	if(!isstr(inname))
+	  error("inname must be a string");
+	elseif(rows(inname) != (Bm - Am))
+	  error(sprintf("%d new inputs requested; inname(%dx%d)", ...
+	    (Bm-Am),rows(inname),columns(inname)));
+	endif
+      else
+	inname = __sysdefioname__(Bm,"u",(Am+1));
+      endif
+      if(Am)   Ain = append(Ain,inname);
+      else     Ain = inname;              endif
 
-  ## Append new input(s) if any
-  Bm = max(columns(d),columns(b)+Am);
-  if(Bm != Am)
-    ## construct new signal names
-    if(nargin >= 6)   # new names were passed
-      if(!isstr(inname))
-        error("inname must be a string");
-      elseif(rows(inname) != (Bm - Am))
-        error(sprintf("%d new inputs requested; inname(%dx%d)", ...
-          (Bm-Am),rows(inname),columns(inname)));
+      ## default b matrix
+      if(isempty(b))     b  = zeros(Ann+Anz,(Bm-Am));
+      elseif(rows(b) != Ann+Anz | columns(b) != (Bm-Am))
+	  error(sprintf("b(%dx%d); should be (%dx%d)", rows(b), columns(b), ...
+	    (Ann+Anz), (Bm-Am)));
       endif
-    else
-      inname = __sysdefioname__(Bm,"u",(Am+1));
-    endif
-    if(Am)   Ain = append(Ain,inname);
-    else     Ain = inname;              endif
 
-    ## default b matrix
-    if(isempty(b))     b  = zeros(Ann+Anz,(Bm-Am));
-    elseif(rows(b) != Ann+Anz | columns(b) != (Bm-Am))
-        error(sprintf("b(%dx%d); should be (%dx%d)", rows(b), columns(b), ...
-          (Ann+Anz), (Bm-Am)));
+      ## append new b matrix
+      Ab = [Ab,b];
     endif
 
-    ## append new b matrix
-    Ab = [Ab,b];    # empty_list_elements_ok=1 makes this ok
-  endif
-
-  ## Append new output(s) if any
-  Bp = max(rows(d),rows(c)+Ap);
-  if(Bp != Ap)
+    ## Append new output(s) if any
+    Bp = max(rows(d),rows(c)+Ap);
+    if(Bp != Ap)
 
-    ## construct new signal names, output classification
-    if(nargin >= 5)  # new names were passed
-      if(!isstr(outname))
-        error("outname must be a string");
-      elseif(rows(outname) != (Bp - Ap))
-        error(sprintf("%d new outputs requested; outname(%dx%d)", ...
-          (Bp-Ap),rows(outname),columns(outname)));
+      ## construct new signal names, output classification
+      if(nargin >= 5)  # new names were passed
+	if(!isstr(outname))
+	  error("outname must be a string");
+	elseif(rows(outname) != (Bp - Ap))
+	  error(sprintf("%d new outputs requested; outname(%dx%d)", ...
+	    (Bp-Ap),rows(outname),columns(outname)));
+	endif
+      else
+	outname = __sysdefioname__(Bp,"y",(Ap+1));
       endif
-    else
-      outname = __sysdefioname__(Bp,"y",(Ap+1));
-    endif
-    if(Ap)   Aout = append(Aout,outname);
-    else     Aout = outname;                endif
+      if(Ap)   Aout = append(Aout,outname);
+      else     Aout = outname;                endif
 
-    ## construct new yd entries
-    if(nargin == 7)
-      if(!isvector(yd))
-        error(sprintf("yd(%dx%d) must be a vector",rows(yd),columns(yd)))
-      elseif(rows(c) != length(yd) & rows(d) != length(yd))
-        error(sprintf("length(yd) = %d; c(%dx%d), d(%dx%d); mismatch", ...
-          length(yd), rows(c), columns(c),rows(d),columns(d)));
+      ## construct new yd entries
+      if(nargin == 7)
+	if(!isvector(yd))
+	  error(sprintf("yd(%dx%d) must be a vector",rows(yd),columns(yd)))
+	elseif(rows(c) != length(yd) & rows(d) != length(yd))
+	  error(sprintf("length(yd) = %d; c(%dx%d), d(%dx%d); mismatch", ...
+	    length(yd), rows(c), columns(c),rows(d),columns(d)));
+	endif
+      else
+	## default yd values
+	yd = ones(1,Bp)*( (Ats > 0) & (Ann == 0)  & isempty(find(Ayd == 0)) ) ;
       endif
-    else
-      ## default yd values
-      yd = ones(1,Bp)*( (Ats > 0) & (Ann == 0)  & isempty(find(Ayd == 0)) ) ;
-    endif
-    Ayd = [vec(Ayd);vec(yd)];
+      Ayd = [vec(Ayd);vec(yd)];
 
-    ## default c matrix
-    if(isempty(c))      c = zeros((Bp-Ap),Ann+Anz);
-    elseif(columns(c) != Ann+Anz | rows(c) != (Bp-Ap))
-        error(sprintf("c(%dx%d); should be (%dx%d)", rows(c), columns(c), ...
-          (Bp-Ap), (Ann+Anz) ));
+      ## default c matrix
+      if(isempty(c))      c = zeros((Bp-Ap),Ann+Anz);
+      elseif(columns(c) != Ann+Anz | rows(c) != (Bp-Ap))
+	  error(sprintf("c(%dx%d); should be (%dx%d)", rows(c), columns(c), ...
+	    (Bp-Ap), (Ann+Anz) ));
+      endif
+
+      ## append new c matrix
+      Ac = [Ac;c];
     endif
 
-    ## append new c matrix
-    Ac = [Ac;c];    # empty_list_elements_ok=1 makes this ok
-  endif
+    ## check d matrix
+    if(isempty(d)) d = zeros(Bp,Bm);
+    elseif(rows(d) != Bp | columns(d) != Bm)
+      error(sprintf("d(%dx%d) should be (%dx%d)",rows(d), columns(d), Bp, Bp));
+    endif
 
-  ## check d matrix
-  if(isempty(d)) d = zeros(Bp,Bm);
-  elseif(rows(d) != Bp | columns(d) != Bm)
-    error(sprintf("d(%dx%d) should be (%dx%d)",rows(d), columns(d), Bp, Bp));
-  endif
+    ## Splice in original D matrix
+    if(Am & Ap)          d(1:Ap, 1:Am) = Ad;       endif
+    Ad = d;
 
-  ## Splice in original D matrix
-  if(Am & Ap)          d(1:Ap, 1:Am) = Ad;       endif
-  Ad = d;
+    ## construct return system
+    retsys = ss2sys(Aa,Ab,Ac,Ad,Ats,Ann,Anz,Ast,Ain,Aout,find(Ayd == 1));
 
-  ## construct return system
-  retsys = ss2sys(Aa,Ab,Ac,Ad,Ats,Ann,Anz,Ast,Ain,Aout,find(Ayd == 1));
-
-  empty_list_elements_ok = sav_empty_list_elements_ok;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/system/syscont.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/syscont.m	Fri Jul 11 18:37:48 2003 +0000
@@ -41,48 +41,51 @@
 
 function [csys, Acd, Ccd] = syscont (sys)
 
-  save_empty = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if (nargin != 1)
-    usage("[csys,Acd,Ccd,Dcd] = syscont(sys)");
-  elseif (!isstruct(sys))
-    error("sys must be in system data structure form");
-  endif
+    if (nargin != 1)
+      usage("[csys,Acd,Ccd,Dcd] = syscont(sys)");
+    elseif (!isstruct(sys))
+      error("sys must be in system data structure form");
+    endif
 
-  sys = sysupdate (sys, "ss");
-  [n_tot, st_c, st_d, y_c, y_d] = __syscont_disc__ (sys);        # get ranges
+    sys = sysupdate (sys, "ss");
+    [n_tot, st_c, st_d, y_c, y_d] = __syscont_disc__ (sys);        # get ranges
 
-  ## assume there's nothing there; build partitions as appropriate
-  Acc = Acd = Bcc = Ccc = Ccd = Dcc = [];
+    ## assume there's nothing there; build partitions as appropriate
+    Acc = Acd = Bcc = Ccc = Ccd = Dcc = [];
 
-  if(isempty(st_c) & isempty(y_c))
-    error("syscont: expecting continous states and/or continous outputs");
-  elseif (isempty(st_c))
-    warning("syscont: no continuous states");
-  elseif(isempty(y_c))
-    warning("syscont: no continuous outputs");
-  endif
+    if(isempty(st_c) & isempty(y_c))
+      error("syscont: expecting continous states and/or continous outputs");
+    elseif (isempty(st_c))
+      warning("syscont: no continuous states");
+    elseif(isempty(y_c))
+      warning("syscont: no continuous outputs");
+    endif
 
-  [sys_a, sys_b, sys_c, sys_d ] = sys2ss(sys);
-  [sys_stname, sys_inname, sys_outname] = sysgetsignals(sys);
-  [sys_n, sys_nz, sys_m, sys_p] = sysdimensions(sys);
-  if(!isempty(st_c))
-    Acc = sys_a(st_c,st_c);
-    stname = sys_stname(st_c);
-    Bcc = sys_b(st_c,:);
-    Ccc = sys_c(y_c,st_c);
-    Acd = sys_a(st_c,st_d);
-  else
-    stname=[];
-  endif
-  outname = sys_outname(y_c);
-  Dcc = sys_d(y_c,:);
-  Ccd = sys_c(y_c,st_d);
-  inname = sys_inname;
+    [sys_a, sys_b, sys_c, sys_d ] = sys2ss(sys);
+    [sys_stname, sys_inname, sys_outname] = sysgetsignals(sys);
+    [sys_n, sys_nz, sys_m, sys_p] = sysdimensions(sys);
+    if(!isempty(st_c))
+      Acc = sys_a(st_c,st_c);
+      stname = sys_stname(st_c);
+      Bcc = sys_b(st_c,:);
+      Ccc = sys_c(y_c,st_c);
+      Acd = sys_a(st_c,st_d);
+    else
+      stname=[];
+    endif
+    outname = sys_outname(y_c);
+    Dcc = sys_d(y_c,:);
+    Ccd = sys_c(y_c,st_d);
+    inname = sys_inname;
 
-  csys = ss2sys(Acc,Bcc,Ccc,Dcc,0,sys_n,0,stname,inname,outname);
+    csys = ss2sys(Acc,Bcc,Ccc,Dcc,0,sys_n,0,stname,inname,outname);
 
-  empty_list_elements_ok = save_empty;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/system/sysdisc.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/sysdisc.m	Fri Jul 11 18:37:48 2003 +0000
@@ -36,63 +36,66 @@
 
 function [dsys, Adc, Cdc] = sysdisc (sys)
 
-  save_empty = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if (nargin != 1)
-    usage("[dsys,Adc,Cdc] = sysdisc(sys)");
-  elseif (!isstruct(sys))
-    error("sys must be in system data structure form");
-  endif
+    if (nargin != 1)
+      usage("[dsys,Adc,Cdc] = sysdisc(sys)");
+    elseif (!isstruct(sys))
+      error("sys must be in system data structure form");
+    endif
 
-  sys = sysupdate (sys, "ss");
-  [n_tot, st_c, st_d, y_c, y_d] = __syscont_disc__ (sys);        # get ranges
+    sys = sysupdate (sys, "ss");
+    [n_tot, st_c, st_d, y_c, y_d] = __syscont_disc__ (sys);        # get ranges
 
-  ## assume there's nothing there; build partitions as appropriate
-  Add = Adc = Bdd = Cdd = Cdc = Ddd = [];
+    ## assume there's nothing there; build partitions as appropriate
+    Add = Adc = Bdd = Cdd = Cdc = Ddd = [];
 
-  if(isempty(st_d) & isempty(y_d))
-    error("sysdisc: expecting discrete states and/or continous outputs");
-  elseif (isempty(st_d))
-    warning("sysdisc: no discrete states");
-  elseif(isempty(y_d))
-    warning("sysdisc: no discrete outputs");
-  endif
+    if(isempty(st_d) & isempty(y_d))
+      error("sysdisc: expecting discrete states and/or continous outputs");
+    elseif (isempty(st_d))
+      warning("sysdisc: no discrete states");
+    elseif(isempty(y_d))
+      warning("sysdisc: no discrete outputs");
+    endif
 
-  [aa,bb,cc,dd] = sys2ss(sys);
-  if(!isempty(st_d) )
-    Add = aa( st_d , st_d);
-    stname = sysgetsignals(sys,"st",st_d);
-    Bdd = bb( st_d , :);
-    if(!isempty(st_c))
-      Adc = aa( st_d , st_c);
+    [aa,bb,cc,dd] = sys2ss(sys);
+    if(!isempty(st_d) )
+      Add = aa( st_d , st_d);
+      stname = sysgetsignals(sys,"st",st_d);
+      Bdd = bb( st_d , :);
+      if(!isempty(st_c))
+	Adc = aa( st_d , st_c);
+      endif
+      if(!isempty(y_d))
+	Cdd = cc(y_d , st_d);
+      endif
+    else
+      stname = [];
     endif
     if(!isempty(y_d))
-      Cdd = cc(y_d , st_d);
-    endif
-  else
-    stname = [];
-  endif
-  if(!isempty(y_d))
-    Ddd = dd(y_d , :);
-    outname = sysgetsignals(sys,"out",y_d);
-    if(!isempty(st_c))
-      Cdc = cc(y_d , st_c);
+      Ddd = dd(y_d , :);
+      outname = sysgetsignals(sys,"out",y_d);
+      if(!isempty(st_c))
+	Cdc = cc(y_d , st_c);
+      endif
+    else
+      outname=[];
     endif
-  else
-    outname=[];
-  endif
-  inname = sysgetsignals(sys,"in");
-  outlist = 1:rows(outname);
+    inname = sysgetsignals(sys,"in");
+    outlist = 1:rows(outname);
 
-  if(!isempty(outname))
-    tsam = sysgettsam(sys);
-    [nc,nz] = sysdimensions(sys);
-    dsys = ss2sys(Add,Bdd,Cdd,Ddd,tsam,0,nz,stname,inname,outname,outlist);
-  else
-    dsys=[];
-  endif
+    if(!isempty(outname))
+      tsam = sysgettsam(sys);
+      [nc,nz] = sysdimensions(sys);
+      dsys = ss2sys(Add,Bdd,Cdd,Ddd,tsam,0,nz,stname,inname,outname,outlist);
+    else
+      dsys=[];
+    endif
 
-  empty_list_elements_ok = save_empty;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/system/sysgroup.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/sysgroup.m	Fri Jul 11 18:37:48 2003 +0000
@@ -52,98 +52,101 @@
 
 function sys = sysgroup (varargin)
 
-  save_emp = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
-
-  if(nargin < 1)
-    usage("sys = sysgroup(Asys{,Bsys,...})");
-  endif
-
-  ## collect all arguments
-  arglist = list();
-  for kk=1:nargin
-    arglist(kk) = varargin{kk};
-    if(!isstruct(nth(arglist,kk)))
-      error("sysgroup: argument %d is not a data structure",kk);
-    endif
-  endfor
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if(nargin == 2)
-    ## the usual case; group the two systems together
-    Asys = nth(arglist,1);
-    Bsys = nth(arglist,2);
-
-    ## extract information from Asys, Bsys to consruct sys
-    Asys = sysupdate(Asys,"ss");
-    Bsys = sysupdate(Bsys,"ss");
-    [n1,nz1,m1,p1] = sysdimensions(Asys);
-    [n2,nz2,m2,p2] = sysdimensions(Bsys);
-    [Aa,Ab,Ac,Ad,Atsam,An,Anz,Ast,Ain,Aout,Ayd] = sys2ss(Asys);
-    [Ba,Bb,Bc,Bd,Btsam,Bn,Bnz,Bst,Bin,Bout,Byd] = sys2ss(Bsys);
-    nA = An + Anz;
-    nB = Bn + Bnz;
-
-    if(p1*m1*p2*m2 == 0)
-      error("sysgroup: argument lacks inputs and/or outputs");
-
-    elseif((Atsam + Btsam > 0) & (Atsam * Btsam == 0) )
-      warning("sysgroup: creating combination of continuous and discrete systems")
-
-    elseif(Atsam != Btsam)
-      error("sysgroup: Asys.tsam=%e, Bsys.tsam =%e", Atsam, Btsam);
+    if(nargin < 1)
+      usage("sys = sysgroup(Asys{,Bsys,...})");
     endif
 
-    A = [Aa,zeros(nA,nB); zeros(nB,nA),Ba];
-    B = [Ab,zeros(nA,m2); zeros(nB,m1),Bb];
-    C = [Ac,zeros(p1,nB); zeros(p2,nA),Bc];
-    D = [Ad,zeros(p1,m2); zeros(p2,m1),Bd];
-    tsam = max(Atsam,Btsam);
+    ## collect all arguments
+    arglist = list();
+    for kk=1:nargin
+      arglist(kk) = varargin{kk};
+      if(!isstruct(nth(arglist,kk)))
+	error("sysgroup: argument %d is not a data structure",kk);
+      endif
+    endfor
+
+    if(nargin == 2)
+      ## the usual case; group the two systems together
+      Asys = nth(arglist,1);
+      Bsys = nth(arglist,2);
+
+      ## extract information from Asys, Bsys to consruct sys
+      Asys = sysupdate(Asys,"ss");
+      Bsys = sysupdate(Bsys,"ss");
+      [n1,nz1,m1,p1] = sysdimensions(Asys);
+      [n2,nz2,m2,p2] = sysdimensions(Bsys);
+      [Aa,Ab,Ac,Ad,Atsam,An,Anz,Ast,Ain,Aout,Ayd] = sys2ss(Asys);
+      [Ba,Bb,Bc,Bd,Btsam,Bn,Bnz,Bst,Bin,Bout,Byd] = sys2ss(Bsys);
+      nA = An + Anz;
+      nB = Bn + Bnz;
+
+      if(p1*m1*p2*m2 == 0)
+	error("sysgroup: argument lacks inputs and/or outputs");
+
+      elseif((Atsam + Btsam > 0) & (Atsam * Btsam == 0) )
+	warning("sysgroup: creating combination of continuous and discrete systems")
+
+      elseif(Atsam != Btsam)
+	error("sysgroup: Asys.tsam=%e, Bsys.tsam =%e", Atsam, Btsam);
+      endif
 
-    ## construct combined signal names; stnames must check for pure gain blocks
-    if(isempty(Ast))
-      stname = Bst;
-    elseif(isempty(Bst))
-      stname = Ast;
+      A = [Aa,zeros(nA,nB); zeros(nB,nA),Ba];
+      B = [Ab,zeros(nA,m2); zeros(nB,m1),Bb];
+      C = [Ac,zeros(p1,nB); zeros(p2,nA),Bc];
+      D = [Ad,zeros(p1,m2); zeros(p2,m1),Bd];
+      tsam = max(Atsam,Btsam);
+
+      ## construct combined signal names; stnames must check for pure gain blocks
+      if(isempty(Ast))
+	stname = Bst;
+      elseif(isempty(Bst))
+	stname = Ast;
+      else
+	stname  = append(Ast, Bst);
+      endif
+      inname  = append(Ain, Bin);
+      outname = append(Aout,Bout);
+
+      ## Sort states into continous first, then discrete
+      dstates = ones(1,(nA+nB));
+      if(An)
+	dstates(1:(An)) = zeros(1,An);
+      endif
+      if(Bn)
+	dstates((nA+1):(nA+Bn)) = zeros(1,Bn);
+      endif
+      [tmp,pv] = sort(dstates);
+      A = A(pv,pv);
+      B = B(pv,:);
+      C = C(:,pv);
+      stname = stname(pv);
+
+      ## check for duplicate signal names
+      inname = __sysgroupn__ (inname, "input");
+      stname = __sysgroupn__ (stname, "state");
+      outname = __sysgroupn__ (outname, "output");
+
+      ## mark discrete outputs
+      outlist = find([Ayd, Byd]);
+
+      ## build new system
+      sys = ss2sys(A,B,C,D,tsam,An+Bn,Anz+Bnz,stname,inname,outname);
+
     else
-      stname  = append(Ast, Bst);
-    endif
-    inname  = append(Ain, Bin);
-    outname = append(Aout,Bout);
-
-    ## Sort states into continous first, then discrete
-    dstates = ones(1,(nA+nB));
-    if(An)
-      dstates(1:(An)) = zeros(1,An);
-    endif
-    if(Bn)
-      dstates((nA+1):(nA+Bn)) = zeros(1,Bn);
+      ## multiple systems (or a single system); combine together one by one
+      sys = nth(arglist,1);
+      for kk=2:length(arglist)
+	printf("sysgroup: kk=%d\n",kk);
+	sys = sysgroup(sys,nth(arglist,kk));
+      endfor
     endif
-    [tmp,pv] = sort(dstates);
-    A = A(pv,pv);
-    B = B(pv,:);
-    C = C(:,pv);
-    stname = stname(pv);
 
-    ## check for duplicate signal names
-    inname = __sysgroupn__ (inname, "input");
-    stname = __sysgroupn__ (stname, "state");
-    outname = __sysgroupn__ (outname, "output");
-
-    ## mark discrete outputs
-    outlist = find([Ayd, Byd]);
-
-    ## build new system
-    sys = ss2sys(A,B,C,D,tsam,An+Bn,Anz+Bnz,stname,inname,outname);
-
-  else
-    ## multiple systems (or a single system); combine together one by one
-    sys = nth(arglist,1);
-    for kk=2:length(arglist)
-      printf("sysgroup: kk=%d\n",kk);
-      sys = sysgroup(sys,nth(arglist,kk));
-    endfor
-  endif
-
-  empty_list_elements_ok = save_emp;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/system/tfout.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/tfout.m	Fri Jul 11 18:37:48 2003 +0000
@@ -29,34 +29,37 @@
 
 function tfout (num, denom, x)
 
-  save_empty = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if (nargin < 2 ) | (nargin > 3) | (nargout != 0 )
-    usage("tfout(num,denom[,x])");
-  endif
+    if (nargin < 2 ) | (nargin > 3) | (nargout != 0 )
+      usage("tfout(num,denom[,x])");
+    endif
 
-  if ( (!isvector(num)) | (!isvector(denom)) )
-    error("tfout: first two argument must be vectors");
-  endif
+    if ( (!isvector(num)) | (!isvector(denom)) )
+      error("tfout: first two argument must be vectors");
+    endif
 
-  if (nargin == 2)
-    x = "s";
-  elseif( ! isstr(x) )
-    error("tfout: third argument must be a string");
-  endif
+    if (nargin == 2)
+      x = "s";
+    elseif( ! isstr(x) )
+      error("tfout: third argument must be a string");
+    endif
 
-  numstring = polyout(num,x);
-  denomstring = polyout(denom,x);
-  len = max(length(numstring),length(denomstring));
-  if(len > 0)
-    y = strrep(blanks(len)," ","-");
-    disp(numstring)
-    disp(y)
-    disp(denomstring)
-  else
-    error ("tfout: empty transfer function")
-  end
+    numstring = polyout(num,x);
+    denomstring = polyout(denom,x);
+    len = max(length(numstring),length(denomstring));
+    if(len > 0)
+      y = strrep(blanks(len)," ","-");
+      disp(numstring)
+      disp(y)
+      disp(denomstring)
+    else
+      error ("tfout: empty transfer function")
+    end
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
-  empty_list_elements_ok = save_empty;
 endfunction
--- a/scripts/control/system/zp2ss.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/zp2ss.m	Fri Jul 11 18:37:48 2003 +0000
@@ -51,104 +51,108 @@
 
 function [a, b, c, d] = zp2ss (zer, pol, k)
 
-  sav_val = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
-
-  if(nargin != 3)
-    error("Incorrect number of input arguments");
-  endif
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if(! (isvector(zer) | isempty(zer)) )
-    error(["zer(",num2str(rows(zer)),",",num2str(columns(zer)), ...
-        ") should be a vector"]);
-  elseif(! (isvector(pol) | isempty(pol) ) )
-    error(["pol(",num2str(rows(pol)),",",num2str(columns(pol)), ...
-        ") should be a vector"]);
-  elseif(! isscalar(k))
-    error(["k(",num2str(rows(k)),",",num2str(columns(k)), ...
-        ") should be a scalar"]);
-  elseif( k != real(k))
-    warning("zp2ss: k is complex")
-  endif
-
-  zpsys = ss2sys([],[],[],k);
+    if(nargin != 3)
+      error("Incorrect number of input arguments");
+    endif
 
-  ## Find the number of zeros and the number of poles
-  nzer=length(zer);
-  npol =length(pol);
-
-  if(nzer > npol)
-    error([num2str(nzer)," zeros, exceeds number of poles=",num2str(npol)]);
-  endif
-
-  ## Sort to place complex conjugate pairs together
-  zer=sortcom(zer);
-  pol=sortcom(pol);
+    if(! (isvector(zer) | isempty(zer)) )
+      error(["zer(",num2str(rows(zer)),",",num2str(columns(zer)), ...
+	  ") should be a vector"]);
+    elseif(! (isvector(pol) | isempty(pol) ) )
+      error(["pol(",num2str(rows(pol)),",",num2str(columns(pol)), ...
+	  ") should be a vector"]);
+    elseif(! isscalar(k))
+      error(["k(",num2str(rows(k)),",",num2str(columns(k)), ...
+	  ") should be a scalar"]);
+    elseif( k != real(k))
+      warning("zp2ss: k is complex")
+    endif
 
-  ## construct the system as a series connection of poles and zeros
-  ## problem: poles and zeros may come in conjugate pairs, and not
-  ## matched up!
-
-  ## approach: remove poles/zeros from the list as they are included in
-  ## the ss system
+    zpsys = ss2sys([],[],[],k);
 
-  while(length(pol))
+    ## Find the number of zeros and the number of poles
+    nzer=length(zer);
+    npol =length(pol);
 
-    ## search for complex poles, zeros
-    cpol=[];    czer = [];
-    if(!isempty(pol))
-      cpol = find(imag(pol) != 0);
-    endif
-    if(!isempty(zer))
-      czer = find(imag(zer) != 0);
+    if(nzer > npol)
+      error([num2str(nzer)," zeros, exceeds number of poles=",num2str(npol)]);
     endif
 
-    if(isempty(cpol) & isempty(czer))
-      pcnt = 1;
-    else
-      pcnt = 2;
-    endif
+    ## Sort to place complex conjugate pairs together
+    zer=sortcom(zer);
+    pol=sortcom(pol);
+
+    ## construct the system as a series connection of poles and zeros
+    ## problem: poles and zeros may come in conjugate pairs, and not
+    ## matched up!
+
+    ## approach: remove poles/zeros from the list as they are included in
+    ## the ss system
+
+    while(length(pol))
 
-    num=1;      # assume no zeros left.
-    switch(pcnt)
-    case(1)
-      ## real pole/zero combination
-      if(length(zer))
-        num = [1, -zer(1)];
-        zer = zer(2:length(zer));
+      ## search for complex poles, zeros
+      cpol=[];    czer = [];
+      if(!isempty(pol))
+	cpol = find(imag(pol) != 0);
       endif
-      den = [1, -pol(1)];
-      pol = pol(2:length(pol));
-    case(2)
-      ## got a complex pole or zero, need two roots (if available)
-      if(length(zer) > 1)
-        [num, zer] = __zp2ssg2__ (zer);       # get two zeros
-      elseif(length(zer) == 1)
-        num = [1, -zer];                # use last zero (better be real!)
-        zer = [];
+      if(!isempty(zer))
+	czer = find(imag(zer) != 0);
+      endif
+
+      if(isempty(cpol) & isempty(czer))
+	pcnt = 1;
+      else
+	pcnt = 2;
       endif
-      [den, pol] = __zp2ssg2__ (pol);         # get two poles
-    otherwise
-      error(["pcnt = ",num2str(pcnt)])
-    endswitch
-
-    ## pack tf into system form and put in series with earlier realization
-    zpsys1 = tf2sys(num,den,0,"u","yy");
 
-    ## change names to avoid warning messages from sysgroup
-    zpsys  = syssetsignals (zpsys, "in", "u1", 1);
-    zpsys1 = sysupdate (zpsys1, "ss");
-    nn     = sysdimensions (zpsys);        # working with continuous system
-    zpsys  = syssetsignals (zpsys, "st", __sysdefioname__ (nn, "x"));
-    nn1    = sysdimensions (zpsys1);
-    zpsys1 = syssetsignals (zpsys1, "st", __sysdefioname__ (nn1, "xx"));
+      num=1;      # assume no zeros left.
+      switch(pcnt)
+      case(1)
+	## real pole/zero combination
+	if(length(zer))
+	  num = [1, -zer(1)];
+	  zer = zer(2:length(zer));
+	endif
+	den = [1, -pol(1)];
+	pol = pol(2:length(pol));
+      case(2)
+	## got a complex pole or zero, need two roots (if available)
+	if(length(zer) > 1)
+	  [num, zer] = __zp2ssg2__ (zer);       # get two zeros
+	elseif(length(zer) == 1)
+	  num = [1, -zer];                # use last zero (better be real!)
+	  zer = [];
+	endif
+	[den, pol] = __zp2ssg2__ (pol);         # get two poles
+      otherwise
+	error(["pcnt = ",num2str(pcnt)])
+      endswitch
 
-    zpsys = sysmult(zpsys,zpsys1);
+      ## pack tf into system form and put in series with earlier realization
+      zpsys1 = tf2sys(num,den,0,"u","yy");
 
-  endwhile
+      ## change names to avoid warning messages from sysgroup
+      zpsys  = syssetsignals (zpsys, "in", "u1", 1);
+      zpsys1 = sysupdate (zpsys1, "ss");
+      nn     = sysdimensions (zpsys);        # working with continuous system
+      zpsys  = syssetsignals (zpsys, "st", __sysdefioname__ (nn, "x"));
+      nn1    = sysdimensions (zpsys1);
+      zpsys1 = syssetsignals (zpsys1, "st", __sysdefioname__ (nn1, "xx"));
 
-  [a,b,c,d] = sys2ss(zpsys);
+      zpsys = sysmult(zpsys,zpsys1);
+
+    endwhile
 
-  empty_list_elements_ok = sav_val;
+    [a,b,c,d] = sys2ss(zpsys);
+
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
+
 endfunction
 
--- a/scripts/control/system/zpout.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/system/zpout.m	Fri Jul 11 18:37:48 2003 +0000
@@ -29,79 +29,82 @@
 
 function zpout (zer, pol, k, x)
 
-  save_empty = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if (nargin < 3 ) | (nargin > 4) | (nargout != 0 )
-    usage("zpout(zer,pol,k[,x])");
-  endif
+    if (nargin < 3 ) | (nargin > 4) | (nargout != 0 )
+      usage("zpout(zer,pol,k[,x])");
+    endif
 
-  if( !(isvector(zer) | isempty(zer)) | !(isvector(pol) | isempty(pol)) )
-    error("zer, pol must be vectors or empty");
-  endif
+    if( !(isvector(zer) | isempty(zer)) | !(isvector(pol) | isempty(pol)) )
+      error("zer, pol must be vectors or empty");
+    endif
 
-  if(!isscalar(k))
-    error("zpout: argument k must be a scalar.")
-  endif
+    if(!isscalar(k))
+      error("zpout: argument k must be a scalar.")
+    endif
 
-  if (nargin == 3)
-    x = "s";
-  elseif( ! isstr(x) )
-    error("zpout: third argument must be a string");
-  endif
+    if (nargin == 3)
+      x = "s";
+    elseif( ! isstr(x) )
+      error("zpout: third argument must be a string");
+    endif
 
-  numstring = num2str(k);
+    numstring = num2str(k);
 
-  if(length(zer))
-    ## find roots at z,s = 0
-    nzr = sum(zer == 0);
-    if(nzr)
-      if(nzr > 1)
-        numstring = [numstring,sprintf(" %s^%d",x,nzr)];
-      else
-        numstring = [numstring,sprintf(" %s",x)];
+    if(length(zer))
+      ## find roots at z,s = 0
+      nzr = sum(zer == 0);
+      if(nzr)
+	if(nzr > 1)
+	  numstring = [numstring,sprintf(" %s^%d",x,nzr)];
+	else
+	  numstring = [numstring,sprintf(" %s",x)];
+	endif
       endif
+      zer = sortcom(-zer);
+      for ii=1:length(zer)
+	if(zer(ii) != 0)
+	  numstring = [numstring,sprintf(" (%s %s)",x,com2str(zer(ii),1) ) ];
+	endif
+      endfor
     endif
-    zer = sortcom(-zer);
-    for ii=1:length(zer)
-      if(zer(ii) != 0)
-        numstring = [numstring,sprintf(" (%s %s)",x,com2str(zer(ii),1) ) ];
-      endif
-    endfor
-  endif
 
-  if(length(pol))
-    ## find roots at z,s = 0
-    nzr = sum(pol == 0);
-    if(nzr)
-      if(nzr > 1)
-        denomstring = [sprintf("%s^%d",x,nzr)];
+    if(length(pol))
+      ## find roots at z,s = 0
+      nzr = sum(pol == 0);
+      if(nzr)
+	if(nzr > 1)
+	  denomstring = [sprintf("%s^%d",x,nzr)];
+	else
+	  denomstring = [sprintf("%s",x)];
+	endif
       else
-        denomstring = [sprintf("%s",x)];
+	denomstring = " ";
+      endif
+      pol = sortcom(-pol);
+      for ii=1:length(pol)
+	if(pol(ii) != 0)
+	  denomstring = [denomstring,sprintf(" (%s %s)",x,com2str(pol(ii),1))];
+	endif
+      endfor
+    endif
+
+    len = max(length(numstring),length(denomstring));
+    if(len > 0)
+      y = strrep(blanks(len)," ","-");
+      disp(numstring)
+      if(length(denomstring))
+	disp(y)
+	disp(denomstring)
       endif
     else
-      denomstring = " ";
-    endif
-    pol = sortcom(-pol);
-    for ii=1:length(pol)
-      if(pol(ii) != 0)
-        denomstring = [denomstring,sprintf(" (%s %s)",x,com2str(pol(ii),1))];
-      endif
-    endfor
-  endif
+      error ("zpout: empty transfer function")
+    end
 
-  len = max(length(numstring),length(denomstring));
-  if(len > 0)
-    y = strrep(blanks(len)," ","-");
-    disp(numstring)
-    if(length(denomstring))
-      disp(y)
-      disp(denomstring)
-    endif
-  else
-    error ("zpout: empty transfer function")
-  end
-
-  empty_list_elements_ok = save_empty;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/control/util/__outlist__.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/control/util/__outlist__.m	Fri Jul 11 18:37:48 2003 +0000
@@ -46,35 +46,36 @@
 
 function str_val = __outlist__ (name_list, tabchar, yd, ilist)
 
-  ## save for restore later
-  save_empty = empty_list_elements_ok;
-  empty_list_elements_ok = 1;
+  save_warn_empty_list_elements = warn_empty_list_elements;
+  unwind_protect
+    warn_empty_list_elements = 0;
 
-  if( nargin < 1 | nargin > 4 )
-    usage("str_val = outlist(x[,tabchar,yd,ilist])");
-  endif
+    if( nargin < 1 | nargin > 4 )
+      usage("str_val = outlist(x[,tabchar,yd,ilist])");
+    endif
 
-  m = length(name_list);
-  if(nargin < 4)           ilist = 1:m;          endif
-  if(nargin ==1)
-    empty_list_elements_ok = 1;
-    tabchar = "";
-  endif
+    m = length(name_list);
+    if(nargin < 4)           ilist = 1:m;          endif
+    if(nargin ==1)
+      tabchar = "";
+    endif
 
-  if(nargin < 3)             yd = zeros(1,m);
-  elseif(isempty(yd))        yd = zeros(1,m);          endif
+    if(nargin < 3)             yd = zeros(1,m);
+    elseif(isempty(yd))        yd = zeros(1,m);          endif
 
-  str_val = "";
-  dstr = list(""," (discrete)");
-  if((m >= 1) && (islist(name_list)))
-    for ii=1:m
-      str_val = sprintf("%s%s%d: %s%s\n",str_val,tabchar, ilist(ii), ...
-          nth(name_list,ii),nth(dstr,yd(ii)+1));
-    endfor
-  else
-    str_val = sprintf("%sNone",tabchar);
-  endif
+    str_val = "";
+    dstr = list(""," (discrete)");
+    if((m >= 1) && (islist(name_list)))
+      for ii=1:m
+	str_val = sprintf("%s%s%d: %s%s\n",str_val,tabchar, ilist(ii), ...
+			  nth(name_list,ii),nth(dstr,yd(ii)+1));
+      endfor
+    else
+      str_val = sprintf("%sNone",tabchar);
+    endif
 
-  empty_list_elements_ok = save_empty;
+  unwind_protect_cleanup
+    warn_empty_list_elements = save_warn_empty_list_elements;
+  end_unwind_protect
 
 endfunction
--- a/scripts/general/shift.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/general/shift.m	Fri Jul 11 18:37:48 2003 +0000
@@ -49,11 +49,9 @@
     error ("shift: b must be an integer");
   endif
 
-  elo = empty_list_elements_ok;
-
+  save_warn_empty_list_elements = warn_empty_list_elements;
   unwind_protect
-
-    empty_list_elements_ok = 1;
+    warn_empty_list_elements = 0;
 
     if (b >= 0)
       b = rem (b, nr);
@@ -68,9 +66,7 @@
     endif
 
   unwind_protect_cleanup
-
-    empty_list_elements_ok = elo;
-
+    warn_empty_list_elements = save_warn_empty_list_elements;
   end_unwind_protect
 
   if (nc == 0)
--- a/scripts/miscellaneous/dump_prefs.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/miscellaneous/dump_prefs.m	Fri Jul 11 18:37:48 2003 +0000
@@ -59,7 +59,6 @@
               "default_save_format";
               "define_all_return_values";
               "echo_executing_commands";
-              "empty_list_elements_ok";
               "fixed_point_format";
               "gnuplot_binary";
               "gnuplot_command_end";
@@ -96,6 +95,7 @@
               "suppress_verbose_help_message";
               "warn_assign_as_truth_value";
               "warn_divide_by_zero";
+              "warn_empty_list_elements";
               "warn_fortran_indexing";
               "warn_function_name_clash";
               "warn_future_time_stamp";
--- a/scripts/signal/arma_rnd.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/signal/arma_rnd.m	Fri Jul 11 18:37:48 2003 +0000
@@ -42,9 +42,9 @@
 
 function x = arma_rnd (a, b, v, t, n)
 
+  save_warn_empty_list_elements = warn_empty_list_elements;
   unwind_protect
-    orig_listelemok = empty_list_elements_ok;
-    empty_list_elements_ok = "true";
+    warn_empty_list_elements = 0;
 
     if (nargin == 4)
       n = 100;
@@ -81,9 +81,7 @@
     x = x(n + 1 : t + n);
 
   unwind_protect_cleanup
-
-    empty_list_elements_ok = orig_listelemok;
-
+    warn_empty_list_elements = save_warn_empty_list_elements;
   end_unwind_protect
 
 endfunction
--- a/scripts/strings/strcat.m	Fri Jul 11 17:46:41 2003 +0000
+++ b/scripts/strings/strcat.m	Fri Jul 11 18:37:48 2003 +0000
@@ -36,9 +36,9 @@
 function st = strcat (s, t, varargin)
 
   if (nargin > 1)
-    save_empty_list_elements_ok = empty_list_elements_ok;
+    save_warn_empty_list_elements = warn_empty_list_elements;
     unwind_protect
-      empty_list_elements_ok = 1;
+      warn_empty_list_elements = 0;
       if (isstr (s) && isstr (t))
         tmpst = [s, t];
       else
@@ -55,7 +55,7 @@
         endif
       endwhile
     unwind_protect_cleanup
-      empty_list_elements_ok = save_empty_list_elements_ok;
+      warn_empty_list_elements = save_warn_empty_list_elements;
     end_unwind_protect
   else
     usage ("strcat (s, t, ...)");
--- a/src/ChangeLog	Fri Jul 11 17:46:41 2003 +0000
+++ b/src/ChangeLog	Fri Jul 11 18:37:48 2003 +0000
@@ -1,3 +1,15 @@
+2003-07-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* pt-mat.cc (Vwarn_empty_list_elements): New variable.
+	(warn_empty_list_elements): New function.
+	(symbols_of_pt_mat): Add DEFVAR for warn_empty_list_elements.
+	(): Check Vwarn_empty_list_elements, not
+	Vempty_list_elements_ok.
+
+	* pt-mat.cc (Vempty_list_elements_ok): Delete.
+	(empty_list_elements_ok): Delete.
+	(symbols_of_pt_mat): Delete DEFVAR for empty_list_elements_ok.
+
 2003-07-11  Russell Standish <R.Standish@unsw.edu.au>
 
 	* TEMPLATE-INST/Array-tc.cc (resize_fill_value): Provide
--- a/src/pt-mat.cc	Fri Jul 11 17:46:41 2003 +0000
+++ b/src/pt-mat.cc	Fri Jul 11 18:37:48 2003 +0000
@@ -42,11 +42,8 @@
 #include "ov.h"
 #include "variables.h"
 
-// Are empty elements in a matrix list ok?  For example, is the empty
-// matrix in an expression like `[[], 1]' ok?  A positive value means
-// yes.  A negative value means yes, but print a warning message.
-// Zero means it should be considered an error.
-static int Vempty_list_elements_ok;
+// If TRUE, print a warning message for empty elements in a matrix list.
+static bool Vwarn_empty_list_elements;
 
 // The character to fill with when creating string arrays.
 char Vstring_fill_char = ' ';
@@ -189,19 +186,7 @@
 	  int this_elt_nr = tmp.rows ();
 	  int this_elt_nc = tmp.columns ();
 
-	  if (this_elt_nr == 0 && this_elt_nc == 0)
-	    {
-	      if (Vempty_list_elements_ok < 0)
-		eval_warning ("empty matrix found in matrix list",
-			      elt->line (), elt->column ());
-	      else if (Vempty_list_elements_ok == 0)
-		{
-		  eval_error ("empty matrix found in matrix list",
-			      elt->line (), elt->column ());
-		  break;
-		}
-	    }
-	  else
+	  if (this_elt_nr > 0 || this_elt_nc > 0)
 	    {
 	      all_mt = false;
 
@@ -222,6 +207,9 @@
 
 	      append (tmp);
 	    }
+	  else if (Vwarn_empty_list_elements)
+	    eval_warning ("empty matrix found in matrix list",
+			  elt->line (), elt->column ());
 
 	  if (all_str && ! tmp.is_string ())
 	    all_str = false;
@@ -358,17 +346,7 @@
 	  int this_elt_nr = elt.rows ();
 	  int this_elt_nc = elt.cols ();
 
-	  if (this_elt_nr == 0 && this_elt_nc == 0)
-	    {
-	      if (Vempty_list_elements_ok < 0)
-		warning ("empty matrix found in matrix list");
-	      else if (Vempty_list_elements_ok == 0)
-		{
-		  ::error ("empty matrix found in matrix list");
-		  break;
-		}
-	    }
-	  else
+	  if (this_elt_nr > 0 || this_elt_nc > 0)
 	    {
 	      all_mt = false;
 
@@ -392,6 +370,8 @@
 
 	      nr += this_elt_nr;
 	    }
+	  else if (Vwarn_empty_list_elements)
+	    warning ("empty matrix found in matrix list");
 	}
     }
 
@@ -588,9 +568,9 @@
 }
 
 static int
-empty_list_elements_ok (void)
+warn_empty_list_elements (void)
 {
-  Vempty_list_elements_ok = check_preference ("empty_list_elements_ok");
+  Vwarn_empty_list_elements = check_preference ("warn_empty_list_elements");
 
   return 0;
 }
@@ -624,25 +604,6 @@
 void
 symbols_of_pt_mat (void)
 {
-  DEFVAR (empty_list_elements_ok, true, empty_list_elements_ok,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} empty_list_elements_ok\n\
-This variable controls whether Octave ignores empty matrices in a matrix\n\
-list.\n\
-\n\
-For example, if the value of @code{empty_list_elements_ok} is\n\
-nonzero, Octave will ignore the empty matrices in the expression\n\
-\n\
-@example\n\
-a = [1, [], 3, [], 5]\n\
-@end example\n\
-\n\
-@noindent\n\
-and the variable @code{a} will be assigned the value @code{[ 1, 3, 5 ]}.\n\
-\n\
-The default value is 1.\n\
-@end defvr");
-
   DEFVAR (string_fill_char, " ", string_fill_char,
     "-*- texinfo -*-\n\
 @defvr {Built-in Variable} string_fill_char\n\
@@ -660,6 +621,21 @@
 @end group\n\
 @end example\n\
 @end defvr");
+
+  DEFVAR (warn_empty_list_elements, false, warn_empty_list_elements,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} warn_empty_list_elements\n\
+If the value of @code{warn_empty_list_elements} is nonzero, print a\n\
+warning when an empty matrix is found in a matrix list.  For example,\n\
+\n\
+@example\n\
+a = [1, [], 3, [], 5]\n\
+@end example\n\
+\n\
+@noindent\n\
+The default value is 0.\n\
+@end defvr");
+
 }
 
 /*