From: <sla...@us...> - 2008-12-28 17:47:20
|
Revision: 5501 http://octave.svn.sourceforge.net/octave/?rev=5501&view=rev Author: slackydeb Date: 2008-12-28 17:47:14 +0000 (Sun, 28 Dec 2008) Log Message: ----------- Added new functions: "balreal", "isct", "isdt". Considered the function "is_digital" as obsolete. Rewritten the function "gram". Modified the function "dgram" to be simple to mantain. Suggested using "is_stable" instead of the missing "isstable". Modified the "INDEX" file to reflect changes. Bumped package version. Modified Paths: -------------- trunk/octave-forge/main/control/DESCRIPTION trunk/octave-forge/main/control/INDEX trunk/octave-forge/main/control/inst/dgram.m trunk/octave-forge/main/control/inst/gram.m Added Paths: ----------- trunk/octave-forge/main/control/inst/balreal.m trunk/octave-forge/main/control/inst/isct.m trunk/octave-forge/main/control/inst/isdt.m Modified: trunk/octave-forge/main/control/DESCRIPTION =================================================================== --- trunk/octave-forge/main/control/DESCRIPTION 2008-12-28 10:13:22 UTC (rev 5500) +++ trunk/octave-forge/main/control/DESCRIPTION 2008-12-28 17:47:14 UTC (rev 5501) @@ -1,5 +1,5 @@ Name: Control -Version: 1.0.8 +Version: 1.0.9 Date: 2008-08-23 Author: Ben Sapp Maintainer: None Modified: trunk/octave-forge/main/control/INDEX =================================================================== --- trunk/octave-forge/main/control/INDEX 2008-12-28 10:13:22 UTC (rev 5500) +++ trunk/octave-forge/main/control/INDEX 2008-12-28 17:47:14 UTC (rev 5501) @@ -40,12 +40,14 @@ are dare dgram dlyap gram lyap pinv dre zgfmul zgfslv zginit zgreduce zgrownorm zgscal zgsgiv zgshsr + balreal System properties analdemo abcddim ctrb h2norm hinfnorm obsv pzmap is_abcd is_controllable is_detectable is_dgkf - is_digital is_observable is_sample is_siso is_stabilizable + is_observable is_sample is_siso is_stabilizable is_signal_list is_stable + isct isdt Time domain analysis c2d d2c dmr2d damp dcgain impulse step Frequency domain analysis @@ -65,6 +67,7 @@ Obsolete dezero dlqg minfo packsys unpacksys swaprows swapcols rotg qzval syschnames series + is_digital Internal __bodquist__ __freqresp__ __stepimp__ __abcddims__ __syschnamesl__ __syscont_disc__ __sysdefioname__ __sysdefstname__ __sysgroupn__ @@ -78,8 +81,6 @@ ssdata= use <f>sys2ss</f> tfdata=use <f>sys2tf</f> zpkdata=use <f>sys2zp</f> - isct=use !<f>is_digital</f> - isdt=use <f>is_digital</f> issiso=use <f>is_siso</f> append(sys)=use <f>sysappend</f> lft=use <f>starp</f> @@ -87,4 +88,4 @@ zero=use <f>tzero</f> or <f>tzero2</f> kalman=use <f>lqe</f> kalmd=use <f>dlqe</f> or <f>dkalman</f> - + isstable=use <f>is_stable</f> Added: trunk/octave-forge/main/control/inst/balreal.m =================================================================== --- trunk/octave-forge/main/control/inst/balreal.m (rev 0) +++ trunk/octave-forge/main/control/inst/balreal.m 2008-12-28 17:47:14 UTC (rev 5501) @@ -0,0 +1,117 @@ +## Copyright (C) 2008 Luca Favatella <sla...@gm...> +## +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{sysb}, @var{g}] =} balreal (@var{sys}) +## @deftypefnx {Function File} {[@var{sysb}, @var{g}, @var{T}, @var{Ti}] =} balreal (@var{sys}) +## Balanced realization of the continuous-time LTI system @var{sys}. +## +## @strong{Input} +## @table @var +## @item sys +## Stable, controllable and observable continuous-time LTI system. +## @end table +## +## @strong{Outputs} +## @table @var +## @item sysb +## Balanced realization of @var{sys}. +## @item g +## Diagonal of the balanced gramians. +## @item T +## State transformation to convert @var{sys} to @var{sysb}. +## @item Ti +## Inverse of T. +## @end table +## +## @seealso{gram} +## @end deftypefn + +## Author: Luca Favatella <sla...@gm...> +## Version: 0.2.4 + + # TODO + # improve continuous-time system test + # test against discrete-time systems + # clean asserts + # clean names Wc2/Wc and Wo2/Wc + # substitute is_stable with isstable + +function [sysb, g, T, Ti] = balreal (sys) + + if (nargin != 1) + print_usage (); + elseif (! is_stable (sys)) + error ("sys must be stable"); + elseif (! is_controllable (sys)) + error ("sys must be controllable"); + elseif (! is_observable (sys)) + error ("sys must be observable"); + else + ASSERT_TOL = 1e-12; ## DEBUG + + ## step 1: compute T1 + Wc2 = gram (sys, 'c'); + [Vc, Sc2, trash] = svd (Wc2); + assert (trash, Vc, ASSERT_TOL); ## DEBUG + T1 = Vc * sqrt (Sc2); + + ## step 2: apply T1 + Atilde = inv (T1) * sys.a * T1; + Btilde = inv (T1) * sys.b; + Ctilde = sys.c * T1; + Wc2tilde = gram (Atilde, Btilde); ## DEBUG + assert (Wc2tilde, eye (size (Wc2tilde)), ASSERT_TOL); ## DEBUG + + ## step 3: compute T2 + Wo2tilde = gram (Atilde', Ctilde'); + [Vo, Sigma2, trash] = svd (Wo2tilde); + assert (trash, Vo, ASSERT_TOL); ## DEBUG + T2 = Vo * (Sigma2 ^ (- 1/4)); + + ## step 4: apply T2 + Abal = inv (T2) * Atilde * T2; + Bbal = inv (T2) * Btilde; + Cbal = Ctilde * T2; + + + ## prepare return values + ## sysb + sysb = ss (Abal, Bbal, Cbal, sys.d); + + ## g + Wc2bal = gram (Abal, Bbal); + g = diag (Wc2bal); + Wo2bal = gram (Abal', Cbal'); ## DEBUG + assert (Wc2bal, Wo2bal, ASSERT_TOL); ## DEBUG + Wo2 = gram (sys, 'o'); ## DEBUG + Sigma = diag (sqrt (sort (eig (Wc2 * Wo2), 'descend'))); ## DEBUG + assert (Wc2bal, Sigma, ASSERT_TOL); ## DEBUG + assert (Wo2bal, Sigma, ASSERT_TOL); ## DEBUG + + ## T and Ti + T = inv (T1 * T2); + Ti = inv (T); + endif +endfunction + + +%!test +%! a = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! b = [1 0; 0 -1; 0 1]; +%! c = [0 0 1; 1 1 0]; +%! balreal (ss (a, b, c)); \ No newline at end of file Modified: trunk/octave-forge/main/control/inst/dgram.m =================================================================== --- trunk/octave-forge/main/control/inst/dgram.m 2008-12-28 10:13:22 UTC (rev 5500) +++ trunk/octave-forge/main/control/inst/dgram.m 2008-12-28 17:47:14 UTC (rev 5501) @@ -62,10 +62,24 @@ if (nargin != 2) print_usage (); + else + + ## this is not efficient, but it is simple to mantain + ## + ## efficiency is not important because this function is here only + ## for backward compatibility + c = zeros (1, length (a)); ## it doesn't matter what the value of c is + d = zeros (rows (c), columns (b)); ## it doesn't matter what the value of d is + Ts = 0.1; ## Ts != 0 + sys = ss (a, b, c, d, Ts); + m = gram (sys, 'c'); endif - ## let dlyap do the error checking... +endfunction - m = dlyap (a, b*b'); -endfunction +%!test +%! a = [-1 0 0; 1/2 1 0; 1/2 0 -1] / 2; +%! b = [1 0; 0 -1; 0 1]; +%! Wc = dgram (a, b); +%! assert (a * Wc * a' - Wc + b * b', zeros (size (a)), 1e-12) \ No newline at end of file Modified: trunk/octave-forge/main/control/inst/gram.m =================================================================== --- trunk/octave-forge/main/control/inst/gram.m 2008-12-28 10:13:22 UTC (rev 5500) +++ trunk/octave-forge/main/control/inst/gram.m 2008-12-28 17:47:14 UTC (rev 5501) @@ -17,30 +17,113 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} gram (@var{a}, @var{b}) -## Return controllability gramian @var{m} of the continuous time system -## @math{dx/dt = a x + b u}. +## @deftypefn {Function File} {@var{W} =} gram (@var{sys}, @var{mode}) +## @deftypefnx {Function File} {@var{Wc} =} gram (@var{a}, @var{b}) +## @code{gram (@var{sys}, 'c')} returns the controllability gramian of +## the (continuous- or discrete-time) system @var{sys}. +## @code{gram (@var{sys}, 'o')} returns the observability gramian of the +## (continuous- or discrete-time) system @var{sys}. +## @code{gram (@var{a}, @var{b})} returns the controllability gramian +## @var{Wc} of the continuous-time system @math{dx/dt = a x + b u}; +## i.e., @var{Wc} satisfies @math{a Wc + m Wc' + b b' = 0}. ## -## @var{m} satisfies @math{a m + m a' + b b' = 0}. ## @end deftypefn ## Author: A. S. Hodel <a.s...@en...> -function m = gram (a, b) + # TODO: substitute is_stable with isstable +function W = gram (argin1, argin2) + if (nargin != 2) print_usage (); - endif + else - ## Let lyap do the error checking... + if (! ischar (argin2)) ## the function was called as "gram (a, b)" + a = argin1; + b = argin2; + if (! is_stable (a)) + error ("the continuous-time system must have a stable 'a' matrix"); + else - m = lyap (a', b*b'); + ## let lyap do the error checking about dimensions + W = lyap (a', b*b'); + endif + else ## the function was called as "gram (sys, mode)" + if (! (strcmp (argin2, 'c') || strcmp (argin2, 'o'))) + print_usage (); + else + if (strcmp (argin2, 'c')) + a = argin1.a; + b = argin1.b; + elseif (strcmp (argin2, 'o')) + a = argin1.a'; + b = argin1.c'; + endif + + if (isct (argin1)) + if (! is_stable (argin1)) + error ("the continuous-time system must be stable"); + else + + ## let lyap do the error checking about dimensions + W = lyap (a', b*b'); + endif + elseif (isdt (argin1)) + if (! is_stable (argin1)) + error ("the discrete-time system must be stable"); + else + + ## let dlyap do the error checking about dimensions + W = dlyap (a, b*b'); + endif + else + error ("strange behaviour in isct/isdt: if you can reproduce \ + this, please submit a bug report"); + endif + endif + endif + + endif + endfunction %!test %! a = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; %! b = [1 0; 0 -1; 0 1]; -%! m = gram (a, b); -%! assert (a * m + m * a' + b *b', zeros (size (a))) \ No newline at end of file +%! c = [0 0 1; 1 1 0]; ## it doesn't matter what the value of c is +%! Wc = gram (ss (a, b, c), 'c'); +%! assert (a * Wc + Wc * a' + b * b', zeros (size (a))) + +%!test +%! a = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! b = [1 0; 0 -1; 0 1]; ## it doesn't matter what the value of b is +%! c = [0 0 1; 1 1 0]; +%! Wo = gram (ss (a, b, c), 'o'); +%! assert (a' * Wo + Wo * a + c' * c, zeros (size (a))) + +%!test +%! a = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! b = [1 0; 0 -1; 0 1]; +%! Wc = gram (a, b); +%! assert (a * Wc + Wc * a' + b * b', zeros (size (a))) + +%!test +%! a = [-1 0 0; 1/2 1 0; 1/2 0 -1] / 2; +%! b = [1 0; 0 -1; 0 1]; +%! c = [0 0 1; 1 1 0]; ## it doesn't matter what the value of c is +%! d = zeros (rows (c), columns (b)); ## it doesn't matter what the value of d is +%! Ts = 0.1; ## Ts != 0 +%! Wc = gram (ss (a, b, c, d, Ts), 'c'); +%! assert (a * Wc * a' - Wc + b * b', zeros (size (a)), 1e-12) + +%!test +%! a = [-1 0 0; 1/2 1 0; 1/2 0 -1] / 2; +%! b = [1 0; 0 -1; 0 1]; ## it doesn't matter what the value of b is +%! c = [0 0 1; 1 1 0]; +%! d = zeros (rows (c), columns (b)); ## it doesn't matter what the value of d is +%! Ts = 0.1; ## Ts != 0 +%! Wo = gram (ss (a, b, c, d, Ts), 'o'); +%! assert (a' * Wo * a - Wo + c' * c, zeros (size (a)), 1e-12) \ No newline at end of file Added: trunk/octave-forge/main/control/inst/isct.m =================================================================== --- trunk/octave-forge/main/control/inst/isct.m (rev 0) +++ trunk/octave-forge/main/control/inst/isct.m 2008-12-28 17:47:14 UTC (rev 5501) @@ -0,0 +1,49 @@ +## Copyright (C) 2008 Luca Favatella <sla...@gm...> +## +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} isct (@var{sys}) +## Return true if the LTI system @var{sys} is continuous-time, false otherwise. +## +## @seealso{isdt} +## @end deftypefn + +## Author: Luca Favatella <sla...@gm...> +## Version: 0.2.1 + +function retval = isct (sys) + if (nargin != 1) + print_usage (); + else + retval = (! is_digital (sys)); + endif +endfunction + + +%!test +%! A = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! B = [1 0; 0 -1; 0 1]; +%! C = [0 0 1; 1 1 0]; +%! assert (isct (ss (A, B, C))); + +%!test +%! A = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! B = [1 0; 0 -1; 0 1]; +%! C = [0 0 1; 1 1 0]; +%! D = zeros (rows (C), columns (B)); +%! Ts = 0.1; +%! assert (! isct (ss (A, B, C, D, Ts))); \ No newline at end of file Added: trunk/octave-forge/main/control/inst/isdt.m =================================================================== --- trunk/octave-forge/main/control/inst/isdt.m (rev 0) +++ trunk/octave-forge/main/control/inst/isdt.m 2008-12-28 17:47:14 UTC (rev 5501) @@ -0,0 +1,49 @@ +## Copyright (C) 2008 Luca Favatella <sla...@gm...> +## +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} isdt (@var{sys}) +## Return true if the LTI system @var{sys} is discrete-time, false otherwise. +## +## @seealso{isct} +## @end deftypefn + +## Author: Luca Favatella <sla...@gm...> +## Version: 0.2.1 + +function retval = isdt (sys) + if (nargin != 1) + print_usage (); + else + retval = is_digital (sys); + endif +endfunction + + +%!test +%! A = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! B = [1 0; 0 -1; 0 1]; +%! C = [0 0 1; 1 1 0]; +%! D = zeros (rows (C), columns (B)); +%! Ts = 0.1; +%! assert (isdt (ss (A, B, C, D, Ts))); + +%!test +%! A = [-1 0 0; 1/2 -1 0; 1/2 0 -1]; +%! B = [1 0; 0 -1; 0 1]; +%! C = [0 0 1; 1 1 0]; +%! assert (! isdt (ss (A, B, C))); \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |