472 lines
15 KiB
Fortran
472 lines
15 KiB
Fortran
SUBROUTINE SB08MD( ACONA, DA, A, RES, E, DWORK, LDWORK, INFO )
|
|
C
|
|
C SLICOT RELEASE 5.0.
|
|
C
|
|
C Copyright (c) 2002-2009 NICONET e.V.
|
|
C
|
|
C This program is free software: you can redistribute it and/or
|
|
C modify it under the terms of the GNU General Public License as
|
|
C published by the Free Software Foundation, either version 2 of
|
|
C the License, or (at your option) any later version.
|
|
C
|
|
C This program is distributed in the hope that it will be useful,
|
|
C but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
C GNU General Public License for more details.
|
|
C
|
|
C You should have received a copy of the GNU General Public License
|
|
C along with this program. If not, see
|
|
C <http://www.gnu.org/licenses/>.
|
|
C
|
|
C PURPOSE
|
|
C
|
|
C To compute a real polynomial E(s) such that
|
|
C
|
|
C (a) E(-s) * E(s) = A(-s) * A(s) and
|
|
C (b) E(s) is stable - that is, all the zeros of E(s) have
|
|
C non-positive real parts,
|
|
C
|
|
C which corresponds to computing the spectral factorization of the
|
|
C real polynomial A(s) arising from continuous optimality problems.
|
|
C
|
|
C The input polynomial may be supplied either in the form
|
|
C
|
|
C A(s) = a(0) + a(1) * s + ... + a(DA) * s**DA
|
|
C
|
|
C or as
|
|
C
|
|
C B(s) = A(-s) * A(s)
|
|
C = b(0) + b(1) * s**2 + ... + b(DA) * s**(2*DA) (1)
|
|
C
|
|
C ARGUMENTS
|
|
C
|
|
C Mode Parameters
|
|
C
|
|
C ACONA CHARACTER*1
|
|
C Indicates whether the coefficients of A(s) or B(s) =
|
|
C A(-s) * A(s) are to be supplied as follows:
|
|
C = 'A': The coefficients of A(s) are to be supplied;
|
|
C = 'B': The coefficients of B(s) are to be supplied.
|
|
C
|
|
C Input/Output Parameters
|
|
C
|
|
C DA (input) INTEGER
|
|
C The degree of the polynomials A(s) and E(s). DA >= 0.
|
|
C
|
|
C A (input/output) DOUBLE PRECISION array, dimension (DA+1)
|
|
C On entry, this array must contain either the coefficients
|
|
C of the polynomial A(s) in increasing powers of s if
|
|
C ACONA = 'A', or the coefficients of the polynomial B(s) in
|
|
C increasing powers of s**2 (see equation (1)) if ACONA =
|
|
C 'B'.
|
|
C On exit, this array contains the coefficients of the
|
|
C polynomial B(s) in increasing powers of s**2.
|
|
C
|
|
C RES (output) DOUBLE PRECISION
|
|
C An estimate of the accuracy with which the coefficients of
|
|
C the polynomial E(s) have been computed (see also METHOD
|
|
C and NUMERICAL ASPECTS).
|
|
C
|
|
C E (output) DOUBLE PRECISION array, dimension (DA+1)
|
|
C The coefficients of the spectral factor E(s) in increasing
|
|
C powers of s.
|
|
C
|
|
C Workspace
|
|
C
|
|
C DWORK DOUBLE PRECISION array, dimension (LDWORK)
|
|
C
|
|
C LDWORK INTEGER
|
|
C The length of the array DWORK. LDWORK >= 5*DA+5.
|
|
C
|
|
C Error Indicator
|
|
C
|
|
C INFO INTEGER
|
|
C = 0: successful exit;
|
|
C < 0: if INFO = -i, the i-th argument had an illegal
|
|
C value;
|
|
C = 1: if on entry, A(I) = 0.0, for I = 1,2,...,DA+1.
|
|
C = 2: if on entry, ACONA = 'B' but the supplied
|
|
C coefficients of the polynomial B(s) are not the
|
|
C coefficients of A(-s) * A(s) for some real A(s);
|
|
C in this case, RES and E are unassigned;
|
|
C = 3: if the iterative process (see METHOD) has failed to
|
|
C converge in 30 iterations;
|
|
C = 4: if the last computed iterate (see METHOD) is
|
|
C unstable. If ACONA = 'B', then the supplied
|
|
C coefficients of the polynomial B(s) may not be the
|
|
C coefficients of A(-s) * A(s) for some real A(s).
|
|
C
|
|
C METHOD
|
|
C _ _
|
|
C Let A(s) be the conjugate polynomial of A(s), i.e., A(s) = A(-s).
|
|
C
|
|
C The method used by the routine is based on applying the
|
|
C Newton-Raphson iteration to the function
|
|
C _ _
|
|
C F(e) = A * A - e * e,
|
|
C
|
|
C which leads to the iteration formulae (see [1]):
|
|
C
|
|
C _(i) (i) _(i) (i) _ )
|
|
C q * x + x * q = 2 A * A )
|
|
C ) for i = 0, 1, 2,...
|
|
C (i+1) (i) (i) )
|
|
C q = (q + x )/2 )
|
|
C
|
|
C (0) DA
|
|
C Starting from q = (1 + s) (which has no zeros in the closed
|
|
C (1) (2) (3)
|
|
C right half-plane), the sequence of iterates q , q , q ,...
|
|
C converges to a solution of F(e) = 0 which has no zeros in the
|
|
C open right half-plane.
|
|
C
|
|
C The iterates satisfy the following conditions:
|
|
C
|
|
C (i)
|
|
C (a) q is a stable polynomial (no zeros in the closed right
|
|
C half-plane) and
|
|
C
|
|
C (i) (i-1)
|
|
C (b) q (1) <= q (1).
|
|
C
|
|
C (i-1) (i)
|
|
C The iterative process stops with q , (where i <= 30) if q
|
|
C violates either (a) or (b), or if the condition
|
|
C _(i) (i) _
|
|
C (c) RES = ||(q q - A A)|| < tol,
|
|
C
|
|
C is satisfied, where || . || denotes the largest coefficient of
|
|
C _(i) (i) _
|
|
C the polynomial (q q - A A) and tol is an estimate of the
|
|
C _(i) (i)
|
|
C rounding error in the computed coefficients of q q . If there
|
|
C is no convergence after 30 iterations then the routine returns
|
|
C with the Error Indicator (INFO) set to 3, and the value of RES may
|
|
C indicate whether or not the last computed iterate is close to the
|
|
C solution.
|
|
C
|
|
C If ACONA = 'B', then it is possible that the equation e(-s) *
|
|
C e(s) = B(s) has no real solution, which will be the case if A(1)
|
|
C < 0 or if ( -1)**DA * A(DA+1) < 0.
|
|
C
|
|
C REFERENCES
|
|
C
|
|
C [1] Vostry, Z.
|
|
C New Algorithm for Polynomial Spectral Factorization with
|
|
C Quadratic Convergence II.
|
|
C Kybernetika, 12, pp. 248-259, 1976.
|
|
C
|
|
C NUMERICAL ASPECTS
|
|
C
|
|
C The conditioning of the problem depends upon the distance of the
|
|
C zeros of A(s) from the imaginary axis and on their multiplicity.
|
|
C For a well-conditioned problem the accuracy of the computed
|
|
C coefficients of E(s) is of the order of RES. However, for problems
|
|
C with zeros near the imaginary axis or with multiple zeros, the
|
|
C value of RES may be an overestimate of the true accuracy.
|
|
C
|
|
C FURTHER COMMENTS
|
|
C
|
|
C In order for the problem e(-s) * e(s) = B(s) to have a real
|
|
C solution e(s), it is necessary and sufficient that B(j*omega)
|
|
C >= 0 for any purely imaginary argument j*omega (see [1]).
|
|
C
|
|
C CONTRIBUTOR
|
|
C
|
|
C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
|
|
C Supersedes Release 2.0 routine SB08AD by A.J. Geurts.
|
|
C
|
|
C REVISIONS
|
|
C
|
|
C -
|
|
C
|
|
C KEYWORDS
|
|
C
|
|
C Factorization, Laplace transform, optimal control, optimal
|
|
C filtering, polynomial operations, spectral factorization, zeros.
|
|
C
|
|
C ******************************************************************
|
|
C
|
|
C .. Parameters ..
|
|
DOUBLE PRECISION ZERO, HALF, ONE
|
|
PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )
|
|
C .. Scalar Arguments ..
|
|
CHARACTER ACONA
|
|
INTEGER DA, INFO, LDWORK
|
|
DOUBLE PRECISION RES
|
|
C .. Array Arguments ..
|
|
DOUBLE PRECISION A(*), DWORK(*), E(*)
|
|
C .. Local Scalars ..
|
|
LOGICAL CONV, LACONA, STABLE
|
|
INTEGER BINC, DA1, I, I0, J, K, LAMBDA, LAY, LAYEND,
|
|
$ LDIF, LPHEND, LPHI, LQ, M, NC
|
|
DOUBLE PRECISION A0, EPS, MU, MUJ, SI, SIGNI, SIGNI0, SIGNJ,
|
|
$ SIMIN1, SQRTA0, SQRTMJ, SQRTMU, TOLPHI, W, XDA
|
|
C .. External Functions ..
|
|
LOGICAL LSAME
|
|
INTEGER IDAMAX
|
|
DOUBLE PRECISION DLAMCH
|
|
EXTERNAL DLAMCH, IDAMAX, LSAME
|
|
C .. External Subroutines ..
|
|
EXTERNAL DAXPY, DCOPY, SB08MY, XERBLA
|
|
C .. Intrinsic Functions ..
|
|
INTRINSIC ABS, DBLE, MOD, SQRT
|
|
C .. Executable Statements ..
|
|
C
|
|
INFO = 0
|
|
LACONA = LSAME( ACONA, 'A' )
|
|
C
|
|
C Test the input scalar arguments.
|
|
C
|
|
IF( .NOT.LACONA .AND. .NOT.LSAME( ACONA, 'B' ) ) THEN
|
|
INFO = -1
|
|
ELSE IF( DA.LT.0 ) THEN
|
|
INFO = -2
|
|
ELSE IF( LDWORK.LT.5*DA + 5 ) THEN
|
|
INFO = -7
|
|
END IF
|
|
C
|
|
IF ( INFO.NE.0 ) THEN
|
|
C
|
|
C Error return.
|
|
C
|
|
CALL XERBLA( 'SB08MD', -INFO )
|
|
RETURN
|
|
END IF
|
|
C
|
|
IF ( .NOT.LACONA ) THEN
|
|
CALL DCOPY( DA+1, A, 1, E, 1 )
|
|
ELSE
|
|
W = ZERO
|
|
CALL SB08MY( DA, A, E, W )
|
|
END IF
|
|
C
|
|
C Reduce E such that the first and the last element are non-zero.
|
|
C
|
|
DA1 = DA + 1
|
|
C
|
|
C WHILE ( DA1 >= 1 and E(DA1) = 0 ) DO
|
|
20 IF ( DA1.GE.1 ) THEN
|
|
IF ( E(DA1).EQ.ZERO ) THEN
|
|
DA1 = DA1 - 1
|
|
GO TO 20
|
|
END IF
|
|
END IF
|
|
C END WHILE 20
|
|
C
|
|
DA1 = DA1 - 1
|
|
IF ( DA1.LT.0 ) THEN
|
|
INFO = 1
|
|
RETURN
|
|
END IF
|
|
C
|
|
I0 = 1
|
|
C
|
|
C WHILE ( E(I0) = 0 ) DO
|
|
40 IF ( E(I0).EQ.ZERO ) THEN
|
|
I0 = I0 + 1
|
|
GO TO 40
|
|
END IF
|
|
C END WHILE 40
|
|
C
|
|
I0 = I0 - 1
|
|
IF ( I0.NE.0 ) THEN
|
|
IF ( MOD( I0, 2 ).EQ.0 ) THEN
|
|
SIGNI0 = ONE
|
|
ELSE
|
|
SIGNI0 = -ONE
|
|
END IF
|
|
C
|
|
DO 60 I = 1, DA1 - I0 + 1
|
|
E(I) = SIGNI0*E(I+I0)
|
|
60 CONTINUE
|
|
C
|
|
DA1 = DA1 - I0
|
|
END IF
|
|
IF ( MOD( DA1, 2 ).EQ.0 ) THEN
|
|
SIGNI = ONE
|
|
ELSE
|
|
SIGNI = -ONE
|
|
END IF
|
|
NC = DA1 + 1
|
|
IF ( ( E(1).LT.ZERO ) .OR. ( ( E(NC)*SIGNI ).LT.ZERO ) ) THEN
|
|
INFO = 2
|
|
RETURN
|
|
END IF
|
|
C
|
|
C Initialization.
|
|
C
|
|
EPS = DLAMCH( 'Epsilon' )
|
|
SI = ONE/DLAMCH( 'Safe minimum' )
|
|
LQ = 1
|
|
LAY = LQ + NC
|
|
LAMBDA = LAY + NC
|
|
LPHI = LAMBDA + NC
|
|
LDIF = LPHI + NC
|
|
C
|
|
A0 = E(1)
|
|
BINC = 1
|
|
C
|
|
C Computation of the starting polynomial and scaling of the input
|
|
C polynomial.
|
|
C
|
|
MU = ( A0/ABS( E(NC) ) )**( ONE/DBLE( DA1 ) )
|
|
MUJ = ONE
|
|
C
|
|
DO 80 J = 1, NC
|
|
W = E(J)*MUJ/A0
|
|
A(J) = W
|
|
E(J) = BINC
|
|
DWORK(LQ+J-1) = BINC
|
|
MUJ = MUJ*MU
|
|
BINC = BINC*( NC - J )/J
|
|
80 CONTINUE
|
|
C
|
|
CONV = .FALSE.
|
|
STABLE = .TRUE.
|
|
C
|
|
C The contents of the arrays is, cf [1],
|
|
C
|
|
C E : the last computed stable polynomial q ;
|
|
C i-1
|
|
C DWORK(LAY+1,...,LAY+DA1-1) : a'(1), ..., a'(DA1-1), these values
|
|
C are changed during the computation
|
|
C into y;
|
|
C (LAMBDA+1,...,LAMBDA+DA1-2) : lambda(1), ..., lambda(DA1-2),
|
|
C the factors of the Routh
|
|
C stability test, (lambda(i) is
|
|
C P(i) in [1]);
|
|
C (LPHI+1,...,LPHI+DA1-1) : phi(1), ..., phi(DA1-1), the values
|
|
C phi(i,j), see [1], scheme (11);
|
|
C (LDIF,...,LDIF+DA1) : the coeffs of q (-s) * q (s) - b(s).
|
|
C i i
|
|
C DWORK(LQ,...,LQ+DA1) : the last computed polynomial q .
|
|
C i
|
|
I = 0
|
|
C
|
|
C WHILE ( I < 30 and CONV = FALSE and STABLE = TRUE ) DO
|
|
100 IF ( I.LT.30 .AND. .NOT.CONV .AND. STABLE ) THEN
|
|
I = I + 1
|
|
CALL DCOPY( NC, A, 1, DWORK(LAY), 1 )
|
|
CALL DCOPY( NC, DWORK(LQ), 1, DWORK(LPHI), 1 )
|
|
M = DA1/2
|
|
LAYEND = LAY + DA1
|
|
LPHEND = LPHI + DA1
|
|
XDA = A(NC)/DWORK(LQ+DA1)
|
|
C
|
|
DO 120 K = 1, M
|
|
DWORK(LAY+K) = DWORK(LAY+K) - DWORK(LPHI+2*K)
|
|
DWORK(LAYEND-K) = DWORK(LAYEND-K) - DWORK(LPHEND-2*K)*XDA
|
|
120 CONTINUE
|
|
C
|
|
C Computation of lambda(k) and y(k).
|
|
C
|
|
K = 1
|
|
C
|
|
C WHILE ( K <= DA1 - 2 and STABLE = TRUE ) DO
|
|
140 IF ( ( K.LE.( DA1 - 2 ) ) .AND. STABLE ) THEN
|
|
IF ( DWORK(LPHI+K).LE.ZERO ) STABLE = .FALSE.
|
|
IF ( STABLE ) THEN
|
|
W = DWORK(LPHI+K-1)/DWORK(LPHI+K)
|
|
DWORK(LAMBDA+K) = W
|
|
CALL DAXPY( ( DA1 - K )/2, -W, DWORK(LPHI+K+2), 2,
|
|
$ DWORK(LPHI+K+1), 2 )
|
|
W = DWORK(LAY+K)/DWORK(LPHI+K)
|
|
DWORK(LAY+K) = W
|
|
CALL DAXPY( ( DA1 - K )/2, -W, DWORK(LPHI+K+2), 2,
|
|
$ DWORK(LAY+K+1), 1 )
|
|
K = K + 1
|
|
END IF
|
|
GO TO 140
|
|
END IF
|
|
C END WHILE 140
|
|
C
|
|
IF ( DWORK(LPHI+DA1-1).LE.ZERO ) THEN
|
|
STABLE = .FALSE.
|
|
ELSE
|
|
DWORK(LAY+DA1-1) = DWORK(LAY+DA1-1)/DWORK(LPHI+DA1-1)
|
|
END IF
|
|
C
|
|
C STABLE = The polynomial q is stable.
|
|
C i-1
|
|
IF ( STABLE ) THEN
|
|
C
|
|
C Computation of x and q .
|
|
C i i
|
|
C
|
|
DO 160 K = DA1 - 2, 1, -1
|
|
W = DWORK(LAMBDA+K)
|
|
CALL DAXPY( ( DA1 - K )/2, -W, DWORK(LAY+K+1), 2,
|
|
$ DWORK(LAY+K), 2 )
|
|
160 CONTINUE
|
|
C
|
|
DWORK(LAY+DA1) = XDA
|
|
C
|
|
CALL DCOPY( NC, DWORK(LQ), 1, E, 1 )
|
|
SIMIN1 = SI
|
|
SI = DWORK(LQ)
|
|
SIGNJ = -ONE
|
|
C
|
|
DO 180 J = 1, DA1
|
|
W = HALF*( DWORK(LQ+J) + SIGNJ*DWORK(LAY+J) )
|
|
DWORK(LQ+J) = W
|
|
SI = SI + W
|
|
SIGNJ = -SIGNJ
|
|
180 CONTINUE
|
|
C
|
|
TOLPHI = EPS
|
|
CALL SB08MY( DA1, E, DWORK(LDIF), TOLPHI )
|
|
CALL DAXPY( NC, -ONE, A, 1, DWORK(LDIF), 1 )
|
|
RES = ABS( DWORK( IDAMAX( NC, DWORK(LDIF), 1 ) + LDIF-1 ) )
|
|
C
|
|
C Convergency test.
|
|
C
|
|
IF ( ( SI.GT.SIMIN1 ) .OR. ( RES.LT.TOLPHI ) ) THEN
|
|
CONV = .TRUE.
|
|
END IF
|
|
GO TO 100
|
|
END IF
|
|
END IF
|
|
C END WHILE 100
|
|
C
|
|
C Backscaling.
|
|
C
|
|
MU = ONE/MU
|
|
SQRTA0 = SQRT( A0 )
|
|
SQRTMU = SQRT( MU )
|
|
MUJ = ONE
|
|
SQRTMJ = ONE
|
|
C
|
|
DO 200 J = 1, NC
|
|
E(J) = E(J)*SQRTA0*SQRTMJ
|
|
A(J) = A(J)*A0*MUJ
|
|
MUJ = MUJ*MU
|
|
SQRTMJ = SQRTMJ*SQRTMU
|
|
200 CONTINUE
|
|
C
|
|
IF ( I0.NE.0 ) THEN
|
|
C
|
|
DO 220 J = NC, 1, -1
|
|
E(I0+J) = E(J)
|
|
A(I0+J) = SIGNI0*A(J)
|
|
220 CONTINUE
|
|
C
|
|
DO 240 J = 1, I0
|
|
E(J) = ZERO
|
|
A(J) = ZERO
|
|
240 CONTINUE
|
|
C
|
|
END IF
|
|
C
|
|
IF ( .NOT.CONV ) THEN
|
|
IF ( STABLE ) THEN
|
|
INFO = 3
|
|
ELSE
|
|
INFO = 4
|
|
END IF
|
|
END IF
|
|
C
|
|
RETURN
|
|
C *** Last line of SB08MD ***
|
|
END
|