|
|
1.1 root 1: subroutine sqrsl(x,ldx,n,k,qraux,y,qy,qty,b,rsd,xb,job,info)
2: integer ldx,n,k,job,info
3: real x(ldx,1),qraux(1),y(1),qy(1),qty(1),b(1),rsd(1),xb(1)
4: c
5: c sqrsl applies the output of sqrdc to compute coordinate
6: c transformations, projections, and least squares solutions.
7: c for k .le. min(n,p), let xk be the matrix
8: c
9: c xk = (x(jpvt(1)),x(jpvt(2)), ... ,x(jpvt(k)))
10: c
11: c formed from columnns jpvt(1), ... ,jpvt(k) of the original
12: c n x p matrix x that was input to sqrdc (if no pivoting was
13: c done, xk consists of the first k columns of x in their
14: c original order). sqrdc produces a factored orthogonal matrix q
15: c and an upper triangular matrix r such that
16: c
17: c xk = q * (r)
18: c (0)
19: c
20: c this information is contained in coded form in the arrays
21: c x and qraux.
22: c
23: c on entry
24: c
25: c x real(ldx,p).
26: c x contains the output of sqrdc.
27: c
28: c ldx integer.
29: c ldx is the leading dimension of the array x.
30: c
31: c n integer.
32: c n is the number of rows of the matrix xk. it must
33: c have the same value as n in sqrdc.
34: c
35: c k integer.
36: c k is the number of columns of the matrix xk. k
37: c must nnot be greater than min(n,p), where p is the
38: c same as in the calling sequence to sqrdc.
39: c
40: c qraux real(p).
41: c qraux contains the auxiliary output from sqrdc.
42: c
43: c y real(n)
44: c y contains an n-vector that is to be manipulated
45: c by sqrsl.
46: c
47: c job integer.
48: c job specifies what is to be computed. job has
49: c the decimal expansion abcde, with the following
50: c meaning.
51: c
52: c if a.ne.0, compute qy.
53: c if b,c,d, or e .ne. 0, compute qty.
54: c if c.ne.0, compute b.
55: c if d.ne.0, compute rsd.
56: c if e.ne.0, compute xb.
57: c
58: c note that a request to compute b, rsd, or xb
59: c automatically triggers the computation of qty, for
60: c which an array must be provided in the calling
61: c sequence.
62: c
63: c on return
64: c
65: c qy real(n).
66: c qy conntains q*y, if its computation has been
67: c requested.
68: c
69: c qty real(n).
70: c qty contains trans(q)*y, if its computation has
71: c been requested. here trans(q) is the
72: c transpose of the matrix q.
73: c
74: c b real(k)
75: c b contains the solution of the least squares problem
76: c
77: c minimize norm2(y - xk*b),
78: c
79: c if its computation has been requested. (note that
80: c if pivoting was requested in sqrdc, the j-th
81: c component of b will be associated with column jpvt(j)
82: c of the original matrix x that was input into sqrdc.)
83: c
84: c rsd real(n).
85: c rsd contains the least squares residual y - xk*b,
86: c if its computation has been requested. rsd is
87: c also the orthogonal projection of y onto the
88: c orthogonal complement of the column space of xk.
89: c
90: c xb real(n).
91: c xb contains the least squares approximation xk*b,
92: c if its computation has been requested. xb is also
93: c the orthogonal projection of y onto the column space
94: c of x.
95: c
96: c info integer.
97: c info is zero unless the computation of b has
98: c been requested and r is exactly singular. in
99: c this case, info is the index of the first zero
100: c diagonal element of r and b is left unaltered.
101: c
102: c the parameters qy, qty, b, rsd, and xb are not referenced
103: c if their computation is not requested and in this case
104: c can be replaced by dummy variables in the calling program.
105: c to save storage, the user may in some cases use the same
106: c array for different parameters in the calling sequence. a
107: c frequently occuring example is when one wishes to compute
108: c any of b, rsd, or xb and does not need y or qty. in this
109: c case one may identify y, qty, and one of b, rsd, or xb, while
110: c providing separate arrays for anything else that is to be
111: c computed. thus the calling sequence
112: c
113: c call sqrsl(x,ldx,n,k,qraux,y,dum,y,b,y,dum,110,info)
114: c
115: c will result in the computation of b and rsd, with rsd
116: c overwriting y. more generally, each item in the following
117: c list contains groups of permissible identifications for
118: c a single callinng sequence.
119: c
120: c 1. (y,qty,b) (rsd) (xb) (qy)
121: c
122: c 2. (y,qty,rsd) (b) (xb) (qy)
123: c
124: c 3. (y,qty,xb) (b) (rsd) (qy)
125: c
126: c 4. (y,qy) (qty,b) (rsd) (xb)
127: c
128: c 5. (y,qy) (qty,rsd) (b) (xb)
129: c
130: c 6. (y,qy) (qty,xb) (b) (rsd)
131: c
132: c in any group the value returned in the array allocated to
133: c the group corresponds to the last member of the group.
134: c
135: c linpack. this version dated 08/14/78 .
136: c g.w. stewart, university of maryland, argonne national lab.
137: c
138: c sqrsl uses the following functions and subprograms.
139: c
140: c blas saxpy,scopy,sdot
141: c fortran abs,min0,mod
142: c
143: c internal variables
144: c
145: integer i,j,jj,ju,kp1
146: real sdot,t,temp
147: logical cb,cqy,cqty,cr,cxb
148: c
149: c
150: c set info flag.
151: c
152: info = 0
153: c
154: c determine what is to be computed.
155: c
156: cqy = job/10000 .ne. 0
157: cqty = mod(job,10000) .ne. 0
158: cb = mod(job,1000)/100 .ne. 0
159: cr = mod(job,100)/10 .ne. 0
160: cxb = mod(job,10) .ne. 0
161: ju = min0(k,n-1)
162: c
163: c special action when n=1.
164: c
165: if (ju .ne. 0) go to 40
166: if (cqy) qy(1) = y(1)
167: if (cqty) qty(1) = y(1)
168: if (cxb) xb(1) = y(1)
169: if (.not.cb) go to 30
170: if (x(1,1) .ne. 0.0e0) go to 10
171: info = 1
172: go to 20
173: 10 continue
174: b(1) = y(1)/x(1,1)
175: 20 continue
176: 30 continue
177: if (cr) rsd(1) = 0.0e0
178: go to 250
179: 40 continue
180: c
181: c set up to compute qy or qty.
182: c
183: if (cqy) call scopy(n,y,1,qy,1)
184: if (cqty) call scopy(n,y,1,qty,1)
185: if (.not.cqy) go to 70
186: c
187: c compute qy.
188: c
189: do 60 jj = 1, ju
190: j = ju - jj + 1
191: if (qraux(j) .eq. 0.0e0) go to 50
192: temp = x(j,j)
193: x(j,j) = qraux(j)
194: t = -sdot(n-j+1,x(j,j),1,qy(j),1)/x(j,j)
195: call saxpy(n-j+1,t,x(j,j),1,qy(j),1)
196: x(j,j) = temp
197: 50 continue
198: 60 continue
199: 70 continue
200: if (.not.cqty) go to 100
201: c
202: c compute trans(q)*y.
203: c
204: do 90 j = 1, ju
205: if (qraux(j) .eq. 0.0e0) go to 80
206: temp = x(j,j)
207: x(j,j) = qraux(j)
208: t = -sdot(n-j+1,x(j,j),1,qty(j),1)/x(j,j)
209: call saxpy(n-j+1,t,x(j,j),1,qty(j),1)
210: x(j,j) = temp
211: 80 continue
212: 90 continue
213: 100 continue
214: c
215: c set up to compute b, rsd, or xb.
216: c
217: if (cb) call scopy(k,qty,1,b,1)
218: kp1 = k + 1
219: if (cxb) call scopy(k,qty,1,xb,1)
220: if (cr .and. k .lt. n) call scopy(n-k,qty(kp1),1,rsd(kp1),1)
221: if (.not.cxb .or. kp1 .gt. n) go to 120
222: do 110 i = kp1, n
223: xb(i) = 0.0e0
224: 110 continue
225: 120 continue
226: if (.not.cr) go to 140
227: do 130 i = 1, k
228: rsd(i) = 0.0e0
229: 130 continue
230: 140 continue
231: if (.not.cb) go to 190
232: c
233: c compute b.
234: c
235: do 170 jj = 1, k
236: j = k - jj + 1
237: if (x(j,j) .ne. 0.0e0) go to 150
238: info = j
239: c ......exit
240: go to 180
241: 150 continue
242: b(j) = b(j)/x(j,j)
243: if (j .eq. 1) go to 160
244: t = -b(j)
245: call saxpy(j-1,t,x(1,j),1,b,1)
246: 160 continue
247: 170 continue
248: 180 continue
249: 190 continue
250: if (.not.cr .and. .not.cxb) go to 240
251: c
252: c compute rsd or xb as required.
253: c
254: do 230 jj = 1, ju
255: j = ju - jj + 1
256: if (qraux(j) .eq. 0.0e0) go to 220
257: temp = x(j,j)
258: x(j,j) = qraux(j)
259: if (.not.cr) go to 200
260: t = -sdot(n-j+1,x(j,j),1,rsd(j),1)/x(j,j)
261: call saxpy(n-j+1,t,x(j,j),1,rsd(j),1)
262: 200 continue
263: if (.not.cxb) go to 210
264: t = -sdot(n-j+1,x(j,j),1,xb(j),1)/x(j,j)
265: call saxpy(n-j+1,t,x(j,j),1,xb(j),1)
266: 210 continue
267: x(j,j) = temp
268: 220 continue
269: 230 continue
270: 240 continue
271: 250 continue
272: return
273: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.