1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
C/MEMBR ADD NAME=RICD,SSI=0
subroutine ricd(nf,nn,f,n,h,g,cond,x,z,nz,w,eps,ipvt,wrk1,wrk2,
& ierr)
C!purpose
C this subroutine solves the discrete-time algebraic matrix
C riccati equation
C
C t t t -1 t
C x = f *x*f - f *x*g1*((g2 + g1 *x*g1) )*g1 *x*f + h
C
C by laub's variant of the hamiltonian-eigenvector approach.
C
C!method
C laub, a.j., a schur method for solving algebraic riccati
C equations, ieee trans. aut. contr., ac-24(1979), 913-921.
C
C the matrix f is assumed to be nonsingular and the matrices g1 and
C g2 are assumed to be combined into the square array g as follows:
C -1 t
C g = g1*g2 *g1
C
C in case f is singular, see: pappas, t., a.j. laub, and n.r.
C sandell, on the numerical solution of the discrete-time
C algebraic riccati equation, ieee trans. aut. contr., ac-25(1980
C 631-641.
C
C!calling sequence
C subroutine ricd (nf,nn,f,n,h,g,cond,x,z,nz,w,eps
C + ipvt,wrk1,wrk2,ierr )
C
C integer nf,ng,nh,nz,n,nn,itype(nn),ipvt(n),ierr
C double precision f(nf,n),g(ng,n),h(nh,n),z(nz,nn),w(nz,nn),
C + ,wrk1(nn),wrk2(nn),x(nf,n)
C on input:
C nf,nz row dimensions of the arrays containing
C (f,g,h) and (z,w), respectively, as
C declared in the calling program dimension
C statement;
C
C n order of the matrices f,g,h;
C
C nn = 2*n = order of the internally generated
C matrices z and w;
C
C f a nonsingular n x n (real) matrix;
C
C g,h n x n symmetric, nonnegative definite
C (real) matrices.
C
C eps relative machine precision
C
C
C on output:
C
C x n x n array containing txe unique positive
C (or nonnegative) definite solution of the
C riccati equation;
C
C
C z,w 2*n x 2*n real scratch arrays used for
C computations involving the symplectic
C matrix associated with the riccati equation;
C
C wrk1,wrk2 real scratch vectors of lengths 2*n
C
C cond
C condition number estimate for the final nth
C order linear matrix equation solved;
C
C ipvt integer scratch vector of length 2*n
C
C ierr error code
C ierr=0 : ok
C ierr=-1 : singular linear system
C ierr=i : i th eigenvalue is badly calculated
C
C ***note: all scratch arrays must be declared and included
C in the call.***
C
C!comments
C it is assumed that:
C (1) f is nonsingular (can be relaxed; see ref. above )
C (2) g and h are nonnegative definite
C (3) (f,g1) is stabilizable and (c,f) is detectable where
C t
C c *c = h (c of full rank = rank(h)).
C under these assumptions the solution (returned in the array h) is
C unique and nonnegative definite.
C
C!originator
C written by alan j. laub (dep't. of elec. engrg. - systems, univ.
C of southern calif., los angeles, ca 90007; ph.: (213) 743-5535),
C sep. 1977.
C most recent version: apr. 15, 1981.
C
C!auxiliary routines
C hqror2,inva,fout,mulwoa,mulwob
C dgeco,dgesl (linpack )
C balanc,balbak,orthes,ortran (eispack )
C ddot (blas)
C!
C
C *****parameters:
integer nf,nz,n,nn,ipvt(nn),ierr
double precision f(nf,n),g(nf,n),h(nf,n),z(nz,nn),w(nz,nn),
& wrk1(nn),wrk2(nn),x(nf,n)
logical fail
integer fout
external fout
C
C *****local variables:
integer i,j,low,igh,nlow,npi,npj,nup
double precision eps,t(1),cond,det(2),ddot
C
C
C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C
C eps is a machine dependent parameter
C specifying the relative precision of realing point arithmetic.
C for example, eps = 16.0d+0**(-13) for double precision arithmetic
C on ibm s360/s370.
C
C
C ( f**-1 (f**-1)*g )
C set up symplectic matrix z=( )
C ( h*(f**-1) h*(f**-1)*g+trans(f) )
C
C z11=f**-1
fail = .false.
do 20 j = 1,n
do 10 i = 1,n
z(i,j) = f(i,j)
10 continue
20 continue
call dgeco(z,nz,n,ipvt,cond,wrk1)
if ((cond+1.0d+0) .le. 1.0d+0) goto 200
call dgedi(z,nz,n,ipvt,det,wrk1,1)
C z21=h*f**-1; z12=(f**-1)*g
do 90 j = 1,n
npj = n + j
do 90 i = 1,n
npi = n + i
z(i,npj) = ddot(n,z(i,1),nz,g(1,j),1)
z(npi,j) = ddot(n,h(i,1),nf,z(1,j),1)
90 continue
C z22=transp(f)+h*(f**-1)*g
do 140 j = 1,n
npj = n + j
do 130 i = 1,n
npi = n + i
z(npi,npj) = f(j,i) + ddot(n,z(npi,1),nz,g(1,j),1)
130 continue
140 continue
C
C balance z
C
call balanc(nz,nn,z,low,igh,wrk1)
C
C reduce z to real schur form with eigenvalues outside the unit
C disk in the upper left n x n upper quasi-triangular block
C
nlow = 1
nup = nn
call orthes(nz,nn,nlow,nup,z,wrk2)
call ortran(nz,nn,nlow,nup,z,wrk2,w)
call hqror2(nz,nn,1,nn,z,t,t,w,ierr,11)
if (ierr .ne. 0) goto 210
call inva(nz,nn,z,w,fout,eps,ndim,fail,ipvt)
if (fail) goto 220
if (ndim .ne. n) goto 230
C
C compute solution of the riccati equation from the orthogonal
C matrix now in the array w. store the result in the array h.
C
call balbak(nz,nn,low,igh,wrk1,nn,w)
C resolution systeme lineaire
call dgeco(w,nz,n,ipvt,cond,wrk1)
if (cond+1.0d+0 .le. 1.0d+0) goto 200
do 160 j = 1,n
npj = n + j
do 150 i = 1,n
x(i,j) = w(npj,i)
150 continue
160 continue
do 165 i = 1,n
165 call dgesl(w,nz,n,ipvt,x(1,i),1)
return
200 continue
C systeme lineaire numeriquement singulier
ierr = -1
return
210 continue
C erreur dans hqror2
ierr = i
return
C
220 continue
C erreur dans inva
return
C
230 continue
C la matrice symplectique n'a pas le
C bon nombre de val. propres de module
C inferieur a 1.
return
C
C last line of ricd
C
end
|