1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) INRIA
// Copyright (C) - 2014 - Samuel GOUGEON <sgougeon@free.fr>
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution. The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
function elts = pfss(S, rmax, cord)
//Syntax : elts = pfss(S)
//Partial fraction decomposition of the linear system S (in state-space form):
// elts is the list of linear systems which add up to S
// i.e. elts = list(S1, S2, S3, ..., Sn) with S1 + S2 +... +Sn = S
// Each Si contains some poles of S according to the block-diagonalization
// of the A matrix of S.
// If S is given in transfer form, it is first converted into state-space
// and each subsystem is then converted in transfer form.
select argn(2)
case 1 then
rmax = [];
cord = [];
case 2 then
if type(rmax) == 10 then
cord = rmax;
rmax=[];
elseif type(rmax) == 1 then
cord = [];
end
end
if and(typeof(S) <> ["rational", "state-space"]) then
error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"), "pfss", 1))
end
if typeof(S) == "rational" then
flag = varn(S("num"))
S = tf2ss(S)
else
flag = ""
end
[f, g, h, dd, dom] = S([2:5, 7]);
[n, n] = size(f);
if rmax == [] then
[f, x, bs] = bdiag(f,max(100,norm(f,1)));
else
[f, x, bs] = bdiag(f, rmax);
end
h = h*x; g = x\g;
k = 1; ll = 0;
elts = list();
for l = bs',
ind = k:k+l-1;
f1l = f(ind, ind);
gl = g(ind, :);
hl = h(:, ind);
elts(ll+1) = syslin("c", f1l, gl, hl)
ll = ll+1; k = k+l;
end;
if argn(2) == 2 then
select cord
case "c"
nb = size(bs, "*");
class = [];
for k = 1:nb
oneortwo = bs(k); ss = elts(k); A = ss(2);
if oneortwo == 1 then
class = [class, real(spec(A))];
end
if oneortwo > 1 then
class = [class, min(real(spec(A)))];
end
end;
[cl, indi] = gsort(-class);
elts1 = elts;
for k = 1:size(elts);
elts(k) = elts1(indi(k));
end
case "d"
nb = size(bs, "*");
class = [];
for k = 1:nb
oneortwo = bs(k); ss = elts(k); A = ss(2);
if oneortwo == 1 then
class = [class, abs(spec(A))];
end
if oneortwo > 1 then
class = [class, max(abs(spec(A)))];
end
end;
[cl, indi] = gsort(-class);
elts1 = elts;
for k = 1:size(elts);
elts(k) = elts1(indi(k));
end
end
end
if type(dd) == 1 then
if norm(dd, "fro") <> 0 then elts(ll+1) = dd, end
end
if type(dd) == 2 then
if norm(coeff(dd), 1) > %eps then elts(ll+1) = dd, end
end
if flag ~= "" then
k = size(elts)
for kk = 1:k
elts(kk) = varn(ss2tf(elts(kk)), flag)
end
end
endfunction
|