1## Copyright (C) 2009-2016 Lukas F. Reichlin 2## 3## This file is part of LTI Syncope. 4## 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. 9## 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. 14## 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/>. 17 18## -*- texinfo -*- 19## @deftypefn {Function File} {@var{sys} =} lft (@var{sys1}, @var{sys2}) 20## @deftypefnx {Function File} {@var{sys} =} lft (@var{sys1}, @var{sys2}, @var{nu}, @var{ny}) 21## Linear fractional tranformation, also known as Redheffer star product. 22## 23## @strong{Inputs} 24## @table @var 25## @item sys1 26## Upper @acronym{LTI} model. 27## @item sys2 28## Lower @acronym{LTI} model. 29## @item nu 30## The last nu inputs of @var{sys1} are connected with the first nu outputs of @var{sys2}. 31## If not specified, @code{min (m1, p2)} is taken. 32## @item ny 33## The last ny outputs of @var{sys1} are connected with the first ny inputs of @var{sys2}. 34## If not specified, @code{min (p1, m2)} is taken. 35## @end table 36## 37## @strong{Outputs} 38## @table @var 39## @item sys 40## Resulting @acronym{LTI} model. 41## @end table 42## 43## @strong{Block Diagram} 44## @example 45## @group 46## .............sys.............. 47## : +--------+ : 48## w1 ------------>| |------------> z1 49## : | sys1 | : 50## : u +---->| |-----+ y : 51## : | +--------+ | : Lower LFT 52## : | | : 53## : | +--------+ | : lft (sys1, sys2) 54## : +-----| sys2 |<----+ : 55## : +--------+ : 56## :............................: 57## @end group 58## @end example 59## @example 60## @group 61## .............sys.............. 62## : +--------+ : 63## : u +---->| sys1 |-----+ y : 64## : | +--------+ | : Upper LFT 65## : | | : 66## : | +--------+ | : lft (sys1, sys2) 67## : +-----| |<----+ : 68## : | sys2 | : 69## z2 <------------| |<------------ w2 70## : +--------+ : 71## :............................: 72## @end group 73## @end example 74## @example 75## @group 76## .............sys.............. 77## : +--------+ : 78## w1 ------------>| |------------> z1 79## : | sys1 | : 80## : u +---->| |-----+ y : 81## : | +--------+ | : 82## : | | : lft (sys1, sys2, nu, ny) 83## : | +--------+ | : 84## : +-----| |<----+ : 85## : | sys2 | : 86## z2 <------------| |<------------ w2 87## : +--------+ : 88## :............................: 89## @end group 90## @end example 91## @end deftypefn 92 93## Author: Lukas Reichlin <lukas.reichlin@gmail.com> 94## Created: October 2009 95## Version: 0.2 96 97function sys = lft (sys1, sys2, nu, ny) 98 99 if (nargin != 2 && nargin != 4) 100 print_usage (); 101 endif 102 103 ## object conversion done by sys_group if necessary 104 105 [p1, m1] = size (sys1); 106 [p2, m2] = size (sys2); 107 108 nu_max = min (m1, p2); 109 ny_max = min (m2, p1); 110 111 if (nargin == 2) # sys = lft (sys1, sys2) 112 nu = nu_max; 113 ny = ny_max; 114 else # sys = lft (sys1, sys2, nu, ny) 115 if (! is_real_scalar (nu) || nu < 0) 116 error ("lft: argument 'nu' must be a positive integer"); 117 endif 118 119 if (! is_real_scalar (ny) || ny < 0) 120 error ("lft: argument 'ny' must be a positive integer"); 121 endif 122 123 if (nu > nu_max) 124 error ("lft: argument 'nu' (%d) must be at most %d", nu, nu_max); 125 endif 126 127 if (ny > ny_max) 128 error ("lft: argument 'ny' (%d) must be at most %d", ny, ny_max); 129 endif 130 endif 131 132 M11 = zeros (m1, p1); 133 M12 = [zeros(m1-nu, p2); eye(nu), zeros(nu, p2-nu)]; 134 M21 = [zeros(ny, p1-ny), eye(ny); zeros(m2-ny, p1)]; 135 M22 = zeros (m2, p2); 136 137 M = [M11, M12; M21, M22]; 138 139 in_idx = [1 : (m1-nu), m1 + (ny+1 : m2)]; 140 out_idx = [1 : (p1-ny), p1 + (nu+1 : p2)]; 141 142 sys = __sys_group__ (sys1, sys2); 143 sys = __sys_connect__ (sys, M); 144 sys = __sys_prune__ (sys, out_idx, in_idx); 145 146 [p, m] = size (sys); 147 148 if (m == 0) 149 warning ("lft: resulting system has no inputs"); 150 endif 151 152 if (p == 0) 153 warning ("lft: resulting system has no outputs"); 154 endif 155 156endfunction 157