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

python-control / Slycot / 6059915458

02 Sep 2023 06:31PM UTC coverage: 80.162%. Remained the same
6059915458

Pull #213

github

web-flow
Merge 9cddda4b0 into 60a5c7119
Pull Request #213: Change transform.py to numpydoc style

8 of 10 new or added lines in 1 file covered. (80.0%)

29 existing lines in 1 file now uncovered.

792 of 988 relevant lines covered (80.16%)

25.65 hits per line

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

71.91
/slycot/transform.py
1
#
2
#       transform.py
3
#
4
#       Copyright 2010-2011 Enrico Avventi <avventi@kth.se>
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
from . import _wrapper
32✔
21
from .exceptions import raise_if_slycot_error, SlycotParameterError
32✔
22

23
import numpy as _np
32✔
24

25
def tb01id(n,m,p,maxred,a,b,c,job='A'):
32✔
26
    """ s_norm,A,B,C,scale = tb01id(n,m,p,maxred,A,B,C,[job])
27

28
    To reduce the 1-norm of a system matrix
29

30
          S =  ( A  B )
31
               ( C  0 )
32

33
    corresponding to the triple (A,B,C), by balancing. This involves
34
    a diagonal similarity transformation inv(D)*A*D applied
35
    iteratively to A to make the rows and columns of
36
                        -1
37
               diag(D,I)  * S * diag(D,I)
38

39
    as close in norm as possible.
40

41
    The balancing can be performed optionally on the following
42
    particular system matrices
43

44
           S = A,    S = ( A  B )    or    S = ( A )
45
                                               ( C )
46
    Parameters
47
    ----------
48
    n : int
49
        The order of the matrix A, the number of rows of matrix B and
50
        the number of columns of matrix C. It represents the dimension of
51
        the state vector.  n > 0.
52
    m : int
53
        The number of columns of matrix B. It represents the dimension of
54
        the input vector.  m > 0.
55
    p : int
56
        The number of rows of matrix C. It represents the dimension of
57
        the output vector.  p > 0.
58
    maxred : float
59
        The maximum allowed reduction in the 1-norm of S  (in an iteration)
60
        if zero rows or columns are encountered.
61
        If maxred > 0.0, maxred must be larger than one (to enable the norm
62
        reduction).
63
        If maxred <= 0.0, then the value 10.0 for maxred is used.
64
    A : (n, n) array_like
65
        The leading n-by-n part of this array must contain the system state
66
        matrix A.
67
    B : (n, m) array_like
68
        The leading n-by-m part of this array must contain the system input
69
        matrix B.
70
    C : (p, n) array_like
71
        The leading p-by-n part of this array must contain the system output
72
        matrix C.
73
    job := {'A', 'B', 'C', 'N'}, optional
74
        Indicates which matrices are involved in balancing, as follows:
75
        = 'A':  All matrices are involved in balancing;
76
        = 'B':  B and A matrices are involved in balancing;
77
        = 'C':  C and A matrices are involved in balancing;
78
        = 'N':  B and C matrices are not involved in balancing.
79
    Returns
80
    -------
81
    s_norm : float
82
        The 1-norm of the given matrix S is non-zero, the ratio between
83
        the 1-norm of the given matrix and the 1-norm of the balanced matrix.
84
    A : (n, n) ndarray
85
        The leading n-by-n part of this array contains the balanced matrix
86
        inv(D)*A*D.
87
    B : (n, m) ndarray
88
        The leading n-by-m part of this array contains the balanced matrix
89
        inv(D)*B.
90
    C : (p ,n) ndarray
91
        The leading p-by-n part of this array contains the balanced matrix C*D.
92
    scale : rank-1 array('d') with bounds (n)
93
        The scaling factors applied to S.  If D(j) is the scaling factor
94
        applied to row and column j, then scale(j) = D(j), for j = 1,...,n.
95

96
    Raises
97
    ------
98
    SlycotParameterError
99
        :info = -i: the i-th argument had an illegal value;
100
    """
101
    hidden = ' (hidden by the wrapper)'
×
UNCOV
102
    arg_list = ['job', 'N', 'M', 'P', 'maxred', 'A', 'LDA'+hidden, 'B',
×
103
        'LDB'+hidden, 'C', 'LDC'+hidden, 'scale', 'INFO'+hidden]
104
    out = _wrapper.tb01id(n,m,p,maxred,a,b,c,job=job)
×
105
    raise_if_slycot_error(out[-1], arg_list)
×
106
    return out[:-1]
×
107

108
def tb01pd(n, m, p, A, B, C, job='M', equil='S', tol=1e-8, ldwork=None):
32✔
109
    """Ar, Br, Cr, nr = tb01pd(n,m,p,A,B,C,[job,equil,tol,ldwork])
110

111
    To find a reduced (controllable, observable, or minimal) state-
112
    space representation (Ar,Br,Cr) for any original state-space
113
    representation (A,B,C). The matrix Ar is in upper block
114
    Hessenberg form.
115

116
    Parameters
117
    ----------
118
    n : int
119
        Order of the State-space representation.
120
    m : int
121
        Number of inputs.
122
    p : int
123
        Number of outputs.
124
    A : (n, n) array_like
125
        State dynamics matrix.
126
    B : (n, max(m,p)) array_like
127
        The leading n-by-m part of this array must contain the original
128
        input/state matrix B; the remainder of the leading n-by-max(m,p)
129
        part is used as internal workspace.
130
    C : (p, n) array_like
131
        The leading p-by-n part of this array must contain the original
132
        state/output matrix C; the remainder of the leading max(1,m,p)-by-n
133
        part is used as internal workspace.
134
    job : {'M', 'C', 'O'}, optional
135
        Indicates whether the user wishes to remove the
136
        uncontrollable and/or unobservable parts as follows:
137
        = 'M':  Remove both the uncontrollable and unobservable
138
                parts to get a minimal state-space representation;
139
        = 'C':  Remove the uncontrollable part only to get a
140
                controllable state-space representation;
141
        = 'O':  Remove the unobservable part only to get an
142
                observable state-space representation.
143
        Default is 'M'.
144
    equil : {'S', 'N'}, optional
145
        Specifies whether the user wishes to preliminarily balance
146
        the triplet (A,B,C) as follows:
147
        = 'S':  Perform balancing (scaling);
148
        = 'N':  Do not perform balancing.
149

150
    Returns
151
    -------
152
    Ar : (nr, nr) ndarray
153
        Contains the upper block Hessenberg state dynamics matrix
154
        Ar of a minimal, controllable, or observable realization
155
        for the original system, depending on the value of JOB,
156
        JOB = 'M', JOB = 'C', or JOB = 'O', respectively.
157
    Br : (nr, m) ndarray
158
        Contains the transformed input/state matrix Br of a
159
        minimal, controllable, or observable realization for the
160
        original system, depending on the value of JOB, JOB = 'M',
161
        JOB = 'C', or JOB = 'O', respectively.  If JOB = 'C', only
162
        the first IWORK(1) rows of B are nonzero.
163
    Cr : (p, nr) ndarray
164
        Contains the transformed state/output matrix Cr of a
165
        minimal, C controllable, or observable realization for the
166
        original C system, depending on the value of JOB, JOB =
167
        'M', C JOB = 'C', or JOB = 'O', respectively.  C If JOB =
168
        'M', or JOB = 'O', only the last IWORK(1) columns C (in
169
        the first NR columns) of C are nonzero.
170
    nr : int
171
        The order of the reduced state-space representation
172
        (Ar,Br,Cr) of a minimal, controllable, or observable
173
        realization for the original system, depending on
174
        JOB = 'M', JOB = 'C', or JOB = 'O'.
175

176
    Raises
177
    ------
178
    SlycotParameterError
179
        :info = -i: the i-th argument had an illegal value
180
    """
181
    hidden = ' (hidden by the wrapper)'
32✔
182
    arg_list = ['job', 'equil', 'n','m','p','A','lda'+hidden,'B','ldb'+hidden,
32✔
183
                'C','ldc'+hidden,'nr','tol','iwork'+hidden,'dwork'+hidden,
184
                'ldwork','info'+hidden]
185
    if ldwork is None:
32✔
186
        ldwork = max(1, n+max(n,3*m,3*p))
32✔
NEW
187
    elif ldwork < max(1, n+max(n,3*m,3*p)):
×
NEW
188
        raise SlycotParameterError("ldwork is too small", -15)
×
189
    out = _wrapper.tb01pd(n=n,m=m,p=p,a=A,b=B,c=C,
32✔
190
                          job=job,equil=equil,tol=tol,ldwork=ldwork)
191

192
    raise_if_slycot_error(out[-1], arg_list)
32✔
193
    return out[:-1]
32✔
194

195
def tb03ad(n,m,p,A,B,C,D,leri,equil='N',tol=0.0,ldwork=None):
32✔
196
    """ A_min,b_min,C_min,nr,index,pcoeff,qcoeff,vcoeff = tb03ad_l(n,m,p,A,B,C,D,leri,[equil,tol,ldwork])
197

198
    To find a relatively prime left or right polynomial matrix representation
199
    with the same transfer matrix as that of a given state-space representation,
200
    i.e. if leri = 'L'
201

202
        inv(P(s))*Q(s) = C*inv(s*I-A)*B + D
203

204
    or, if leri = 'R'
205

206
        Q(s)*inv(P(s)) = C*inv(s*I-A)*B + D.
207

208
    Additionally a minimal realization (A_min,B_min,C_min) of the original
209
    system (A,B,C) is returned.
210

211
    Parameters
212
    ----------
213
    n : int
214
        The order of the state-space representation, i.e. the order of
215
        the original state dynamics matrix A. n > 0.
216
    m : int
217
        The number of system inputs. m > 0.
218
    p : int
219
        The number of system outputs. p > 0.
220
    A : (n, n) array_like
221
        The leading n-by-n part of this array must contain the original
222
        state dynamics matrix A.
223
    B : (n, max(m,p)) array_like
224
        The leading n-by-m part of this array must contain the original
225
        input/state matrix B; the remainder of the leading n-by-max(m,p)
226
        part is used as internal workspace.
227
    C : (max(m,p), n)
228
        The leading p-by-n part of this array must contain the original
229
        state/output matrix C; the remainder of the leading max(m,p)-by-n
230
        part is used as internal workspace.
231
    D : (max(m,p), max(m,p)) array_like
232
        The leading p-by-m part of this array must contain the original
233
        direct transmission matrix D; the remainder of the leading
234
        max(m,p)-by-max(m,p) part is used as internal workspace.
235
    leri : {'L', 'R'}
236
        Indicates whether the left polynomial matrix representation or
237
        the right polynomial matrix representation is required.
238
        = 'L':  A left matrix fraction is required;
239
        = 'R':  A right matrix fraction is required.
240
    equil : {'S', 'N'}, optional
241
        Specifies whether the user wishes to balance the triplet (A,B,C),
242
        before computing a minimal state-space representation, as follows:
243
        = 'S':  Perform balancing (scaling);
244
        = 'N':  Do not perform balancing.
245
        Default is `N`.
246
    tol : float, optional
247
        The tolerance to be used in rank determination when transforming
248
        (A, B). If tol <= 0 a default value is used.
249
        Default is `0.0`.
250
    ldwork : int, optional
251
        The length of the cache array.
252
        ldwork >= max( n + max(n, 3*m, 3*p), pm*(pm + 2))
253
        where pm = p, if leri = 'L';
254
                pm = m, if leri = 'R'.
255
        For optimum performance it should be larger.
256
        Default is None.
257

258
    Returns
259
    -------
260
    A_min : (n, n) ndarray
261
        The leading nr-by-nr part of this array contains the upper block
262
        Hessenberg state dynamics matrix A_min of a minimal realization for
263
        the original system.
264
    B_min : (n, max(m,p)) ndarray
265
        The leading nr-by-m part of this array contains the transformed
266
        input/state matrix B_min.
267
    C_min : (max(m,p), n) ndarray
268
        The leading p-by-nr part of this array contains the transformed
269
        state/output matrix C_min.
270
    nr : int
271
        The order of the minimal state-space representation
272
        (A_min,B_min,C_min).
273
    index : (p, ) or (m, ) ndarray
274
        If leri = 'L', index(i), i = 1,2,...,p, contains the maximum degree
275
        of the polynomials in the i-th row of the denominator matrix P(s)
276
        of the left polynomial matrix representation. These elements are
277
        ordered so that index(1) >= index(2) >= ... >= index(p).
278
        If leri = 'R', index(i), i = 1,2,...,m, contains the maximum degree
279
        of the polynomials in the i-th column of the denominator matrix P(s)
280
        of the right polynomial matrix representation. These elements are
281
        ordered so that index(1) >= index(2) >= ... >= index(m).
282
    pcoeff : (p, p, n+1) or (m, m, n+1) ndarray
283
        If leri = 'L' then porm = p, otherwise porm = m.
284
        The leading porm-by-porm-by-kpcoef part of this array contains
285
        the coefficients of the denominator matrix P(s), where
286
        kpcoef = max(index) + 1.
287
        pcoeff(i,j,k) is the coefficient in s**(index(iorj)-k+1) of
288
        polynomial (i,j) of P(s), where k = 1,2,...,kpcoef; if leri = 'L'
289
        then iorj = I, otherwise iorj = J. Thus for leri = 'L',
290
        P(s) = diag(s**index)*(pcoeff(.,.,1)+pcoeff(.,.,2)/s+...).
291
    qcoeff : (p, m, n+1) or (max(m,p), max(m,p), n+1) ndarray
292
        If leri = 'L' then porp = m, otherwise porp = p.
293
        If leri = 'L', the leading porm-by-porp-by-kpcoef part of this array
294
        contains the coefficients of the numerator matrix Q(s).
295
        If leri = 'R', the leading porp-by-porm-by-kpcoef part of this array
296
        contains the coefficients of the numerator matrix Q(s).
297
        qcoeff(i,j,k) is defined as for pcoeff(i,j,k).
298
    vcoeff : (p, n, n+1) or (m, n, n+1) ndarray
299
        The leading porm-by-nr-by-kpcoef part of this array contains
300
        the coefficients of the intermediate matrix V(s).
301
        vcoeff(i,j,k) is defined as for pcoeff(i,j,k).
302

303
    Raises
304
    ------
305
    SlycotParameterError
306
        :info = -i: the i-th argument had an illegal value;
307
    SlycotArithmeticError
308
        :info == 1:
309
            A singular matrix was encountered during the
310
            computation of V(s);
311
        :info == 2:
312
            A singular matrix was encountered during the
313
            computation of P(s).
314
    """
315
    hidden = ' (hidden by the wrapper)'
32✔
316
    arg_list = ['leri', 'equil', 'n', 'm', 'P', 'A', 'LDA'+hidden, 'B',
32✔
317
        'LDB'+hidden, 'C', 'LDC'+hidden, 'D', 'LDD'+hidden, 'nr', 'index',
318
        'pcoeff', 'LDPCO1'+hidden, 'LDPCO2'+hidden, 'qcoeff', 'LDQCO1'+hidden,
319
        'LDQCO2'+hidden, 'vcoeff', 'LDVCO1'+hidden, 'LDVCO2'+hidden, 'tol',
320
        'IWORK'+hidden, 'DWORK'+hidden, 'ldwork', 'INFO'+hidden]
321
    wfun = {"L": _wrapper.tb03ad_l,
32✔
322
            "R": _wrapper.tb03ad_r}
323
    mp_ = {"L": p, "R": m}
32✔
324
    mp = mp_[leri]
32✔
325
    if leri not in wfun.keys():
32✔
UNCOV
326
        raise SlycotParameterError('leri must be either L or R', -1)
×
327
    if ldwork is None:
32✔
328
        ldwork = max(2*n + 3*max(m, p), mp*(mp+2))
32✔
329
    out = wfun[leri](n, m, p, A, B, C, D, equil=equil, tol=tol, ldwork=ldwork)
32✔
330
    raise_if_slycot_error(out[-1], arg_list)
32✔
331
    return out[:-1]
32✔
332

333

334
def tb04ad(n,m,p,A,B,C,D,tol1=0.0,tol2=0.0,ldwork=None):
32✔
335
    """ Ar,Br,Cr,nr,denom_degs,denom_coeffs,num_coeffs = tb04ad(n,m,p,A,B,C,D,[tol1,tol2,ldwork])
336

337
    Convert a state-space system to a transfer function or matrix of transfer functions.
338
    The transfer function is given as rows over common denominators.
339

340
    Parameters
341
    ----------
342
    n : int
343
        state dimension
344
    m : int
345
        input dimension
346
    p : int
347
        output dimension
348
    A :  (n, n) array_like
349
        state dynamics matrix.
350
    B : (n, m) array_like
351
        input matrix
352
    C : (p, n) array_like
353
        output matrix
354
    D : (p, m) array_like
355
        direct transmission matrix
356
    tol1 : float, optional
357
        tolerance in determining the transfer function coefficients,
358
        when set to 0, a default value is used
359
        Default is `0.0`.
360
    tol2 : float, optional
361
        tolerance in separating out a controllable/observable subsystem
362
        of (A,B,C), when set to 0, a default value is used
363
        Default is `0.0`.
364
    ldwork : int, optional
365
        The length of the cache array. The default values is
366
        max(1,n*(n+1)+max(n*m+2*n+max(n,p),max(3*m,p)))
367
        Default is None.
368

369
    Returns
370
    -------
371
    nr : int
372
        state dimension of the controllable subsystem
373
    Ar : (nr, nr) ndarray
374
        state dynamics matrix of the controllable subsystem
375
    Br : (nr, m) ndarray
376
        input matrix of the controllable subsystem
377
    Cr : (p, nr) ndarray
378
        output matrix of the controllable subsystem
379
    index : (p, ) ndarray
380
        array of orders of the denominator polynomials
381
    dcoeff : (p, max(index)+1) ndarray
382
        array of denominator coefficients
383
    ucoeff : (p, m, max(index)+1) ndarray
384
        array of numerator coefficients
385

386
    Raises
387
    ------
388
    SlycotParameterError
389
        :info = -i: the i-th argument had an illegal value
390
    """
391
    hidden = ' (hidden by the wrapper)'
32✔
392
    arg_list = ['rowcol','n','m','p','A','lda'+hidden,'B','ldb'+hidden,'C','ldc'+hidden,'D', 'ldd'+hidden,
32✔
393
        'nr','index','dcoeff','lddcoe'+hidden, 'ucoeff','lduco1'+hidden,'lduco2'+hidden,'tol1','tol2','iwork'+hidden,'dwork'+hidden,'ldwork','info'+hidden]
394

395
    mp, pm = m, p
32✔
396
    porm, porp = p, m
32✔
397
    if ldwork is None:
32✔
398
        ldwork = max(1,n*(n+1)+max(n*mp+2*n+max(n,mp),3*mp,pm))
32✔
399
    if B.shape != (n, m):
32✔
UNCOV
400
        raise SlycotParameterError("The shape of B is ({}, {}), "
×
401
                                   "but expected ({}, {})"
402
                                   "".format(*(B.shape + (n, m))),
403
                                   -7)
404
    if C.shape != (p, n):
32✔
UNCOV
405
        raise SlycotParameterError("The shape of C is ({}, {}), "
×
406
                                   "but expected ({}, {})"
407
                                   "".format(*(C.shape + (p, n))),
408
                                   -9)
409
    if D.shape != (max(1, p), m):
32✔
UNCOV
410
        raise SlycotParameterError("The shape of D is ({}, {}), "
×
411
                                   "but expected ({}, {})"
412
                                   "".format(*(D.shape + (max(1, p), m))),
413
                                   -11)
414
    out = _wrapper.tb04ad_r(n,m,p,A,B,C,D,tol1,tol2,ldwork)
32✔
415

416
    raise_if_slycot_error(out[-1], arg_list)
32✔
417

418
    A,B,C,Nr,index,dcoeff,ucoeff = out[:-1]
32✔
419
    kdcoef = max(index)+1
32✔
420
    return A[:Nr,:Nr],B[:Nr,:m],C[:p,:Nr],Nr,index,dcoeff[:porm,:kdcoef],ucoeff[:porm,:porp,:kdcoef]
32✔
421

422

423
def tb05ad(n, m, p, jomega, A, B, C, job='NG'):
32✔
424
    """tb05ad(n, m, p, jomega, A, B, C, job='NG')
425

426
    To find the complex frequency response matrix (transfer matrix)
427
    G(freq) of the state-space representation (A,B,C) given by
428

429
    ::
430

431
                                  -1
432
       G(freq) = C * ((freq*I - A)  ) * B
433

434
    where A, B and C are real N-by-N, N-by-M and P-by-N matrices
435
    respectively and freq is a complex scalar.
436

437
    Parameters
438
    ----------
439
    n : int
440
        The number of states, i.e. the order of the state
441
        transition matrix A.
442
    m : int
443
        The number of inputs, i.e. the number of columns in the
444
        matrix B.
445
    p : int
446
        The number of outputs, i.e. the number of rows in the
447
        matrix C.
448
    jomega : complex float
449
        The frequency at which the frequency response matrix
450
        (transfer matrix) is to be evaluated. For continuous time
451
        systems, this is j*omega, where omega is the frequency to
452
        be evaluated. For discrete time systems,
453
        freq = exp(j*omega*Ts)
454
    A : (n, n) ndarray
455
        On entry, this array must contain the state transition
456
        matrix A.
457
    B : (n, m) ndarray
458
        On entry, this array must contain the input/state matrix B.
459
    C : (p, n) ndarray
460
        On entry, of this array must contain the state/output matrix C.
461
    job : {'AG', 'NG', 'NH'}, optional
462
        If job = 'AG' (i.e., 'all', 'general matrix'), the A matrix is
463
        first balanced. The balancing transformation
464
        is then appropriately applied to matrices B and C. The A matrix
465
        is (again) transformed to an upper Hessenberg representation and
466
        the B and C matrices are also transformed. In addition,
467
        the condition number of the problem is calculated as well as the
468
        eigenvalues of A.
469

470
        If job='NG' (i.e., 'none', 'general matrix'), no balancing is done.
471
        Neither the condition number nor the eigenvalues are calculated.
472
        The routine still transforms A into upper Hessenberg form. The
473
        matrices B and C are also appropriately transformed.
474

475
        If job = 'NH' (i.e., 'none', 'hessenberg matrix'), the function
476
        assumes the matrices have already been transformed into Hessenberg
477
        form, i.e., by a previous function call tb05ad. If this not the
478
        case, the routine will return a wrong result without warning.
479

480
    Returns
481
    -------
482
    if job = 'AG'
483
    -------------
484
    At : The A matrix which has been both balanced and
485
        transformed to upper Hessenberg form. The balancing
486
        transforms A according to
487
                    A1 =   P^-1 * A * P.
488
        The transformation to upper Hessenberg form then yields
489
                    At = Q^T * (P^-1 * A * P ) * Q.
490
        Note that the lower triangle of At is in general not zero.
491
        Rather, it contains information on the orthogonal matrix Q
492
        used to transform A1 to Hessenberg form. See docs for lappack
493
        DGEHRD():
494
        http://www.netlib.org/lapack/explore-3.1.1-html/dgehrd.f.html
495
        However, it does not apparently contain information on P, the
496
        matrix used in the balancing procedure.
497
    Bt : The matrix B transformed according to
498
                    Bt = Q^T * P^-1 * B.
499
    Ct : The matrix C transformed according to
500
                    Ct = C * P * Q
501
    rcond : RCOND contains an estimate of the reciprocal of the
502
            condition number of matrix H with respect to inversion, where
503
                    H = (j*freq * I - A)
504
    g_jw : complex p-by-m array, which contains the frequency response
505
         matrix G(freq).
506
    ev : Eigenvalues of the matrix A.
507
    hinvb : complex n-by-m array, which  contains the product
508
             -1
509
            H  B.
510

511
    if job = 'NG'
512
    -------------
513
    At : The matrix A transformed to upper Hessenberg form according
514
         to
515
                At = Q^T  * A  * Q.
516
        The lower triangle is not zero. It containts info on the
517
        orthoganal transformation. See docs for linpack DGEHRD()
518
        http://www.netlib.org/lapack/explore-3.1.1-html/dgehrd.f.html
519
    Bt : The matrix B transformed according to
520
                Bt = Q^T * B.
521
    Ct : The matrix C transformed according to
522
                Ct = C * Q
523
    g_jw : complex array with dim p-by-m which contains the frequency
524
         response matrix G(freq).
525
    hinvb : complex array with dimension p-by-m.
526
          This array contains the
527
                   -1
528
          product H  B.
529
    if job = 'NH'
530
    -------------
531
    g_jw : complex p-by-m array which contains the frequency
532
         response matrix G(freq).
533

534
    hinvb : complex p-by-m array which contains the
535
                   -1
536
          product H  B.
537

538
    Raises
539
    ------
540
    SlycotParameterError
541
        :info = -i: the i-th argument had an illegal value
542
    SlycotArithmeticError
543
        :info = 1:
544
            More than {n30} (30*`n`) iterations were required to isolate the
545
            eigenvalues of A. The computations are continued.
546
        :info = 2:
547
            Either `freq`={jomega} is too near to an eigenvalue of A,
548
            or `rcond` is less than the machine precision EPS.
549

550
    Example
551
    -------
552
    >>> A = np.array([[0.0, 1.0],
553
                [-100.0,   -20.1]])
554
    >>> B = np.array([[0.],[100]])
555
    >>> C = np.array([[1., 0.]])
556
    >>> n = np.shape(A)[0]
557
    >>> m = np.shape(B)[1]
558
    >>> p = np.shape(C)[0]
559
    >>> jw_s = [1j*10, 1j*15]
560
    >>> at, bt, ct, g_1, hinvb, info = slycot.tb05ad(n, m, p, jw_s[0],
561
                                                    A, B, C, job='NG')
562
    >>> g_2, hinv2,info = slycot.tb05ad(n, m, p, jw_s[1], at, bt, ct, job='NH')
563

564
    """
565
    hidden = ' (hidden by the wrapper)'
32✔
566
    arg_list = ['baleig'+hidden, 'inita'+hidden, 'n', 'm', 'p', 'freq', 'a',
32✔
567
                'lda'+hidden, 'b', 'ldb'+hidden, 'c', 'ldc'+hidden, 'rcond',
568
                'g', 'ldg'+hidden, 'evre', 'evim', 'hinvb', 'ldhinv'+hidden,
569
                'iwork'+hidden, 'dwork'+hidden, 'ldwork'+hidden,
570
                'zwork'+hidden, 'lzwork'+hidden, 'info'+hidden]
571
    # Fortran function prototype:
572
    # TB05AD(baleig,inita,n,m,p,freq,a,lda,b,ldb,c,ldc,rcond,g,ldg,evre,evim,hinvb,ldhinv,
573
    # iwork,dwork,ldwork,zwork,lzwork,info)
574

575
    # Sanity check on matrix dimensions
576
    if A.shape != (n, n):
32✔
577
        raise SlycotParameterError("The shape of A is ({0:}, {1:}), "
32✔
578
                                   "but expected ({2:}, {2:})"
579
                                   "".format(*(A.shape + (n,))),
580
                                   -7)
581
    if B.shape != (n, m):
32✔
582
        raise SlycotParameterError("The shape of B is ({0:}, {1:}), "
32✔
583
                                   "but expected ({2:}, {3:})"
584
                                   "".format(*(B.shape + (n, m))),
585
                                   -9)
586
    if C.shape != (p, n):
32✔
587
        raise SlycotParameterError("The shape of C is ({0:}, {1:}), "
32✔
588
                                   "but expected ({2:}, {3:})"
589
                                   "".format(*(C.shape + (p, n))),
590
                                   -11)
591

592
    # ----------------------------------------------------
593
    # Checks done, do computation.
594
    n30 = 30*n  # for INFO = 1 error docstring
32✔
595
    if job == 'AG':
32✔
596
        out = _wrapper.tb05ad_ag(n, m, p, jomega, A, B, C)
32✔
597
        At, Bt, Ct, rcond, g_jw, evre, evim, hinvb, info = out
32✔
598
        raise_if_slycot_error(info, arg_list, tb05ad.__doc__, locals())
32✔
599
        ev = _np.zeros(n, 'complex64')
32✔
600
        ev.real = evre
32✔
601
        ev.imag = evim
32✔
602
        return At, Bt, Ct, g_jw, rcond, ev, hinvb, info
32✔
603
    elif job == 'NG':
32✔
604
        # use tb05ad_ng, for 'NONE' , and 'General', because balancing
605
        # (option 'A' for 'ALL') seems to have  a bug.
606
        out = _wrapper.tb05ad_ng(n, m, p, jomega, A, B, C)
32✔
607
        At, Bt, Ct, g_jw, hinvb, info = out
32✔
608
        raise_if_slycot_error(info, arg_list, tb05ad.__doc__, locals())
32✔
609
        return At, Bt, Ct, g_jw, hinvb, info
32✔
610
    elif job == 'NH':
32✔
611
        out = _wrapper.tb05ad_nh(n, m, p, jomega, A, B, C)
32✔
612
        g_i, hinvb, info = out
32✔
613
        raise_if_slycot_error(info, arg_list, tb05ad.__doc__, locals())
32✔
614
        return g_i, hinvb, info
32✔
615
    else:
616
        raise SlycotParameterError("Unrecognized job. Expected job = 'AG' or "
32✔
617
                                   "job='NG' or job = 'NH' but received job={}"
618
                                   "".format(job),
619
                                   -1)  # job is baleig and inita together
620

621

622
def td04ad(rowcol,m,p,index,dcoeff,ucoeff,tol=0.0,ldwork=None):
32✔
623
    """ nr,A,B,C,D = td04ad(rowcol,m,p,index,dcoeff,ucoeff,[tol,ldwork])
624

625
    Convert a transfer function or matrix of transfer functions to
626
    a minimum state space realization.
627

628
    Parameters
629
    ----------
630
    rowcol : {R', 'C'}
631
        indicates whether the transfer matrix T(s) is given
632
        as rows ('R') or colums ('C') over common denominators.
633
    m : int
634
        input dimension
635
    p : int
636
        output dimension
637
    index : (p,) or (m,) array_like
638
        array of orders of the denominator polynomials. Different
639
        shapes corresponding to rowcol=='R' and rowcol=='C'
640
        respectively.
641
    dcoeff : (p,max(index)+1) or (m,max(index)+1) ndarray
642
        array of denominator coefficients. Different shapes
643
        corresponding to rowcol=='R' and rowcol=='C' respectively.
644
    ucoeff : (p,m,max(index)+1) or (max(p,m),max(p,m),max(index)+1) ndarray
645
        array of numerator coefficients. Different shapes
646
        corresponding to rowcol=='R' and rowcol=='C' respectively.
647
    tol : float, optional
648
        tolerance in determining the state space system,
649
        when set to 0, a default value is used.
650
    ldwork : int, optional
651
        The length of the cache array. The default values is
652
        max(1,sum(index)+max(sum(index),max(3*m,3*p)))
653

654
    Returns
655
    -------
656
    nr : int
657
        minimal state dimension
658
    A : (nr,nr) ndarray
659
        state dynamics matrix.
660
    B : (nr,m) ndarray
661
        input matrix
662
    C : (p,nr) ndarray
663
        output matrix
664
    D : (p,m) ndarray
665
        direct transmission matrix
666

667
    Raises
668
    ------
669
    SlycotParameterError
670
        :info = -i: the i-th argument had an illegal value;
671
    SlycotArithmeticError
672
        :info > 0:
673
            i={info} is the first index of `dcoeff` for which
674
            ``abs( dcoeff(i,1) )`` is so small that the calculations
675
            would overflow (see SLICOT Library routine TD03AY);
676
            that is, the leading coefficient of a polynomial is
677
            nearly zero;
678
    """
679
    hidden = ' (hidden by the wrapper)'
32✔
680
    arg_list = ['rowcol','m','p','index','dcoeff','lddcoe'+hidden, 'ucoeff', 'lduco1'+hidden,'lduco2'+hidden,
32✔
681
        'nr','A','lda'+hidden,'B','ldb'+hidden,'C','ldc'+hidden,'D', 'ldd'+hidden,
682
        'tol','iwork'+hidden,'dwork'+hidden,'ldwork','info'+hidden]
683
    if ldwork is None:
32✔
684
        n = sum(index)
32✔
685
        ldwork = max(1,n+max(n,max(3*m,3*p)))
32✔
686

687
    kdcoef = max(index)+1
32✔
688
    if rowcol == 'R':
32✔
689
        if ucoeff.ndim != 3:
32✔
UNCOV
690
            raise SlycotParameterError("The numerator is not a 3D array!", -7)
×
691
        expectedshape = (max(1, p), max(1, m), kdcoef)
32✔
692
        if ucoeff.shape != expectedshape:
32✔
UNCOV
693
            raise SlycotParameterError("The numerator shape is ({}, {}, {}), "
×
694
                                       "but expected ({}, {}, {})".format(
695
                                           *(ucoeff.shape + expectedshape)),
696
                                       -7)
697
        expectedshape = (max(1, p), kdcoef)
32✔
698
        if dcoeff.shape != expectedshape:
32✔
UNCOV
699
            raise SlycotParameterError("The denominator shape is ({}, {}), "
×
700
                                       "but expected ({}, {})".format(
701
                                           *(dcoeff.shape + expectedshape)),
702
                                       -5)
703
        out = _wrapper.td04ad_r(m,p,index,dcoeff,ucoeff,n,tol,ldwork)
32✔
704
    elif rowcol == 'C':
32✔
705
        if ucoeff.ndim != 3:
32✔
UNCOV
706
            raise SlycotParameterError("The numerator is not a 3D array!", -7)
×
707
        expectedshape = (max(1, m, p), max(1, m, p), kdcoef)
32✔
708
        if ucoeff.shape != expectedshape:
32✔
UNCOV
709
            raise SlycotParameterError("The numerator shape is ({}, {}, {}), "
×
710
                                       "but expected ({}, {}, {})".format(
711
                                           *(ucoeff.shape + expectedshape)),
712
                                       -7)
713
        expectedshape = (max(1, m), kdcoef)
32✔
714
        if dcoeff.shape != expectedshape:
32✔
UNCOV
715
            raise SlycotParameterError("The denominator shape is ({}, {}), "
×
716
                                       "but expected ({}, {})".format(
717
                                           *(dcoeff.shape + expectedshape)),
718
                                       -5)
719
        out = _wrapper.td04ad_c(m,p,index,dcoeff,ucoeff,n,tol,ldwork)
32✔
720
    else:
UNCOV
721
        raise SlycotParameterError("Parameter rowcol had an illegal value", -1)
×
722

723
    raise_if_slycot_error(out[-1], arg_list, td04ad.__doc__)
32✔
724
    Nr, A, B, C, D = out[:-1]
32✔
725
    return Nr, A[:Nr,:Nr], B[:Nr,:m], C[:p,:Nr], D[:p,:m]
32✔
726

727
def tc04ad(m,p,index,pcoeff,qcoeff,leri,ldwork=None):
32✔
728
    """ n,rcond,a,b,c,d = tc04ad_l(m,p,index,pcoeff,qcoeff,leri,[ldwork])
729

730
    To find a state-space representation (A,B,C,D) with the same
731
    transfer matrix as that of a given left or right polynomial
732
    matrix representation, i.e.
733

734
        C*inv(sI-A)*B + D = inv(P(s))*Q(s)
735

736
    or
737

738
        C*inv(sI-A)*B + D = Q(s)*inv(P(s))
739

740
    respectively.
741

742
    Parameters
743
    ----------
744
    m : int
745
        The number of system inputs. m > 0.
746
    p : int
747
        The number of system outputs. p > 0.
748
        lend(index)
749
    index : (p) or (m) array_like
750
        If leri = 'L', index(i), i = 1,2,...,p, must contain the maximum
751
        degree of the polynomials in the I-th row of the denominator matrix
752
        P(s) of the given left polynomial matrix representation.
753
        If leri = 'R', index(i), i = 1,2,...,m, must contain the maximum
754
        degree of the polynomials in the I-th column of the denominator
755
        matrix P(s) of the given right polynomial matrix representation.
756
    pcoeff : (p,p,*) or (m,m,*) array_like
757
        If leri = 'L' then porm = p, otherwise porm = m. The leading
758
        porm-by-porm-by-kpcoef part of this array must contain
759
        the coefficients of the denominator matrix P(s). pcoeff(i,j,k) is
760
        the coefficient in s**(index(iorj)-K+1) of polynomial (I,J) of P(s),
761
        where k = 1,2,...,kpcoef and kpcoef = max(index) + 1; if leri = 'L'
762
        then iorj = i, otherwise iorj = j. Thus for leri = 'L',
763
        P(s) = diag(s**index)*(pcoeff(.,.,1)+pcoeff(.,.,2)/s+...).
764
        If leri = 'R', pcoeff is modified by the routine but restored on exit.
765
    qcoeff : (p, m, *) or (max(m,p), max(m,p), *) array_like
766
        If leri = 'L' then porp = m, otherwise porp = p. The leading
767
        porm-by-porp-by-kpcoef part of this array must contain
768
        the coefficients of the numerator matrix Q(s).
769
        qcoeff(i,j,k) is defined as for pcoeff(i,j,k).
770
        If leri = 'R', qcoeff is modified by the routine but restored on exit.
771
    leri : {'L', 'R'}
772
        Indicates whether a left polynomial matrix representation or a right
773
        polynomial matrix representation is input as follows:
774
        = 'L':  A left matrix fraction is input;
775
        = 'R':  A right matrix fraction is input.
776
    ldwork : int, optional
777
        The length of the cache array. ldwork >= max(m,p)*(max(m,p)+4)
778
        For optimum performance it should be larger.
779
        Default is None.
780

781
    Returns
782
    -------
783
    n : int
784
        The order of the resulting state-space representation.
785
        That is, n = sum(index).
786
    rcond : float
787
        The estimated reciprocal of the condition number of the leading row
788
        (if leri = 'L') or the leading column (if leri = 'R') coefficient
789
        matrix of P(s).
790
        If rcond is nearly zero, P(s) is nearly row or column non-proper.
791
    A : (n, n) ndarray
792
        The leading n-by-n part of this array contains the state dynamics matrix A.
793
    B : rank-2 array('d') with bounds (n,max(m,p))
794
        The leading n-by-n part of this array contains the input/state matrix B;
795
        the remainder of the leading n-by-max(m,p) part is used as internal
796
        workspace.
797
    C : (max(m,p), n) ndarray
798
        The leading p-by-n part of this array contains the state/output matrix C;
799
        the remainder of the leading max(m,p)-by-n part is used as internal
800
        workspace.
801
    D : (max(m,p), max(m,p)) ndarray
802
        The leading p-by-m part of this array contains the direct transmission
803
        matrix D; the remainder of the leading max(m,p)-by-max(m,p) part is
804
        used as internal workspace.
805
    
806
    Raises
807
    ------
808
    SlycotParameterError
809
        :info = -i: the i-th argument had an illegal value
810
    SlycotArithmeticError
811
        :info == 1 and leri = 'L':
812
            P(s) is not row proper
813
        :info == 1 and leri = 'R':
814
            P(s) is not column proper
815
    """
816
    hidden = ' (hidden by the wrapper)'
32✔
817
    arg_list = ['leri', 'm', 'P', 'index',
32✔
818
                'pcoeff', 'LDPCO1' + hidden, 'LDPCO2' + hidden,
819
                'qcoeff', 'LDQCO1' + hidden, 'LDQCO2' + hidden,
820
                'N', 'rcond',
821
                'A', 'LDA' + hidden, 'B', 'LDB' + hidden,
822
                'C', 'LDC' + hidden, 'D', 'LDD' + hidden,
823
                'IWORK' + hidden, 'DWORK' + hidden, 'ldwork',
824
                'INFO' + hidden]
825
    if ldwork is None:
32✔
826
        ldwork = max(m, p)*(max(m, p)+4)
32✔
827
    n = sum(index)
32✔
828
    wfun = {"L": _wrapper.tc04ad_l, "R": _wrapper.tc04ad_r}
32✔
829
    if leri not in wfun.keys():
32✔
830
        raise SlycotParameterError('leri must be either L or R', -1)
×
831
    out = wfun[leri](m, p, index, pcoeff, qcoeff, n)
32✔
832
    raise_if_slycot_error(out[-1], arg_list, tc04ad.__doc__, locals())
32✔
833
    return out[:-1]
32✔
834

835
def tc01od(m,p,indlin,pcoeff,qcoeff,leri):
32✔
836
    """ pcoeff,qcoeff = tc01od_l(m,p,indlim,pcoeff,qcoeff,leri)
837

838
    To find the dual right (left) polynomial matrix representation of a given
839
    left (right) polynomial matrix representation, where the right and left
840
    polynomial matrix representations are of the form Q(s)*inv(P(s)) and
841
    inv(P(s))*Q(s) respectively.
842

843
    Parameters
844
    ----------
845
    m : int
846
        The number of system inputs. m > 0.
847
    p : int
848
        The number of system outputs. p > 0.
849
    indlim : int
850
        The highest value of k for which pcoeff(.,.,k) and qcoeff(.,.,k)
851
        are to be transposed.
852
        k = kpcoef + 1, where kpcoef is the maximum degree of the polynomials
853
        in P(s).  indlim > 0.
854
    pcoeff : (p, p, indlim) or (m, m, indlim) array_like
855
        If leri = 'L' then porm = p, otherwise porm = m.
856
        On entry, the leading porm-by-porm-by-indlim part of this array
857
        must contain the coefficients of the denominator matrix P(s).
858
        pcoeff(i,j,k) is the coefficient in s**(indlim-k) of polynomial
859
        (i,j) of P(s), where k = 1,2,...,indlim.
860
    qcoeff : (max(m,p), max(m,p), indlim) array_like
861
        On entry, the leading p-by-m-by-indlim part of this array must
862
        contain the coefficients of the numerator matrix Q(s).
863
        qcoeff(i,j,k) is the coefficient in s**(indlim-k) of polynomial
864
        (i,j) of Q(s), where k = 1,2,...,indlim.
865
    leri : {'L', 'R'}
866
        = 'L':  A left matrix fraction is input;
867
        = 'R':  A right matrix fraction is input.
868

869
    Returns
870
    -------
871
    pcoeff : (p, p, indlim) ndarray
872
        On exit, the leading porm-by-porm-by-indlim part of this array
873
        contains the coefficients of the denominator matrix P'(s) of
874
        the dual system.
875
    qcoeff : (max(m,p), max(m,p), indlim) ndarray
876
        On exit, the leading m-by-p-by-indlim part of the array contains
877
        the coefficients of the numerator matrix Q'(s) of the dual system.
878

879
    Raises
880
    ------
881
    SlycotParameterError
882
        :info = -i: the i-th argument had an illegal value
883
    """
UNCOV
884
    hidden = ' (hidden by the wrapper)'
×
UNCOV
885
    arg_list = ['leri', 'M', 'P', 'indlim', 'pcoeff', 'LDPCO1'+hidden,
×
886
        'LDPCO2'+hidden, 'qcoeff', 'LDQCO1'+hidden, 'LDQCO2'+hidden,
887
        'INFO'+hidden]
888
    if leri == 'L':
×
889
        out = _wrapper.tc01od_l(m,p,indlin,pcoeff,qcoeff)
×
890
        raise_if_slycot_error(out[-1], arg_list)
×
891
        return out[:-1]
×
892
    if leri == 'R':
×
893
        out = _wrapper.tc01od_r(m,p,indlin,pcoeff,qcoeff)
×
894
        raise_if_slycot_error(out[-1], arg_list)
×
895
        return out[:-1]
×
896
    raise SlycotParameterError('leri must be either L or R', -1)
×
897

898
def tf01md(n,m,p,N,A,B,C,D,u,x0):
32✔
899
    """ xf,y = tf01md(n,m,p,N,A,B,C,D,u,x0)
900

901
    To compute the output sequence of a linear time-invariant
902
    open-loop system given by its discrete-time state-space model
903

904
    Parameters
905
    ----------
906
    n : int
907
        Order of the State-space representation.
908
    m : int
909
        Number of inputs.
910
    p : int
911
        Number of outputs.
912
    N : int
913
        Number of output samples to be computed.
914
    A : (n, n) array_like
915
        State dynamics matrix.
916
    B : (n, m) array_like
917
        Input/state matrix.
918
    C : (p, n) array_like
919
        State/output matrix.
920
    D : (p, m) array_like
921
        Direct transmission matrix.
922
    u : (m, n)
923
        Input signal.
924
    x0 : (n, ) array_like
925
        Initial state, at time 0.
926
    
927
    Returns
928
    -------
929
    xf : (n) ndarray
930
        Final state, at time n+1.
931
    y : (p, n) ndarray
932
        Output signal.
933

934
    Raises
935
    ------
936
    SlycotParameterError
937
        :info = -i: the i-th argument had an illegal value
938
    """
939
    hidden = ' (hidden by the wrapper)'
×
940
    arg_list = ['n','m','p','ny','A','lda'+hidden,'B','ldb'+hidden,
×
941
        'C','ldc'+hidden,'D','ldd'+hidden,'u','ldu'+hidden,'x0',
942
        'y'+hidden,'ldy'+hidden,'dwork'+hidden,'info'+hidden]
943

944
    out = _wrapper.tf01md(n,m,p,N,A,B,C,D,u,x0)
×
945
    raise_if_slycot_error(out[-1], arg_list)
×
946
    return out[:-1]
×
947

948
def tf01rd(n,m,p,N,A,B,C,ldwork=None):
32✔
949
    """ H = tf01rd(n,m,p,N,A,B,C,[ldwork])
950

951
    To compute N Markov parameters M_1, M_2,..., M_N from the
952
    parameters (A,B,C) of a linear time-invariant system, where each
953
    M_k is an p-by-m matrix and k = 1,2,...,N.
954

955
    All matrices are treated as dense, and hence TF01RD is not
956
    intended for large sparse problems.
957

958
    Parameters
959
    ----------
960
    n : int
961
        Order of the State-space representation.
962
    m : int
963
        Number of inputs.
964
    p : int
965
        Number of outputs.
966
    N : int
967
        Number of Markov parameters to be computed.
968
    A : (n, n) array_like
969
        State dynamics matrix.
970
    B : (n, m) array_like
971
        Input/state matrix.
972
    C : (p, n) array_like
973
        State/output matrix.
974
    ldwork : int, optional
975
        The length of the array DWORK.
976
        ldwork >= max(1, 2*n*p).
977

978
    Returns
979
    -------
980
    H : (p, N*m) ndarray
981
        H[:,(k-1)*m : k*m] contains the k-th Markov parameter,
982
        for k = 1,2...N.
983

984
    Raises
985
    ------
986
    SlycotParameterError
987
        :info = -i: the i-th argument had an illegal value
988
    """
UNCOV
989
    hidden = ' (hidden by the wrapper)'
×
UNCOV
990
    arg_list = ['n','m','p','N','A','lda'+hidden,'B','ldb'+hidden,'C',
×
991
        'ldc'+hidden,'H','ldh'+hidden,'dwork'+hidden,'ldwork','info'+hidden]
992

UNCOV
993
    if ldwork is None:
×
UNCOV
994
        out = _wrapper.tf01rd(n,m,p,N,A,B,C)
×
995
    else:
UNCOV
996
        out = _wrapper.tf01rd(n,m,p,N,A,B,C,ldwork=ldwork)
×
UNCOV
997
    raise_if_slycot_error(out[-1], arg_list)
×
UNCOV
998
    return out[0]
×
999

1000
def tg01ad(l,n,m,p,A,E,B,C,thresh=0.0,job='A'):
32✔
1001
    """ A,E,B,C,lscale,rscale = tg01ad(l,n,m,p,A,E,B,C,[thresh,job])
1002

1003
    To balance the matrices of the system pencil
1004

1005
            S =  ( A  B ) - lambda ( E  0 ) :=  Q - lambda Z,
1006
                 ( C  0 )          ( 0  0 )
1007

1008
    corresponding to the descriptor triple (A-lambda E,B,C),
1009
    by balancing. This involves diagonal similarity transformations
1010
    (Dl*A*Dr - lambda Dl*E*Dr, Dl*B, C*Dr) applied to the system
1011
    (A-lambda E,B,C) to make the rows and columns of system pencil
1012
    matrices
1013

1014
                diag(Dl,I) * S * diag(Dr,I)
1015

1016
    as close in norm as possible. Balancing may reduce the 1-norms
1017
    of the matrices of the system pencil S.
1018

1019
    The balancing can be performed optionally on the following
1020
    particular system pencils
1021

1022
            S = A-lambda E,
1023

1024
            S = ( A-lambda E  B ),    or
1025

1026
            S = ( A-lambda E ).
1027
                (     C      )
1028

1029
    Parameters
1030
    ----------
1031
    l : int
1032
        The number of rows of matrices A, B, and E.  l >= 0.
1033
    n : int
1034
        The number of columns of matrices A, E, and C.  n >= 0.
1035
    m : int
1036
        The number of columns of matrix B.  m >= 0.
1037
    p : int
1038
        The number of rows of matrix C.  P >= 0.
1039
    A : (l, n) array_like
1040
        The leading L-by-N part of this array must
1041
        contain the state dynamics matrix A.
1042
    E : (l, n) array_like
1043
        The leading L-by-N part of this array must
1044
        contain the descriptor matrix E.
1045
    B : (l, m) array_like
1046
        The leading L-by-M part of this array must
1047
        contain the input/state matrix B.
1048
        The array B is not referenced if M = 0.
1049
    C : (p, n) array_like
1050
        The leading P-by-N part of this array must
1051
        contain the state/output matrix C.
1052
        The array C is not referenced if P = 0.
1053
    job : {'A', 'B', 'C', 'N'}, optional
1054
        Indicates which matrices are involved in balancing, as
1055
        follows:
1056
        = 'A':  All matrices are involved in balancing;
1057
        = 'B':  B, A and E matrices are involved in balancing;
1058
        = 'C':  C, A and E matrices are involved in balancing;
1059
        = 'N':  B and C matrices are not involved in balancing.
1060
        Default is 'A'.
1061
    thresh : float, optional
1062
        Threshold value for magnitude of elements:
1063
        elements with magnitude less than or equal to
1064
        THRESH are ignored for balancing. THRESH >= 0.
1065
        Default is `0.0`.
1066
    
1067
    Returns
1068
    -------
1069
    A : (l, n) ndarray
1070
        The leading L-by-N part of this array contains
1071
        the balanced matrix Dl*A*Dr.
1072
    E : (l, n) ndarray
1073
        The leading L-by-N part of this array contains
1074
        the balanced matrix Dl*E*Dr.
1075
    B : (l, m) ndarray
1076
        If M > 0, the leading L-by-M part of this array
1077
        contains the balanced matrix Dl*B.
1078
        The array B is not referenced if M = 0.
1079
    C : (p, n) ndarray
1080
        If P > 0, the leading P-by-N part of this array
1081
        contains the balanced matrix C*Dr.
1082
        The array C is not referenced if P = 0.
1083
    lscale : (l, ) ndarray
1084
        The scaling factors applied to S from left.  If Dl(j) is
1085
        the scaling factor applied to row j, then
1086
        SCALE(j) = Dl(j), for j = 1,...,L.
1087
    rscale : (n, ) ndarray
1088
        The scaling factors applied to S from right.  If Dr(j) is
1089
        the scaling factor applied to column j, then
1090
        SCALE(j) = Dr(j), for j = 1,...,N.
1091

1092
    Raises
1093
    ------
1094
    SlycotParameterError
1095
        :info = -i: the i-th argument had an illegal value
1096
    """
1097

1098
    hidden = ' (hidden by the wrapper)'
32✔
1099
    arg_list = ['job', 'l', 'n', 'm', 'p', 'thresh', 'A', 'lda'+hidden, 'E','lde'+hidden,'B','ldb'+hidden,'C','ldc'+hidden, 'lscale', 'rscale', 'dwork'+hidden, 'info']
32✔
1100

1101
    A,E,B,C,lscale,rscale,info = _wrapper.tg01ad(job,l,n,m,p,thresh,A,E,B,C)
32✔
1102
    raise_if_slycot_error(info, arg_list)
32✔
1103
    return A,E,B,C,lscale,rscale
32✔
1104

1105
def tg01fd(l,n,m,p,A,E,B,C,Q=None,Z=None,compq='N',compz='N',joba='N',tol=0.0,ldwork=None):
32✔
1106
    """ A,E,B,C,ranke,rnka22,Q,Z = tg01fd(l,n,m,p,A,E,B,C,[Q,Z,compq,compz,joba,tol,ldwork])
1107

1108
    To compute for the descriptor system (A-lambda E,B,C)
1109
    the orthogonal transformation matrices Q and Z such that the
1110
    transformed system (Q'*A*Z-lambda Q'*E*Z, Q'*B, C*Z) is
1111
    in a SVD-like coordinate form with
1112

1113
                 ( A11  A12 )             ( Er  0 )
1114
        Q'*A*Z = (          ) ,  Q'*E*Z = (       ) ,
1115
                 ( A21  A22 )             (  0  0 )
1116

1117
    where Er is an upper triangular invertible matrix.
1118
    Optionally, the A22 matrix can be further reduced to the form
1119

1120
                  ( Ar  X )
1121
            A22 = (       ) ,
1122
                  (  0  0 )
1123

1124
    with Ar an upper triangular invertible matrix, and X either a full
1125
    or a zero matrix.
1126
    The left and/or right orthogonal transformations performed
1127
    to reduce E and A22 can be optionally accumulated.
1128

1129
    Parameters
1130
    ----------
1131
    l : int
1132
        The number of rows of matrices A, B, and E.  l >= 0.
1133
    n : int
1134
        The number of columns of matrices A, E, and C.  n >= 0.
1135
    m : int
1136
        The number of columns of matrix B.  m >= 0.
1137
    p : int
1138
        The number of rows of matrix C.  p >= 0.
1139
    A : (l, n) array_like
1140
        The leading l-by-n part of this array must
1141
        contain the state dynamics matrix A.
1142
    E : (l, n) array_like
1143
        The leading l-by-n part of this array must
1144
        contain the descriptor matrix E.
1145
    B : (l, m) array_like
1146
        The leading L-by-M part of this array must
1147
        contain the input/state matrix B.
1148
    C : (p, n) array_like
1149
        The leading P-by-N part of this array must
1150
    contain the state/output matrix C.
1151
    Q : (l, l) array_like, optional
1152
        If COMPQ = 'N':  Q is not referenced.
1153
        If COMPQ = 'I':  Q need not be set.
1154
        If COMPQ = 'U':  The leading l-by-l part of this
1155
                        array must contain an orthogonal matrix
1156
                        Q1.
1157
        Default is None.
1158
    Z : (n, n) array_like, optional
1159
        If COMPZ = 'N':  Z is not referenced.
1160
        If COMPZ = 'I':  Z need not be set.
1161
        If COMPZ = 'U':  The leading n-by-n part of this
1162
                        array must contain an orthogonal matrix
1163
                        Z1.
1164
        Default is None.
1165
    compq : {'N', 'I', 'U'}, optional
1166
        = 'N':  do not compute Q.
1167
        = 'I':  Q is initialized to the unit matrix, and the
1168
                orthogonal matrix Q is returned.
1169
        = 'U':  Q must contain an orthogonal matrix Q1 on entry,
1170
                and the product Q1*Q is returned.
1171
        Default is 'N'.
1172
    compz :  {'N', 'I', 'U'}, optional
1173
        = 'N':  do not compute Z.
1174
        = 'I':  Z is initialized to the unit matrix, and the
1175
                orthogonal matrix Z is returned.
1176
        = 'U':  Z must contain an orthogonal matrix Z1 on entry,
1177
                and the product Z1*Z is returned.
1178
        Default is 'N'.
1179
    joba :  {'N', 'R', 'T'}, optional
1180
        = 'N':  do not reduce A22.
1181
        = 'R':  reduce A22 to a SVD-like upper triangular form.
1182
        = 'T':  reduce A22 to an upper trapezoidal form.
1183
        Default is 'N'.
1184
    tol : float, optional
1185
        The tolerance to be used in determining the rank of E
1186
        and of A22. If the user sets TOL > 0, then the given
1187
        value of TOL is used as a lower bound for the
1188
        reciprocal condition numbers of leading submatrices
1189
        of R or R22 in the QR decompositions E * P = Q * R of E
1190
        or A22 * P22 = Q22 * R22 of A22.
1191
        A submatrix whose estimated condition number is less than
1192
        1/TOL is considered to be of full rank.  If the user sets
1193
        TOL <= 0, then an implicitly computed, default tolerance,
1194
        defined by  TOLDEF = L*N*EPS,  is used instead, where
1195
        EPS is the machine precision (see LAPACK Library routine
1196
        DLAMCH). TOL < 1.
1197
        Default is `0.0`.
1198
    ldwork : int, optional
1199
        The length of the cache array.
1200
        ldwork >= MAX( 1, n+p, MIN(l,n)+MAX(3*n-1,m,l) ).
1201
        For optimal performance, ldwork should be larger.
1202
        Default is None.
1203
    
1204
    Returns
1205
    -------
1206
    A : (l, n) ndarray
1207
        On entry, the leading L-by-N part of this array must
1208
        contain the state dynamics matrix A.
1209
        On exit, the leading L-by-N part of this array contains
1210
        the transformed matrix Q'*A*Z. If JOBA = 'T', this matrix
1211
        is in the form
1212

1213
                        ( A11  *   *  )
1214
            Q'*A*Z = (  *   Ar  X  ) ,
1215
                        (  *   0   0  )
1216

1217
        where A11 is a RANKE-by-RANKE matrix and Ar is a
1218
        RNKA22-by-RNKA22 invertible upper triangular matrix.
1219
        If JOBA = 'R' then A has the above form with X = 0.
1220
    E : (l, n) ndarray
1221
        The leading L-by-N part of this array contains
1222
        the transformed matrix Q'*E*Z.
1223

1224
                    ( Er  0 )
1225
        Q'*E*Z = (       ) ,
1226
                    (  0  0 )
1227

1228
        where Er is a RANKE-by-RANKE upper triangular invertible
1229
        matrix.
1230
    B : (l, m) ndarray
1231
        The leading L-by-M part of this array contains
1232
        the transformed matrix Q'*B.
1233
    C : (p, n) ndarray
1234
        The leading P-by-N part of this array contains
1235
        the transformed matrix C*Z.
1236
    Q : (l, l) ndarray
1237
        If COMPQ = 'N':  Q is not referenced.
1238
        If COMPQ = 'I':  The leading L-by-L part of this
1239
                        array contains the orthogonal matrix Q,
1240
                        where Q' is the product of Householder
1241
                        transformations which are applied to A,
1242
                        E, and B on the left.
1243
        If COMPQ = 'U':  The leading L-by-L part of this
1244
                        array contains the orthogonal matrix
1245
                        Q1*Q.
1246
    Z : (n, n) ndarray
1247
        If COMPZ = 'N':  Z is not referenced.
1248
        If COMPZ = 'I':  The leading N-by-N part of this
1249
                        array contains the orthogonal matrix Z,
1250
                        which is the product of Householder
1251
                        transformations applied to A, E, and C
1252
                        on the right.
1253
        If COMPZ = 'U':  The leading N-by-N part of this
1254
                        array contains the orthogonal matrix
1255
                        Z1*Z.
1256
    ranke : int
1257
        The estimated rank of matrix E, and thus also the order
1258
        of the invertible upper triangular submatrix Er.
1259
    rnka22 : int
1260
        If JOBA = 'R' or 'T', then RNKA22 is the estimated rank of
1261
        matrix A22, and thus also the order of the invertible
1262
        upper triangular submatrix Ar.
1263
        If JOBA = 'N', then RNKA22 is not referenced.
1264

1265
    Raises
1266
    ------
1267
    SlycotParameterError
1268
        :info = -i: the i-th argument had an illegal value
1269
    """
1270

1271
    hidden = ' (hidden by the wrapper)'
32✔
1272
    arg_list = ['compq', 'compz', 'joba', 'l', 'n', 'm', 'p', 'A', 'lda'+hidden, 'E','lde'+hidden,'B','ldb'+hidden,'C','ldc'+hidden,'Q','ldq'+hidden,'Z','ldz'+hidden,'ranke','rnka22','tol','iwork'+hidden, 'dwork'+hidden, 'ldwork', 'info']
32✔
1273

1274

1275
    if compq != 'N' and compq != 'I' and compq != 'U':
32✔
UNCOV
1276
        raise SlycotParameterError('Parameter compq had an illegal value', -1)
×
1277

1278
    if compz != 'N' and compz != 'I' and compz != 'U':
32✔
UNCOV
1279
        raise SlycotParameterError('Parameter compz had an illegal value', -2)
×
1280

1281
    if joba != 'N' and joba != 'R' and joba != 'T':
32✔
UNCOV
1282
        raise SlycotParameterError('Parameter joba had an illegal value', -3)
×
1283

1284
    if ldwork is None:
32✔
1285
        ldwork = max(1, n+p, min(l,n) + max(3*n-1, m, l))
32✔
1286

1287

1288
    if compq == 'N' and compz == 'N':
32✔
UNCOV
1289
        A,E,B,C,ranke,rnka22,info = _wrapper.tg01fd_nn(joba,l,n,m,p,A,E,B,C,tol,ldwork)
×
UNCOV
1290
        Q = None
×
UNCOV
1291
        Z = None
×
1292
    elif compq == 'I' and compz == 'I':
32✔
1293
        A,E,B,C,Q,Z,ranke,rnka22,info = _wrapper.tg01fd_ii(joba,l,n,m,p,A,E,B,C,tol,ldwork)
32✔
1294
    elif compq == 'U' and compz == 'U':
32✔
1295
        A,E,B,C,Q,Z,ranke,rnka22,info = _wrapper.tg01fd_uu(joba,l,n,m,p,A,E,B,C,Q,Z,tol,ldwork)
32✔
1296
    else:
UNCOV
1297
        raise NotImplementedError(
×
1298
            "The combination of compq and compz is not implemented")
1299

1300
    raise_if_slycot_error(info, arg_list)
32✔
1301

1302
    if joba == 'N':
32✔
UNCOV
1303
        rnka22 = None
×
1304

1305
    return A,E,B,C,ranke,rnka22,Q,Z
32✔
1306

1307
# to be replaced by python wrappers
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