1      SUBROUTINE SB01FY( DISCR, N, M, A, LDA, B, LDB, F, LDF, V, LDV,
2     $                   INFO )
3C
4C     WARNING
5C
6C     This file alters the SLICOT routine SB01FY. It is intended
7C     for use from the Octave Control Systems Package and modifies
8C     the original SLICOT implementation.  This file itself is *NOT*
9C     part of SLICOT and the authors from NICONET e.V. are *NOT*
10C     responsible for it.  See file DESCRIPTION for the current
11C     maintainer of the Octave control package.
12C
13C     In altered implementation the deprecated LAPACK routine DLATZM
14C     is replaced by ODLTZM.
15C
16C
17C     SLICOT RELEASE 5.0.
18C
19C     Copyright (c) 2002-2010 NICONET e.V.
20C
21C     This program is free software: you can redistribute it and/or
22C     modify it under the terms of the GNU General Public License as
23C     published by the Free Software Foundation, either version 2 of
24C     the License, or (at your option) any later version.
25C
26C     This program is distributed in the hope that it will be useful,
27C     but WITHOUT ANY WARRANTY; without even the implied warranty of
28C     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29C     GNU General Public License for more details.
30C
31C     You should have received a copy of the GNU General Public License
32C     along with this program.  If not, see
33C     <http://www.gnu.org/licenses/>.
34C
35C     PURPOSE
36C
37C     To compute the inner denominator of a right-coprime factorization
38C     of a system of order N, where N is either 1 or 2. Specifically,
39C     given the N-by-N unstable system state matrix A and the N-by-M
40C     system input matrix B, an M-by-N state-feedback matrix F and
41C     an M-by-M matrix V are constructed, such that the system
42C     (A + B*F, B*V, F, V) is inner.
43C
44C     ARGUMENTS
45C
46C     Mode Parameters
47C
48C     DISCR   LOGICAL
49C             Specifies the type of system as follows:
50C             = .FALSE.:  continuous-time system;
51C             = .TRUE. :  discrete-time system.
52C
53C     Input/Output Parameters
54C
55C     N       (input) INTEGER
56C             The order of the matrix A and also the number of rows of
57C             the matrix B and the number of columns of the matrix F.
58C             N is either 1 or 2.
59C
60C     M       (input) INTEGER
61C             The number of columns of the matrices B and V, and also
62C             the number of rows of the matrix F.  M >= 0.
63C
64C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
65C             The leading N-by-N part of this array must contain the
66C             system state matrix A whose eigenvalues must have positive
67C             real parts if DISCR = .FALSE. or moduli greater than unity
68C             if DISCR = .TRUE..
69C
70C     LDA     INTEGER
71C             The leading dimension of array A.  LDA >= N.
72C
73C     B       (input) DOUBLE PRECISION array, dimension (LDB,M)
74C             The leading N-by-M part of this array must contain the
75C             system input matrix B.
76C
77C     LDB     INTEGER
78C             The leading dimension of array B.  LDB >= N.
79C
80C     F       (output) DOUBLE PRECISION array, dimension (LDF,N)
81C             The leading M-by-N part of this array contains the state-
82C             feedback matrix F which assigns one eigenvalue (if N = 1)
83C             or two eigenvalues (if N = 2) of the matrix A + B*F in
84C             symmetric positions with respect to the imaginary axis
85C             (if DISCR = .FALSE.) or the unit circle (if
86C             DISCR = .TRUE.).
87C
88C     LDF     INTEGER
89C             The leading dimension of array F.  LDF >= MAX(1,M).
90C
91C     V       (output) DOUBLE PRECISION array, dimension (LDV,M)
92C             The leading M-by-M upper triangular part of this array
93C             contains the input/output matrix V of the resulting inner
94C             system in upper triangular form.
95C             If DISCR = .FALSE., the resulting V is an identity matrix.
96C
97C     LDV     INTEGER
98C             The leading dimension of array V.  LDF >= MAX(1,M).
99C
100C     Error Indicator
101C
102C     INFO    INTEGER
103C             = 0:  successful exit;
104C             = 1:  if uncontrollability of the pair (A,B) is detected;
105C             = 2:  if A is stable or at the stability limit;
106C             = 3:  if N = 2 and A has a pair of real eigenvalues.
107C
108C     CONTRIBUTOR
109C
110C     A. Varga, German Aerospace Center,
111C     DLR Oberpfaffenhofen, July 1998.
112C     Based on the RASP routine RCFID2.
113C
114C     REVISIONS
115C
116C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
117C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
118C     Feb. 1999, A. Varga, DLR Oberpfaffenhofen.
119C
120C     KEYWORDS
121C
122C     Coprime factorization, eigenvalue, eigenvalue assignment,
123C     feedback control, pole placement, state-space model.
124C
125C     ******************************************************************
126C
127C     .. Parameters ..
128      DOUBLE PRECISION  ONE, TWO, ZERO
129      PARAMETER         ( ONE = 1.0D0, TWO = 2.0D0, ZERO = 0.0D0 )
130C     .. Scalar Arguments ..
131      LOGICAL           DISCR
132      INTEGER           INFO, LDA, LDB, LDF, LDV, M, N
133C     .. Array Arguments ..
134      DOUBLE PRECISION  A(LDA,*), B(LDB,*), F(LDF,*), V(LDV,*)
135C     .. Local Scalars ..
136      INTEGER           I
137      DOUBLE PRECISION  CS, R11, R12, R22, SCALE, SN, TEMP
138C     .. Local Arrays ..
139      DOUBLE PRECISION  AT(2,2), DUMMY(2,2), U(2,2)
140C     .. External Functions ..
141      DOUBLE PRECISION  DLAPY2, DLAPY3
142      EXTERNAL          DLAPY2, DLAPY3
143C     .. External Subroutines ..
144      EXTERNAL          DLARFG, DLASET, ODLTZM, DROTG, DTRTRI, MA02AD,
145     $                  MB04OX, SB03OY
146C     .. Intrinsic Functions ..
147      INTRINSIC         ABS, SQRT
148C     .. Executable Statements ..
149C
150C     For efficiency reasons, the parameters are not checked.
151C
152      INFO = 0
153C
154C     Compute an N-by-N upper triangular R such that R'*R = B*B' and
155C     find an upper triangular matrix U in the equation
156C
157C     A'*U'*U + U'*U*A = R'*R if DISCR = .FALSE. or
158C     A'*U'*U*A - U'*U = R'*R if DISCR = .TRUE. .
159C
160      CALL MA02AD( 'Full', N, M, B, LDB, F, LDF )
161C
162      IF( N.EQ.1 ) THEN
163C
164C        The N = 1 case.
165C
166         IF( M.GT.1 )
167     $      CALL DLARFG( M, F(1,1), F(2,1), 1, TEMP )
168         R11 = ABS( F(1,1) )
169C
170C        Make sure A is unstable or divergent and find U.
171C
172         IF( DISCR ) THEN
173            TEMP = ABS( A(1,1) )
174            IF( TEMP.LE.ONE ) THEN
175               INFO = 2
176               RETURN
177            ELSE
178               TEMP = R11 / SQRT( ( TEMP - ONE )*( TEMP + ONE ) )
179            END IF
180         ELSE
181            IF( A(1,1).LE.ZERO ) THEN
182               INFO = 2
183               RETURN
184            ELSE
185               TEMP = R11 / SQRT( ABS( TWO*A(1,1) ) )
186            END IF
187         END IF
188         U(1,1) = TEMP
189         SCALE  = ONE
190      ELSE
191C
192C        The N = 2 case.
193C
194         IF( M.GT.1 ) THEN
195            CALL DLARFG( M, F(1,1), F(2,1), 1, TEMP )
196            CALL ODLTZM( 'Left', M, N-1, F(2,1), 1, TEMP, F(1,2),
197     $                   F(2,2), LDF, V )
198         END IF
199         R11 = F(1,1)
200         R12 = F(1,2)
201         IF( M.GT.2 )
202     $      CALL DLARFG( M-1, F(2,2), F(3,2), 1, TEMP )
203         IF( M.EQ.1 ) THEN
204            R22 = ZERO
205         ELSE
206            R22 = F(2,2)
207         END IF
208         AT(1,1) = A(1,1)
209         AT(1,2) = A(2,1)
210         AT(2,1) = A(1,2)
211         AT(2,2) = A(2,2)
212         U(1,1)  = R11
213         U(1,2)  = R12
214         U(2,2)  = R22
215         CALL SB03OY( DISCR, .FALSE., -1, AT, 2, U, 2, DUMMY, 2,
216     $                SCALE, INFO )
217         IF( INFO.NE.0 ) THEN
218            IF( INFO.NE.4 ) THEN
219               INFO = 2
220            ELSE
221               INFO = 3
222            END IF
223            RETURN
224         END IF
225      END IF
226C
227C     Check the controllability of the pair (A,B).
228C
229C     Warning. Only an exact controllability check is performed.
230C              If the pair (A,B) is nearly uncontrollable, then
231C              the computed results may be inaccurate.
232C
233      DO 10 I = 1, N
234         IF( U(I,I).EQ.ZERO ) THEN
235            INFO = 1
236            RETURN
237         END IF
238   10 CONTINUE
239C
240C     Set V = I.
241C
242      CALL DLASET( 'Upper', M, M, ZERO, ONE, V, LDV )
243C
244      IF( DISCR ) THEN
245C
246C        Compute an upper triangular matrix V such that
247C                                 -1
248C        V*V' = (I+B'*inv(U'*U)*B)  .
249C
250C        First compute F = B'*inv(U) and the Cholesky factorization
251C        of I + F*F'.
252C
253         DO 20 I = 1, M
254            F(I,1) = B(1,I)/U(1,1)*SCALE
255   20    CONTINUE
256         IF( N.EQ.2 ) THEN
257            DO 30 I = 1, M
258               F(I,2) = ( B(2,I) - F(I,1)*U(1,2) )/U(2,2)*SCALE
259   30       CONTINUE
260            CALL MB04OX( M, V, LDV, F(1,2), 1 )
261         END IF
262         CALL MB04OX( M, V, LDV, F(1,1), 1 )
263         CALL DTRTRI( 'Upper', 'NonUnit', M, V, LDV, INFO )
264      END IF
265C
266C     Compute the feedback matrix F as:
267C
268C     1)   If DISCR = .FALSE.
269C
270C             F = -B'*inv(U'*U);
271C
272C     2)   If DISCR = .TRUE.
273C                                -1
274C             F = -B'*(U'*U+B*B')  *A.
275C
276      IF( N.EQ.1 ) THEN
277         IF( DISCR ) THEN
278            TEMP = -A(1,1)
279            R11  = DLAPY2( U(1,1), R11 )
280            DO 40 I = 1, M
281               F(I,1) = ( ( B(1,I)/R11 )/R11 )*TEMP
282   40       CONTINUE
283         ELSE
284            R11 = U(1,1)
285            DO 50 I = 1, M
286               F(I,1) = -( ( B(1,I)/R11 )/R11 )
287   50       CONTINUE
288         END IF
289      ELSE
290C
291C        Set R = U  if DISCR = .FALSE. or compute the Cholesky
292C        factorization of R'*R = U'*U+B*B' if DISCR = .TRUE..
293C
294         IF( DISCR ) THEN
295            TEMP = U(1,1)
296            CALL DROTG( R11, TEMP, CS, SN )
297            TEMP = -SN*R12 + CS*U(1,2)
298            R12  =  CS*R12 + SN*U(1,2)
299            R22  = DLAPY3( R22, TEMP, U(2,2) )
300         ELSE
301            R11 = U(1,1)
302            R12 = U(1,2)
303            R22 = U(2,2)
304         END IF
305C
306C        Compute F = -B'*inv(R'*R).
307C
308         DO 60 I = 1, M
309            F(I,1) = -B(1,I)/R11
310            F(I,2) = -( B(2,I) + F(I,1)*R12 )/R22
311            F(I,2) =  F(I,2)/R22
312            F(I,1) =  ( F(I,1) - F(I,2)*R12 )/R11
313   60    CONTINUE
314         IF( DISCR ) THEN
315C
316C           Compute F <-- F*A.
317C
318            DO 70 I = 1, M
319               TEMP   = F(I,1)*A(1,1) + F(I,2)*A(2,1)
320               F(I,2) = F(I,1)*A(1,2) + F(I,2)*A(2,2)
321               F(I,1) = TEMP
322   70       CONTINUE
323         END IF
324      END IF
325C
326      RETURN
327C *** Last line of SB01FY ***
328      END
329