• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

python-control / Slycot / 5701705336

pending completion
5701705336

Pull #201

github

web-flow
Merge 7aa877a3a into 294eae04a
Pull Request #201: Add ab04md

11 of 11 new or added lines in 2 files covered. (100.0%)

36 existing lines in 1 file now uncovered.

776 of 971 relevant lines covered (79.92%)

25.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.74
/slycot/analysis.py
1
#
2
#       analysis.py
3
#
4
#       Copyright 2010 Enrico Avventi <avventi@Lonewolf>
5
#
6
#       This program is free software; you can redistribute it and/or modify
7
#       it under the terms of the GNU General Public License version 2 as
8
#       published by the Free Software Foundation.
9
#
10
#       This program 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 this program; if not, write to the Free Software
17
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
#       MA 02110-1301, USA.
19

20
import numpy as np
32✔
21

22
from . import _wrapper
32✔
23
from .exceptions import raise_if_slycot_error, SlycotParameterError
32✔
24

25

26
def ab01nd(n, m, A, B, jobz='N', tol=0, ldwork=None):
32✔
27
    """ Ac,Bc,ncont,indcon,nblk,Z,tau = ab01nd_i(n,m,A,B,[jobz,tol,ldwork])
28

29
    To find a controllable realization for the linear time-invariant
30
    multi-input system
31

32
    ::
33

34
          dX/dt = A * X + B * U,
35

36
    where A and B are N-by-N and N-by-M matrices, respectively,
37
    which are reduced by this routine to orthogonal canonical form
38
    using (and optionally accumulating) orthogonal similarity
39
    transformations.  Specifically, the pair ``(A, B)`` is reduced to
40
    the pair ``(Ac, Bc),  Ac = Z' * A * Z,  Bc = Z' * B``,  given by
41

42
    ::
43

44
          [ Acont     *    ]         [ Bcont ]
45
     Ac = [                ],   Bc = [       ],
46
          [   0    Auncont ]         [   0   ]
47

48
     and
49

50
             [ A11 A12  . . .  A1,p-1 A1p ]         [ B1 ]
51
             [ A21 A22  . . .  A2,p-1 A2p ]         [ 0  ]
52
             [  0  A32  . . .  A3,p-1 A3p ]         [ 0  ]
53
     Acont = [  .   .   . . .    .     .  ],   Bc = [ .  ],
54
             [  .   .     . .    .     .  ]         [ .  ]
55
             [  .   .       .    .     .  ]         [ .  ]
56
             [  0   0   . . .  Ap,p-1 App ]         [ 0  ]
57

58
    where the blocks ``B1, A21, ..., Ap,p-1`` have full row ranks and
59
    `p` is the controllability index of the pair.  The size of the
60
    block `Auncont` is equal to the dimension of the uncontrollable
61
    subspace of the pair ``(A, B)``.
62

63
    Parameters
64
    ----------
65
    n : int
66
        The order of the original state-space representation, i.e.
67
        the order of the matrix A.  ``n > 0``.
68
    m : int
69
        The number of system inputs, or of columns of B.  ``m > 0``.
70
    A : (n,n) array_like
71
        The original state dynamics matrix A.
72
    B : (n,m) array_like
73
        The input matrix B.
74
    jobz : {'N', 'F', 'I'}, optional
75
        Indicates whether the user wishes to accumulate in a matrix Z
76
        the orthogonal similarity transformations for reducing the system,
77
        as follows:
78

79
        := 'N':  Do not form Z and do not store the orthogonal transformations;
80
                 (default)
81
        := 'F':  Do not form Z, but store the orthogonal transformations in
82
                 the factored form;
83
        := 'I':  Z is initialized to the unit matrix and the orthogonal
84
                 transformation matrix Z is returned.
85
    tol : float, optional
86
        The tolerance to be used in rank determination when transforming
87
        ``(A, B)``. If ``tol <= 0`` a default value is used.
88
    ldwork : int, optional
89
        The length of the cache array. ``ldwork >= max(n, 3*m)``.
90
        For optimum performance it should be larger.
91
        default: ``ldwork = max(n, 3*m)``
92

93
    Returns
94
    -------
95
    Ac : (n,n) ndarray
96
        The leading ncont-by-ncont part contains the upper block
97
        Hessenberg state dynamics matrix Acont in Ac, given by Z'*A*Z,
98
        of a controllable realization for the original system. The
99
        elements below the first block-subdiagonal are set to zero.
100
    Bc : (n,m) ndarray
101
        The leading ncont-by-m part of this array contains the transformed
102
        input matrix Bcont in Bc, given by ``Z'*B``, with all elements but the
103
        first block set to zero.
104
    ncont : int
105
        The order of the controllable state-space representation.
106
    indcon : int
107
        The controllability index of the controllable part of the system
108
        representation.
109
    nblk : (n,) int ndarray
110
        The leading indcon elements of this array contain the the orders of
111
        the diagonal blocks of Acont.
112
    Z : (n,n) ndarray
113
        - If jobz = 'I', then the leading N-by-N part of this array contains
114
          the matrix of accumulated orthogonal similarity transformations
115
          which reduces the given system to orthogonal canonical form.
116
        - If jobz = 'F', the elements below the diagonal, with the array tau,
117
          represent the orthogonal transformation matrix as a product of
118
          elementary reflectors. The transformation matrix can then be
119
          obtained by calling the LAPACK Library routine DORGQR.
120
        - If jobz = 'N', the array Z is `None`.
121
    tau : (n, ) ndarray
122
        The elements of tau contain the scalar factors of the
123
        elementary reflectors used in the reduction of B and A.
124
    """
125

126
    hidden = ' (hidden by the wrapper)'
32✔
127
    arg_list = ['jobz', 'n', 'm', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden,
32✔
128
                'ncont', 'indcon', 'nblk', 'Z', 'LDZ'+hidden, 'tau', 'tol',
129
                'IWORK'+hidden, 'DWORK'+hidden, 'ldwork', 'info'+hidden]
130

131
    if ldwork is None:
32✔
132
        ldwork = max(n, 3*m)
32✔
133

134
    Ac, Bc, ncont, indcon, nblk, Z, tau, info = _wrapper.ab01nd(
32✔
135
        jobz, n, m, A, B, tol=tol, ldwork=ldwork)
136
    raise_if_slycot_error(info, arg_list)
32✔
137

138
    if jobz == "N":
32✔
139
        Z = None
32✔
140
    return Ac, Bc, ncont, indcon, nblk, Z, tau
32✔
141

142
def ab04md(type_t, n, m, p, A, B, C, D, alpha=1.0, beta=1.0, ldwork=None):
32✔
143
    """ At,Bt,Ct,Dt = ab04md(type_bn, n, m, p, A, B, C, D, [alpha, beta,ldwork])
144

145
    Parameters
146
    ----------
147
    type_t : {'D','C'}
148
            Indicates the type of the original system and the
149
            transformation to be performed as follows:
150
            = 'D':  discrete-time   -> continuous-time;
151
            = 'C':  continuous-time -> discrete-time.
152
    n : input int
153
        The order of the matrix A, the number of rows of matrix B and
154
        the number of columns of matrix C. It represents the dimension of
155
        the state vector.  n > 0.        
156
    m : input int
157
        The number of columns of matrix B. It represents the dimension of
158
        the input vector.  m > 0.
159
    p : input int
160
        The number of rows of matrix C. It represents the dimension of
161
        the output vector.  p > 0.
162
    A : input rank-2 array('d') with bounds (n,n)
163
        The leading n-by-n part of this array must contain the system state
164
        matrix A.
165
    B : input rank-2 array('d') with bounds (n,m)
166
        The leading n-by-m part of this array must contain the system input
167
        matrix B.
168
    C : input rank-2 array('d') with bounds (p,n)
169
        The leading p-by-n part of this array must contain the system output
170
        matrix C.
171
    D : input rank-2 array('d') with bounds (p,m)
172
        The leading p-by-m part of this array must contain the system direct
173
        transmission matrix D.
174
    alpha : double
175
        Parameter specifying the bilinear transformation.
176
        Recommended values for stable systems: alpha = 1, alpha != 0,
177
    beta : double
178
        Parameter specifying the bilinear transformation.
179
        Recommended values for stable systems: beta = 1, beta != 0,
180
    ldwork : int
181
        The length of the cache array.
182
        ldwork >= max(1, n)
183
    Returns
184
    -------
185
    At : output rank-2 array('d') with bounds (n,n)
186
        The state matrix At of the transformed system.
187
    Bt : output rank-2 array('d') with bounds (n,m)
188
        The input matrix Bt of the transformed system.
189
    Ct : output rank-2 array('d') with bounds (p,n)
190
        The output matrix Ct of the transformed system.
191
    Dt : output rank-2 array('d') with bounds (p,m)
192
        The transmission matrix Dt of the transformed system.
193
    Raises
194
    ------
195
    SlycotArithmeticError
196
        :info == 1: 
197
            If the matrix (ALPHA*I + A) is exactly singular
198
        :info == 2: 
199
            If the matrix  (BETA*I - A) is exactly singular.
200
    """
201

202
    hidden = ' (hidden by the wrapper)'  
32✔
203
    arg_list = ['type_t', 'n', 'm', 'p', 'alpha', 'beta', 
32✔
204
                'A', 'LDA'+hidden, 'B', 'LDB'+hidden, 'C', 'LDC'+hidden, 'D', 'LDD'+hidden,
205
                'IWORK'+hidden, 'DWORK'+hidden, 'ldwork', 'info'+hidden]
206

207
    if ldwork is None:
32✔
208
        ldwork = max(1, n)
32✔
209

210
    out = _wrapper.ab04md(type_t, n, m, p, alpha, beta, A, B, C, D, ldwork=ldwork)
32✔
211
    info=out[-1]
32✔
212
    raise_if_slycot_error(info, arg_list)
32✔
213

214
    return out[:-1]
32✔
215

216
def ab05md(n1,m1,p1,n2,p2,A1,B1,C1,D1,A2,B2,C2,D2,uplo='U'):
32✔
217
    """ n,a,b,c,d = ab05md(n1,m1,p1,n2,p2,a1,b1,c1,d1,a2,b2,c2,d2,[uplo])
218

219
    To obtain the state-space model (A,B,C,D) for the cascaded
220
    inter-connection of two systems, each given in state-space form.
221

222
    Required arguments:
223
        n1 : input int
224
            The number of state variables in the first system, i.e. the order
225
            of the matrix A1.  n1 > 0.
226
        m1 : input int
227
            The number of input variables for the first system. m1 > 0.
228
        p1 : input int
229
            The number of output variables from the first system and the number
230
            of input variables for the second system. p1 > 0.
231
        n2 : input int
232
            The number of state variables in the second system, i.e. the order
233
            of the matrix A2.  n2 > 0.
234
        p2 : input int
235
            The number of output variables from the second system. p2 > 0.
236
        A1 : input rank-2 array('d') with bounds (n1,n1)
237
            The leading n1-by-n1 part of this array must contain the state
238
            transition matrix A1 for the first system.
239
        B1 : input rank-2 array('d') with bounds (n1,m1)
240
            The leading n1-by-m1 part of this array must contain the input/state
241
            matrix B1 for the first system.
242
        C1 : input rank-2 array('d') with bounds (p1,n1)
243
            The leading p1-by-n1 part of this array must contain the state/output
244
            matrix C1 for the first system.
245
        D1 : input rank-2 array('d') with bounds (p1,m1)
246
            The leading p1-by-m1 part of this array must contain the input/output
247
            matrix D1 for the first system.
248
        A2 : input rank-2 array('d') with bounds (n2,n2)
249
            The leading n2-by-n2 part of this array must contain the state
250
            transition matrix A2 for the second system.
251
        B2 : input rank-2 array('d') with bounds (n2,p1)
252
            The leading n2-by-p1 part of this array must contain the input/state
253
            matrix B2 for the second system.
254
        C2 : input rank-2 array('d') with bounds (p2,n2)
255
            The leading p2-by-n2 part of this array must contain the state/output
256
            matrix C2 for the second system.
257
        D2 : input rank-2 array('d') with bounds (p2,p1)
258
            The leading p2-by-p1 part of this array must contain the input/output
259
            matrix D2 for the second system.
260
    Optional arguments:
261
        uplo := 'U' input string(len=1)
262
            Indicates whether the user wishes to obtain the matrix A in
263
            the upper or lower block diagonal form, as follows:
264
                = 'U':  Obtain A in the upper block diagonal form;
265
                = 'L':  Obtain A in the lower block diagonal form.
266
    Return objects:
267
        n : int
268
            The number of state variables (n1 + n2) in the resulting system,
269
            i.e. the order of the matrix A, the number of rows of B and
270
            the number of columns of C.
271
        A : rank-2 array('d') with bounds (n1+n2,n1+n2)
272
            The leading N-by-N part of this array contains the state transition
273
            matrix A for the cascaded system.
274
        B : rank-2 array('d') with bounds (n1+n2,m1)
275
            The leading n-by-m1 part of this array contains the input/state
276
            matrix B for the cascaded system.
277
        C : rank-2 array('d') with bounds (p2,n1+n2)
278
            The leading p2-by-n part of this array contains the state/output
279
            matrix C for the cascaded system.
280
        D : rank-2 array('d') with bounds (p2,m1)
281
            The leading p2-by-m1 part of this array contains the input/output
282
            matrix D for the cascaded system.
283

284
    Notes:
285
        The implemented methods rely on accuracy enhancing square-root or
286
        balancing-free square-root techniques.
287
        The algorithms require less than 30N^3  floating point operations.
288
    """
UNCOV
289
    hidden = ' (hidden by the wrapper)'
×
UNCOV
290
    arg_list = ['uplo', 'OVER'+hidden, 'n1', 'm1', 'p1', 'n2', 'p2', 'A1',
×
291
        'LDA1'+hidden, 'B1', 'LDB1'+hidden, 'C1', 'LDC1'+hidden, 'D1',
292
        'LDD1'+hidden, 'A2', 'LDA2'+hidden, 'B2', 'LDB2'+hidden, 'C2',
293
        'LDC2'+hidden, 'D2', 'LDD2'+hidden, 'n', 'A', 'LDA'+hidden, 'B',
294
        'LDB'+hidden, 'C', 'LDC'+hidden, 'D', 'LDD'+hidden, 'DWORK'+hidden,
295
        'ldwork', 'info'+hidden ]
UNCOV
296
    out = _wrapper.ab05md(n1,m1,p1,n2,p2,A1,B1,C1,D1,A2,B2,C2,D2,uplo=uplo)
×
UNCOV
297
    raise_if_slycot_error(out[-1], arg_list)
×
298
    return out[:-1]
×
299

300
def ab05nd(n1,m1,p1,n2,A1,B1,C1,D1,A2,B2,C2,D2,alpha=1.0,ldwork=None):
32✔
301
    """  n,A,B,C,D = ab05nd(n1,m1,p1,n2,A1,B1,C1,D1,A2,B2,C2,D2,[alpha,ldwork])
302

303
    To obtain the state-space model (A,B,C,D) for the feedback inter-connection
304
    of two systems, each given in state-space form.
305

306
    Required arguments:
307
        n1 : input int
308
            The number of state variables in the first system, i.e. the order
309
            of the matrix A1.  n1 > 0.
310
        m1 : input int
311
            The number of input variables for the first system and the number
312
            of output variables from the second system. m1 > 0.
313
        p1 : input int
314
            The number of output variables from the first system and the number
315
            of input variables for the second system. p1 > 0.
316
        n2 : input int
317
            The number of state variables in the second system, i.e. the order
318
            of the matrix A2.  n2 > 0.
319
        A1 : input rank-2 array('d') with bounds (n1,n1)
320
            The leading n1-by-n1 part of this array must contain the state
321
            transition matrix A1 for the first system.
322
        B1 : input rank-2 array('d') with bounds (n1,m1)
323
            The leading n1-by-m1 part of this array must contain the input/state
324
            matrix B1 for the first system.
325
        C1 : input rank-2 array('d') with bounds (p1,n1)
326
            The leading p1-by-n1 part of this array must contain the state/output
327
            matrix C1 for the first system.
328
        D1 : input rank-2 array('d') with bounds (p1,m1)
329
            The leading p1-by-m1 part of this array must contain the input/output
330
            matrix D1 for the first system.
331
        A2 : input rank-2 array('d') with bounds (n2,n2)
332
            The leading n2-by-n2 part of this array must contain the state
333
            transition matrix A2 for the second system.
334
        B2 : input rank-2 array('d') with bounds (n2,p1)
335
            The leading n2-by-p1 part of this array must contain the input/state
336
            matrix B2 for the second system.
337
        C2 : input rank-2 array('d') with bounds (m1,n2)
338
            The leading m1-by-n2 part of this array must contain the state/output
339
            matrix C2 for the second system.
340
        D2 : input rank-2 array('d') with bounds (m1,p1)
341
            The leading m1-by-p1 part of this array must contain the input/output
342
            matrix D2 for the second system.
343
    Optional arguments:
344
        alpha := 1.0 input float
345
            A coefficient multiplying the transfer-function matrix (or the
346
            output equation) of the second system. i.e alpha = +1 corresponds
347
            to positive feedback, and alpha = -1 corresponds to negative
348
            feedback.
349
        ldwork := max(p1*p1,m1*m1,n1*p1) input int
350
            The length of the cache array. ldwork >= max(p1*p1,m1*m1,n1*p1).
351
    Return objects:
352
        n : int
353
            The number of state variables (n1 + n2) in the connected system, i.e.
354
            the order of the matrix A, the number of rows of B and the number of
355
            columns of C.
356
        A : rank-2 array('d') with bounds (n1+n2,n1+n2)
357
            The leading n-by-n part of this array contains the state transition
358
            matrix A for the connected system.
359
        B : rank-2 array('d') with bounds (n1+n2,m1)
360
            The leading n-by-m1 part of this array contains the input/state
361
            matrix B for the connected system.
362
        C : rank-3 array('d') with bounds (p1,n1,n2)
363
            The leading p1-by-n part of this array contains the state/output
364
            matrix C for the connected system.
365
        D : rank-2 array('d') with bounds (p1,m1)
366
            The leading p1-by-m1 part of this array contains the input/output
367
            matrix D for the connected system.
368

369
    Raises
370
    ------
371
    SlycotArithmeticError
372
        :1 <= info <= p1:
373
            the system is not completely controllable. That is, the matrix
374
            ``(I + ALPHA*D1*D2)`` is exactly singular (the element
375
            ``U(i,i)```` of the upper triangular factor of ``LU```
376
            factorization is exactly zero), possibly due to
377
            rounding errors.
378
    """
UNCOV
379
    hidden = ' (hidden by the wrapper)'
×
UNCOV
380
    arg_list = ['over'+hidden, 'n1', 'm1', 'p1', 'n2', 'alpha', 'A1', 'LDA1'+hidden,
×
381
        'B1', 'LDB1'+hidden, 'C1', 'LDC1'+hidden, 'D1', 'LDD1'+hidden, 'A2',
382
        'LDA2'+hidden, 'B2', 'LDB2'+hidden, 'C2', 'LDC2'+hidden, 'D2',
383
        'LDD2'+hidden, 'n', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden, 'C',
384
        'LDC'+hidden, 'D', 'LDD'+hidden, 'IWORK'+hidden, 'DWORK'+hidden,
385
        'ldwork', 'info'+hidden]
UNCOV
386
    if ldwork is None:
×
UNCOV
387
        ldwork = max(p1*p1,m1*m1,n1*p1)
×
388
    out = _wrapper.ab05nd(n1,m1,p1,n2,alpha,A1,B1,C1,D1,A2,B2,C2,D2,ldwork=ldwork)
×
389
    raise_if_slycot_error(out[-1], arg_list, ab05nd, locals())
×
390
    return out[:-1]
×
391

392
def ab07nd(n,m,A,B,C,D,ldwork=None):
32✔
393
    """ A_i,B_i,C_i,D_i,rcond = ab07nd(n,m,A,B,C,D,[ldwork])
394

395
    To compute the inverse (A_i,B_i,C_i,D_i) of a given system (A,B,C,D).
396

397
    Required arguments:
398
        n : input int
399
            The order of the state matrix A.  n >= 0.
400
        m : input int
401
            The number of system inputs and outputs.  m >= 0.
402
        A : input rank-2 array('d') with bounds (n,n)
403
            The leading n-by-n part of this array must contain the state matrix
404
            A of the original system.
405
        B : input rank-2 array('d') with bounds (n,m)
406
            The leading n-by-m part of this array must contain the input matrix
407
            B of the original system.
408
        C : input rank-2 array('d') with bounds (m,n)
409
            The leading m-by-n part of this array must contain the output matrix
410
            C of the original system.
411
        D : input rank-2 array('d') with bounds (m,m)
412
            The leading m-by-m part of this array must contain the feedthrough
413
            matrix D of the original system.
414
    Optional arguments:
415
        ldwork := None input int
416
            The length of the cache array. The default value is max(1,4*m),
417
            for better performance should be larger.
418
    Return objects:
419
        A_i : rank-2 array('d') with bounds (n,n)
420
            The leading n-by-n part of this array contains the state matrix A_i
421
            of the inverse system.
422
        B_i : rank-2 array('d') with bounds (n,m)
423
            The leading n-by-m part of this array contains the input matrix B_i
424
            of the inverse system.
425
        C_i : rank-2 array('d') with bounds (m,n)
426
            The leading m-by-n part of this array contains the output matrix C_i
427
            of the inverse system.
428
        D_i : rank-2 array('d') with bounds (m,m)
429
            The leading m-by-m part of this array contains the feedthrough
430
            matrix D_i of the inverse system.
431
        rcond : float
432
            The estimated reciprocal condition number of the feedthrough matrix
433
            D of the original system.
434

435
    Warns
436
    -----
437
    SlycotResultWarning
438
        :1 <= info <= m:
439
            the matrix `D` is exactly singular; the ({info},{info})
440
            diagonal element is zero, `RCOND` was set to zero;
441
        :info == m+1:
442
            the matrix `D` is numerically singular, i.e., `RCOND`
443
            is less than the relative machine precision, `EPS`
444
            (see LAPACK Library routine DLAMCH). The
445
            calculations have been completed, but the results
446
            could be very inaccurate.
447
    """
UNCOV
448
    hidden = ' (hidden by the wrapper)'
×
UNCOV
449
    arg_list = ['n', 'm', 'A', 'LDA' + hidden, 'B', 'LDB' + hidden,
×
450
                'C', 'LDC' + hidden, 'D', 'LDD' + hidden, 'rcond',
451
                'IWORK' + hidden, 'DWORK' + hidden, 'ldwork', 'INFO' + hidden]
UNCOV
452
    if ldwork is None:
×
UNCOV
453
        ldwork = max(1, 4*m)
×
454
    out = _wrapper.ab07nd(n, m, A, B, C, D, ldwork=ldwork)
×
455
    raise_if_slycot_error(out[-1], arg_list, ab07nd.__doc__, locals())
×
456
    return out[:-1]
×
457

458

459
def ab08nd(n,m,p,A,B,C,D,equil='N',tol=0,ldwork=None):
32✔
460
    """ nu,rank,dinfz,nkror,nkrol,infz,kronr,kronl,Af,Bf = ab08nd(n,m,p,A,B,C,D,[equil,tol,ldwork])
461

462
    To construct for a linear multivariable system described by a state-space
463
    model (A,B,C,D) a regular pencil (Af - lambda*Bf ) which has the invariant
464
    zeros of the system as generalized eigenvalues.
465
    The routine also computes the orders of the infinite zeros and the
466
    right and left Kronecker indices of the system (A,B,C,D).
467

468
    Required arguments:
469
        n : input int
470
            The number of state variables.  n >= 0.
471
        m : input int
472
            The number of system inputs.  m >= 0.
473
        p : input int
474
            The number of system outputs.  p >= 0.
475
        A : input rank-2 array('d') with bounds (n,n)
476
            The leading n-by-n part of this array must contain the state
477
            dynamics matrix A of the system.
478
        B : input rank-2 array('d') with bounds (n,m)
479
            The leading n-by-m part of this array must contain the input/state
480
            matrix B of the system.
481
        C : input rank-2 array('d') with bounds (p,n)
482
            The leading p-by-n part of this array must contain the state/output
483
            matrix C of the system.
484
        D : input rank-2 array('d') with bounds (p,m)
485
            The leading p-by-m part of this array must contain the direct
486
            transmission matrix D of the system.
487
    Optional arguments:
488
        equil := 'N' input string(len=1)
489
            Specifies whether the user wishes to balance the compound matrix
490
            as follows:
491
            = 'S':  Perform balancing (scaling);
492
            = 'N':  Do not perform balancing.
493
        tol := 0.0 input float
494
            A tolerance used in rank decisions to determine the effective rank,
495
            which is defined as the order of the largest leading (or trailing)
496
            triangular submatrix in the QR (or RQ) factorization with column
497
            (or row) pivoting whose estimated condition number is less than 1/tol.
498
        ldwork := None input int
499
            The length of the cache array. The default value is n + 3*max(m,p),
500
            for better performance should be larger.
501
    Return objects:
502
        nu : int
503
            The number of (finite) invariant zeros.
504
        rank : int
505
            The normal rank of the transfer function matrix.
506
        dinfz : int
507
            The maximum degree of infinite elementary divisors.
508
        nkror : int
509
            The number of right Kronecker indices.
510
        nkrol : int
511
            The number of left Kronecker indices.
512
        infz : rank-1 array('i') with bounds (n)
513
            The leading dinfz elements of infz contain information on the
514
            infinite elementary divisors as follows: the system has infz(i)
515
            infinite elementary divisors of degree i, where i = 1,2,...,dinfz.
516
        kronr : rank-1 array('i') with bounds (max(n,m)+1)
517
            the leading nkror elements of this array contain the right kronecker
518
            (column) indices.
519
        kronl : rank-1 array('i') with bounds (max(n,p)+1)
520
            the leading nkrol elements of this array contain the left kronecker
521
            (row) indices.
522
        Af : rank-2 array('d') with bounds (max(1,n+m),n+min(p,m))
523
            the leading nu-by-nu part of this array contains the coefficient
524
            matrix Af of the reduced pencil. the remainder of the leading
525
            (n+m)-by-(n+min(p,m)) part is used as internal workspace.
526
        Bf : rank-2 array('d') with bounds (max(1,n+p),n+m)
527
            The leading nu-by-nu part of this array contains the coefficient
528
            matrix Bf of the reduced pencil. the remainder of the leading
529
            (n+p)-by-(n+m) part is used as internal workspace.
530
    """
531
    hidden = ' (hidden by the wrapper)'
32✔
532
    arg_list = ['equil', 'n', 'm', 'p', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden,
32✔
533
        'C', 'LDC'+hidden, 'D', 'LDD'+hidden, 'nu', 'rank', 'dinfz', 'nkror',
534
        'nkrol', 'infz', 'kronr', 'kronl', 'Af', 'LDAF'+hidden, 'Bf',
535
        'LDBF'+hidden, 'tol', 'IWORK'+hidden, 'DWORK'+hidden, 'ldwork',
536
        'INFO'+hidden]
537
    if ldwork is None:
32✔
538
        ldwork = n+3*max(m,p) #only an upper bound
32✔
539
    out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
32✔
540
    raise_if_slycot_error(out[-1], arg_list)
32✔
541
    return out[:-1]
32✔
542

543
def ab08nz(n, m, p, A, B, C, D, equil='N', tol=0., lzwork=None):
32✔
544
    """ nu,rank,dinfz,nkror,nkrol,infz,kronr,kronl,Af,Bf = ab08nz(n,m,p,A,B,C,D,[equil,tol,lzwork])
545

546
    To construct for a linear multivariable system described by a state-space
547
    model (A,B,C,D) a regular pencil (Af - lambda*Bf ) which has the invariant
548
    zeros of the system as generalized eigenvalues.
549
    The routine also computes the orders of the infinite zeros and the
550
    right and left Kronecker indices of the system (A,B,C,D).
551

552
    Required arguments:
553
        n : input int
554
            The number of state variables.  n >= 0.
555
        m : input int
556
            The number of system inputs.  m >= 0.
557
        p : input int
558
            The number of system outputs.  p >= 0.
559
        A : input rank-2 array('d') with bounds (n,n)
560
            The leading n-by-n part of this array must contain the state
561
            dynamics matrix A of the system.
562
        B : input rank-2 array('d') with bounds (n,m)
563
            The leading n-by-m part of this array must contain the input/state
564
            matrix B of the system.
565
        C : input rank-2 array('d') with bounds (p,n)
566
            The leading p-by-n part of this array must contain the state/output
567
            matrix C of the system.
568
        D : input rank-2 array('d') with bounds (p,m)
569
            The leading p-by-m part of this array must contain the direct
570
            transmission matrix D of the system.
571
    Optional arguments:
572
        equil := 'N' input string(len=1)
573
            Specifies whether the user wishes to balance the compound matrix
574
            as follows:
575
            = 'S':  Perform balancing (scaling);
576
            = 'N':  Do not perform balancing.
577
        tol := 0.0 input float
578
            A tolerance used in rank decisions to determine the effective rank,
579
            which is defined as the order of the largest leading (or trailing)
580
            triangular submatrix in the QR (or RQ) factorization with column
581
            (or row) pivoting whose estimated condition number is less than 1/tol.
582
            If tol is set to less than SQRT((N+P)*(N+M))*EPS
583
            then the tolerance is taken as SQRT((N+P)*(N+M))*EPS,
584
            where EPS is the machine precision (see LAPACK Library
585
            Routine DLAMCH).
586
        lzwork := None input int
587
            The length of the internal cache array ZWORK. The default value is
588
            calculated to
589
               MAX( 1,
590
                    MIN(P,M) + MAX(3*M-1,N),
591
                    MIN(P,N) + MAX(3*P-1,N+P,N+M),
592
                    MIN(M,N) + MAX(3*M-1,N+M) )
593
            For optimum performance lzwork should be larger.
594
            If lzwork = -1, then a workspace query is assumed;
595
            the routine only calculates the optimal size of the
596
            ZWORK array, and returns this value in lzwork_opt
597
    Return objects:
598
        nu : int
599
            The number of (finite) invariant zeros.
600
        rank : int
601
            The normal rank of the transfer function matrix.
602
        dinfz : int
603
            The maximum degree of infinite elementary divisors.
604
        nkror : int
605
            The number of right Kronecker indices.
606
        nkrol : int
607
            The number of left Kronecker indices.
608
        infz : rank-1 array('i') with bounds (n)
609
            The leading dinfz elements of infz contain information on the
610
            infinite elementary divisors as follows: the system has infz(i)
611
            infinite elementary divisors of degree i, where i = 1,2,...,dinfz.
612
        kronr : rank-1 array('i') with bounds (max(n,m)+1)
613
            the leading nkror elements of this array contain the right kronecker
614
            (column) indices.
615
        kronl : rank-1 array('i') with bounds (max(n,p)+1)
616
            the leading nkrol elements of this array contain the left kronecker
617
            (row) indices.
618
        Af : rank-2 array('d') with bounds (max(1,n+m),n+min(p,m))
619
            the leading nu-by-nu part of this array contains the coefficient
620
            matrix Af of the reduced pencil. the remainder of the leading
621
            (n+m)-by-(n+min(p,m)) part is used as internal workspace.
622
        Bf : rank-2 array('d') with bounds (max(1,n+p),n+m)
623
            The leading nu-by-nu part of this array contains the coefficient
624
            matrix Bf of the reduced pencil. the remainder of the leading
625
            (n+p)-by-(n+m) part is used as internal workspace.
626
        lzwork_opt : int
627
            The optimal value of lzwork.
628
    """
629
    hidden = ' (hidden by the wrapper)'
32✔
630
    arg_list = ['equil', 'n', 'm', 'p',
32✔
631
                'a', 'lda' + hidden, 'b', 'ldb' + hidden,
632
                'c', 'ldc' + hidden, 'd', 'ldd' + hidden,
633
                'nu', 'rank', 'dinfz', 'nkror', 'nkrol', 'infz', 'kronr',
634
                'kronl', 'af', 'ldaf' + hidden, 'bf', 'ldbf' + hidden,
635
                'tol', 'iwork' + hidden, 'dwork' + hidden, 'zwork',
636
                'lzwork', 'info']
637
    if lzwork is None:
32✔
638
        lzwork = max(min(p, m) + max(3*m-1, n),
32✔
639
                     min(p, n) + max(3*p-1, n+p, n+m),
640
                     min(m, n) + max(3*m-1, n+m))
641

642
    nu, rank, dinfz, nkror, nkrol, infz, kronr, kronl, Af, Bf, zwork, info \
32✔
643
        = _wrapper.ab08nz(n, m, p, A, B, C, D,
644
                          equil=equil, tol=tol, lzwork=lzwork)
645

646
    raise_if_slycot_error(info, arg_list)
32✔
647
    return (nu, rank, dinfz, nkror, nkrol, infz, kronr, kronl, Af, Bf,
32✔
648
            int(zwork[0].real))
649

650

651
def ab09ad(dico,job,equil,n,m,p,A,B,C,nr=None,tol=0,ldwork=None):
32✔
652
    """ nr,Ar,Br,Cr,hsv = ab09ad(dico,job,equil,n,m,p,A,B,C,[nr,tol,ldwork])
653

654
    Compute reduced order State-Space-Model (Ar, Br, Cr) for a stable system
655
    (A, B, C) by using either the square-root or the balancing-free square-
656
    root Balance & truncate (B & T) model reduction method.
657

658
    Required arguments:
659
        dico : {'D', 'C'} input string(len=1)
660
            Indicate whether the system is discrete `D` or continuous `C`
661
        job : {'B', 'N'} input string(len=1)
662
            Balance `B` or not `N`
663
        equil : {'S', 'N'} input string(len=1)
664
            Scale `S` or not `N`
665
        n : input int
666
            The number of state variables.  n >= 0.
667
        m : input int
668
            The number of system inputs.  m >= 0.
669
        p : input int
670
            The number of system outputs.  p >= 0.
671
        A : input rank-2 array('d') with bounds (n,n)
672
            The leading n-by-n part of this array must contain the state
673
            dynamics matrix A of the system.
674
        B : input rank-2 array('d') with bounds (n,m)
675
            The leading n-by-m part of this array must contain the input/state
676
            matrix B of the system.
677
        C : input rank-2 array('d') with bounds (p,n)
678
            The leading p-by-n part of this array must contain the
679
            state/output matrix C of the system.
680

681
    Optional arguments:
682
        nr := None input int
683
            `nr` is the desired order of the resulting reduced order
684
            system.  ``0 <= nr <= n``. Automatically determined by `tol` if
685
            ``nr is None`` and returned. See return object `nr`.
686
        tol := 0 input double precision
687
            If ``nr is None``, `tol`contains the tolerance for determining the
688
            order of the reduced system. For model reduction, th recommended
689
            value is ``tol = c * HNORM(A, B, C)``, where `c` is a constan in the
690
            interval ``[0.00001, 0.001]`` and ``HNORM(A, B, C)`` is the
691
            Hankel-Norm of the given sysstem (computed in ``HSV(1)``). For
692
            computing a minimal realization, the recommended value is
693
            ``tol = n * eps * HNORM(A, B, C)``, where `eps` is the machine
694
            precision (see LAPACK Library Routine `DLAMCH`). This value is
695
            used by default if ``tol <= 0`` on entry. If `nr` is specified,
696
            the value of `tol` is ignored.
697
        ldwork := None input int
698
            The length of the cache array. The default value is
699
            ``n*(2*n+max(n,m,p)+5) + n*(n+1)/2 ~= 3.5*n**2 + 5*n``,
700
            a larger value should lead to better performance.
701

702
    Return objects :
703
        nr : output int
704
            `nr` is the order of the resulting reduced order model.
705
            `nr` is set as follows:
706
            If on input ``nr is not None``, `nr` is equal to ``MIN(nr,NMIN)``,
707
            where `nr` is the desired order on entry and `NMIN` is the order
708
            of a minimal realization of the given system; `NMIN` is
709
            determined as the number of Hankel singular values greater
710
            than ``n*eps*HNORM(A,B,C)``, where `eps` is the machine
711
            precision (see LAPACK Library Routine DLAMCH) and
712
            ``HNORM(A,B,C)`` is the Hankel norm of the system (computed
713
            in ``HSV(1)``);
714
            If on input ``nr is None``, `nr` is equal to the number of Hankel
715
            singular values greater than ``MAX(tol,n*eps*HNORM(A,B,C))``.
716
        Ar : rank-2 array('d') with bounds ``(nr,nr)``
717
            This array contains the state dynamics matrix `Ar` of the reduced
718
            order system.
719
        Br : rank-2 array('d') with bounds ``(nr,m)``
720
            Tthis array contains the input/state matrix `Br` of the reduced
721
            order system.
722
        Cr : rank-2 array('d') with bounds ``(p,nr)``
723
            This array contains the state/output matrix `Cr` of the reduced
724
            order system.
725
        hsv : output double precision array, dimension ``(n)``
726
            If ``INFO = 0``, it contains the Hankel singular values of
727
            the original system ordered decreasingly. ``HSV(1)`` is the
728
            Hankel norm of the system.
729

730
    Raises
731
    ------
732
    SlycotArithmeticError
733
        :info == 1:
734
            The reduction of A to the real Schur form failed
735
        :info == 2 and dico == 'C':
736
            The state matrix A is not stable
737
        :info == 2 and dico == 'D':
738
            The state matrix A is not convergent
739
        :info == 3:
740
            The computation of Hankel singular values failed
741

742
    Warns
743
    -----
744
    SlycotResultWarning
745
        :iwarn == 1:
746
                The selected order {nr} is greater
747
                than the order of a minimal realization of the
748
                given system. `nr` was set automatically to {Nr}
749
                corresponding to the order of a minimal realization
750
                of the system
751
    """
752
    hidden = ' (hidden by the wrapper)'
32✔
753
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr',
32✔
754
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
755
                'hsv', 'tol', 'iwork' + hidden, 'dwork ' + hidden, 'ldwork',
756
                'iwarn', 'info']
757
    if ldwork is None:
32✔
758
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
32✔
759
    if nr is None:
32✔
UNCOV
760
        ordsel = 'A'
×
UNCOV
761
        nr = 0  # order will be computed by the routine
×
762
    else:
763
        ordsel = 'F'
32✔
764
    out = _wrapper.ab09ad(dico, job, equil, ordsel,
32✔
765
                          n, m, p, nr, A, B, C, tol, ldwork)
766
    Nr, A, B, C, hsv = out[:-2]
32✔
767
    raise_if_slycot_error(out[-2:], arg_list, ab09ad.__doc__, locals())
32✔
768
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], hsv
32✔
769

770

771
def ab09ax(dico,job,n,m,p,A,B,C,nr=None,tol=0.0,ldwork=None):
32✔
772
    """``nr,Ar,Br,Cr,hsv,T,Ti = ab09ad(dico,job,equil,n,m,p,nr,A,B,C,[nr,tol,ldwork])``
773

774
    To compute a reduced order model ``(Ar,Br,Cr)`` for a stable original
775
    state-space representation ``(A,B,C)`` by using either the square-root
776
    or the balancing-free square-root Balance & Truncate model
777
    reduction method. The state dynamics matrix `A` of the original
778
    system is an upper quasi-triangular matrix in *real Schur canonical
779
    form.* The matrices of the reduced order system are computed using
780
    the truncation formulas:
781

782
        ``Ar = TI * A * T ,  Br = TI * B ,  Cr = C * T`` .
783

784
    Required arguments :
785
        dico : {'D', 'C'} input string(len=1)
786
            Indicate whether the system is discrete `D` or continuous `C`
787
        job : {'B', 'N'} input string(len=1)
788
            Balance `B` or not `N`
789
        n : input int
790
            The number of state variables.  n >= 0.
791
        m : input int
792
            The number of system inputs.  m >= 0.
793
        p : input int
794
            The number of system outputs.  p >= 0.
795
        A : input rank-2 array('d') with bounds (n,n)
796
            The leading n-by-n part of this array must contain the state
797
            dynamics matrix A of the system *in real Schur form.*
798
        B : input rank-2 array('d') with bounds (n,m)
799
            The leading n-by-m part of this array must contain the input/state
800
            matrix B of the system.
801
        C : input rank-2 array('d') with bounds (p,n)
802
            The leading p-by-n part of this array must contain the
803
            state/output matrix C of the system.
804

805
    Optional arguments:
806
        nr := None input int
807
            `nr` is the desired order of the resulting reduced order
808
            system.  ``0 <= nr <= n``. Automatically determined by `tol` if
809
            ``nr is None`` and returned. See return object `nr`.
810
        tol := 0 input double precision
811
            If ``nr is None``, `tol`contains the tolerance for determining the
812
            order of the reduced system. For model reduction, the recommended
813
            value is ``tol = c * HNORM(A, B, C)``, where `c` is a constant in
814
            the interval ``[0.00001, 0.001]`` and ``HNORM(A, B, C)`` is
815
            the Hankel-Norm of the given sysstem (computed in ``HSV(1)``). For
816
            computing a minimal realization, the recommended value is
817
            ``tol = n * eps * HNORM(A, B, C)``, where `eps` is the machine
818
            precision (see LAPACK Library Routine `DLAMCH`). This value is
819
            used by default if ``tol <= 0`` on entry. If `nr` is specified,
820
            the value of `tol` is ignored.
821
        ldwork := None input int
822
            The length of the cache array. The default value is
823
            ``n*(2*n+max(n,m,p)+5) + n*(n+1)/2 ~= 3.5*n**2 + 5*n``,
824
            a larger value should lead to better performance.
825

826
    Return objects :
827
        nr : output int
828
            `nr` is the order of the resulting reduced order model.
829
            `nr` is set as follows:
830
            If on input ``nr is not None``, `nr` is equal to ``MIN(nr,NMIN)``,
831
            where `nr` is the desired order on entry and `NMIN` is the order
832
            of a minimal realization of the given system; `NMIN` is
833
            determined as the number of Hankel singular values greater
834
            than ``n*eps*HNORM(A,B,C)``, where `eps` is the machine
835
            precision (see LAPACK Library Routine DLAMCH) and
836
            ``HNORM(A,B,C)`` is the Hankel norm of the system (computed
837
            in ``HSV(1)``);
838
            If on input ``nr is None``, `nr` is equal to the number of Hankel
839
            singular values greater than ``MAX(tol,n*eps*HNORM(A,B,C))``.
840
        Ar : rank-2 array('d') with bounds ``(nr,nr)``
841
            This array contains the state dynamics matrix `Ar` of the reduced
842
            order system.
843
        Br : rank-2 array('d') with bounds ``(nr,m)``
844
            Tthis array contains the input/state matrix `Br` of the reduced
845
            order system.
846
        Cr : rank-2 array('d') with bounds ``(p,nr)``
847
            This array contains the state/output matrix `Cr` of the reduced
848
            order system.
849
        hsv : output double precision array, dimension ``(n)``
850
            If ``INFO = 0``, it contains the Hankel singular values of
851
            the original system ordered decreasingly. ``HSV(1)`` is the
852
            Hankel norm of the system.
853
        T : rank-2 array('d') with bounds ``(n,nr)``
854
            This array contains the right truncation matrix `T` of the reduced
855
            order system.
856
        Ti : rank-2 array('d') with bounds ``(nr,n)``
857
            This array contains the left truncation matrix `Ti` of the reduced
858
            order system.
859

860
    Raises
861
    ------
862
    SlycotArithmeticError
863
        :info == 1 and dico == 'C':
864
            The state matrix A is not stable
865
        :info == 1 and dico == 'D':
866
            The state matrix A is not convergent
867
        :info == 2:
868
            The computation of Hankel singular values failed
869

870
    Warns
871
    -----
872
    SlycotResultWarning
873
        :iwarn == 1:
874
                The selected order {nr} is greater
875
                than the order of a minimal realization of the
876
                given system. `nr` was set automatically to {Nr}
877
                corresponding to the order of a minimal realization
878
                of the system
879
    """
UNCOV
880
    hidden = ' (hidden by the wrapper)'
×
UNCOV
881
    arg_list = ['dico', 'job', 'ordsel', 'n', 'm', 'p', 'nr',
×
882
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
883
                'hsv', 'T', 'ldt' + hidden, 'Ti', 'ldti' + hidden, 'tol',
884
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
885
    if ldwork is None:
×
UNCOV
886
        ldwork = max(1, n*(2*n + max(n, max(m, p))+5)+n*(n+1)/2)
×
887
    if nr is None:
×
888
        ordsel = 'A'
×
889
        nr = 0  # order will be computed by the routine
×
890
    else:
891
        ordsel = 'F'
×
UNCOV
892
    out = _wrapper.ab09ax(dico, job, ordsel, n, m, p, nr, A, B, C, tol, ldwork)
×
893
    Nr, A, B, C, hsv, T, Ti = out[:-2]
×
894
    raise_if_slycot_error(out[-2:], arg_list, ab09ax.__doc__, locals())
×
895
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], hsv, T[:, :Nr], Ti[:Nr, :]
×
896

897
def ab09bd(dico,job,equil,n,m,p,A,B,C,D,nr=None,tol1=0,tol2=0,ldwork=None):
32✔
898
    """ nr,Ar,Br,Cr,Dr,hsv = ab09bd(dico,job,equil,n,m,p,A,B,C,D,[nr,tol1,tol2,ldwork])
899

900
    To compute a reduced order model (Ar,Br,Cr,Dr) for a stable
901
    original state-space representation (A,B,C,D) by using either the
902
    square-root or the balancing-free square-root Singular
903
    Perturbation Approximation (SPA) model reduction method.
904
    Must supply either nr or tolerance values.
905

906
    Arguments
907
        Mode Parameters
908
            dico
909
                Specifies the type of the original system as follows:
910
                = 'C':  continuous-time system;
911
                = 'D':  discrete-time system.
912
            job
913
                Specifies the model reduction approach to be used
914
                as follows:
915
                = 'B':  use the square-root SPA method;
916
                = 'N':  use the balancing-free square-root SPA method.
917
            equil
918
                Specifies whether the user wishes to preliminarily
919
                equilibrate the triplet (A,B,C) as follows:
920
                = 'S':  perform equilibration (scaling);
921
                = 'N':  do not perform equilibration.
922

923
        Required arguments
924
            n : input int
925
                The order of the original state-space representation, i.e.
926
                the order of the matrix A.  n >= 0.
927
            m : input int
928
                The number of system inputs.  m >= 0.
929
            p : input int
930
                The number of system outputs.  p >= 0.
931
            A : input rank-2 array('d') with bounds (n,n)
932
                On entry, the leading n-by-n part of this array must
933
                contain the state dynamics matrix A.
934
            B : input rank-2 array('d') with bounds (n,m)
935
                On entry, the leading n-by-m part of this array must
936
                contain the original input/state matrix B.
937
            C : input rank-2 array('d') with bounds (p,n)
938
                On entry, the leading p-by-n part of this array must
939
                contain the original state/output matrix C.
940
            D : input rank-2 array('d') with bounds (p,m)
941
                On entry, the leading p-by-m part of this array must
942
                contain the original input/output matrix D.
943

944
        Optional arguments :
945
            nr :=None input int
946
                nr is the desired order of
947
                the resulting reduced order system.  0 <= nr <= n.
948
            tol1 :=0 input double precision
949
                If ordsel = 'A', tol1 contains the tolerance for
950
                determining the order of reduced system.
951
                For model reduction, the recommended value is
952
                tol1 = c*hnorm(A,B,C), where c is a constant in the
953
                interval [0.00001,0.001], and hnorm(A,B,C) is the
954
                Hankel-norm of the given system (computed in hsv(1)).
955
                For computing a minimal realization, the recommended
956
                value is tol1 = n*eps*hnorm(A,B,C), where eps is the
957
                machine precision (see LAPACK Library Routine DLAMCH).
958
                This value is used by default if tol1 <= 0 on entry.
959
                If ordsel = 'F', the value of tol1 is ignored.
960
            tol2 :=0 input double precision
961
                The tolerance for determining the order of a minimal
962
                realization of the given system. The recommended value is
963
                tol2 = n*eps*hnorm(A,B,C). This value is used by default
964
                if tol2 <= 0 on entry.
965
                If tol2 > 0, then tol2 <= tol1.
966
            ldwork := None input int
967
                The length of the cache array. The default value is n + 3*max(m,p),
968
                for better performance should be larger.
969

970
        Return objects
971
            nr : output int
972
                nr is the order of the resulting reduced order model.
973
                nr is set as follows:
974
                if ordsel = 'F', nr is equal to min(nr,nmin), where nr
975
                is the desired order on entry and nmin is the order of a
976
                minimal realization of the given system; nmin is
977
                determined as the number of Hankel singular values greater
978
                than n*eps*hnorm(A,B,C), where eps is the machine
979
                precision (see LAPACK Library Routine DLAMCH) and
980
                hnorm(A,B,C) is the Hankel norm of the system (computed
981
                in hsv(1));
982
                if ordsel = 'A', nr is equal to the number of Hankel
983
                singular values greater than max(tol1,n*eps*hnorm(A,B,C)).
984
            Ar : rank-2 array('d') with bounds (nr,nr)
985
                the leading nr-by-nr part of this array contains the
986
                state dynamics matrix Ar of the reduced order system.
987
            Br : rank-2 array('d') with bounds (nr,m)
988
                the leading nr-by-m part of this array contains the
989
                input/state matrix Br of the reduced order system.
990
            Cr : rank-2 array('d') with bounds (p,nr)
991
                the leading p-by-nr part of this array contains the
992
                state/output matrix Cr of the reduced order system.
993
            Dr : rank-2 array('d') with bounds (p,m)
994
                the leading p-by-m part of this array contains the
995
                input/output matrix Dr of the reduced order system.
996
            hsv : output double precision array, dimension (n)
997
                If info = 0, it contains the Hankel singular values of
998
                the original system ordered decreasingly. hsv(1) is the
999
                Hankel norm of the system.
1000

1001
    Raises
1002
    ------
1003
    SlycotArithmeticError
1004
        :info == 1:
1005
            The reduction of A to the real Schur form failed
1006
        :info == 2 and dico == 'C':
1007
            The state matrix A is not stable
1008
        :info == 2 and dico == 'D':
1009
            The state matrix A is not convergent
1010
        :info == 3:
1011
            The computation of Hankel singular values failed
1012

1013
    Warns
1014
    -----
1015
    SlycotResultWarning
1016
        :iwarn == 1:
1017
                The selected order {nr} is greater
1018
                than the order of a minimal realization of the
1019
                given system. `nr` was set automatically to {Nr}
1020
                corresponding to the order of a minimal realization
1021
                of the system
1022
    """
1023

UNCOV
1024
    hidden = ' (hidden by the wrapper)'
×
UNCOV
1025
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr',
×
1026
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1027
                'D', 'ldd' + hidden, 'hsv', 'tol1', 'tol2',
1028
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
1029
    if ldwork is None:
×
UNCOV
1030
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
×
1031
    if nr is None:
×
1032
        ordsel = 'A'
×
1033
        nr = 0  # order will be computed by the routine
×
1034
    else:
1035
        ordsel = 'F'
×
UNCOV
1036
    out = _wrapper.ab09bd(dico, job, equil, ordsel,
×
1037
                          n, m, p, nr, A, B, C, D, tol1, tol2, ldwork)
1038
    Nr, A, B, C, D, hsv = out[:-2]
×
UNCOV
1039
    raise_if_slycot_error(out[-2:], arg_list, ab09bd.__doc__, locals())
×
1040
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[ :,:Nr], D[:, :], hsv
×
1041

1042
def ab09md(dico,job,equil,n,m,p,A,B,C,alpha=None,nr=None,tol=0,ldwork=None):
32✔
1043
    """ nr,Ar,Br,Cr,ns,hsv = ab09md(dico,job,equil,n,m,p,A,B,C,[alpha,nr,tol,ldwork])
1044

1045
    To compute a reduced order model (Ar,Br,Cr) for an original
1046
    state-space representation (A,B,C) by using either the square-root
1047
    or the balancing-free square-root Balance & Truncate (B & T)
1048
    model reduction method for the ALPHA-stable part of the system.
1049

1050
    Arguments
1051
        Mode Parameters
1052
            dico
1053
                Specifies the type of the original system as follows:
1054
                = 'C':  continuous-time system;
1055
                = 'D':  discrete-time system.
1056
            job
1057
                Specifies the model reduction approach to be used
1058
                as follows:
1059
                = 'B':  use the square-root Balance & Truncate method;
1060
                = 'N':  use the balancing-free square-root
1061
                        Balance & Truncate method.
1062
            equil
1063
                Specifies whether the user wishes to preliminarily
1064
                equilibrate the triplet (A,B,C) as follows:
1065
                = 'S':  perform equilibration (scaling);
1066
                = 'N':  do not perform equilibration.
1067

1068
        Required arguments
1069
            n : input int
1070
                The order of the original state-space representation, i.e.
1071
                the order of the matrix A.  n >= 0.
1072
            m : input int
1073
                The number of system inputs.  m >= 0.
1074
            p : input int
1075
                The number of system outputs.  p >= 0.
1076
            A : input rank-2 array('d'), dimension (n,n)
1077
                On entry, the leading N-by-N part of this array must
1078
                contain the state dynamics matrix A.
1079
            B : input rank-2 array('d'), dimension (n,m)
1080
                On entry, the leading N-by-M part of this array must
1081
                contain the original input/state matrix B.
1082
            C : input rank-2 array('d'), dimension (p,n)
1083
                On entry, the leading P-by-N part of this array must
1084
                contain the original state/output matrix C.
1085

1086
         Optional arguments
1087
            alpha :=None input double precision
1088
                Specifies the alpha-stability boundary for the eigenvalues
1089
                of the state dynamics matrix A. For a continuous-time
1090
                system (dico = 'C'), alpha <= 0 is the boundary value for
1091
                the real parts of eigenvalues, while for a discrete-time
1092
                system (dico = 'D'), 0 <= alpha <= 1 represents the
1093
                boundary value for the moduli of eigenvalues.
1094
                The alpha-stability domain does not include the boundary.
1095
            nr := None input int
1096
                On entry with ordsel = 'F', nr is the desired order of the
1097
                resulting reduced order system.  0 <= nr <= n.
1098
            tol :=0 input double precision
1099
                If ordsel = 'A', tol contains the tolerance for
1100
                determining the order of reduced system.
1101
                For model reduction, the recommended value is
1102
                tol = c*hnorm(As,Bs,Cs), where c is a constant in the
1103
                interval [0.00001,0.001], and hnorm(As,Bs,Cs) is the
1104
                Hankel-norm of the alpha-stable part of the given system
1105
                (computed in hsv(1)).
1106
                If tol <= 0 on entry, the used default value is
1107
                tol = ns*eps*hnorm(As,Bs,Cs), where ns is the number of
1108
                alpha-stable eigenvalues of A and eps is the machine
1109
                precision (see LAPACK Library Routine DLAMCH).
1110
                This value is appropriate to compute a minimal realization
1111
                of the alpha-stable part.
1112
                If ordsel = 'F', the value of tol is ignored.
1113
            ldwork :=None input int
1114
                The length of the array dwork.
1115
                ldwork >= max(1,n*(2*n+max(n,m,p)+5) + n*(n+1)/2).
1116
                For optimum performance ldwork should be larger.
1117

1118
         Return objects
1119
            nr : output int
1120
                On exit, if info = 0, nr is the order of the resulting
1121
                reduced order model. For a system with nu alpha-unstable
1122
                eigenvalues and ns alpha-stable eigenvalues (nu+ns = n),
1123
                nr is set as follows: if ordsel = 'F', nr is equal to
1124
                nu+min(max(0,nr-nu),nmin), where nr is the desired order
1125
                on entry, and nmin is the order of a minimal realization
1126
                of the alpha-stable part of the given system; nmin is
1127
                determined as the number of Hankel singular values greater
1128
                than ns*eps*hnorm(As,Bs,Cs), where eps is the machine
1129
                precision (see LAPACK Library Routine DLAMCH) and
1130
                hnorm(As,Bs,Cs) is the Hankel norm of the alpha-stable
1131
                part of the given system (computed in hsv(1));
1132
                if ordsel = 'A', nr is the sum of nu and the number of
1133
                Hankel singular values greater than
1134
                max(tol,ns*eps*hnorm(As,Bs,Cs)).
1135
            Ar : rank-2 array('d') with bounds (nr,nr)
1136
                On exit, if info = 0, the leading nr-by-nr part of this
1137
                array contains the state dynamics matrix Ar of the reduced
1138
                order system.
1139
                The resulting A has a block-diagonal form with two blocks.
1140
                For a system with nu alpha-unstable eigenvalues and
1141
                ns alpha-stable eigenvalues (nu+ns = n), the leading
1142
                nu-by-nu block contains the unreduced part of A
1143
                corresponding to alpha-unstable eigenvalues in an
1144
                upper real Schur form.
1145
                The trailing (nr+ns-n)-by-(nr+ns-n) block contains
1146
                the reduced part of A corresponding to alpha-stable
1147
                eigenvalues.
1148
            Br : rank-2 array('d') with bounds (nr,m)
1149
                On exit, if info = 0, the leading nr-by-m part of this
1150
                array contains the input/state matrix Br of the reduced
1151
                order system.
1152
            Cr : rank-2 array('d') with bounds (p,nr)
1153
                On exit, if info = 0, the leading p-by-nr part of this
1154
                array contains the state/output matrix Cr of the reduced
1155
                order system.
1156
            ns : output int
1157
                The dimension of the alpha-stable subsystem.
1158
            hsv : output double precision array, dimension (n)
1159
                If info = 0, the leading ns elements of hsv contain the
1160
                Hankel singular values of the alpha-stable part of the
1161
                original system ordered decreasingly.
1162
                hsv(1) is the Hankel norm of the alpha-stable subsystem.
1163

1164
    Raises
1165
    ------
1166
    SlycotArithmeticError : e
1167
        :info == 1:
1168
            The computation of the ordered real Schur form of A failed
1169
        :info == 2:
1170
            The separation of the {alpha}-stable/unstable diagonal
1171
            blocks failed because of very close eigenvalues
1172
        :info == 3:
1173
            The computation of Hankel singular values failed
1174

1175
    Warns
1176
    -----
1177
    SlycotResultWarning : e
1178
        :iwarn == 1:
1179
            The selected order {nr} is greater
1180
            than `nsmin`, the sum of the order of the
1181
            {alpha}-unstable part and the order of a minimal
1182
            realization of the {alpha}-stable part of the given
1183
            system. The resulting `nr`  is set to `nsmin` = {Nr}
1184
        :iwarn == 2:
1185
            The selected order {nr} is less
1186
            than the order of the {alpha}-unstable part of the
1187
            given system. In this case `nr` is set equal to the
1188
            order of the {alpha}-unstable part {Nr}.
1189
    """
UNCOV
1190
    hidden = ' (hidden by the wrapper)'
×
UNCOV
1191
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr', 'alpha',
×
1192
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1193
                'ns', 'hsv', 'tol',
1194
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
1195
    if ldwork is None:
×
UNCOV
1196
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
×
1197
    if nr is None:
×
1198
        ordsel = 'A'
×
1199
        nr = 0  # order will be computed by the routine
×
1200
    else:
1201
        ordsel = 'F'
×
UNCOV
1202
    if alpha is None:
×
1203
        alpha = {'C': 0, 'D': 1.}[dico]
×
1204
    out = _wrapper.ab09md(dico, job, equil, ordsel,
×
1205
                          n, m, p, nr, alpha, A, B, C, tol, ldwork)
1206
    Nr, A, B, C, Ns, hsv = out[:-2]
×
UNCOV
1207
    raise_if_slycot_error(out[-2:], arg_list, ab09md.__doc__, locals())
×
1208
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], Ns, hsv
×
1209

1210
def ab09nd(dico,job,equil,n,m,p,A,B,C,D,alpha=None,nr=None,tol1=0,tol2=0,ldwork=None):
32✔
1211
    """ nr,Ar,Br,Cr,Dr,ns,hsv = ab09nd(dico,job,equil,n,m,p,A,B,C,D,[alpha,nr,tol1,tol2,ldwork])
1212

1213
    To compute a reduced order model (Ar,Br,Cr,Dr) for an original
1214
    state-space representation (A,B,C,D) by using either the
1215
    square-root or the balancing-free square-root Singular
1216
    Perturbation Approximation (SPA) model reduction method for the
1217
    alpha-stable part of the system.
1218

1219
    Arguments
1220
        Mode Parameters
1221
            dico
1222
                Specifies the type of the original system as follows:
1223
                = 'C':  continuous-time system;
1224
                = 'D':  discrete-time system.
1225
            job
1226
                Specifies the model reduction approach to be used
1227
                as follows:
1228
                = 'B':  use the square-root SPA method;
1229
                = 'N':  use the balancing-free square-root SPA method.
1230
            equil
1231
                Specifies whether the user wishes to preliminarily
1232
                equilibrate the triplet (A,B,C) as follows:
1233
                = 'S':  perform equilibration (scaling);
1234
                = 'N':  do not perform equilibration.
1235

1236
        Required arguments
1237
            n : input int
1238
                The order of the original state-space representation, i.e.
1239
                the order of the matrix A.  n >= 0.
1240
            m : input int
1241
                The number of system inputs.  m >= 0.
1242
            p : input int
1243
                The number of system outputs.  p >= 0.
1244
            A : input rank-2 array('d') with bounds (n,n)
1245
                On entry, the leading n-by-n part of this array must
1246
                contain the state dynamics matrix A.
1247
            B : input rank-2 array('d') with bounds (n,m)
1248
                On entry, the leading n-by-m part of this array must
1249
                contain the original input/state matrix B.
1250
            C : input rank-2 array('d') with bounds (p,n)
1251
                On entry, the leading p-by-n part of this array must
1252
                contain the original state/output matrix C.
1253
            D : input rank-2 array('d') with bounds (p,m)
1254
                On entry, the leading p-by-m part of this array must
1255
                contain the original input/output matrix D.
1256

1257
        Optional arguments
1258
            alpha :=None input double precision
1259
                Specifies the alpha-stability boundary for the eigenvalues
1260
                of the state dynamics matrix A. For a continuous-time
1261
                system (dico = 'C'), alpha <= 0 is the boundary value for
1262
                the real parts of eigenvalues, while for a discrete-time
1263
                system (dico = 'D'), 0 <= alpha <= 1 represents the
1264
                boundary value for the moduli of eigenvalues.
1265
                The alpha-stability domain does not include the boundary.
1266
            nr :=None input int
1267
                nr is the desired order of
1268
                the resulting reduced order system.  0 <= nr <= n.
1269
            tol1 :=0 input double precision
1270
                If ordsel = 'A', tol1 contains the tolerance for
1271
                determining the order of reduced system.
1272
                For model reduction, the recommended value is
1273
                tol1 = c*hnorm(As,Bs,Cs), where c is a constant in the
1274
                interval [0.00001,0.001], and hnorm(As,Bs,Cs) is the
1275
                Hankel-norm of the alpha-stable part of the given system
1276
                (computed in hsv(1)).
1277
                If tol1 <= 0 on entry, the used default value is
1278
                tol1 = ns*eps*hnorm(As,Bs,Cs), where NS is the number of
1279
                alpha-stable eigenvalues of A and eps is the machine
1280
                precision (see LAPACK Library Routine DLAMCH).
1281
                This value is appropriate to compute a minimal realization
1282
                of the alpha-stable part.
1283
                If ordsel = 'F', the value of tol1 is ignored.
1284
            tol2 :=0 input double precision
1285
                The tolerance for determining the order of a minimal
1286
                realization of the alpha-stable part of the given system.
1287
                The recommended value is tol2 = ns*eps*hnorm(As,Bs,Cs).
1288
                This value is used by default if tol2 <= 0 on entry.
1289
                If tol2 > 0, then tol2 <= tol1.
1290
            ldwork := None input int
1291
                The length of the array dwork.
1292
                ldwork >= max(1,n*(2*n+max(n,m,p)+5) + n*(n+1)/2).
1293
                For optimum performance ldwork should be larger.
1294

1295
        Return objects
1296
            nr : output int
1297
                nr is the order of the resulting reduced order model.
1298
                nr is set as follows:
1299
                if ordsel = 'F', nr is equal to min(nr,nmin), where nr
1300
                is the desired order on entry and nmin is the order of a
1301
                minimal realization of the given system; nmin is
1302
                determined as the number of Hankel singular values greater
1303
                than n*eps*hnorm(A,B,C), where eps is the machine
1304
                precision (see LAPACK Library Routine DLAMCH) and
1305
                hnorm(A,B,C) is the Hankel norm of the system (computed
1306
                in hsv(1));
1307
                if ordsel = 'A', nr is equal to the number of Hankel
1308
                singular values greater than max(TOL1,n*eps*hnorm(A,B,C)).
1309
            Ar : rank-2 array('d') with bounds (nr,nr)
1310
                the leading nr-by-nr part of this array contains the
1311
                state dynamics matrix Ar of the reduced order system.
1312
            Br : rank-2 array('d') with bounds (nr,m)
1313
                the leading nr-by-m part of this array contains the
1314
                input/state matrix Br of the reduced order system.
1315
            Cr : rank-2 array('d') with bounds (p,nr)
1316
                the leading p-by-nr part of this array contains the
1317
                state/output matrix Cr of the reduced order system.
1318
            Dr : rank-2 array('d') with bounds (p,m)
1319
                the leading p-by-m part of this array contains the
1320
                input/output matrix Dr of the reduced order system.
1321
            ns : output int
1322
                The dimension of the alpha-stable subsystem.
1323
            hsv : output double precision array, dimension (n)
1324
                If info = 0, it contains the Hankel singular values of
1325
                the original system ordered decreasingly. hsv(1) is the
1326
                Hankel norm of the system.
1327

1328

1329
    Raises
1330
    ------
1331
    SlycotArithmeticError
1332
        :info == 1:
1333
            The computation of the ordered real Schur form of A failed
1334
        :info == 2:
1335
            The separation of the {alpha}-stable/unstable diagonal
1336
            blocks failed because of very close eigenvalues
1337
        :info == 3:
1338
            The computation of Hankel singular values failed
1339

1340
    Warns
1341
    -----
1342
    SlycotResultWarning
1343
        :iwarn == 1:
1344
            The selected order {nr} is greater
1345
            than `nsmin`, the sum of the order of the
1346
            {alpha}-unstable part and the order of a minimal
1347
            realization of the {alpha}-stable part of the given
1348
            system. The resulting `nr`  is set to `nsmin` = {Nr}
1349
        :iwarn == 2:
1350
            The selected order {nr} is less
1351
            than the order of the {alpha}-unstable part of the
1352
            given system. In this case `nr` is set equal to the
1353
            order of the {alpha}-unstable part {Nr}.
1354
    """
1355
    hidden = ' (hidden by the wrapper)'
32✔
1356
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr', 'alpha',
32✔
1357
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1358
                'D', 'ldc' + hidden, 'ns', 'hsv', 'tol1', 'tol2',
1359
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
1360
    if ldwork is None:
32✔
1361
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
32✔
1362
    if nr is None:
32✔
UNCOV
1363
        ordsel = 'A'
×
UNCOV
1364
        nr = 0  # order will be computed by the routine
×
1365
    else:
1366
        ordsel = 'F'
32✔
1367
    if alpha is None:
32✔
UNCOV
1368
        alpha = {'C': 0, 'D': 1.}[dico]
×
1369
    out = _wrapper.ab09nd(dico, job, equil, ordsel,
32✔
1370
                          n, m, p, nr, alpha, A, B, C, D, tol1, tol2, ldwork)
1371
    Nr, A, B, C, D, Ns, hsv = out[:-2]
32✔
1372
    raise_if_slycot_error(out[-2:], arg_list, ab09nd.__doc__, locals())
32✔
1373
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], D, Ns, hsv
32✔
1374

1375

1376
def ab13bd(dico, jobn, n, m, p, A, B, C, D, tol = 0.0):
32✔
1377
    """norm = ab13bd(dico, jobn, n, m, p, A, B, C, D, [tol])
1378

1379
    To compute the H2 or L2 norm of the transfer-function matrix G
1380
    of the system (A,B,C,D). G must not have poles on the imaginary
1381
    axis, for a continuous-time system, or on the unit circle, for
1382
    a discrete-time system. If the H2-norm is computed, the system
1383
    must be stable.
1384

1385
    Parameters
1386
    ----------
1387
    dico : {'D', 'C'}
1388
        Indicate whether the system is discrete 'D' or continuous 'C'.
1389
    jobn : {'H', 'L'}
1390
        H2-norm 'H' or L2-norm 'L' to be computed.
1391
    n : int
1392
        The number of state variables.  n >= 0.
1393
    m : int
1394
        The number of system inputs.  m >= 0.
1395
    p : int
1396
        The number of system outputs.  p >= 0.
1397
    A : (n,n) ndarray
1398
        The leading n-by-n part of this array must contain the state
1399
        dynamics matrix A of the system.
1400
    B : (n,m) ndarray
1401
        The leading n-by-m part of this array must contain the input/state
1402
        matrix B of the system.
1403
    C : (p,n) ndarray
1404
        The leading p-by-n part of this array must contain the state/output
1405
        matrix C of the system.
1406
    D : (p,m) ndarray
1407
        The leading p-by-m part of this array must contain the direct
1408
        transmission matrix D of the system.
1409
    tol : float, optional
1410
        The absolute tolerance level below which the elements of
1411
        B are considered zero (used for controllability tests).
1412
        If the user sets tol <= 0, then an implicitly computed,
1413
        default tolerance, defined by  toldef = n*eps*norm(B),
1414
        is used instead, where eps is the machine precision
1415
        (see LAPACK Library routine DLAMCH) and norm(B) denotes
1416
        the 1-norm of B.
1417

1418
    Returns
1419
    -------
1420
    norm:  H2 or L2 norm of the system (A,B,C,D)
1421

1422
    Raises
1423
    ------
1424
    SlycotArithmeticError
1425
        :info == 1:
1426
            The reduction of A to a real Schur form failed
1427
        :info == 2:
1428
            A failure was detected during the reordering of the
1429
            real Schur form of A, or in the iterative process for
1430
            reordering the eigenvalues of `` Z'*(A + B*F)*Z`` along the
1431
            diagonal (see SLICOT routine SB08DD)
1432
        :info == 3 and dico == 'C':
1433
            The matrix A has a controllable eigenvalue on the imaginary axis
1434
        :info == 3 and dico == 'D':
1435
            The matrix A has a controllable eigenvalue on the unit circle
1436
        :info == 4:
1437
            The solution of Lyapunov equation failed because the
1438
            equation is singular
1439
        :info == 5:
1440
            D is a nonzero matrix
1441
        :info == 6:
1442
            The system is unstable
1443

1444
    Warns
1445
    -----
1446
    SlycotResultWarning
1447
        :iwarn > 0:
1448
            {iwarn} violations of the numerical stability condition
1449
            occured during the assignment of eigenvalues in
1450
            computing the right coprime factorization with inner
1451
            denominator of `G` (see the SLICOT subroutine SB08DD).
1452
    """
1453

1454
    out = _wrapper.ab13bd(dico, jobn, n, m, p, A, B, C, D, tol)
32✔
1455

1456
    hidden = ' (hidden by the wrapper)'
32✔
1457
    arg_list = ('dico', 'jobn', 'n', 'm', 'p',
32✔
1458
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1459
                'D', 'ldd' + hidden, 'nq' + hidden,'tol', 'dwork' + hidden,
1460
                'ldwork' + hidden, 'iwarn', 'info')
1461
    raise_if_slycot_error(out[-2:], arg_list, ab13bd.__doc__, locals())
32✔
1462
    return out[0]
32✔
1463

1464
def ab13dd(dico, jobe, equil, jobd, n, m, p, A, E, B, C, D, tol = 1e-10):
32✔
1465
    """gpeak, fpeak = ab13dd(dico, jobe, equil, jobd, n, m, p, A, E, B, C, D, [tol])
1466

1467
    To compute the L-infinity norm of a continuous-time or
1468
    discrete-time system, either standard or in the descriptor form,
1469

1470
                                  -1
1471
     G(lambda) = C*( lambda*E - A ) *B + D .
1472

1473
    The norm is finite if and only if the matrix pair (A,E) has no
1474
    eigenvalue on the boundary of the stability domain, i.e., the
1475
    imaginary axis, or the unit circle, respectively. It is assumed
1476
    that the matrix E is nonsingular.
1477

1478
    Required arguments:
1479
        dico : {'D', 'C'} input string(len=1)
1480
               Indicate whether the system is discrete 'D' or continuous 'C'.
1481
        jobe : {'G', 'I'} input string(len=1)
1482
               Specifies whether E is a general square or an identity
1483
               matrix, as follows:
1484
               = 'G':  E is a general square matrix;
1485
               = 'I':  E is the identity matrix.
1486
        equil : {'S', 'N'} input string(len=1)
1487
                Specifies whether the user wishes to preliminarily
1488
                equilibrate the system (A,E,B,C) or (A,B,C), as follows:
1489
                = 'S':  perform equilibration (scaling);
1490
                = 'N':  do not perform equilibration.
1491
        jobd : {'D', 'Z'} input string(len=1)
1492
               Specifies whether or not a non-zero matrix D appears in
1493
               the given state space model:
1494
               = 'D':  D is present;
1495
               = 'Z':  D is assumed a zero matrix.
1496
        n : input int
1497
            The number of state variables.  n >= 0.
1498
        m : input int
1499
            The number of system inputs.  m >= 0.
1500
        p : input int
1501
            The number of system outputs.  p >= 0.
1502
        A : input rank-2 array('d') with bounds (n,n)
1503
            The leading n-by-n part of this array must contain the state
1504
            dynamics matrix A of the system.
1505
        E : input rank-2 array('d') with bounds (n,n)
1506
            If jobe = 'G', the leading N-by-N part of this array must
1507
            contain the descriptor matrix E of the system.
1508
            If jobe = 'I', then E is assumed to be the identity
1509
            matrix and is not referenced.
1510
        B : input rank-2 array('d') with bounds (n,m)
1511
            The leading n-by-m part of this array must contain the input/state
1512
            matrix B of the system.
1513
        C : input rank-2 array('d') with bounds (p,n)
1514
            The leading p-by-n part of this array must contain the state/output
1515
            matrix C of the system.
1516
        D : input rank-2 array('d') with bounds (p,m)
1517
            The leading p-by-m part of this array must contain the direct
1518
            transmission matrix D of the system.
1519

1520
    Optional arguments:
1521
        tol : Tolerance used to set the accuracy in determining the
1522
              norm.  0 <= tol < 1.
1523

1524
    Return objects:
1525
        gpeak : float
1526
                The L-infinity norm of the system, i.e., the peak gain
1527
                of the frequency response (as measured by the largest
1528
                singular value in the MIMO case).
1529
        fpeak : float
1530
                The frequency where the gain of the frequency response
1531
                achieves its peak value gpeak, i.e.,
1532

1533
                  || G ( j*fpeak ) || = gpeak ,  if dico = 'C', or
1534

1535
                          j*fpeak
1536
                  || G ( e       ) || = gpeak ,  if dico = 'D'.
1537

1538
    Raises
1539
    ------
1540
    SlycotArithmeticError
1541
        :info = 1:
1542
            The matrix E is (numerically) singular
1543
        :info = 2:
1544
            The (periodic) QR (or QZ) algorithm for computing
1545
            eigenvalues did not converge
1546
        :info = 3:
1547
            The SVD algorithm for computing singular values did
1548
            not converge
1549
        :info = 4:
1550
            The tolerance is too small and the algorithm did not converge
1551
    """
1552
    hidden = ' (hidden by the wrapper)'
32✔
1553
    arg_list = ('dico', 'jobe', 'equil', 'jobd', 'n', 'm', 'p',
32✔
1554
                'fpeak' + hidden,
1555
                'A', 'lda' + hidden, 'E', 'lde' + hidden, 'B', 'ldb' + hidden,
1556
                'C', 'ldc' + hidden, 'D', 'ldd' + hidden,
1557
                'gpeak' + hidden, 'tol', 'iwork' + hidden, 'dwork' + hidden,
1558
                'ldwork' + hidden, 'cwork' + hidden, 'lcwork' + hidden,
1559
                'info' + hidden)
1560
    if dico != 'C' and dico != 'D':
32✔
UNCOV
1561
        raise SlycotParameterError('dico must be "C" or "D"', -1)
×
1562
    if jobe != 'G' and jobe != 'I':
32✔
1563
        raise SlycotParameterError('jobe must be "G" or "I"', -2)
×
1564
    if equil != 'S' and equil != 'N':
32✔
1565
        raise SlycotParameterError('equil must be "S" or "N"', -3)
×
1566
    if jobd != 'D' and jobd != 'Z':
32✔
1567
        raise SlycotParameterError('jobd must be "D" or "Z"', -4)
×
1568
    out = _wrapper.ab13dd(dico, jobe, equil, jobd,
32✔
1569
                          n, m, p, [0.0, 1.0], A, E, B, C, D, tol)
1570
    raise_if_slycot_error(out[-1], arg_list, ab13dd.__doc__)
32✔
1571

1572
    fpeak = out[0][0] if out[0][1] > 0 else float('inf')
32✔
1573
    gpeak = out[1][0] if out[1][1] > 0 else float('inf')
32✔
1574
    return gpeak, fpeak
32✔
1575

1576

1577

1578
def ab13ed(n, A, tol = 9.0):
32✔
1579
    """low, high = ab13ed(n, A, [tol])
1580

1581
    To estimate beta(A), the 2-norm distance from a real matrix A to
1582
    the nearest complex matrix with an eigenvalue on the imaginary
1583
    axis. The estimate is given as
1584

1585
         ``low <= beta(A) <= high,``
1586

1587
    where either
1588

1589
         ``(1 + tol) * low >= high,``
1590

1591
    or
1592

1593
         ``low = 0   and   high = delta,``
1594

1595
    and delta is a small number approximately equal to the square root
1596
    of machine precision times the Frobenius norm (Euclidean norm)
1597
    of A. If A is stable in the sense that all eigenvalues of A lie
1598
    in the open left half complex plane, then beta(A) is the distance
1599
    to the nearest unstable complex matrix, i.e., the complex
1600
    stability radius.
1601

1602
    Parameters
1603
    ----------
1604
    n : int
1605
        The order of the matrix A.  ``n >= 0.``
1606
    A : (n,n) array_like
1607
        The leading n-by-n part of this array must contain the matrix A.
1608
    tol : float optional
1609
        Specifies the accuracy with which low and high approximate
1610
        beta(A). If the user sets tol to be less than sqrt(eps),
1611
        where eps is the machine precision (see LAPACK Library
1612
        Routine DLAMCH), then the tolerance is taken to be
1613
        sqrt(eps).
1614
        The recommended value is tol = 9, which gives an estimate
1615
        of beta(A) correct to within an order of magnitude.
1616

1617
    Returns
1618
    -------
1619
    low : float
1620
          A lower bound for beta(A).
1621
    high : float
1622
           An upper bound for beta(A).
1623

1624
    Raises
1625
    ------
1626
    SlycotArithmeticError
1627
        :info = 1:
1628
            The QR algorithm fails to converge
1629
    """
1630
    hidden = ' (hidden by the wrapper)'
32✔
1631
    arg_list = ['n', 'A', 'lda' + hidden, 'low' + hidden, 'high' + hidden, 'tol',
32✔
1632
                'dwork' + hidden, 'ldwork' + hidden, 'info' + hidden]
1633
    out = _wrapper.ab13ed(n, A, tol)
32✔
1634
    raise_if_slycot_error(out[-1], arg_list, ab13ed.__doc__)
32✔
1635
    return out[:-1]
32✔
1636

1637
def ab13fd(n, A, tol = 0.0):
32✔
1638
    """beta, omega = ab13fd(n, A, [tol])
1639

1640
    To compute beta(A), the 2-norm distance from a real matrix A to
1641
    the nearest complex matrix with an eigenvalue on the imaginary
1642
    axis. If A is stable in the sense that all eigenvalues of A lie
1643
    in the open left half complex plane, then beta(A) is the complex
1644
    stability radius, i.e., the distance to the nearest unstable
1645
    complex matrix. The value of beta(A) is the minimum of the
1646
    smallest singular value of (A - jwI), taken over all real w.
1647
    The value of w corresponding to the minimum is also computed.
1648

1649
    Required arguments:
1650
        n : input int
1651
            The order of the matrix A.  n >= 0.
1652
        A : input rank-2 array('d') with bounds (n,n)
1653
            The leading n-by-n part of this array must contain the matrix A.
1654

1655
    Optional arguments:
1656
        tol : Specifies the accuracy with which beta(A) is to be
1657
              calculated. (See the Numerical Aspects section below.)
1658
              If the user sets tol to be less than eps, where eps is the
1659
              machine precision (see LAPACK Library Routine DLAMCH),
1660
              then the tolerance is taken to be eps.
1661

1662
    Return objects:
1663
        beta : float
1664
               The computed value of beta(A), which actually is an upper
1665
               bound.
1666
        omega : float
1667
                The value of w such that the smallest singular value of
1668
                (A - jwI) equals beta(A).
1669

1670
    Numerical Aspects:
1671
        In the presence of rounding errors, the computed function value
1672
        beta satisfies
1673
              beta(A) <= beta + epsilon,
1674
              beta/(1+tol) - delta <= max(beta(A), sqrt(2*n*eps)*norm(A)),
1675
        where norm(A) is the Frobenius norm of A,
1676
              epsilon = p(n) * eps * norm(A),
1677
        and
1678
              delta   = p(n) * sqrt(eps) * norm(A),
1679
        and p(n) is a low degree polynomial. It is recommended to choose
1680
        tol greater than sqrt(eps). Although rounding errors can cause
1681
        AB13FD to fail for smaller values of tol, nevertheless, it usually
1682
        succeeds. Regardless of success or failure, the first inequality
1683
        holds.
1684

1685
    Raises
1686
    ------
1687
    SlycotArithmeticError
1688
        :info = 2:
1689
            Either the QR or SVD algorithm fails to converge
1690

1691
    Warns
1692
    -----
1693
    SlycotResultWarning
1694
        :info = 1:
1695
            Failed to compute beta(A) within the specified tolerance.
1696
            Nevertheless, the returned value is an upper bound on beta(A);
1697
    """
1698
    hidden = ' (hidden by the wrapper)'
32✔
1699
    arg_list = ['n', 'A', 'lda' + hidden, 'beta' + hidden, 'omega' + hidden, 'tol',
32✔
1700
                'dwork' + hidden, 'ldwork' + hidden, 'cwork' + hidden,
1701
                'lcwork' + hidden, 'info' + hidden]
1702
    out = _wrapper.ab13fd(n, A, tol)
32✔
1703
    raise_if_slycot_error(out[-1], arg_list, ab13fd.__doc__)
32✔
1704
    return out[0], out[1]
32✔
1705

1706

1707
def ab13md(Z, nblock, itype, x=None):
32✔
1708
    """mubound, d, g, xout = ab13md(Z, nblock, itype, [x])
1709

1710
    Find an upper bound for the structured singular value of complex
1711
    matrix Z and given block diagonal structure.
1712

1713
    Parameters
1714
    ----------
1715
    Z : (n,n) complex array
1716
      Matrix to find structured singular value upper bound of
1717

1718
    nblock : (m,) integer array
1719
      The size of the block diagonals of the uncertainty structure;
1720
      i.e., nblock(i)=p means that the ith block is pxp.
1721

1722
    itype : (m,) integer array
1723
      The type of each block diagonal uncertainty defined in nblock.
1724
      itype(i)==1 means that the ith block is real, while itype(i)==2
1725
      means the the ith block is complex.  Real blocks must be 1x1,
1726
      i.e., if itype(i)==1, nblock(i) must be 1.
1727

1728
    x : (q,) real array or None
1729
      If not None, must be the output of a previous call to ab13md.
1730
      The previous call must have been with the same values of n,
1731
      nblock, and itype; and the previous call's Z should be "close"
1732
      to the current call's Z.
1733

1734
      q is determined by the block structure; see SLICOT AB13MD for
1735
      details.
1736

1737
    Returns
1738
    -------
1739
    mubound : non-negative real scalar
1740
      Upper bound on structure singular value for given arguments
1741

1742
    d, g : (n,) real arrays
1743
      Real arrays such that if D=np.diag(g), G=np.diag(G), and ZH = Z.T.conj(), then
1744
        ZH @ D**2 @ Z + 1j * (G@Z - ZH@G) - mu**2 * D**2
1745
      will be negative semi-definite.
1746

1747
    xout : (q,) real array
1748
      For use as ``x`` argument in subsequent call to ``ab13md``.
1749

1750
    For scalar Z and real uncertainty (ntype=1, itype=1), returns 0
1751
    instead of abs(Z).
1752

1753
    Raises
1754
    ------
1755
    SlycotArithmeticError
1756
        :info = 1: Block sizes must be positive
1757
        :info = 2: Block sizes must sum to n
1758
        :info = 3: Real blocks must be of size 1
1759
        :info = 4: Block types must be 1 or 2
1760
        :info = 5: Error in linear equation solution
1761
        :info = 6: Error in eigenvalue or singular value computation
1762

1763
    Notes
1764
    -----
1765
    This wraps SLICOT routine AB13MD, which implements the upper bound
1766
    of [1].
1767

1768
    References
1769
    ----------
1770
    .. [1] Fan, M.K.H., Tits, A.L., and Doyle, J.C., "Robustness in
1771
       the presence of mixed parametric uncertainty and unmodeled
1772
       dynamics," IEEE Trans. Automatic Control, vol. AC-36, 1991,
1773
       pp. 25-38.
1774

1775
    """
1776
    hidden = ' (hidden by the wrapper)'
32✔
1777

1778
    arg_list = ['fact', 'n' + hidden, 'z', 'ldz' + hidden, 'm' + hidden,
32✔
1779
                'nblock', 'itype', 'x', 'bound', 'd', 'g',
1780
                'iwork' + hidden, 'dwork' + hidden, 'ldwork' + hidden,
1781
                'zwork' + hidden, 'lzwork' + hidden, 'info']
1782

1783
    # prepare the "x" input and output
1784

1785
    # x, in SLICOT, needs to be length m+mr-1. m is the length of
1786
    # nblock (and itype), and mr is the number of real blocks.
1787

1788
    # In analysis.pyf x is specified as length 2*m-1, since I couldn't
1789
    # figure out how to express the m+mr-1 constraint there.
1790

1791
    # The code here is to arrange for the user-visible part of x,
1792
    # which is length m+mr-1, to be packed into the 2*m-1-length array
1793
    # to pass the SLICOT routine.
1794

1795
    m = len(nblock)
32✔
1796
    mr = np.count_nonzero(1==itype)
32✔
1797

1798
    if x is None:
32✔
1799
        fact='N'
32✔
1800
        x = np.empty(2*m-1)
32✔
1801
    else:
1802
        fact='F'
32✔
1803
        if len(x) != m+mr-1:
32✔
1804
            raise ValueError(f'Require len(x)==m+mr-1, but'
32✔
1805
                             + f' len(x)={len(x)}, m={m}, mr={mr}')
1806
        x = np.concatenate([x,np.zeros(2*m-1-len(x))])
32✔
1807

1808
    x, bound, d, g, info = _wrapper.ab13md(fact, Z, nblock, itype, x)
32✔
1809

1810
    raise_if_slycot_error(info, arg_list, ab13md.__doc__)
32✔
1811

1812
    return bound, d, g, x[:m+mr-1]
32✔
1813

1814

1815
def ag08bd(l,n,m,p,A,E,B,C,D,equil='N',tol=0.0,ldwork=None):
32✔
1816
    """ Af,Ef,nrank,niz,infz,kronr,infe,kronl = ag08bd(l,n,m,p,A,E,B,C,D,[equil,tol,ldwork])
1817

1818
    To extract from the system pencil
1819

1820
                        ( A-lambda*E B )
1821
            S(lambda) = (              )
1822
                        (      C     D )
1823

1824
    a regular pencil Af-lambda*Ef which has the finite Smith zeros of
1825
    S(lambda) as generalized eigenvalues. The routine also computes
1826
    the orders of the infinite Smith zeros and determines the singular
1827
    and infinite Kronecker structure of system pencil, i.e., the right
1828
    and left Kronecker indices, and the multiplicities of infinite
1829
    eigenvalues.
1830

1831
    Required arguments:
1832
        l : input int
1833
            The number of rows of matrices A, B, and E.  l >= 0.
1834
        n : input int
1835
            The number of columns of matrices A, E, and C.  n >= 0.
1836
        m : input int
1837
            The number of columns of matrix B.  m >= 0.
1838
        p : input int
1839
            The number of rows of matrix C.  p >= 0.
1840
        A : rank-2 array('d') with bounds (l,n)
1841
            The leading l-by-n part of this array must
1842
            contain the state dynamics matrix A of the system.
1843
        E : rank-2 array('d') with bounds (l,n)
1844
            The leading l-by-n part of this array must
1845
            contain the descriptor matrix E of the system.
1846
        B : rank-2 array('d') with bounds (l,m)
1847
            The leading l-by-m part of this array must
1848
            contain the input/state matrix B of the system.
1849
        C : rank-2 array('d') with bounds (p,n)
1850
            The leading p-by-n part of this array must
1851
            contain the state/output matrix C of the system.
1852
        D : rank-2 array('d') with bounds (p,m)
1853
            The leading p-by-m part of this array must contain the
1854
            direct transmission matrix D of the system.
1855
    Optional arguments:
1856
        equil := 'N' input string(len=1)
1857
            Specifies whether the user wishes to balance the system
1858
            matrix as follows:
1859
            = 'S':  Perform balancing (scaling);
1860
            = 'N':  Do not perform balancing.
1861
        tol := 0 input float
1862
            A tolerance used in rank decisions to determine the
1863
            effective rank, which is defined as the order of the
1864
            largest leading (or trailing) triangular submatrix in the
1865
            QR (or RQ) factorization with column (or row) pivoting
1866
            whose estimated condition number is less than 1/TOL.
1867
            If the user sets TOL <= 0, then default tolerances are
1868
            used instead, as follows: TOLDEF = L*N*EPS in TG01FD
1869
            (to determine the rank of E) and TOLDEF = (L+P)*(N+M)*EPS
1870
            in the rest, where EPS is the machine precision
1871
            (see LAPACK Library routine DLAMCH).  TOL < 1.
1872
        ldwork : input int
1873
            The length of the cache array.
1874
            ldwork >= max( 4*(l,n), ldw ), if equil = 'S',
1875
            ldwork >= ldw,                 if equil = 'N', where
1876
            ldw = max(l+p,m+n)*(m+n) + max(1,5*max(l+p,m+n)).
1877
            For optimum performance ldwork should be larger.
1878
    Return objects:
1879
        Af : rank-2 array('d')
1880
            the leading NFZ-by-NFZ part of this array
1881
            contains the matrix Af of the reduced pencil.
1882
        Ef : rank-2 array('d')
1883
            the leading NFZ-by-NFZ part of this array
1884
            contains the matrix Ef of the reduced pencil.
1885
        nrank : output int
1886
            The normal rank of the system pencil.
1887
        niz : output int
1888
            The number of infinite zeros.
1889
        infz : rank-1 array('i')
1890
            The leading DINFZ elements of infz contain information
1891
            on the infinite elementary divisors as follows:
1892
            the system has infz(i) infinite elementary divisors of
1893
            degree i in the Smith form, where i = 1,2,...,DINFZ.
1894
        kronr : rank-1 array('i')
1895
            The leading NKROR elements of this array contain the
1896
            right Kronecker (column) indices.
1897
        infe : rank-1 array('i')
1898
            The leading NINFE elements of infe contain the
1899
            multiplicities of infinite eigenvalues.
1900
    """
1901
    hidden = ' (hidden by the wrapper)'
32✔
1902
    arg_list = ['equil', 'l', 'n', 'm', 'p',
32✔
1903
                'A', 'lda' + hidden, 'E', 'lde' + hidden, 'B', 'ldb' + hidden,
1904
                'C', 'ldc' + hidden, 'D', 'ldd' + hidden,
1905
                'nfz', 'nrank', 'niz', 'dinfz', 'nkror', 'ninfe', 'nkrol',
1906
                'infz', 'kronr', 'infe', 'kronl', 'tol',
1907
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'info']
1908

1909
    if ldwork is None:
32✔
1910
        ldw = max(l+p, m+n)*(m+n) + max(1, 5*max(l+p, m+n))
32✔
1911
        if equil == 'S':
32✔
UNCOV
1912
            ldwork = max(4*(l+n), ldw)
×
1913
        else:  # equil == 'N'
1914
            ldwork = ldw
32✔
1915

1916
    out = _wrapper.ag08bd(equil, l, n, m, p, A, E, B, C, D, tol, ldwork)
32✔
1917
    [Af, Ef, nfz, nrank, niz,
32✔
1918
     dinfz, nkror, ninfe, nkrol, infz, kronr, infe, kronl, info] = out
1919
    raise_if_slycot_error(info, arg_list)
32✔
1920

1921
    return (Af[:nfz, :nfz], Ef[:nfz, :nfz], nrank, niz,
32✔
1922
            infz[:dinfz], kronr[:nkror], infe[:ninfe], kronl[:nkrol])
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc