]> Creatis software - CreaPhase.git/blob - octave_packages/control-2.3.52/@lti/lft.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / control-2.3.52 / @lti / lft.m
1 ## Copyright (C) 2009   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 LTI model.
27 ## @item sys2
28 ## Lower 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 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
97 function 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
156 endfunction