# HG changeset patch # User jwe # Date 1057948668 0 # Node ID cef48c4b902db231f2fcdd8386fe10f3c0bcf306 # Parent 75ee1995d2b49fca4949ced2d6b7240a17763f02 [project @ 2003-07-11 18:37:48 by jwe] diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-07-11 John W. Eaton + + * 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 * emacs/octave-mod.el (octave-variables): Add warn_neg_dim_as_zero diff --git a/doc/interpreter/numbers.txi b/doc/interpreter/numbers.txi --- a/doc/interpreter/numbers.txi +++ b/doc/interpreter/numbers.txi @@ -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 diff --git a/doc/interpreter/var.txi b/doc/interpreter/var.txi --- a/doc/interpreter/var.txi +++ b/doc/interpreter/var.txi @@ -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}. diff --git a/emacs/octave-mod.el b/emacs/octave-mod.el --- a/emacs/octave-mod.el +++ b/emacs/octave-mod.el @@ -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.") diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,17 @@ +2003-07-11 John W. Eaton + + * 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 * miscellaneous/dump_prefs.m: Include warn_neg_dim_as_zero in the diff --git a/scripts/control/base/__freqresp__.m b/scripts/control/base/__freqresp__.m --- a/scripts/control/base/__freqresp__.m +++ b/scripts/control/base/__freqresp__.m @@ -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 diff --git a/scripts/control/base/place.m b/scripts/control/base/place.m --- a/scripts/control/base/place.m +++ b/scripts/control/base/place.m @@ -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 diff --git a/scripts/control/base/pzmap.m b/scripts/control/base/pzmap.m --- a/scripts/control/base/pzmap.m +++ b/scripts/control/base/pzmap.m @@ -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 diff --git a/scripts/control/system/sysappend.m b/scripts/control/system/sysappend.m --- a/scripts/control/system/sysappend.m +++ b/scripts/control/system/sysappend.m @@ -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 diff --git a/scripts/control/system/syscont.m b/scripts/control/system/syscont.m --- a/scripts/control/system/syscont.m +++ b/scripts/control/system/syscont.m @@ -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 diff --git a/scripts/control/system/sysdisc.m b/scripts/control/system/sysdisc.m --- a/scripts/control/system/sysdisc.m +++ b/scripts/control/system/sysdisc.m @@ -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 diff --git a/scripts/control/system/sysgroup.m b/scripts/control/system/sysgroup.m --- a/scripts/control/system/sysgroup.m +++ b/scripts/control/system/sysgroup.m @@ -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 diff --git a/scripts/control/system/tfout.m b/scripts/control/system/tfout.m --- a/scripts/control/system/tfout.m +++ b/scripts/control/system/tfout.m @@ -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 diff --git a/scripts/control/system/zp2ss.m b/scripts/control/system/zp2ss.m --- a/scripts/control/system/zp2ss.m +++ b/scripts/control/system/zp2ss.m @@ -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 diff --git a/scripts/control/system/zpout.m b/scripts/control/system/zpout.m --- a/scripts/control/system/zpout.m +++ b/scripts/control/system/zpout.m @@ -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 diff --git a/scripts/control/util/__outlist__.m b/scripts/control/util/__outlist__.m --- a/scripts/control/util/__outlist__.m +++ b/scripts/control/util/__outlist__.m @@ -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 diff --git a/scripts/general/shift.m b/scripts/general/shift.m --- a/scripts/general/shift.m +++ b/scripts/general/shift.m @@ -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) diff --git a/scripts/miscellaneous/dump_prefs.m b/scripts/miscellaneous/dump_prefs.m --- a/scripts/miscellaneous/dump_prefs.m +++ b/scripts/miscellaneous/dump_prefs.m @@ -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"; diff --git a/scripts/signal/arma_rnd.m b/scripts/signal/arma_rnd.m --- a/scripts/signal/arma_rnd.m +++ b/scripts/signal/arma_rnd.m @@ -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 diff --git a/scripts/strings/strcat.m b/scripts/strings/strcat.m --- a/scripts/strings/strcat.m +++ b/scripts/strings/strcat.m @@ -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, ...)"); diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2003-07-11 John W. Eaton + + * 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 * TEMPLATE-INST/Array-tc.cc (resize_fill_value): Provide diff --git a/src/pt-mat.cc b/src/pt-mat.cc --- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -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"); + } /*