1 ## Copyright (C) 2011 Lukas F. Reichlin
3 ## This file is part of LTI Syncope.
5 ## LTI Syncope is free software: you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation, either version 3 of the License, or
8 ## (at your option) any later version.
10 ## LTI Syncope is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>.
19 ## @deftypefn{Function File} {[@var{Kr}, @var{info}] =} __conred_sb16ad__ (@var{method}, @dots{})
20 ## Backend for btaconred and spaconred.
23 ## Author: Lukas Reichlin <lukas.reichlin@gmail.com>
24 ## Created: December 2011
27 function [Kr, info] = __conred_sb16ad__ (method, varargin)
33 if (method != "bta" && method != "spa")
34 error ("modred: invalid method");
39 varargin = varargin(3:end);
42 error ("%sconred: first argument must be an LTI system", method);
46 error ("%sconred: second argument must be an LTI system", method);
49 if (nargin > 3) # *conred (G, K, ...)
50 if (is_real_scalar (varargin{1})) # *conred (G, K, nr)
51 varargin = horzcat (varargin(2:end), {"order"}, varargin(1));
53 if (isstruct (varargin{1})) # *conred (G, K, opt, ...), *conred (G, K, nr, opt, ...)
54 varargin = horzcat (__opt2cell__ (varargin{1}), varargin(2:end));
56 ## order placed at the end such that nr from *conred (G, K, nr, ...)
57 ## and *conred (G, K, nr, opt, ...) overrides possible nr's from
58 ## key/value-pairs and inside opt struct (later keys override former keys,
59 ## nr > key/value > opt)
62 nkv = numel (varargin); # number of keys and values
65 error ("%sconred: keys and values must come in pairs", method);
68 [a, b, c, d, tsam, scaled] = ssdata (G);
69 [ac, bc, cc, dc, tsamc, scaledc] = ssdata (K);
74 if (p != mc || m != pc)
75 error ("%sconred: dimensions of controller (%dx%d) and plant (%dx%d) don't match", \
76 method, pc, mc, p, c);
81 alpha = __modred_default_alpha__ (dt);
85 bf = true; # balancing-free
87 equil = scaled && scaledc;
90 negfb = false; # positive feedback controller
93 ## handle keys and values
95 key = lower (varargin{k});
99 switch (lower (val(1)))
102 case {"l", "o"} # left, output
104 case {"r", "i"} # right, input
106 case {"b", "p"} # both, performance
109 error ("%sconred: '%s' is an invalid value for key weight", method, val);
112 case {"order", "ncr", "nr"}
113 [ncr, ordsel] = __modred_check_order__ (val, rows (ac));
116 tol1 = __modred_check_tol__ (val, "tol1");
119 tol2 = __modred_check_tol__ (val, "tol2");
122 alpha = __modred_check_alpha__ (val, dt);
125 switch (tolower (val))
131 error ("modred: '%s' is an invalid approach", val);
134 case {"jobc", "gram-ctrb"}
135 jobc = __modred_check_gram__ (val, "gram-ctrb");
137 case {"jobo", "gram-obsv"}
138 jobo = __modred_check_gram__ (val, "gram-obsv");
140 case {"equil", "equilibrate", "equilibration", "scale", "scaling"}
141 scaled = __modred_check_equil__ (val);
144 negfb = __conred_check_feedback_sign__ (val);
147 warning ("%sconred: invalid property name '%s' ignored", method, key);
152 ## handle model reduction approach
153 if (method == "bta" && ! bf) # 'B': use the square-root Balance & Truncate method
155 elseif (method == "bta" && bf) # 'F': use the balancing-free square-root Balance & Truncate method
157 elseif (method == "spa" && ! bf) # 'S': use the square-root Singular Perturbation Approximation method
159 elseif (method == "spa" && bf) # 'P': use the balancing-free square-root Singular Perturbation Approximation method
162 error ("%smodred: invalid jobmr option"); # this should never happen
165 ## handle negative feedback controllers
167 [ac, bc, cc, dc] = ssdata (-K);
171 ## perform model order reduction
172 [acr, bcr, ccr, dcr, ncr, hsvc, ncs] = slsb16ad (a, b, c, d, dt, equil, ncr, ordsel, alpha, jobmr, \
174 weight, jobc, jobo, tol1, tol2);
176 ## assemble reduced order controller
177 Kr = ss (acr, bcr, ccr, dcr, tsamc);
179 ## handle negative feedback controllers
184 ## assemble info struct
185 info = struct ("ncr", ncr, "ncs", ncs, "hsvc", hsvc);