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

python-control / Slycot / 5954991619

23 Aug 2023 06:16PM UTC coverage: 79.603%. Remained the same
5954991619

Pull #206

github

web-flow
Merge 661b72750 into 8ae9c2543
Pull Request #206: Change analysis.py to numpydoc style

0 of 3 new or added lines in 1 file covered. (0.0%)

57 existing lines in 1 file now uncovered.

761 of 956 relevant lines covered (79.6%)

25.47 hits per line

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

62.98
/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
    Raises
126
    ------
127
    SlycotParameterError
128
        :info = -i: the i-th argument had an illegal value;
129
    """
130

131
    hidden = ' (hidden by the wrapper)'
32✔
132
    arg_list = ['jobz', 'n', 'm', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden,
32✔
133
                'ncont', 'indcon', 'nblk', 'Z', 'LDZ'+hidden, 'tau', 'tol',
134
                'IWORK'+hidden, 'DWORK'+hidden, 'ldwork', 'info'+hidden]
135

136
    if ldwork is None:
32✔
137
        ldwork = max(n, 3*m)
32✔
138

139
    Ac, Bc, ncont, indcon, nblk, Z, tau, info = _wrapper.ab01nd(
32✔
140
        jobz, n, m, A, B, tol=tol, ldwork=ldwork)
141
    raise_if_slycot_error(info, arg_list)
32✔
142

143
    if jobz == "N":
32✔
144
        Z = None
32✔
145
    return Ac, Bc, ncont, indcon, nblk, Z, tau
32✔
146

147

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

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

154
    Required arguments:
155
        n1 : input int
156
            The number of state variables in the first system, i.e. the order
157
            of the matrix A1.  n1 > 0.
158
        m1 : input int
159
            The number of input variables for the first system. m1 > 0.
160
        p1 : input int
161
            The number of output variables from the first system and the number
162
            of input variables for the second system. p1 > 0.
163
        n2 : input int
164
            The number of state variables in the second system, i.e. the order
165
            of the matrix A2.  n2 > 0.
166
        p2 : input int
167
            The number of output variables from the second system. p2 > 0.
168
        A1 : input rank-2 array('d') with bounds (n1,n1)
169
            The leading n1-by-n1 part of this array must contain the state
170
            transition matrix A1 for the first system.
171
        B1 : input rank-2 array('d') with bounds (n1,m1)
172
            The leading n1-by-m1 part of this array must contain the input/state
173
            matrix B1 for the first system.
174
        C1 : input rank-2 array('d') with bounds (p1,n1)
175
            The leading p1-by-n1 part of this array must contain the state/output
176
            matrix C1 for the first system.
177
        D1 : input rank-2 array('d') with bounds (p1,m1)
178
            The leading p1-by-m1 part of this array must contain the input/output
179
            matrix D1 for the first system.
180
        A2 : input rank-2 array('d') with bounds (n2,n2)
181
            The leading n2-by-n2 part of this array must contain the state
182
            transition matrix A2 for the second system.
183
        B2 : input rank-2 array('d') with bounds (n2,p1)
184
            The leading n2-by-p1 part of this array must contain the input/state
185
            matrix B2 for the second system.
186
        C2 : input rank-2 array('d') with bounds (p2,n2)
187
            The leading p2-by-n2 part of this array must contain the state/output
188
            matrix C2 for the second system.
189
        D2 : input rank-2 array('d') with bounds (p2,p1)
190
            The leading p2-by-p1 part of this array must contain the input/output
191
            matrix D2 for the second system.
192
    Optional arguments:
193
        uplo := 'U' input string(len=1)
194
            Indicates whether the user wishes to obtain the matrix A in
195
            the upper or lower block diagonal form, as follows:
196
                = 'U':  Obtain A in the upper block diagonal form;
197
                = 'L':  Obtain A in the lower block diagonal form.
198
    Return objects:
199
        n : int
200
            The number of state variables (n1 + n2) in the resulting system,
201
            i.e. the order of the matrix A, the number of rows of B and
202
            the number of columns of C.
203
        A : rank-2 array('d') with bounds (n1+n2,n1+n2)
204
            The leading N-by-N part of this array contains the state transition
205
            matrix A for the cascaded system.
206
        B : rank-2 array('d') with bounds (n1+n2,m1)
207
            The leading n-by-m1 part of this array contains the input/state
208
            matrix B for the cascaded system.
209
        C : rank-2 array('d') with bounds (p2,n1+n2)
210
            The leading p2-by-n part of this array contains the state/output
211
            matrix C for the cascaded system.
212
        D : rank-2 array('d') with bounds (p2,m1)
213
            The leading p2-by-m1 part of this array contains the input/output
214
            matrix D for the cascaded system.
215

216
    Notes:
217
        The implemented methods rely on accuracy enhancing square-root or
218
        balancing-free square-root techniques.
219
        The algorithms require less than 30N^3  floating point operations.
220
    """
NEW
221
    hidden = ' (hidden by the wrapper)'
×
NEW
222
    arg_list = ['uplo', 'OVER'+hidden, 'n1', 'm1', 'p1', 'n2', 'p2', 'A1',
×
223
        'LDA1'+hidden, 'B1', 'LDB1'+hidden, 'C1', 'LDC1'+hidden, 'D1',
224
        'LDD1'+hidden, 'A2', 'LDA2'+hidden, 'B2', 'LDB2'+hidden, 'C2',
225
        'LDC2'+hidden, 'D2', 'LDD2'+hidden, 'n', 'A', 'LDA'+hidden, 'B',
226
        'LDB'+hidden, 'C', 'LDC'+hidden, 'D', 'LDD'+hidden, 'DWORK'+hidden,
227
        'ldwork', 'info'+hidden ]
UNCOV
228
    out = _wrapper.ab05md(n1,m1,p1,n2,p2,A1,B1,C1,D1,A2,B2,C2,D2,uplo=uplo)
×
229
    raise_if_slycot_error(out[-1], arg_list)
×
230
    return out[:-1]
×
231

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

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

238
    Required arguments:
239
        n1 : input int
240
            The number of state variables in the first system, i.e. the order
241
            of the matrix A1.  n1 > 0.
242
        m1 : input int
243
            The number of input variables for the first system and the number
244
            of output variables from the second system. m1 > 0.
245
        p1 : input int
246
            The number of output variables from the first system and the number
247
            of input variables for the second system. p1 > 0.
248
        n2 : input int
249
            The number of state variables in the second system, i.e. the order
250
            of the matrix A2.  n2 > 0.
251
        A1 : input rank-2 array('d') with bounds (n1,n1)
252
            The leading n1-by-n1 part of this array must contain the state
253
            transition matrix A1 for the first system.
254
        B1 : input rank-2 array('d') with bounds (n1,m1)
255
            The leading n1-by-m1 part of this array must contain the input/state
256
            matrix B1 for the first system.
257
        C1 : input rank-2 array('d') with bounds (p1,n1)
258
            The leading p1-by-n1 part of this array must contain the state/output
259
            matrix C1 for the first system.
260
        D1 : input rank-2 array('d') with bounds (p1,m1)
261
            The leading p1-by-m1 part of this array must contain the input/output
262
            matrix D1 for the first system.
263
        A2 : input rank-2 array('d') with bounds (n2,n2)
264
            The leading n2-by-n2 part of this array must contain the state
265
            transition matrix A2 for the second system.
266
        B2 : input rank-2 array('d') with bounds (n2,p1)
267
            The leading n2-by-p1 part of this array must contain the input/state
268
            matrix B2 for the second system.
269
        C2 : input rank-2 array('d') with bounds (m1,n2)
270
            The leading m1-by-n2 part of this array must contain the state/output
271
            matrix C2 for the second system.
272
        D2 : input rank-2 array('d') with bounds (m1,p1)
273
            The leading m1-by-p1 part of this array must contain the input/output
274
            matrix D2 for the second system.
275
    Optional arguments:
276
        alpha := 1.0 input float
277
            A coefficient multiplying the transfer-function matrix (or the
278
            output equation) of the second system. i.e alpha = +1 corresponds
279
            to positive feedback, and alpha = -1 corresponds to negative
280
            feedback.
281
        ldwork := max(p1*p1,m1*m1,n1*p1) input int
282
            The length of the cache array. ldwork >= max(p1*p1,m1*m1,n1*p1).
283
    Return objects:
284
        n : int
285
            The number of state variables (n1 + n2) in the connected system, i.e.
286
            the order of the matrix A, the number of rows of B and the number of
287
            columns of C.
288
        A : rank-2 array('d') with bounds (n1+n2,n1+n2)
289
            The leading n-by-n part of this array contains the state transition
290
            matrix A for the connected system.
291
        B : rank-2 array('d') with bounds (n1+n2,m1)
292
            The leading n-by-m1 part of this array contains the input/state
293
            matrix B for the connected system.
294
        C : rank-3 array('d') with bounds (p1,n1,n2)
295
            The leading p1-by-n part of this array contains the state/output
296
            matrix C for the connected system.
297
        D : rank-2 array('d') with bounds (p1,m1)
298
            The leading p1-by-m1 part of this array contains the input/output
299
            matrix D for the connected system.
300

301
    Raises
302
    ------
303
    SlycotArithmeticError
304
        :1 <= info <= p1:
305
            the system is not completely controllable. That is, the matrix
306
            ``(I + ALPHA*D1*D2)`` is exactly singular (the element
307
            ``U(i,i)```` of the upper triangular factor of ``LU```
308
            factorization is exactly zero), possibly due to
309
            rounding errors.
310
    """
NEW
311
    hidden = ' (hidden by the wrapper)'
×
UNCOV
312
    arg_list = ['over'+hidden, 'n1', 'm1', 'p1', 'n2', 'alpha', 'A1', 'LDA1'+hidden,
×
313
        'B1', 'LDB1'+hidden, 'C1', 'LDC1'+hidden, 'D1', 'LDD1'+hidden, 'A2',
314
        'LDA2'+hidden, 'B2', 'LDB2'+hidden, 'C2', 'LDC2'+hidden, 'D2',
315
        'LDD2'+hidden, 'n', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden, 'C',
316
        'LDC'+hidden, 'D', 'LDD'+hidden, 'IWORK'+hidden, 'DWORK'+hidden,
317
        'ldwork', 'info'+hidden]
UNCOV
318
    if ldwork is None:
×
UNCOV
319
        ldwork = max(p1*p1,m1*m1,n1*p1)
×
UNCOV
320
    out = _wrapper.ab05nd(n1,m1,p1,n2,alpha,A1,B1,C1,D1,A2,B2,C2,D2,ldwork=ldwork)
×
UNCOV
321
    raise_if_slycot_error(out[-1], arg_list, ab05nd, locals())
×
UNCOV
322
    return out[:-1]
×
323

324
def ab07nd(n,m,A,B,C,D,ldwork=None):
32✔
325
    """ Ai,Bi,Ci,Di,rcond = ab07nd(n,m,A,B,C,D,[ldwork])
326

327
    To compute the inverse (Ai,Bi,Ci,Di) of a given system (A,B,C,D).
328

329
    Parameters
330
    ----------
331
    n : int
332
        The order of the state matrix A.  n >= 0.
333
    m : int
334
        The number of system inputs and outputs.  m >= 0.
335
    A : (n,n) array_like
336
        The leading n-by-n part of this array must contain the state matrix
337
        A of the original system.
338
    B : (n,m) array_like
339
        The leading n-by-m part of this array must contain the input matrix
340
        B of the original system.
341
    C : (m,n) array_like
342
        The leading m-by-n part of this array must contain the output matrix
343
        C of the original system.
344
    D : (m,m) array_like
345
        The leading m-by-m part of this array must contain the feedthrough
346
        matrix D of the original system.
347
    ldwork : int, optional
348
        The length of the cache array. The default value is max(1,4*m),
349
        for better performance should be larger.
350

351
    Returns
352
    -------
353
    Ai : (n,n) ndarray
354
        The leading n-by-n part of this array contains the state matrix Ai
355
        of the inverse system.
356
    Bi : (n,m) ndarray
357
        The leading n-by-m part of this array contains the input matrix Bi
358
        of the inverse system.
359
    Ci : (m,n) ndarray
360
        The leading m-by-n part of this array contains the output matrix Ci
361
        of the inverse system.
362
    Di : (m,m) ndarray
363
        The leading m-by-m part of this array contains the feedthrough
364
        matrix Di of the inverse system.
365
    rcond : float
366
        The estimated reciprocal condition number of the feedthrough matrix
367
        D of the original system.
368

369
    Warns
370
    -----
371
    SlycotResultWarning
372
        :1 <= info <= m:
373
            the matrix `D` is exactly singular; the ({info},{info})
374
            diagonal element is zero, `RCOND` was set to zero;
375
        :info == m+1:
376
            the matrix `D` is numerically singular, i.e., `RCOND`
377
            is less than the relative machine precision, `EPS`
378
            (see LAPACK Library routine DLAMCH). The
379
            calculations have been completed, but the results
380
            could be very inaccurate.
381
    """
UNCOV
382
    hidden = ' (hidden by the wrapper)'
×
UNCOV
383
    arg_list = ['n', 'm', 'A', 'LDA' + hidden, 'B', 'LDB' + hidden,
×
384
                'C', 'LDC' + hidden, 'D', 'LDD' + hidden, 'rcond',
385
                'IWORK' + hidden, 'DWORK' + hidden, 'ldwork', 'INFO' + hidden]
UNCOV
386
    if ldwork is None:
×
UNCOV
387
        ldwork = max(1, 4*m)
×
UNCOV
388
    out = _wrapper.ab07nd(n, m, A, B, C, D, ldwork=ldwork)
×
UNCOV
389
    raise_if_slycot_error(out[-1], arg_list, ab07nd.__doc__, locals())
×
UNCOV
390
    return out[:-1]
×
391

392

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

396
    To construct for a linear multivariable system described by a state-space
397
    model (A,B,C,D) a regular pencil (Af - lambda*Bf ) which has the invariant
398
    zeros of the system as generalized eigenvalues.
399
    The routine also computes the orders of the infinite zeros and the
400
    right and left Kronecker indices of the system (A,B,C,D).
401

402
    Required arguments:
403
        n : input int
404
            The number of state variables.  n >= 0.
405
        m : input int
406
            The number of system inputs.  m >= 0.
407
        p : input int
408
            The number of system outputs.  p >= 0.
409
        A : input rank-2 array('d') with bounds (n,n)
410
            The leading n-by-n part of this array must contain the state
411
            dynamics matrix A of the system.
412
        B : input rank-2 array('d') with bounds (n,m)
413
            The leading n-by-m part of this array must contain the input/state
414
            matrix B of the system.
415
        C : input rank-2 array('d') with bounds (p,n)
416
            The leading p-by-n part of this array must contain the state/output
417
            matrix C of the system.
418
        D : input rank-2 array('d') with bounds (p,m)
419
            The leading p-by-m part of this array must contain the direct
420
            transmission matrix D of the system.
421
    Optional arguments:
422
        equil := 'N' input string(len=1)
423
            Specifies whether the user wishes to balance the compound matrix
424
            as follows:
425
            = 'S':  Perform balancing (scaling);
426
            = 'N':  Do not perform balancing.
427
        tol := 0.0 input float
428
            A tolerance used in rank decisions to determine the effective rank,
429
            which is defined as the order of the largest leading (or trailing)
430
            triangular submatrix in the QR (or RQ) factorization with column
431
            (or row) pivoting whose estimated condition number is less than 1/tol.
432
        ldwork := None input int
433
            The length of the cache array. The default value is n + 3*max(m,p),
434
            for better performance should be larger.
435
    Return objects:
436
        nu : int
437
            The number of (finite) invariant zeros.
438
        rank : int
439
            The normal rank of the transfer function matrix.
440
        dinfz : int
441
            The maximum degree of infinite elementary divisors.
442
        nkror : int
443
            The number of right Kronecker indices.
444
        nkrol : int
445
            The number of left Kronecker indices.
446
        infz : rank-1 array('i') with bounds (n)
447
            The leading dinfz elements of infz contain information on the
448
            infinite elementary divisors as follows: the system has infz(i)
449
            infinite elementary divisors of degree i, where i = 1,2,...,dinfz.
450
        kronr : rank-1 array('i') with bounds (max(n,m)+1)
451
            the leading nkror elements of this array contain the right kronecker
452
            (column) indices.
453
        kronl : rank-1 array('i') with bounds (max(n,p)+1)
454
            the leading nkrol elements of this array contain the left kronecker
455
            (row) indices.
456
        Af : rank-2 array('d') with bounds (max(1,n+m),n+min(p,m))
457
            the leading nu-by-nu part of this array contains the coefficient
458
            matrix Af of the reduced pencil. the remainder of the leading
459
            (n+m)-by-(n+min(p,m)) part is used as internal workspace.
460
        Bf : rank-2 array('d') with bounds (max(1,n+p),n+m)
461
            The leading nu-by-nu part of this array contains the coefficient
462
            matrix Bf of the reduced pencil. the remainder of the leading
463
            (n+p)-by-(n+m) part is used as internal workspace.
464
    """
465
    hidden = ' (hidden by the wrapper)'
32✔
466
    arg_list = ['equil', 'n', 'm', 'p', 'A', 'LDA'+hidden, 'B', 'LDB'+hidden,
32✔
467
        'C', 'LDC'+hidden, 'D', 'LDD'+hidden, 'nu', 'rank', 'dinfz', 'nkror',
468
        'nkrol', 'infz', 'kronr', 'kronl', 'Af', 'LDAF'+hidden, 'Bf',
469
        'LDBF'+hidden, 'tol', 'IWORK'+hidden, 'DWORK'+hidden, 'ldwork',
470
        'INFO'+hidden]
471
    if ldwork is None:
32✔
472
        ldwork = n+3*max(m,p) #only an upper bound
32✔
473
    out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
32✔
474
    raise_if_slycot_error(out[-1], arg_list)
32✔
475
    return out[:-1]
32✔
476

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

480
    To construct for a linear multivariable system described by a state-space
481
    model (A,B,C,D) a regular pencil (Af - lambda*Bf ) which has the invariant
482
    zeros of the system as generalized eigenvalues.
483
    The routine also computes the orders of the infinite zeros and the
484
    right and left Kronecker indices of the system (A,B,C,D).
485

486
    Required arguments:
487
        n : input int
488
            The number of state variables.  n >= 0.
489
        m : input int
490
            The number of system inputs.  m >= 0.
491
        p : input int
492
            The number of system outputs.  p >= 0.
493
        A : input rank-2 array('d') with bounds (n,n)
494
            The leading n-by-n part of this array must contain the state
495
            dynamics matrix A of the system.
496
        B : input rank-2 array('d') with bounds (n,m)
497
            The leading n-by-m part of this array must contain the input/state
498
            matrix B of the system.
499
        C : input rank-2 array('d') with bounds (p,n)
500
            The leading p-by-n part of this array must contain the state/output
501
            matrix C of the system.
502
        D : input rank-2 array('d') with bounds (p,m)
503
            The leading p-by-m part of this array must contain the direct
504
            transmission matrix D of the system.
505
    Optional arguments:
506
        equil := 'N' input string(len=1)
507
            Specifies whether the user wishes to balance the compound matrix
508
            as follows:
509
            = 'S':  Perform balancing (scaling);
510
            = 'N':  Do not perform balancing.
511
        tol := 0.0 input float
512
            A tolerance used in rank decisions to determine the effective rank,
513
            which is defined as the order of the largest leading (or trailing)
514
            triangular submatrix in the QR (or RQ) factorization with column
515
            (or row) pivoting whose estimated condition number is less than 1/tol.
516
            If tol is set to less than SQRT((N+P)*(N+M))*EPS
517
            then the tolerance is taken as SQRT((N+P)*(N+M))*EPS,
518
            where EPS is the machine precision (see LAPACK Library
519
            Routine DLAMCH).
520
        lzwork := None input int
521
            The length of the internal cache array ZWORK. The default value is
522
            calculated to
523
               MAX( 1,
524
                    MIN(P,M) + MAX(3*M-1,N),
525
                    MIN(P,N) + MAX(3*P-1,N+P,N+M),
526
                    MIN(M,N) + MAX(3*M-1,N+M) )
527
            For optimum performance lzwork should be larger.
528
            If lzwork = -1, then a workspace query is assumed;
529
            the routine only calculates the optimal size of the
530
            ZWORK array, and returns this value in lzwork_opt
531
    Return objects:
532
        nu : int
533
            The number of (finite) invariant zeros.
534
        rank : int
535
            The normal rank of the transfer function matrix.
536
        dinfz : int
537
            The maximum degree of infinite elementary divisors.
538
        nkror : int
539
            The number of right Kronecker indices.
540
        nkrol : int
541
            The number of left Kronecker indices.
542
        infz : rank-1 array('i') with bounds (n)
543
            The leading dinfz elements of infz contain information on the
544
            infinite elementary divisors as follows: the system has infz(i)
545
            infinite elementary divisors of degree i, where i = 1,2,...,dinfz.
546
        kronr : rank-1 array('i') with bounds (max(n,m)+1)
547
            the leading nkror elements of this array contain the right kronecker
548
            (column) indices.
549
        kronl : rank-1 array('i') with bounds (max(n,p)+1)
550
            the leading nkrol elements of this array contain the left kronecker
551
            (row) indices.
552
        Af : rank-2 array('d') with bounds (max(1,n+m),n+min(p,m))
553
            the leading nu-by-nu part of this array contains the coefficient
554
            matrix Af of the reduced pencil. the remainder of the leading
555
            (n+m)-by-(n+min(p,m)) part is used as internal workspace.
556
        Bf : rank-2 array('d') with bounds (max(1,n+p),n+m)
557
            The leading nu-by-nu part of this array contains the coefficient
558
            matrix Bf of the reduced pencil. the remainder of the leading
559
            (n+p)-by-(n+m) part is used as internal workspace.
560
        lzwork_opt : int
561
            The optimal value of lzwork.
562
    """
563
    hidden = ' (hidden by the wrapper)'
32✔
564
    arg_list = ['equil', 'n', 'm', 'p',
32✔
565
                'a', 'lda' + hidden, 'b', 'ldb' + hidden,
566
                'c', 'ldc' + hidden, 'd', 'ldd' + hidden,
567
                'nu', 'rank', 'dinfz', 'nkror', 'nkrol', 'infz', 'kronr',
568
                'kronl', 'af', 'ldaf' + hidden, 'bf', 'ldbf' + hidden,
569
                'tol', 'iwork' + hidden, 'dwork' + hidden, 'zwork',
570
                'lzwork', 'info']
571
    if lzwork is None:
32✔
572
        lzwork = max(min(p, m) + max(3*m-1, n),
32✔
573
                     min(p, n) + max(3*p-1, n+p, n+m),
574
                     min(m, n) + max(3*m-1, n+m))
575

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

580
    raise_if_slycot_error(info, arg_list)
32✔
581
    return (nu, rank, dinfz, nkror, nkrol, infz, kronr, kronl, Af, Bf,
32✔
582
            int(zwork[0].real))
583

584

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

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

592
    Required arguments:
593
        dico : {'D', 'C'} input string(len=1)
594
            Indicate whether the system is discrete `D` or continuous `C`
595
        job : {'B', 'N'} input string(len=1)
596
            Balance `B` or not `N`
597
        equil : {'S', 'N'} input string(len=1)
598
            Scale `S` or not `N`
599
        n : input int
600
            The number of state variables.  n >= 0.
601
        m : input int
602
            The number of system inputs.  m >= 0.
603
        p : input int
604
            The number of system outputs.  p >= 0.
605
        A : input rank-2 array('d') with bounds (n,n)
606
            The leading n-by-n part of this array must contain the state
607
            dynamics matrix A of the system.
608
        B : input rank-2 array('d') with bounds (n,m)
609
            The leading n-by-m part of this array must contain the input/state
610
            matrix B of the system.
611
        C : input rank-2 array('d') with bounds (p,n)
612
            The leading p-by-n part of this array must contain the
613
            state/output matrix C of the system.
614

615
    Optional arguments:
616
        nr := None input int
617
            `nr` is the desired order of the resulting reduced order
618
            system.  ``0 <= nr <= n``. Automatically determined by `tol` if
619
            ``nr is None`` and returned. See return object `nr`.
620
        tol := 0 input double precision
621
            If ``nr is None``, `tol`contains the tolerance for determining the
622
            order of the reduced system. For model reduction, th recommended
623
            value is ``tol = c * HNORM(A, B, C)``, where `c` is a constan in the
624
            interval ``[0.00001, 0.001]`` and ``HNORM(A, B, C)`` is the
625
            Hankel-Norm of the given sysstem (computed in ``HSV(1)``). For
626
            computing a minimal realization, the recommended value is
627
            ``tol = n * eps * HNORM(A, B, C)``, where `eps` is the machine
628
            precision (see LAPACK Library Routine `DLAMCH`). This value is
629
            used by default if ``tol <= 0`` on entry. If `nr` is specified,
630
            the value of `tol` is ignored.
631
        ldwork := None input int
632
            The length of the cache array. The default value is
633
            ``n*(2*n+max(n,m,p)+5) + n*(n+1)/2 ~= 3.5*n**2 + 5*n``,
634
            a larger value should lead to better performance.
635

636
    Return objects :
637
        nr : output int
638
            `nr` is the order of the resulting reduced order model.
639
            `nr` is set as follows:
640
            If on input ``nr is not None``, `nr` is equal to ``MIN(nr,NMIN)``,
641
            where `nr` is the desired order on entry and `NMIN` is the order
642
            of a minimal realization of the given system; `NMIN` is
643
            determined as the number of Hankel singular values greater
644
            than ``n*eps*HNORM(A,B,C)``, where `eps` is the machine
645
            precision (see LAPACK Library Routine DLAMCH) and
646
            ``HNORM(A,B,C)`` is the Hankel norm of the system (computed
647
            in ``HSV(1)``);
648
            If on input ``nr is None``, `nr` is equal to the number of Hankel
649
            singular values greater than ``MAX(tol,n*eps*HNORM(A,B,C))``.
650
        Ar : rank-2 array('d') with bounds ``(nr,nr)``
651
            This array contains the state dynamics matrix `Ar` of the reduced
652
            order system.
653
        Br : rank-2 array('d') with bounds ``(nr,m)``
654
            Tthis array contains the input/state matrix `Br` of the reduced
655
            order system.
656
        Cr : rank-2 array('d') with bounds ``(p,nr)``
657
            This array contains the state/output matrix `Cr` of the reduced
658
            order system.
659
        hsv : output double precision array, dimension ``(n)``
660
            If ``INFO = 0``, it contains the Hankel singular values of
661
            the original system ordered decreasingly. ``HSV(1)`` is the
662
            Hankel norm of the system.
663

664
    Raises
665
    ------
666
    SlycotArithmeticError
667
        :info == 1:
668
            The reduction of A to the real Schur form failed
669
        :info == 2 and dico == 'C':
670
            The state matrix A is not stable
671
        :info == 2 and dico == 'D':
672
            The state matrix A is not convergent
673
        :info == 3:
674
            The computation of Hankel singular values failed
675

676
    Warns
677
    -----
678
    SlycotResultWarning
679
        :iwarn == 1:
680
                The selected order {nr} is greater
681
                than the order of a minimal realization of the
682
                given system. `nr` was set automatically to {Nr}
683
                corresponding to the order of a minimal realization
684
                of the system
685
    """
686
    hidden = ' (hidden by the wrapper)'
32✔
687
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr',
32✔
688
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
689
                'hsv', 'tol', 'iwork' + hidden, 'dwork ' + hidden, 'ldwork',
690
                'iwarn', 'info']
691
    if ldwork is None:
32✔
692
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
32✔
693
    if nr is None:
32✔
UNCOV
694
        ordsel = 'A'
×
UNCOV
695
        nr = 0  # order will be computed by the routine
×
696
    else:
697
        ordsel = 'F'
32✔
698
    out = _wrapper.ab09ad(dico, job, equil, ordsel,
32✔
699
                          n, m, p, nr, A, B, C, tol, ldwork)
700
    Nr, A, B, C, hsv = out[:-2]
32✔
701
    raise_if_slycot_error(out[-2:], arg_list, ab09ad.__doc__, locals())
32✔
702
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], hsv
32✔
703

704

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

708
    To compute a reduced order model ``(Ar,Br,Cr)`` for a stable original
709
    state-space representation ``(A,B,C)`` by using either the square-root
710
    or the balancing-free square-root Balance & Truncate model
711
    reduction method. The state dynamics matrix `A` of the original
712
    system is an upper quasi-triangular matrix in *real Schur canonical
713
    form.* The matrices of the reduced order system are computed using
714
    the truncation formulas:
715

716
        ``Ar = TI * A * T ,  Br = TI * B ,  Cr = C * T`` .
717

718
    Required arguments :
719
        dico : {'D', 'C'} input string(len=1)
720
            Indicate whether the system is discrete `D` or continuous `C`
721
        job : {'B', 'N'} input string(len=1)
722
            Balance `B` or not `N`
723
        n : input int
724
            The number of state variables.  n >= 0.
725
        m : input int
726
            The number of system inputs.  m >= 0.
727
        p : input int
728
            The number of system outputs.  p >= 0.
729
        A : input rank-2 array('d') with bounds (n,n)
730
            The leading n-by-n part of this array must contain the state
731
            dynamics matrix A of the system *in real Schur form.*
732
        B : input rank-2 array('d') with bounds (n,m)
733
            The leading n-by-m part of this array must contain the input/state
734
            matrix B of the system.
735
        C : input rank-2 array('d') with bounds (p,n)
736
            The leading p-by-n part of this array must contain the
737
            state/output matrix C of the system.
738

739
    Optional arguments:
740
        nr := None input int
741
            `nr` is the desired order of the resulting reduced order
742
            system.  ``0 <= nr <= n``. Automatically determined by `tol` if
743
            ``nr is None`` and returned. See return object `nr`.
744
        tol := 0 input double precision
745
            If ``nr is None``, `tol`contains the tolerance for determining the
746
            order of the reduced system. For model reduction, the recommended
747
            value is ``tol = c * HNORM(A, B, C)``, where `c` is a constant in
748
            the interval ``[0.00001, 0.001]`` and ``HNORM(A, B, C)`` is
749
            the Hankel-Norm of the given sysstem (computed in ``HSV(1)``). For
750
            computing a minimal realization, the recommended value is
751
            ``tol = n * eps * HNORM(A, B, C)``, where `eps` is the machine
752
            precision (see LAPACK Library Routine `DLAMCH`). This value is
753
            used by default if ``tol <= 0`` on entry. If `nr` is specified,
754
            the value of `tol` is ignored.
755
        ldwork := None input int
756
            The length of the cache array. The default value is
757
            ``n*(2*n+max(n,m,p)+5) + n*(n+1)/2 ~= 3.5*n**2 + 5*n``,
758
            a larger value should lead to better performance.
759

760
    Return objects :
761
        nr : output int
762
            `nr` is the order of the resulting reduced order model.
763
            `nr` is set as follows:
764
            If on input ``nr is not None``, `nr` is equal to ``MIN(nr,NMIN)``,
765
            where `nr` is the desired order on entry and `NMIN` is the order
766
            of a minimal realization of the given system; `NMIN` is
767
            determined as the number of Hankel singular values greater
768
            than ``n*eps*HNORM(A,B,C)``, where `eps` is the machine
769
            precision (see LAPACK Library Routine DLAMCH) and
770
            ``HNORM(A,B,C)`` is the Hankel norm of the system (computed
771
            in ``HSV(1)``);
772
            If on input ``nr is None``, `nr` is equal to the number of Hankel
773
            singular values greater than ``MAX(tol,n*eps*HNORM(A,B,C))``.
774
        Ar : rank-2 array('d') with bounds ``(nr,nr)``
775
            This array contains the state dynamics matrix `Ar` of the reduced
776
            order system.
777
        Br : rank-2 array('d') with bounds ``(nr,m)``
778
            Tthis array contains the input/state matrix `Br` of the reduced
779
            order system.
780
        Cr : rank-2 array('d') with bounds ``(p,nr)``
781
            This array contains the state/output matrix `Cr` of the reduced
782
            order system.
783
        hsv : output double precision array, dimension ``(n)``
784
            If ``INFO = 0``, it contains the Hankel singular values of
785
            the original system ordered decreasingly. ``HSV(1)`` is the
786
            Hankel norm of the system.
787
        T : rank-2 array('d') with bounds ``(n,nr)``
788
            This array contains the right truncation matrix `T` of the reduced
789
            order system.
790
        Ti : rank-2 array('d') with bounds ``(nr,n)``
791
            This array contains the left truncation matrix `Ti` of the reduced
792
            order system.
793

794
    Raises
795
    ------
796
    SlycotArithmeticError
797
        :info == 1 and dico == 'C':
798
            The state matrix A is not stable
799
        :info == 1 and dico == 'D':
800
            The state matrix A is not convergent
801
        :info == 2:
802
            The computation of Hankel singular values failed
803

804
    Warns
805
    -----
806
    SlycotResultWarning
807
        :iwarn == 1:
808
                The selected order {nr} is greater
809
                than the order of a minimal realization of the
810
                given system. `nr` was set automatically to {Nr}
811
                corresponding to the order of a minimal realization
812
                of the system
813
    """
UNCOV
814
    hidden = ' (hidden by the wrapper)'
×
UNCOV
815
    arg_list = ['dico', 'job', 'ordsel', 'n', 'm', 'p', 'nr',
×
816
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
817
                'hsv', 'T', 'ldt' + hidden, 'Ti', 'ldti' + hidden, 'tol',
818
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
819
    if ldwork is None:
×
UNCOV
820
        ldwork = max(1, n*(2*n + max(n, max(m, p))+5)+n*(n+1)/2)
×
UNCOV
821
    if nr is None:
×
UNCOV
822
        ordsel = 'A'
×
UNCOV
823
        nr = 0  # order will be computed by the routine
×
824
    else:
UNCOV
825
        ordsel = 'F'
×
UNCOV
826
    out = _wrapper.ab09ax(dico, job, ordsel, n, m, p, nr, A, B, C, tol, ldwork)
×
UNCOV
827
    Nr, A, B, C, hsv, T, Ti = out[:-2]
×
828
    raise_if_slycot_error(out[-2:], arg_list, ab09ax.__doc__, locals())
×
829
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], hsv, T[:, :Nr], Ti[:Nr, :]
×
830

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

834
    To compute a reduced order model (Ar,Br,Cr,Dr) for a stable
835
    original state-space representation (A,B,C,D) by using either the
836
    square-root or the balancing-free square-root Singular
837
    Perturbation Approximation (SPA) model reduction method.
838
    Must supply either nr or tolerance values.
839

840
    Arguments
841
        Mode Parameters
842
            dico
843
                Specifies the type of the original system as follows:
844
                = 'C':  continuous-time system;
845
                = 'D':  discrete-time system.
846
            job
847
                Specifies the model reduction approach to be used
848
                as follows:
849
                = 'B':  use the square-root SPA method;
850
                = 'N':  use the balancing-free square-root SPA method.
851
            equil
852
                Specifies whether the user wishes to preliminarily
853
                equilibrate the triplet (A,B,C) as follows:
854
                = 'S':  perform equilibration (scaling);
855
                = 'N':  do not perform equilibration.
856

857
        Required arguments
858
            n : input int
859
                The order of the original state-space representation, i.e.
860
                the order of the matrix A.  n >= 0.
861
            m : input int
862
                The number of system inputs.  m >= 0.
863
            p : input int
864
                The number of system outputs.  p >= 0.
865
            A : input rank-2 array('d') with bounds (n,n)
866
                On entry, the leading n-by-n part of this array must
867
                contain the state dynamics matrix A.
868
            B : input rank-2 array('d') with bounds (n,m)
869
                On entry, the leading n-by-m part of this array must
870
                contain the original input/state matrix B.
871
            C : input rank-2 array('d') with bounds (p,n)
872
                On entry, the leading p-by-n part of this array must
873
                contain the original state/output matrix C.
874
            D : input rank-2 array('d') with bounds (p,m)
875
                On entry, the leading p-by-m part of this array must
876
                contain the original input/output matrix D.
877

878
        Optional arguments :
879
            nr :=None input int
880
                nr is the desired order of
881
                the resulting reduced order system.  0 <= nr <= n.
882
            tol1 :=0 input double precision
883
                If ordsel = 'A', tol1 contains the tolerance for
884
                determining the order of reduced system.
885
                For model reduction, the recommended value is
886
                tol1 = c*hnorm(A,B,C), where c is a constant in the
887
                interval [0.00001,0.001], and hnorm(A,B,C) is the
888
                Hankel-norm of the given system (computed in hsv(1)).
889
                For computing a minimal realization, the recommended
890
                value is tol1 = n*eps*hnorm(A,B,C), where eps is the
891
                machine precision (see LAPACK Library Routine DLAMCH).
892
                This value is used by default if tol1 <= 0 on entry.
893
                If ordsel = 'F', the value of tol1 is ignored.
894
            tol2 :=0 input double precision
895
                The tolerance for determining the order of a minimal
896
                realization of the given system. The recommended value is
897
                tol2 = n*eps*hnorm(A,B,C). This value is used by default
898
                if tol2 <= 0 on entry.
899
                If tol2 > 0, then tol2 <= tol1.
900
            ldwork := None input int
901
                The length of the cache array. The default value is n + 3*max(m,p),
902
                for better performance should be larger.
903

904
        Return objects
905
            nr : output int
906
                nr is the order of the resulting reduced order model.
907
                nr is set as follows:
908
                if ordsel = 'F', nr is equal to min(nr,nmin), where nr
909
                is the desired order on entry and nmin is the order of a
910
                minimal realization of the given system; nmin is
911
                determined as the number of Hankel singular values greater
912
                than n*eps*hnorm(A,B,C), where eps is the machine
913
                precision (see LAPACK Library Routine DLAMCH) and
914
                hnorm(A,B,C) is the Hankel norm of the system (computed
915
                in hsv(1));
916
                if ordsel = 'A', nr is equal to the number of Hankel
917
                singular values greater than max(tol1,n*eps*hnorm(A,B,C)).
918
            Ar : rank-2 array('d') with bounds (nr,nr)
919
                the leading nr-by-nr part of this array contains the
920
                state dynamics matrix Ar of the reduced order system.
921
            Br : rank-2 array('d') with bounds (nr,m)
922
                the leading nr-by-m part of this array contains the
923
                input/state matrix Br of the reduced order system.
924
            Cr : rank-2 array('d') with bounds (p,nr)
925
                the leading p-by-nr part of this array contains the
926
                state/output matrix Cr of the reduced order system.
927
            Dr : rank-2 array('d') with bounds (p,m)
928
                the leading p-by-m part of this array contains the
929
                input/output matrix Dr of the reduced order system.
930
            hsv : output double precision array, dimension (n)
931
                If info = 0, it contains the Hankel singular values of
932
                the original system ordered decreasingly. hsv(1) is the
933
                Hankel norm of the system.
934

935
    Raises
936
    ------
937
    SlycotArithmeticError
938
        :info == 1:
939
            The reduction of A to the real Schur form failed
940
        :info == 2 and dico == 'C':
941
            The state matrix A is not stable
942
        :info == 2 and dico == 'D':
943
            The state matrix A is not convergent
944
        :info == 3:
945
            The computation of Hankel singular values failed
946

947
    Warns
948
    -----
949
    SlycotResultWarning
950
        :iwarn == 1:
951
                The selected order {nr} is greater
952
                than the order of a minimal realization of the
953
                given system. `nr` was set automatically to {Nr}
954
                corresponding to the order of a minimal realization
955
                of the system
956
    """
957

UNCOV
958
    hidden = ' (hidden by the wrapper)'
×
UNCOV
959
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr',
×
960
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
961
                'D', 'ldd' + hidden, 'hsv', 'tol1', 'tol2',
962
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
963
    if ldwork is None:
×
UNCOV
964
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
×
UNCOV
965
    if nr is None:
×
UNCOV
966
        ordsel = 'A'
×
UNCOV
967
        nr = 0  # order will be computed by the routine
×
968
    else:
UNCOV
969
        ordsel = 'F'
×
UNCOV
970
    out = _wrapper.ab09bd(dico, job, equil, ordsel,
×
971
                          n, m, p, nr, A, B, C, D, tol1, tol2, ldwork)
972
    Nr, A, B, C, D, hsv = out[:-2]
×
973
    raise_if_slycot_error(out[-2:], arg_list, ab09bd.__doc__, locals())
×
UNCOV
974
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[ :,:Nr], D[:, :], hsv
×
975

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

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

984
    Arguments
985
        Mode Parameters
986
            dico
987
                Specifies the type of the original system as follows:
988
                = 'C':  continuous-time system;
989
                = 'D':  discrete-time system.
990
            job
991
                Specifies the model reduction approach to be used
992
                as follows:
993
                = 'B':  use the square-root Balance & Truncate method;
994
                = 'N':  use the balancing-free square-root
995
                        Balance & Truncate method.
996
            equil
997
                Specifies whether the user wishes to preliminarily
998
                equilibrate the triplet (A,B,C) as follows:
999
                = 'S':  perform equilibration (scaling);
1000
                = 'N':  do not perform equilibration.
1001

1002
        Required arguments
1003
            n : input int
1004
                The order of the original state-space representation, i.e.
1005
                the order of the matrix A.  n >= 0.
1006
            m : input int
1007
                The number of system inputs.  m >= 0.
1008
            p : input int
1009
                The number of system outputs.  p >= 0.
1010
            A : input rank-2 array('d'), dimension (n,n)
1011
                On entry, the leading N-by-N part of this array must
1012
                contain the state dynamics matrix A.
1013
            B : input rank-2 array('d'), dimension (n,m)
1014
                On entry, the leading N-by-M part of this array must
1015
                contain the original input/state matrix B.
1016
            C : input rank-2 array('d'), dimension (p,n)
1017
                On entry, the leading P-by-N part of this array must
1018
                contain the original state/output matrix C.
1019

1020
         Optional arguments
1021
            alpha :=None input double precision
1022
                Specifies the alpha-stability boundary for the eigenvalues
1023
                of the state dynamics matrix A. For a continuous-time
1024
                system (dico = 'C'), alpha <= 0 is the boundary value for
1025
                the real parts of eigenvalues, while for a discrete-time
1026
                system (dico = 'D'), 0 <= alpha <= 1 represents the
1027
                boundary value for the moduli of eigenvalues.
1028
                The alpha-stability domain does not include the boundary.
1029
            nr := None input int
1030
                On entry with ordsel = 'F', nr is the desired order of the
1031
                resulting reduced order system.  0 <= nr <= n.
1032
            tol :=0 input double precision
1033
                If ordsel = 'A', tol contains the tolerance for
1034
                determining the order of reduced system.
1035
                For model reduction, the recommended value is
1036
                tol = c*hnorm(As,Bs,Cs), where c is a constant in the
1037
                interval [0.00001,0.001], and hnorm(As,Bs,Cs) is the
1038
                Hankel-norm of the alpha-stable part of the given system
1039
                (computed in hsv(1)).
1040
                If tol <= 0 on entry, the used default value is
1041
                tol = ns*eps*hnorm(As,Bs,Cs), where ns is the number of
1042
                alpha-stable eigenvalues of A and eps is the machine
1043
                precision (see LAPACK Library Routine DLAMCH).
1044
                This value is appropriate to compute a minimal realization
1045
                of the alpha-stable part.
1046
                If ordsel = 'F', the value of tol is ignored.
1047
            ldwork :=None input int
1048
                The length of the array dwork.
1049
                ldwork >= max(1,n*(2*n+max(n,m,p)+5) + n*(n+1)/2).
1050
                For optimum performance ldwork should be larger.
1051

1052
         Return objects
1053
            nr : output int
1054
                On exit, if info = 0, nr is the order of the resulting
1055
                reduced order model. For a system with nu alpha-unstable
1056
                eigenvalues and ns alpha-stable eigenvalues (nu+ns = n),
1057
                nr is set as follows: if ordsel = 'F', nr is equal to
1058
                nu+min(max(0,nr-nu),nmin), where nr is the desired order
1059
                on entry, and nmin is the order of a minimal realization
1060
                of the alpha-stable part of the given system; nmin is
1061
                determined as the number of Hankel singular values greater
1062
                than ns*eps*hnorm(As,Bs,Cs), where eps is the machine
1063
                precision (see LAPACK Library Routine DLAMCH) and
1064
                hnorm(As,Bs,Cs) is the Hankel norm of the alpha-stable
1065
                part of the given system (computed in hsv(1));
1066
                if ordsel = 'A', nr is the sum of nu and the number of
1067
                Hankel singular values greater than
1068
                max(tol,ns*eps*hnorm(As,Bs,Cs)).
1069
            Ar : rank-2 array('d') with bounds (nr,nr)
1070
                On exit, if info = 0, the leading nr-by-nr part of this
1071
                array contains the state dynamics matrix Ar of the reduced
1072
                order system.
1073
                The resulting A has a block-diagonal form with two blocks.
1074
                For a system with nu alpha-unstable eigenvalues and
1075
                ns alpha-stable eigenvalues (nu+ns = n), the leading
1076
                nu-by-nu block contains the unreduced part of A
1077
                corresponding to alpha-unstable eigenvalues in an
1078
                upper real Schur form.
1079
                The trailing (nr+ns-n)-by-(nr+ns-n) block contains
1080
                the reduced part of A corresponding to alpha-stable
1081
                eigenvalues.
1082
            Br : rank-2 array('d') with bounds (nr,m)
1083
                On exit, if info = 0, the leading nr-by-m part of this
1084
                array contains the input/state matrix Br of the reduced
1085
                order system.
1086
            Cr : rank-2 array('d') with bounds (p,nr)
1087
                On exit, if info = 0, the leading p-by-nr part of this
1088
                array contains the state/output matrix Cr of the reduced
1089
                order system.
1090
            ns : output int
1091
                The dimension of the alpha-stable subsystem.
1092
            hsv : output double precision array, dimension (n)
1093
                If info = 0, the leading ns elements of hsv contain the
1094
                Hankel singular values of the alpha-stable part of the
1095
                original system ordered decreasingly.
1096
                hsv(1) is the Hankel norm of the alpha-stable subsystem.
1097

1098
    Raises
1099
    ------
1100
    SlycotArithmeticError : e
1101
        :info == 1:
1102
            The computation of the ordered real Schur form of A failed
1103
        :info == 2:
1104
            The separation of the {alpha}-stable/unstable diagonal
1105
            blocks failed because of very close eigenvalues
1106
        :info == 3:
1107
            The computation of Hankel singular values failed
1108

1109
    Warns
1110
    -----
1111
    SlycotResultWarning : e
1112
        :iwarn == 1:
1113
            The selected order {nr} is greater
1114
            than `nsmin`, the sum of the order of the
1115
            {alpha}-unstable part and the order of a minimal
1116
            realization of the {alpha}-stable part of the given
1117
            system. The resulting `nr`  is set to `nsmin` = {Nr}
1118
        :iwarn == 2:
1119
            The selected order {nr} is less
1120
            than the order of the {alpha}-unstable part of the
1121
            given system. In this case `nr` is set equal to the
1122
            order of the {alpha}-unstable part {Nr}.
1123
    """
UNCOV
1124
    hidden = ' (hidden by the wrapper)'
×
UNCOV
1125
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr', 'alpha',
×
1126
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1127
                'ns', 'hsv', 'tol',
1128
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
UNCOV
1129
    if ldwork is None:
×
UNCOV
1130
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
×
UNCOV
1131
    if nr is None:
×
UNCOV
1132
        ordsel = 'A'
×
UNCOV
1133
        nr = 0  # order will be computed by the routine
×
1134
    else:
UNCOV
1135
        ordsel = 'F'
×
UNCOV
1136
    if alpha is None:
×
UNCOV
1137
        alpha = {'C': 0, 'D': 1.}[dico]
×
1138
    out = _wrapper.ab09md(dico, job, equil, ordsel,
×
1139
                          n, m, p, nr, alpha, A, B, C, tol, ldwork)
UNCOV
1140
    Nr, A, B, C, Ns, hsv = out[:-2]
×
UNCOV
1141
    raise_if_slycot_error(out[-2:], arg_list, ab09md.__doc__, locals())
×
UNCOV
1142
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], Ns, hsv
×
1143

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

1147
    To compute a reduced order model (Ar,Br,Cr,Dr) for an original
1148
    state-space representation (A,B,C,D) by using either the
1149
    square-root or the balancing-free square-root Singular
1150
    Perturbation Approximation (SPA) model reduction method for the
1151
    alpha-stable part of the system.
1152

1153
    Arguments
1154
        Mode Parameters
1155
            dico
1156
                Specifies the type of the original system as follows:
1157
                = 'C':  continuous-time system;
1158
                = 'D':  discrete-time system.
1159
            job
1160
                Specifies the model reduction approach to be used
1161
                as follows:
1162
                = 'B':  use the square-root SPA method;
1163
                = 'N':  use the balancing-free square-root SPA method.
1164
            equil
1165
                Specifies whether the user wishes to preliminarily
1166
                equilibrate the triplet (A,B,C) as follows:
1167
                = 'S':  perform equilibration (scaling);
1168
                = 'N':  do not perform equilibration.
1169

1170
        Required arguments
1171
            n : input int
1172
                The order of the original state-space representation, i.e.
1173
                the order of the matrix A.  n >= 0.
1174
            m : input int
1175
                The number of system inputs.  m >= 0.
1176
            p : input int
1177
                The number of system outputs.  p >= 0.
1178
            A : input rank-2 array('d') with bounds (n,n)
1179
                On entry, the leading n-by-n part of this array must
1180
                contain the state dynamics matrix A.
1181
            B : input rank-2 array('d') with bounds (n,m)
1182
                On entry, the leading n-by-m part of this array must
1183
                contain the original input/state matrix B.
1184
            C : input rank-2 array('d') with bounds (p,n)
1185
                On entry, the leading p-by-n part of this array must
1186
                contain the original state/output matrix C.
1187
            D : input rank-2 array('d') with bounds (p,m)
1188
                On entry, the leading p-by-m part of this array must
1189
                contain the original input/output matrix D.
1190

1191
        Optional arguments
1192
            alpha :=None input double precision
1193
                Specifies the alpha-stability boundary for the eigenvalues
1194
                of the state dynamics matrix A. For a continuous-time
1195
                system (dico = 'C'), alpha <= 0 is the boundary value for
1196
                the real parts of eigenvalues, while for a discrete-time
1197
                system (dico = 'D'), 0 <= alpha <= 1 represents the
1198
                boundary value for the moduli of eigenvalues.
1199
                The alpha-stability domain does not include the boundary.
1200
            nr :=None input int
1201
                nr is the desired order of
1202
                the resulting reduced order system.  0 <= nr <= n.
1203
            tol1 :=0 input double precision
1204
                If ordsel = 'A', tol1 contains the tolerance for
1205
                determining the order of reduced system.
1206
                For model reduction, the recommended value is
1207
                tol1 = c*hnorm(As,Bs,Cs), where c is a constant in the
1208
                interval [0.00001,0.001], and hnorm(As,Bs,Cs) is the
1209
                Hankel-norm of the alpha-stable part of the given system
1210
                (computed in hsv(1)).
1211
                If tol1 <= 0 on entry, the used default value is
1212
                tol1 = ns*eps*hnorm(As,Bs,Cs), where NS is the number of
1213
                alpha-stable eigenvalues of A and eps is the machine
1214
                precision (see LAPACK Library Routine DLAMCH).
1215
                This value is appropriate to compute a minimal realization
1216
                of the alpha-stable part.
1217
                If ordsel = 'F', the value of tol1 is ignored.
1218
            tol2 :=0 input double precision
1219
                The tolerance for determining the order of a minimal
1220
                realization of the alpha-stable part of the given system.
1221
                The recommended value is tol2 = ns*eps*hnorm(As,Bs,Cs).
1222
                This value is used by default if tol2 <= 0 on entry.
1223
                If tol2 > 0, then tol2 <= tol1.
1224
            ldwork := None input int
1225
                The length of the array dwork.
1226
                ldwork >= max(1,n*(2*n+max(n,m,p)+5) + n*(n+1)/2).
1227
                For optimum performance ldwork should be larger.
1228

1229
        Return objects
1230
            nr : output int
1231
                nr is the order of the resulting reduced order model.
1232
                nr is set as follows:
1233
                if ordsel = 'F', nr is equal to min(nr,nmin), where nr
1234
                is the desired order on entry and nmin is the order of a
1235
                minimal realization of the given system; nmin is
1236
                determined as the number of Hankel singular values greater
1237
                than n*eps*hnorm(A,B,C), where eps is the machine
1238
                precision (see LAPACK Library Routine DLAMCH) and
1239
                hnorm(A,B,C) is the Hankel norm of the system (computed
1240
                in hsv(1));
1241
                if ordsel = 'A', nr is equal to the number of Hankel
1242
                singular values greater than max(TOL1,n*eps*hnorm(A,B,C)).
1243
            Ar : rank-2 array('d') with bounds (nr,nr)
1244
                the leading nr-by-nr part of this array contains the
1245
                state dynamics matrix Ar of the reduced order system.
1246
            Br : rank-2 array('d') with bounds (nr,m)
1247
                the leading nr-by-m part of this array contains the
1248
                input/state matrix Br of the reduced order system.
1249
            Cr : rank-2 array('d') with bounds (p,nr)
1250
                the leading p-by-nr part of this array contains the
1251
                state/output matrix Cr of the reduced order system.
1252
            Dr : rank-2 array('d') with bounds (p,m)
1253
                the leading p-by-m part of this array contains the
1254
                input/output matrix Dr of the reduced order system.
1255
            ns : output int
1256
                The dimension of the alpha-stable subsystem.
1257
            hsv : output double precision array, dimension (n)
1258
                If info = 0, it contains the Hankel singular values of
1259
                the original system ordered decreasingly. hsv(1) is the
1260
                Hankel norm of the system.
1261

1262

1263
    Raises
1264
    ------
1265
    SlycotArithmeticError
1266
        :info == 1:
1267
            The computation of the ordered real Schur form of A failed
1268
        :info == 2:
1269
            The separation of the {alpha}-stable/unstable diagonal
1270
            blocks failed because of very close eigenvalues
1271
        :info == 3:
1272
            The computation of Hankel singular values failed
1273

1274
    Warns
1275
    -----
1276
    SlycotResultWarning
1277
        :iwarn == 1:
1278
            The selected order {nr} is greater
1279
            than `nsmin`, the sum of the order of the
1280
            {alpha}-unstable part and the order of a minimal
1281
            realization of the {alpha}-stable part of the given
1282
            system. The resulting `nr`  is set to `nsmin` = {Nr}
1283
        :iwarn == 2:
1284
            The selected order {nr} is less
1285
            than the order of the {alpha}-unstable part of the
1286
            given system. In this case `nr` is set equal to the
1287
            order of the {alpha}-unstable part {Nr}.
1288
    """
1289
    hidden = ' (hidden by the wrapper)'
32✔
1290
    arg_list = ['dico', 'job', 'equil', 'ordsel', 'n', 'm', 'p', 'nr', 'alpha',
32✔
1291
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1292
                'D', 'ldc' + hidden, 'ns', 'hsv', 'tol1', 'tol2',
1293
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'iwarn', 'info']
1294
    if ldwork is None:
32✔
1295
        ldwork = max(1, n*(2*n+max(n, max(m, p))+5)+n*(n+1)/2)
32✔
1296
    if nr is None:
32✔
UNCOV
1297
        ordsel = 'A'
×
UNCOV
1298
        nr = 0  # order will be computed by the routine
×
1299
    else:
1300
        ordsel = 'F'
32✔
1301
    if alpha is None:
32✔
UNCOV
1302
        alpha = {'C': 0, 'D': 1.}[dico]
×
1303
    out = _wrapper.ab09nd(dico, job, equil, ordsel,
32✔
1304
                          n, m, p, nr, alpha, A, B, C, D, tol1, tol2, ldwork)
1305
    Nr, A, B, C, D, Ns, hsv = out[:-2]
32✔
1306
    raise_if_slycot_error(out[-2:], arg_list, ab09nd.__doc__, locals())
32✔
1307
    return Nr, A[:Nr, :Nr], B[:Nr, :], C[:, :Nr], D, Ns, hsv
32✔
1308

1309

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

1313
    To compute the H2 or L2 norm of the transfer-function matrix G
1314
    of the system (A,B,C,D). G must not have poles on the imaginary
1315
    axis, for a continuous-time system, or on the unit circle, for
1316
    a discrete-time system. If the H2-norm is computed, the system
1317
    must be stable.
1318

1319
    Parameters
1320
    ----------
1321
    dico : {'D', 'C'}
1322
        Indicate whether the system is discrete 'D' or continuous 'C'.
1323
    jobn : {'H', 'L'}
1324
        H2-norm 'H' or L2-norm 'L' to be computed.
1325
    n : int
1326
        The number of state variables.  n >= 0.
1327
    m : int
1328
        The number of system inputs.  m >= 0.
1329
    p : int
1330
        The number of system outputs.  p >= 0.
1331
    A : (n,n) ndarray
1332
        The leading n-by-n part of this array must contain the state
1333
        dynamics matrix A of the system.
1334
    B : (n,m) ndarray
1335
        The leading n-by-m part of this array must contain the input/state
1336
        matrix B of the system.
1337
    C : (p,n) ndarray
1338
        The leading p-by-n part of this array must contain the state/output
1339
        matrix C of the system.
1340
    D : (p,m) ndarray
1341
        The leading p-by-m part of this array must contain the direct
1342
        transmission matrix D of the system.
1343
    tol : float, optional
1344
        The absolute tolerance level below which the elements of
1345
        B are considered zero (used for controllability tests).
1346
        If the user sets tol <= 0, then an implicitly computed,
1347
        default tolerance, defined by  toldef = n*eps*norm(B),
1348
        is used instead, where eps is the machine precision
1349
        (see LAPACK Library routine DLAMCH) and norm(B) denotes
1350
        the 1-norm of B.
1351

1352
    Returns
1353
    -------
1354
    norm:  H2 or L2 norm of the system (A,B,C,D)
1355

1356
    Raises
1357
    ------
1358
    SlycotArithmeticError
1359
        :info == 1:
1360
            The reduction of A to a real Schur form failed
1361
        :info == 2:
1362
            A failure was detected during the reordering of the
1363
            real Schur form of A, or in the iterative process for
1364
            reordering the eigenvalues of `` Z'*(A + B*F)*Z`` along the
1365
            diagonal (see SLICOT routine SB08DD)
1366
        :info == 3 and dico == 'C':
1367
            The matrix A has a controllable eigenvalue on the imaginary axis
1368
        :info == 3 and dico == 'D':
1369
            The matrix A has a controllable eigenvalue on the unit circle
1370
        :info == 4:
1371
            The solution of Lyapunov equation failed because the
1372
            equation is singular
1373
        :info == 5:
1374
            D is a nonzero matrix
1375
        :info == 6:
1376
            The system is unstable
1377

1378
    Warns
1379
    -----
1380
    SlycotResultWarning
1381
        :iwarn > 0:
1382
            {iwarn} violations of the numerical stability condition
1383
            occured during the assignment of eigenvalues in
1384
            computing the right coprime factorization with inner
1385
            denominator of `G` (see the SLICOT subroutine SB08DD).
1386
    """
1387

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

1390
    hidden = ' (hidden by the wrapper)'
32✔
1391
    arg_list = ('dico', 'jobn', 'n', 'm', 'p',
32✔
1392
                'A', 'lda' + hidden, 'B', 'ldb' + hidden, 'C', 'ldc' + hidden,
1393
                'D', 'ldd' + hidden, 'nq' + hidden,'tol', 'dwork' + hidden,
1394
                'ldwork' + hidden, 'iwarn', 'info')
1395
    raise_if_slycot_error(out[-2:], arg_list, ab13bd.__doc__, locals())
32✔
1396
    return out[0]
32✔
1397

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

1401
    To compute the L-infinity norm of a continuous-time or
1402
    discrete-time system, either standard or in the descriptor form,
1403

1404
                                  -1
1405
     G(lambda) = C*( lambda*E - A ) *B + D .
1406

1407
    The norm is finite if and only if the matrix pair (A,E) has no
1408
    eigenvalue on the boundary of the stability domain, i.e., the
1409
    imaginary axis, or the unit circle, respectively. It is assumed
1410
    that the matrix E is nonsingular.
1411

1412
    Required arguments:
1413
        dico : {'D', 'C'} input string(len=1)
1414
               Indicate whether the system is discrete 'D' or continuous 'C'.
1415
        jobe : {'G', 'I'} input string(len=1)
1416
               Specifies whether E is a general square or an identity
1417
               matrix, as follows:
1418
               = 'G':  E is a general square matrix;
1419
               = 'I':  E is the identity matrix.
1420
        equil : {'S', 'N'} input string(len=1)
1421
                Specifies whether the user wishes to preliminarily
1422
                equilibrate the system (A,E,B,C) or (A,B,C), as follows:
1423
                = 'S':  perform equilibration (scaling);
1424
                = 'N':  do not perform equilibration.
1425
        jobd : {'D', 'Z'} input string(len=1)
1426
               Specifies whether or not a non-zero matrix D appears in
1427
               the given state space model:
1428
               = 'D':  D is present;
1429
               = 'Z':  D is assumed a zero matrix.
1430
        n : input int
1431
            The number of state variables.  n >= 0.
1432
        m : input int
1433
            The number of system inputs.  m >= 0.
1434
        p : input int
1435
            The number of system outputs.  p >= 0.
1436
        A : input rank-2 array('d') with bounds (n,n)
1437
            The leading n-by-n part of this array must contain the state
1438
            dynamics matrix A of the system.
1439
        E : input rank-2 array('d') with bounds (n,n)
1440
            If jobe = 'G', the leading N-by-N part of this array must
1441
            contain the descriptor matrix E of the system.
1442
            If jobe = 'I', then E is assumed to be the identity
1443
            matrix and is not referenced.
1444
        B : input rank-2 array('d') with bounds (n,m)
1445
            The leading n-by-m part of this array must contain the input/state
1446
            matrix B of the system.
1447
        C : input rank-2 array('d') with bounds (p,n)
1448
            The leading p-by-n part of this array must contain the state/output
1449
            matrix C of the system.
1450
        D : input rank-2 array('d') with bounds (p,m)
1451
            The leading p-by-m part of this array must contain the direct
1452
            transmission matrix D of the system.
1453

1454
    Optional arguments:
1455
        tol : Tolerance used to set the accuracy in determining the
1456
              norm.  0 <= tol < 1.
1457

1458
    Return objects:
1459
        gpeak : float
1460
                The L-infinity norm of the system, i.e., the peak gain
1461
                of the frequency response (as measured by the largest
1462
                singular value in the MIMO case).
1463
        fpeak : float
1464
                The frequency where the gain of the frequency response
1465
                achieves its peak value gpeak, i.e.,
1466

1467
                  || G ( j*fpeak ) || = gpeak ,  if dico = 'C', or
1468

1469
                          j*fpeak
1470
                  || G ( e       ) || = gpeak ,  if dico = 'D'.
1471

1472
    Raises
1473
    ------
1474
    SlycotArithmeticError
1475
        :info = 1:
1476
            The matrix E is (numerically) singular
1477
        :info = 2:
1478
            The (periodic) QR (or QZ) algorithm for computing
1479
            eigenvalues did not converge
1480
        :info = 3:
1481
            The SVD algorithm for computing singular values did
1482
            not converge
1483
        :info = 4:
1484
            The tolerance is too small and the algorithm did not converge
1485
    """
1486
    hidden = ' (hidden by the wrapper)'
32✔
1487
    arg_list = ('dico', 'jobe', 'equil', 'jobd', 'n', 'm', 'p',
32✔
1488
                'fpeak' + hidden,
1489
                'A', 'lda' + hidden, 'E', 'lde' + hidden, 'B', 'ldb' + hidden,
1490
                'C', 'ldc' + hidden, 'D', 'ldd' + hidden,
1491
                'gpeak' + hidden, 'tol', 'iwork' + hidden, 'dwork' + hidden,
1492
                'ldwork' + hidden, 'cwork' + hidden, 'lcwork' + hidden,
1493
                'info' + hidden)
1494
    if dico != 'C' and dico != 'D':
32✔
UNCOV
1495
        raise SlycotParameterError('dico must be "C" or "D"', -1)
×
1496
    if jobe != 'G' and jobe != 'I':
32✔
UNCOV
1497
        raise SlycotParameterError('jobe must be "G" or "I"', -2)
×
1498
    if equil != 'S' and equil != 'N':
32✔
UNCOV
1499
        raise SlycotParameterError('equil must be "S" or "N"', -3)
×
1500
    if jobd != 'D' and jobd != 'Z':
32✔
UNCOV
1501
        raise SlycotParameterError('jobd must be "D" or "Z"', -4)
×
1502
    out = _wrapper.ab13dd(dico, jobe, equil, jobd,
32✔
1503
                          n, m, p, [0.0, 1.0], A, E, B, C, D, tol)
1504
    raise_if_slycot_error(out[-1], arg_list, ab13dd.__doc__)
32✔
1505

1506
    fpeak = out[0][0] if out[0][1] > 0 else float('inf')
32✔
1507
    gpeak = out[1][0] if out[1][1] > 0 else float('inf')
32✔
1508
    return gpeak, fpeak
32✔
1509

1510

1511

1512
def ab13ed(n, A, tol = 9.0):
32✔
1513
    """low, high = ab13ed(n, A, [tol])
1514

1515
    To estimate beta(A), the 2-norm distance from a real matrix A to
1516
    the nearest complex matrix with an eigenvalue on the imaginary
1517
    axis. The estimate is given as
1518

1519
         ``low <= beta(A) <= high,``
1520

1521
    where either
1522

1523
         ``(1 + tol) * low >= high,``
1524

1525
    or
1526

1527
         ``low = 0   and   high = delta,``
1528

1529
    and delta is a small number approximately equal to the square root
1530
    of machine precision times the Frobenius norm (Euclidean norm)
1531
    of A. If A is stable in the sense that all eigenvalues of A lie
1532
    in the open left half complex plane, then beta(A) is the distance
1533
    to the nearest unstable complex matrix, i.e., the complex
1534
    stability radius.
1535

1536
    Parameters
1537
    ----------
1538
    n : int
1539
        The order of the matrix A.  ``n >= 0.``
1540
    A : (n,n) array_like
1541
        The leading n-by-n part of this array must contain the matrix A.
1542
    tol : float optional
1543
        Specifies the accuracy with which low and high approximate
1544
        beta(A). If the user sets tol to be less than sqrt(eps),
1545
        where eps is the machine precision (see LAPACK Library
1546
        Routine DLAMCH), then the tolerance is taken to be
1547
        sqrt(eps).
1548
        The recommended value is tol = 9, which gives an estimate
1549
        of beta(A) correct to within an order of magnitude.
1550

1551
    Returns
1552
    -------
1553
    low : float
1554
          A lower bound for beta(A).
1555
    high : float
1556
           An upper bound for beta(A).
1557

1558
    Raises
1559
    ------
1560
    SlycotArithmeticError
1561
        :info = 1:
1562
            The QR algorithm fails to converge
1563
    """
1564
    hidden = ' (hidden by the wrapper)'
32✔
1565
    arg_list = ['n', 'A', 'lda' + hidden, 'low' + hidden, 'high' + hidden, 'tol',
32✔
1566
                'dwork' + hidden, 'ldwork' + hidden, 'info' + hidden]
1567
    out = _wrapper.ab13ed(n, A, tol)
32✔
1568
    raise_if_slycot_error(out[-1], arg_list, ab13ed.__doc__)
32✔
1569
    return out[:-1]
32✔
1570

1571
def ab13fd(n, A, tol = 0.0):
32✔
1572
    """beta, omega = ab13fd(n, A, [tol])
1573

1574
    To compute beta(A), the 2-norm distance from a real matrix A to
1575
    the nearest complex matrix with an eigenvalue on the imaginary
1576
    axis. If A is stable in the sense that all eigenvalues of A lie
1577
    in the open left half complex plane, then beta(A) is the complex
1578
    stability radius, i.e., the distance to the nearest unstable
1579
    complex matrix. The value of beta(A) is the minimum of the
1580
    smallest singular value of (A - jwI), taken over all real w.
1581
    The value of w corresponding to the minimum is also computed.
1582

1583
    Required arguments:
1584
        n : input int
1585
            The order of the matrix A.  n >= 0.
1586
        A : input rank-2 array('d') with bounds (n,n)
1587
            The leading n-by-n part of this array must contain the matrix A.
1588

1589
    Optional arguments:
1590
        tol : Specifies the accuracy with which beta(A) is to be
1591
              calculated. (See the Numerical Aspects section below.)
1592
              If the user sets tol to be less than eps, where eps is the
1593
              machine precision (see LAPACK Library Routine DLAMCH),
1594
              then the tolerance is taken to be eps.
1595

1596
    Return objects:
1597
        beta : float
1598
               The computed value of beta(A), which actually is an upper
1599
               bound.
1600
        omega : float
1601
                The value of w such that the smallest singular value of
1602
                (A - jwI) equals beta(A).
1603

1604
    Numerical Aspects:
1605
        In the presence of rounding errors, the computed function value
1606
        beta satisfies
1607
              beta(A) <= beta + epsilon,
1608
              beta/(1+tol) - delta <= max(beta(A), sqrt(2*n*eps)*norm(A)),
1609
        where norm(A) is the Frobenius norm of A,
1610
              epsilon = p(n) * eps * norm(A),
1611
        and
1612
              delta   = p(n) * sqrt(eps) * norm(A),
1613
        and p(n) is a low degree polynomial. It is recommended to choose
1614
        tol greater than sqrt(eps). Although rounding errors can cause
1615
        AB13FD to fail for smaller values of tol, nevertheless, it usually
1616
        succeeds. Regardless of success or failure, the first inequality
1617
        holds.
1618

1619
    Raises
1620
    ------
1621
    SlycotArithmeticError
1622
        :info = 2:
1623
            Either the QR or SVD algorithm fails to converge
1624

1625
    Warns
1626
    -----
1627
    SlycotResultWarning
1628
        :info = 1:
1629
            Failed to compute beta(A) within the specified tolerance.
1630
            Nevertheless, the returned value is an upper bound on beta(A);
1631
    """
1632
    hidden = ' (hidden by the wrapper)'
32✔
1633
    arg_list = ['n', 'A', 'lda' + hidden, 'beta' + hidden, 'omega' + hidden, 'tol',
32✔
1634
                'dwork' + hidden, 'ldwork' + hidden, 'cwork' + hidden,
1635
                'lcwork' + hidden, 'info' + hidden]
1636
    out = _wrapper.ab13fd(n, A, tol)
32✔
1637
    raise_if_slycot_error(out[-1], arg_list, ab13fd.__doc__)
32✔
1638
    return out[0], out[1]
32✔
1639

1640

1641
def ab13md(Z, nblock, itype, x=None):
32✔
1642
    """mubound, d, g, xout = ab13md(Z, nblock, itype, [x])
1643

1644
    Find an upper bound for the structured singular value of complex
1645
    matrix Z and given block diagonal structure.
1646

1647
    Parameters
1648
    ----------
1649
    Z : (n,n) complex array
1650
      Matrix to find structured singular value upper bound of
1651

1652
    nblock : (m,) integer array
1653
      The size of the block diagonals of the uncertainty structure;
1654
      i.e., nblock(i)=p means that the ith block is pxp.
1655

1656
    itype : (m,) integer array
1657
      The type of each block diagonal uncertainty defined in nblock.
1658
      itype(i)==1 means that the ith block is real, while itype(i)==2
1659
      means the the ith block is complex.  Real blocks must be 1x1,
1660
      i.e., if itype(i)==1, nblock(i) must be 1.
1661

1662
    x : (q,) real array or None
1663
      If not None, must be the output of a previous call to ab13md.
1664
      The previous call must have been with the same values of n,
1665
      nblock, and itype; and the previous call's Z should be "close"
1666
      to the current call's Z.
1667

1668
      q is determined by the block structure; see SLICOT AB13MD for
1669
      details.
1670

1671
    Returns
1672
    -------
1673
    mubound : non-negative real scalar
1674
      Upper bound on structure singular value for given arguments
1675

1676
    d, g : (n,) real arrays
1677
      Real arrays such that if D=np.diag(g), G=np.diag(G), and ZH = Z.T.conj(), then
1678
        ZH @ D**2 @ Z + 1j * (G@Z - ZH@G) - mu**2 * D**2
1679
      will be negative semi-definite.
1680

1681
    xout : (q,) real array
1682
      For use as ``x`` argument in subsequent call to ``ab13md``.
1683

1684
    For scalar Z and real uncertainty (ntype=1, itype=1), returns 0
1685
    instead of abs(Z).
1686

1687
    Raises
1688
    ------
1689
    SlycotArithmeticError
1690
        :info = 1: Block sizes must be positive
1691
        :info = 2: Block sizes must sum to n
1692
        :info = 3: Real blocks must be of size 1
1693
        :info = 4: Block types must be 1 or 2
1694
        :info = 5: Error in linear equation solution
1695
        :info = 6: Error in eigenvalue or singular value computation
1696

1697
    Notes
1698
    -----
1699
    This wraps SLICOT routine AB13MD, which implements the upper bound
1700
    of [1].
1701

1702
    References
1703
    ----------
1704
    .. [1] Fan, M.K.H., Tits, A.L., and Doyle, J.C., "Robustness in
1705
       the presence of mixed parametric uncertainty and unmodeled
1706
       dynamics," IEEE Trans. Automatic Control, vol. AC-36, 1991,
1707
       pp. 25-38.
1708

1709
    """
1710
    hidden = ' (hidden by the wrapper)'
32✔
1711

1712
    arg_list = ['fact', 'n' + hidden, 'z', 'ldz' + hidden, 'm' + hidden,
32✔
1713
                'nblock', 'itype', 'x', 'bound', 'd', 'g',
1714
                'iwork' + hidden, 'dwork' + hidden, 'ldwork' + hidden,
1715
                'zwork' + hidden, 'lzwork' + hidden, 'info']
1716

1717
    # prepare the "x" input and output
1718

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

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

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

1729
    m = len(nblock)
32✔
1730
    mr = np.count_nonzero(1==itype)
32✔
1731

1732
    if x is None:
32✔
1733
        fact='N'
32✔
1734
        x = np.empty(2*m-1)
32✔
1735
    else:
1736
        fact='F'
32✔
1737
        if len(x) != m+mr-1:
32✔
1738
            raise ValueError(f'Require len(x)==m+mr-1, but'
32✔
1739
                             + f' len(x)={len(x)}, m={m}, mr={mr}')
1740
        x = np.concatenate([x,np.zeros(2*m-1-len(x))])
32✔
1741

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

1744
    raise_if_slycot_error(info, arg_list, ab13md.__doc__)
32✔
1745

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

1748

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

1752
    To extract from the system pencil
1753

1754
                        ( A-lambda*E B )
1755
            S(lambda) = (              )
1756
                        (      C     D )
1757

1758
    a regular pencil Af-lambda*Ef which has the finite Smith zeros of
1759
    S(lambda) as generalized eigenvalues. The routine also computes
1760
    the orders of the infinite Smith zeros and determines the singular
1761
    and infinite Kronecker structure of system pencil, i.e., the right
1762
    and left Kronecker indices, and the multiplicities of infinite
1763
    eigenvalues.
1764

1765
    Required arguments:
1766
        l : input int
1767
            The number of rows of matrices A, B, and E.  l >= 0.
1768
        n : input int
1769
            The number of columns of matrices A, E, and C.  n >= 0.
1770
        m : input int
1771
            The number of columns of matrix B.  m >= 0.
1772
        p : input int
1773
            The number of rows of matrix C.  p >= 0.
1774
        A : rank-2 array('d') with bounds (l,n)
1775
            The leading l-by-n part of this array must
1776
            contain the state dynamics matrix A of the system.
1777
        E : rank-2 array('d') with bounds (l,n)
1778
            The leading l-by-n part of this array must
1779
            contain the descriptor matrix E of the system.
1780
        B : rank-2 array('d') with bounds (l,m)
1781
            The leading l-by-m part of this array must
1782
            contain the input/state matrix B of the system.
1783
        C : rank-2 array('d') with bounds (p,n)
1784
            The leading p-by-n part of this array must
1785
            contain the state/output matrix C of the system.
1786
        D : rank-2 array('d') with bounds (p,m)
1787
            The leading p-by-m part of this array must contain the
1788
            direct transmission matrix D of the system.
1789
    Optional arguments:
1790
        equil := 'N' input string(len=1)
1791
            Specifies whether the user wishes to balance the system
1792
            matrix as follows:
1793
            = 'S':  Perform balancing (scaling);
1794
            = 'N':  Do not perform balancing.
1795
        tol := 0 input float
1796
            A tolerance used in rank decisions to determine the
1797
            effective rank, which is defined as the order of the
1798
            largest leading (or trailing) triangular submatrix in the
1799
            QR (or RQ) factorization with column (or row) pivoting
1800
            whose estimated condition number is less than 1/TOL.
1801
            If the user sets TOL <= 0, then default tolerances are
1802
            used instead, as follows: TOLDEF = L*N*EPS in TG01FD
1803
            (to determine the rank of E) and TOLDEF = (L+P)*(N+M)*EPS
1804
            in the rest, where EPS is the machine precision
1805
            (see LAPACK Library routine DLAMCH).  TOL < 1.
1806
        ldwork : input int
1807
            The length of the cache array.
1808
            ldwork >= max( 4*(l,n), ldw ), if equil = 'S',
1809
            ldwork >= ldw,                 if equil = 'N', where
1810
            ldw = max(l+p,m+n)*(m+n) + max(1,5*max(l+p,m+n)).
1811
            For optimum performance ldwork should be larger.
1812
    Return objects:
1813
        Af : rank-2 array('d')
1814
            the leading NFZ-by-NFZ part of this array
1815
            contains the matrix Af of the reduced pencil.
1816
        Ef : rank-2 array('d')
1817
            the leading NFZ-by-NFZ part of this array
1818
            contains the matrix Ef of the reduced pencil.
1819
        nrank : output int
1820
            The normal rank of the system pencil.
1821
        niz : output int
1822
            The number of infinite zeros.
1823
        infz : rank-1 array('i')
1824
            The leading DINFZ elements of infz contain information
1825
            on the infinite elementary divisors as follows:
1826
            the system has infz(i) infinite elementary divisors of
1827
            degree i in the Smith form, where i = 1,2,...,DINFZ.
1828
        kronr : rank-1 array('i')
1829
            The leading NKROR elements of this array contain the
1830
            right Kronecker (column) indices.
1831
        infe : rank-1 array('i')
1832
            The leading NINFE elements of infe contain the
1833
            multiplicities of infinite eigenvalues.
1834
    """
1835
    hidden = ' (hidden by the wrapper)'
32✔
1836
    arg_list = ['equil', 'l', 'n', 'm', 'p',
32✔
1837
                'A', 'lda' + hidden, 'E', 'lde' + hidden, 'B', 'ldb' + hidden,
1838
                'C', 'ldc' + hidden, 'D', 'ldd' + hidden,
1839
                'nfz', 'nrank', 'niz', 'dinfz', 'nkror', 'ninfe', 'nkrol',
1840
                'infz', 'kronr', 'infe', 'kronl', 'tol',
1841
                'iwork' + hidden, 'dwork' + hidden, 'ldwork', 'info']
1842

1843
    if ldwork is None:
32✔
1844
        ldw = max(l+p, m+n)*(m+n) + max(1, 5*max(l+p, m+n))
32✔
1845
        if equil == 'S':
32✔
UNCOV
1846
            ldwork = max(4*(l+n), ldw)
×
1847
        else:  # equil == 'N'
1848
            ldwork = ldw
32✔
1849

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

1855
    return (Af[:nfz, :nfz], Ef[:nfz, :nfz], nrank, niz,
32✔
1856
            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