/[ascend]/trunk/minos54/mi65rmod.f
ViewVC logotype

Annotation of /trunk/minos54/mi65rmod.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download)
Fri Oct 29 20:54:12 2004 UTC (19 years, 11 months ago) by aw0a
File size: 16666 byte(s)
Setting up web subdirectory in repository
1 aw0a 1 ************************************************************************
2     *
3     * File mi65rmod fortran.
4     *
5     * m6bfgs m6bswp m6radd m6rcnd m6rdel
6     * m6rmod m6rset m6rsol m6swap
7     *
8     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9    
10     subroutine m6bfgs( maxr, n, nr, r, g, g2, p, v,
11     $ step, told, tolz, inform )
12    
13     implicit double precision (a-h,o-z)
14     double precision r(nr), g(n), g2(n), p(n), v(n)
15    
16     * ------------------------------------------------------------------
17     * m6bfgs applies the BFGS update to the upper-triangular matrix r,
18     * which holds the cholesky factor of the quasi-newton approximation
19     * of the (projected) hessian.
20     *
21     * r contains a triangle of size ncolr = min( n, maxr ).
22     * If n .gt. maxr, r also contains a diagonal of size n - maxr.
23     *
24     * p holds the search direction. It is overwritten.
25     * v must satisfy r(t)*v = g. It is overwritten.
26     *
27     * On exit,
28     * inform = 0 if no update was performed,
29     * = 1 if the update was successful,
30     * = 2 if it was nearly singular.
31     * ------------------------------------------------------------------
32    
33     intrinsic abs, min, sqrt
34     parameter ( one = 1.0d+0 )
35    
36     inform = 0
37     ncolr = min( n, maxr )
38     gtp = ddot ( n, g , 1, p, 1 )
39     gtp2 = ddot ( n, g2, 1, p, 1 )
40     if (gtp2 .le. 0.91*gtp) return
41    
42     delta1 = one / sqrt( abs( gtp ) )
43     delta2 = one / sqrt( step*(gtp2 - gtp) )
44    
45     * Normalize v and change its sign.
46    
47     call dscal ( n, (- delta1), v, 1 )
48    
49     * Avoid cancellation error in forming the new vector p.
50    
51     if ( abs( delta1/delta2 - one ) .ge. 0.5d+0) then
52     do 100 j = 1, n
53     p(j) = delta2*( g2(j) - g(j) ) + delta1*g(j)
54     100 continue
55     else
56     d = delta1 - delta2
57     do 120 j = 1, n
58     p(j) = delta2*g2(j) + d*g(j)
59     120 continue
60     end if
61    
62     * Find the last nonzero in v.
63    
64     do 450 ii = 1, ncolr
65     lastv = ncolr + 1 - ii
66     if (abs( v(lastv) ) .gt. tolz) go to 500
67     450 continue
68     lastv = 1
69    
70     * Triangularize r + v * p(t).
71    
72     500 call m6rmod( ncolr, nr, r, v, p, lastv, told, tolz, inform )
73    
74     * Deal with surplus diagonals of r.
75    
76     if (n .gt. maxr) then
77     j1 = maxr + 1
78     l = maxr*j1/2
79     do 650 j = j1, n
80     l = l + 1
81     r(l) = r(l) + v(j)*p(j)
82     650 continue
83     end if
84    
85     * end of m6bfgs
86     end
87    
88     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
89    
90     subroutine m6bswp( n, nr, r, v, w, lastv, told, tolz, inform )
91    
92     implicit double precision (a-h,o-z)
93     double precision r(nr), v(n), w(n)
94    
95     * ------------------------------------------------------------------
96     * m6bswp modifies the upper-triangular matrix r
97     * to account for a basis exchange in which the lastv-th
98     * superbasic variable becomes basic. r is changed to
99     * r + v*w(t), which is triangularized by r1mod,
100     * where v is the lastv-th column of r, and w is input.
101     * ------------------------------------------------------------------
102    
103     * Set v = lastv-th column of r and find its norm.
104    
105     l = (lastv - 1)*lastv/2
106     call dcopy ( lastv, r(l+1), 1, v, 1 )
107     vnorm = dasum ( lastv, v, 1 )
108     call m6rmod( n, nr, r, v, w, lastv,
109     $ (vnorm*told), (vnorm*tolz), inform )
110    
111     * end of m6bswp
112     end
113    
114     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
115    
116     subroutine m6radd( maxr, nr, ns, r )
117    
118     implicit double precision (a-h,o-z)
119     double precision r(nr)
120    
121     * ------------------------------------------------------------------
122     * m6radd adds column ns to the upper triangular matrix r.
123     * In this version (Sep 1984) it is just a unit vector.
124     *
125     * Modified Jan 1983 to add a diagonal only, if ns .gt. maxr.
126     * ------------------------------------------------------------------
127    
128     parameter ( zero = 0.0d+0, one = 1.0d+0 )
129    
130     if (ns .eq. 1) then
131     r(1) = one
132     else if (ns .le. maxr) then
133     ldiag1 = (ns - 1)*ns/2
134     ldiag2 = ldiag1 + ns
135     call dload ( ns, zero, r(ldiag1+1), 1 )
136     r(ldiag2) = one
137     else
138     ldiag2 = maxr*(maxr + 1)/2 + (ns - maxr)
139     r(ldiag2) = one
140     end if
141    
142     * end of m6radd
143     end
144    
145     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
146    
147     subroutine m6rcnd( maxr, nr, ns, r, dmax, dmin, cond )
148    
149     implicit double precision (a-h,o-z)
150     double precision r(nr)
151    
152     * ------------------------------------------------------------------
153     * m6rcnd finds the largest and smallest diagonals of the
154     * upper triangular matrix r, and returns the square of their ratio.
155     * This is a lower bound on the condition number of r(t)*r.
156     * ------------------------------------------------------------------
157    
158     intrinsic abs, max, min
159    
160     ncolr = min( maxr, ns )
161     dmax = abs( r(1) )
162     dmin = dmax
163    
164     if (ncolr .gt. 1) then
165     l = 1
166     do 100 j = 2, ncolr
167     l = l + j
168     d = abs( r(l) )
169     dmax = max( dmax, d )
170     dmin = min( dmin, d )
171     100 continue
172     end if
173    
174     cond = (dmax/dmin)**2
175    
176     * end of m6rcnd
177     end
178    
179     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
180    
181     subroutine m6rdel( m, maxr, nr, ns, ms,
182     $ kb, bbl, bbu, grd, r, rg, x, jq, rset )
183    
184     implicit double precision (a-h,o-z)
185     integer kb(ms)
186     double precision bbl(ms), bbu(ms), grd(ms)
187     double precision r(nr), rg(ns), x(ms)
188     logical rset
189    
190     * ------------------------------------------------------------------
191     * m6rdel deletes the jq-th superbasic variable from r
192     * and from various arrays kb, bbl, bbu, grd, rg, x.
193     * ------------------------------------------------------------------
194    
195     common /m1eps / eps,eps0,eps1,eps2,eps3,eps4,eps5,plinfy
196    
197     intrinsic abs, max, min, sqrt
198     parameter ( zero = 0.0d+0 )
199    
200     if (jq .eq. ns) return
201     if (.not. rset) go to 500
202    
203     * Delete the jq-th column of r and triangularize the
204     * remaining columns using a partial forward sweep of rotations.
205    
206     ncolr = min( maxr, ns )
207     k = jq*(jq + 1)/2
208    
209     do 50 i = jq + 1, ncolr
210     k = k + i
211     t1 = r(k-1)
212     t2 = r(k)
213     d = sqrt( t1*t1 + t2*t2 )
214     r(k-1) = d
215     if (i .eq. ncolr) go to 20
216     sn = t2/d
217     cs = t1/d
218     if (abs( cs ) .le. eps0) cs = zero
219     j1 = i + 1
220     k1 = k + i
221     do 10 j = j1, ncolr
222     t1 = r(k1-1)
223     t2 = r(k1)
224     r(k1-1) = cs*t1 + sn*t2
225     r(k1) = sn*t1 - cs*t2
226     k1 = k1 + j
227     10 continue
228     20 k1 = i - 1
229     j2 = k - i
230     j1 = j2 - i + 2
231     do 30 j = j1, j2
232     r(j) = r(j+k1)
233     30 continue
234     50 continue
235    
236     * If necessary, clear out the last column of r.
237    
238     if (ns .gt. maxr) then
239     lastr = maxr*(maxr + 1)/2
240     l = lastr - maxr + 1
241     if (jq .le. maxr) call dload ( maxr, zero, r(l), 1 )
242    
243     * Shift surplus diagonals of r to the left.
244    
245     j1 = max( maxr, jq )
246     j2 = ns - 1
247     l = lastr + (j1 - maxr)
248     do 320 j = j1, j2
249     r(l) = r(l+1)
250     320 continue
251     end if
252    
253     * Shift all the arrays one place to the left.
254    
255     500 j2 = ns - 1
256     do 550 j = jq, j2
257     rg(j) = rg(j+1)
258     k = m + j
259     kb(k) = kb(k+1)
260     bbl(k) = bbl(k+1)
261     bbu(k) = bbu(k+1)
262     grd(k) = grd(k+1)
263     x(k) = x(k+1)
264     550 continue
265    
266     * end of m6rdel
267     end
268    
269     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
270    
271     subroutine m6rmod( n, nr, r, v, w, lastv, told, tolz, inform )
272    
273     implicit double precision (a-h,o-z)
274     double precision r(nr), v(n), w(n)
275    
276     * ------------------------------------------------------------------
277     * m6rmod modifies the upper-triangular matrix r so that
278     * q*(r + v*w(t)) is upper triangular, where q is orthogonal,
279     * v and w are vectors, and the new r overwrites the old.
280     *
281     * q is the product of two sweeps of plane rotations (not stored).
282     * These affect the lastv-th row of r, which is temporarily held
283     * in the vector v. Thus, v is overwritten. w is not altered.
284     *
285     * lastv points to the last nonzero of v. The value lastv = n
286     * would always be ok, but sometimes it is known to be less
287     * than n, so q reduces to two partial sweeps of
288     * rotations.
289     *
290     * told is a tolerance on the lastv-th diagonal of r.
291     * tolz is a tolerance for negligible elements in v.
292     *
293     * On exit,
294     * inform = 1 if the diagonal of r is larger than told,
295     * = 2 if not (in which case it is reset to told).
296     * ------------------------------------------------------------------
297    
298     intrinsic sqrt
299     parameter ( zero = 0.0d+0 )
300    
301     vlast = v(lastv)
302     lm1 = lastv - 1
303     lastr = lastv*(lastv + 1)/2
304    
305     * Copy the lastv-th row of r into the end of v.
306    
307     l = lastr
308     do 100 j = lastv, n
309     v(j) = r(l)
310     l = l + j
311     100 continue
312    
313     * Reduce v to a multiple of e(lastv)
314     * using a partial backward sweep of rotations.
315     * This fills in the lastv-th row of r (held in v).
316    
317     v2 = vlast**2
318     ldiag = lastr
319    
320     do 300 ii = 1, lm1
321     i = lastv - ii
322     ldiag = ldiag - i - 1
323     s = v(i)
324     v(i) = zero
325     if (abs(s) .le. tolz) go to 300
326     v2 = s**2 + v2
327     root = sqrt(v2)
328     cs = vlast/root
329     sn = s/root
330     vlast = root
331     l = ldiag
332    
333     do 200 j = i, n
334     s = v(j)
335     t = r(l)
336     v(j) = cs*s + sn*t
337     r(l) = sn*s - cs*t
338     l = l + j
339     200 continue
340     300 continue
341    
342     * Set v = v + vlast*w.
343    
344     call daxpy ( n, vlast, w, 1, v, 1 )
345    
346     * Eliminate the front of the lastv-th row of r (held in v)
347     * using a partial forward sweep of rotations.
348    
349     ldiag = 0
350    
351     do 700 i = 1, lm1
352     ldiag = ldiag + i
353     t = v(i)
354     if (abs(t) .le. tolz) go to 700
355     s = r(ldiag)
356     root = sqrt(s**2 + t**2)
357     cs = s/root
358     sn = t/root
359     r(ldiag) = root
360     l = ldiag + i
361    
362     do 600 j = i + 1, n
363     s = r(l)
364     t = v(j)
365     r(l) = cs*s + sn*t
366     v(j) = sn*s - cs*t
367     l = l + j
368     600 continue
369     700 continue
370    
371     * Insert the new lastv-th row of r.
372    
373     l = lastr
374     do 900 j = lastv, n
375     r(l) = v(j)
376     l = l + j
377     900 continue
378    
379     * Test for (unlikely) singularity.
380    
381     inform = 1
382     if (abs( r(lastr) ) .le. told) then
383     inform = 2
384     r(lastr) = told
385     end if
386    
387     * end of m6rmod
388     end
389    
390     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
391    
392     subroutine m6rset( maxr, nr, ns, r, cond )
393    
394     implicit double precision (a-h,o-z)
395     double precision r(nr)
396    
397     * ------------------------------------------------------------------
398     * m6rset alters r, the upper-triangular factor of the
399     * approximation to the reduced hessian.
400     *
401     * If r(1) = zero, r does not exist.
402     * In this case, r is initialized to the identity matrix.
403     *
404     * Otherwise, r already exists and we attempt to make it better
405     * conditioned by scaling its columns by the square roots of its
406     * current diagonals.
407     * ------------------------------------------------------------------
408    
409     common /m1file/ iread,iprint,isumm
410    
411     intrinsic abs, max, min, sqrt
412     parameter ( zero = 0.0d+0, one = 1.0d+0 )
413    
414     cond = one
415     ncolr = min( maxr, ns )
416     if (ncolr .eq. 0 ) return
417    
418     dmax = abs( r(1) )
419     if (dmax .eq. zero) then
420    
421     * Set r = the identity.
422    
423     l = ncolr*(ncolr + 1)/2
424     call dload ( l, zero, r, 1 )
425     ldiag = 0
426    
427     do 100 k = 1, ncolr
428     ldiag = ldiag + k
429     r(ldiag) = one
430     100 continue
431    
432     do 120 k = maxr + 1, ns
433     ldiag = ldiag + 1
434     r(ldiag) = one
435     120 continue
436     else
437    
438     * Scale the columns of r.
439    
440     dmin = dmax
441     ldiag = 0
442    
443     do 250 k = 1, ncolr
444     l = ldiag + 1
445     ldiag = ldiag + k
446     diag = abs( r(ldiag) )
447     dmax = max( dmax, diag )
448     dmin = min( dmin, diag )
449     s = one / sqrt( diag )
450     do 240 i = l, ldiag
451     r(i) = r(i)*s
452     240 continue
453     250 continue
454    
455     cond = dmax / dmin
456     if (iprint .gt. 0) write(iprint, 2000) dmax, dmin, cond
457     end if
458     return
459    
460     2000 format(/ ' XXX Hessian modified. Diags =', 1p, 2e11.2,
461     $ ', Cond R(t)*R =', e11.2)
462    
463     * end of m6rset
464     end
465    
466     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
467    
468     subroutine m6rsol( mode, maxr, nr, ns, r, y )
469    
470     implicit double precision (a-h,o-z)
471     double precision r(nr), y(ns)
472    
473     * ------------------------------------------------------------------
474     * m6rsol solves R*x = y or R(t)*x = y, where R is an
475     * upper-triangular matrix stored by columns in r(nr).
476     * The solution x overwrites y.
477     * ------------------------------------------------------------------
478    
479     intrinsic min
480    
481     ncolr = min( maxr, ns )
482    
483     if (mode .eq. 1) then
484    
485     * mode = 1 -- solve R*y = y.
486    
487     l = ncolr*(ncolr + 1)/2
488     do 120 i = ncolr, 2, -1
489     t = y(i) / r(l)
490     y(i) = t
491     l = l - i
492     call daxpy ( i-1, (-t), r(l+1), 1, y, 1 )
493     120 continue
494     y(1) = y(1) / r(1)
495     else
496    
497     * mode = 2 -- solve R(t)*y = y.
498    
499     y(1) = y(1) / r(1)
500     l = 1
501     do 220 i = 2, ncolr
502     t = ddot ( i-1, r(l+1), 1, y, 1 )
503     l = l + i
504     y(i) = (y(i) - t) / r(l)
505     220 continue
506     end if
507    
508     * Deal with surplus diagonals of r.
509    
510     if (ns .gt. maxr) then
511     l = maxr*i/2
512     do 320 j = maxr + 1, ns
513     l = l + 1
514     y(j) = y(j) / r(l)
515     320 continue
516     end if
517    
518     * end of m6rsol
519     end
520    
521     *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
522    
523     subroutine m6swap( m, maxr, nr, ns, ms,
524     $ kb, bbl, bbu, grd, r, rg, x )
525    
526     implicit double precision (a-h,o-z)
527     integer kb(ms)
528     double precision bbl(ms), bbu(ms), grd(ms)
529     double precision r(nr), rg(ns), x(ms)
530    
531     * ------------------------------------------------------------------
532     * m6swap (superbasic swap) finds the largest reduced gradient in
533     * the range rg(maxr+1), ..., rg(ns) and swaps it into position
534     * maxr + 1 (so we know where it is).
535     * ------------------------------------------------------------------
536    
537     k1 = maxr + 1
538     if (ns .gt. k1) then
539     nz2 = ns - maxr
540     k2 = maxr + idamax( nz2, rg(k1), 1 )
541     if (k2 .gt. k1) then
542     j = m + k1
543     k = m + k2
544     lastr = maxr*k1/2
545     ldiag1 = lastr + 1
546     ldiag2 = lastr + (k2 - maxr)
547    
548     rdiag1 = r(ldiag1)
549     rg1 = rg(k1)
550     j1 = kb(j)
551     bl1 = bbl(j)
552     bu1 = bbu(j)
553     grd1 = grd(j)
554     x1 = x(j)
555    
556     r(ldiag1) = r(ldiag2)
557     rg(k1) = rg(k2)
558     kb(j) = kb(k)
559     bbl(j) = bbl(k)
560     bbu(j) = bbu(k)
561     grd(j) = grd(k)
562     x(j) = x(k)
563    
564     r(ldiag2) = rdiag1
565     rg(k2) = rg1
566     kb(k) = j1
567     bbl(k) = bl1
568     bbu(k) = bu1
569     grd(k) = grd1
570     x(k) = x1
571     end if
572     end if
573    
574     * end of m6swap
575     end

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22