1
subroutine polmc(nm,ng,n,m,a,b,g,wr,wi,z,inc,invr,ierr,jpvt,
2
x rm1,rm2,rv1,rv2,rv3,rv4)
4
double precision a(nm,n),b(nm,m),g(ng,n),wr(n),wi(n),z(nm,n),
5
x rm1(m,m),rm2(m,*),rv1(n),rv2(n),rv3(m),rv4(m)
6
double precision p,q,r,s,t,zz
7
integer invr(n),jpvt(m)
10
c this subroutine determines the state feedback matrix g of the
11
c linear time-invariant multi-input system
13
c dx / dt = a * x + b * u,
15
c where a is a nxn and b is a nxm matrix, such that the
18
c dx / dt = (a - b * g) * x
20
c has desired poles. the system must be preliminary reduced into
21
c orthogonal canonical form using the subroutine trmcf.
24
c subroutine polmc(nm,ng,n,m,a,b,g,wr,wi,z,inc,invr,ierr,jpvt,
25
c x rm1,rm2,rv1,rv2,rv3,rv4)
29
c nm is an integer variable set equal to the row dimension
30
c of the two-dimensional arrays a, b and z as
31
c specified in the dimension statements for a, b and z
32
c in the calling program,
34
c ng is an integer variable set equal to the row dimension
35
c of the two-dimensional array g as specified in the
36
c dimension statement for g in the calling program,
38
c n is an integer variable set equal to the order of the
39
c matrices a and z. n must be not greater than nm,
41
c m is an integer variable set equal to the number of the
42
c columns of the matrix b. m must be not greater than
45
c a is a working precision real two-dimensional variable with
46
c row dimension nm and column dimension at least n
47
c containing the block-hessenberg canonical form of the
48
c matrix a. the elements below the subdiagonal blocks
49
c must be equal to zero,
51
c b is a working precision real two-dimensional variable with
52
c row dimension nm and column dimension at least m
53
c containing the canonical form of the matrix b. the
54
c elements below the invr(1)-th row must be equal to zero,
56
c wr,wi are working precision real one-dimensional variables
57
c of dimension at least n containing the real and
58
c imaginery parts, respectively, of the desired poles,
59
c the poles can be unordered except that the complex
60
c conjugate pairs of poles must appfar consecutively.
61
c note that on output the imaginery parts of the poles
64
c z is a working precision real two-dimensonal variale with
65
c row dimension nm and column dimension at least n
66
c containing the orthogonal transformation matrix produced
67
c in trmcf which reduces the system into canonical form,
69
c inc is an integer variable set equal to the controllability
70
c index of the system,
72
c invr is an integer one-dimensional variable of dimension at
73
c least inc containing the dimensons of the
74
c controllable subsystems in the canonical form.
78
c a contains the upper quast-triangular form of the closed-
79
c loop system matrix a - b * g, that is triangular except
80
c of possible 2x2 blocks on the diagonal,
82
c b contains the transformed matrix b,
84
c g is a working precision real two-dimensional variable with
85
c row dimension ng and column dimension at least n
86
c containing the state feedback matrix g of the original
89
c z contains the orthogonal matrix which reduces the closed-
90
c loop system matrix a - b * g to the upper quasi-
93
c ierr is an integer variable set equal to
94
c zero for normal return,
95
c 1 if the system is not completely controllable,
97
c jpvt is an integer temporary one-dimensonal array of
98
c dimension at least m used in the solution of linear
101
c rm1 is a working precision real temporary two-dimensonal
102
c array of dimension at least mxm used in the solution
103
c of linear equations,
105
c rm2 is a working precision real temporary two-dimensional
106
c array od dimension at least mxmax(2,m) used in the
107
c solution of linear equations,
109
c rv1, are working precision real temporary one-dimensional
110
c rv2 arrays of dimension at least n used to hold the
111
c real and imaginery parts, respectively, of the
112
c eigenvectors during the reduction,
114
c rv3, are working precision real temporary one-dimensional
115
c rv4 arrays of dimension at least m used in the solution
116
c of linear equations.
121
c fortran abs,min,sqrt
123
c p.hr.petkov, higher institute of mechanical and electrical
124
c engineering, sofia, bulgaria.
125
c modified by serge Steer INRIA
134
if (inc .eq. 1) go to 350
140
complx = wi(l) .ne. 0.0d+0
143
if (complx) rv2(i) = 0.0d+0
147
if (.not. complx) go to 20
148
if (mr .eq. 1) rv2(nr) = 1.0d+0
149
if (mr .gt. 1) rv2(nr+1) = 1.0d+0
152
wi(l+1) = t * wi(l+1)
154
c compute and transform eigenvector
156
20 do 200 ip = 1, inc
157
if (ip .eq. inc .and. inc .eq. 2) go to 200
158
if (ip .eq. inc) go to 120
170
if (ip .eq. 1) go to 70
181
if (complx) s = s + abs(rv2(i))
187
if (complx) rv2(i) = rv2(i) / s
190
if (complx .and. np1 .le. n) rv2(np1) = rv2(np1) / s
191
70 if (ip .eq. 1) mp1 = 1
200
s = s - a(i,j) * rv1(j)
204
if (.not. complx) go to 100
205
rm2(ii,1) = rm2(ii,1) + wi(l+1) * rv2(i)
206
s = wr(l+1) * rv2(i) + wi(l) * rv1(i)
209
c la ligne suivante a ete rajoutee par mes soins
211
s = s - a(i,j) * rv2(j)
214
if (np1 .le. n) s = s - a(i,np1) * rv2(np1)
218
c solving linear equations for the eigenvector elements
222
call dqrsm(rm1,m,mr,mr1,rm2,m,nc,rm2,m,ir,jpvt,
224
if (ir .lt. mr) go to 600
229
if (complx) rv2(i) = rm2(ii,2)
232
if (ip .eq. 1 .and. inc .gt. 2) go to 195
234
if (ip .lt. inc) nj = nr1
237
if (ip .gt. 1) ni = ni + invr(inc2)
238
if (ip .gt. 2) ni = ni + 1
239
if (complx .and. ip .gt. 2) ni = min(ni+1,n)
241
if (ip .gt. 1) kmr = mr
246
if (ip .eq. 1) k = nr - kk
248
if (ll .eq. 2) p = rv2(k)
250
if (ll .eq. 2) q = rv2(k+1)
257
if (ll .eq. 2) rv2(k) = t
259
if (ll .eq. 2) rv2(k+1) = 0.0d+0
267
a(k,j) = p * zz + q * a(k+1,j)
268
a(k+1,j) = p * a(k+1,j) - q * zz
273
a(i,k) = p * zz + q * a(i,k+1)
274
a(i,k+1) = p * a(i,k+1) - q * zz
277
if (k .eq. lp1 .and. ll .eq. 1 .or. k .gt. lp1) go to 170
283
b(k,j) = p * zz + q * b(k+1,j)
284
b(k+1,j) = p * b(k+1,j) - q * zz
287
c accumulate transformations
291
z(i,k) = p * zz + q * z(i,k+1)
292
z(i,k+1) = p * z(i,k+1) - q * zz
295
if (.not. complx .or. ll .eq. 2) go to 190
297
rv2(k) = p * zz + q * rv2(k+1)
298
rv2(k+1) = p * rv2(k+1) - q * zz
299
if (k + 2 .gt. n) go to 190
305
if (ip .eq. inc) go to 200
308
if (ip .eq. inc1) go to 200
314
if (complx) go to 250
316
c find one column of g
322
210 rm1(ii,j) = b(i,j)
327
call dqrsm(rm1,m,m1,m,rm2,m,1,g(1,l),ng,ir,jpvt,rv3,rv4)
328
if (ir .lt. m1) go to 600
333
230 a(i,l) = a(i,l) - b(i,j) * g(j,l)
339
c find two columns of g
342
if (lp1 .lt. n) lp1 = lp1 + 1
346
if (l + m1 .gt. n) i = i - 1
348
c la ligne suivante a ete rajoutee par mes soins
350
cxxx if(abs(b(i,j)).le.abs(b(l,j))) i=i-1
351
260 rm1(ii,j) = b(i,j)
354
if (i .eq. l) p = p - (rv2(i) / rv1(i-1)) * wi(i)
357
if (i .eq. l) q = q - wr(i) + (rv2(i-1) / rv1(i-1)) *wi(i)
361
call dqrsm(rm1,m,m1,m,rm2,m,2,rm2,m,ir,jpvt,rv3,rv4)
362
if (ir .lt. m1) go to 600
379
300 a(i,j) = a(i,j) - b(i,k)*g(k,j)
385
if (l .eq. n) go to 500
386
330 invr(inc) = invr(inc) - 1
387
if (invr(inc) .eq. 0) inc = inc - 1
388
if (complx) invr(inc) = invr(inc) - 1
389
if (invr(inc) .eq. 0) inc = inc - 1
392
c find the rest columns of g
394
350 do 370 ii = 1, mr
398
360 rm1(ii,j) = b(i,j)
407
if (ii .lt. jj) rm2(ii,jj) = 0.0d+0
408
if (ii .gt. jj) rm2(ii,jj) = a(i,j)
416
if (wi(i) .ne. 0.0d+0) go to 420
417
rm2(ii,ii) = a(i,i) - wr(i)
418
if (ii .eq. mr) go to 430
419
c la ligne suivante a ete rajoutee par mes soins
421
420 rm2(ii,ii) = a(i,i) - wr(i)
422
rm2(ii,ii+1) = a(i,i+1) - wi(i)
423
rm2(ii+1,ii) = a(i+1,i) - wi(i+1)
424
rm2(ii+1,ii+1) = a(i+1,i+1) - wr(i+1)
426
if (ii .lt. mr) go to 410
427
430 call dqrsm(rm1,m,mr,m,rm2,m,m,rm2,m,ir,jpvt,rv3,rv4)
428
if (ir .lt. mr) go to 600
444
460 a(i,j) = a(i,j) - b(i,k) * g(k,j)
458
510 s = s + g(i,k) * z(j,k)
470
c set error -- the system is not completely controllable
475
c last card of subroutine polmc