This is an example driver routine for running LSQR. It generates a test problem, solves it, and examines the results. Note that subroutine aprod must be declared external if it is used only in the call to LSQR (and acheck).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(test_solver), | intent(inout) | :: | me | |||
| integer | :: | m | ||||
| integer | :: | n | ||||
| integer | :: | nduplc | ||||
| integer | :: | npower | ||||
| real(kind=wp) | :: | damp |
subroutine test ( me, m, n, nduplc, npower, damp ) class(test_solver),intent(inout) :: me integer :: m, n, nduplc, npower real(wp) :: damp integer,parameter :: maxm = 2000 integer,parameter :: maxn = 2000 integer,parameter :: mxmn = 2000 real(wp),parameter :: eps = epsilon(1.0_wp) !! machine precision character(len=34),parameter :: line = '----------------------------------' integer :: inform, istop, itnlim, j, itn, maxmn, minmn, nprint integer :: locd, lochy, lochz, locw, ltotal logical :: wantse real(wp) :: b(maxm), u(maxm), & v(maxn), w(mxmn), x(maxn), & se(maxn), xtrue(maxn), y(mxmn) real(wp) :: atol, btol, conlim, & anorm, acond, rnorm, arnorm, & enorm, etol, xnorm, test1, test2, test3, wnorm if (m > maxm .or. n > maxn) then ! m or n too large. write(me%nout, 8000) return end if ! Set the desired solution xtrue. ! For least-squares problems, this is it. ! For underdetermined systems, lstp may alter it. do j = 1, n ! xtrue(j) = one xtrue(j) = j * 0.1_wp end do ! Generate the specified test problem. ! The workspace array rw is used for the following vectors: ! d(minmn), hy(m), hz(n), w(maxmn). ! The vectors d, hy, hz will define the test matrix A. ! w is needed for workspace in aprod1 and aprod2. maxmn = max( m, n ) minmn = min( m, n ) locd = 1 lochy = locd + minmn lochz = lochy + m locw = lochz + n ltotal = locw + maxmn - 1 if (ltotal > lenrw) then ! Not enough workspace. write(me%nout, 9000) ltotal end if call me%lstp ( m, n, maxmn, minmn, nduplc, npower, damp, xtrue, & b, me%rw(locd), me%rw(lochy), me%rw(lochz), me%rw(locw), & acond, rnorm ) write(me%nout, 1000) line, line, & m, n, nduplc, npower, damp, acond, rnorm, & line, line ! Check that aprod generates y + Ax and x + A'y consistently. call me%acheck( m, n, me%nout, eps, v, w, x, y, inform ) if (inform > 0) then write(me%nout, '(a)') ' Check eps and power in subroutine acheck' stop end if ! Solve the problem defined by aprod, damp and b. ! Copy the rhs vector b into u (LSQR will overwrite u) ! and set the other input parameters for LSQR. ! We ask for standard errors only if they are well-defined. call dcopy ( m, b, 1, u, 1 ) !--- wantse = m > n .or. damp > zero wantse = .false. atol = eps**0.99_wp btol = atol conlim = 1000.0_wp * acond itnlim = 4*(m + n + 50) call me%lsqr( m, n, damp, wantse, & u, v, w, x, se, & atol, btol, conlim, itnlim, me%nout, & istop, itn, anorm, acond, rnorm, arnorm, xnorm ) ! Examine the results. !- if (damp == zero) then !- write(nout, 2000) xnorm, rnorm, arnorm !- else !- write(nout, 2100) damp, xnorm, rnorm, arnorm !- end if call me%xcheck( m, n, me%nout, anorm, damp, eps, & b, u, v, w, x, & inform, test1, test2, test3 ) ! Print the solution and standard error estimates from LSQR. nprint = min( m, n, 8 ) write(me%nout, 2500) (j, x(j) , j = 1, nprint) if ( wantse ) then write(me%nout, 2600) (j, se(j), j = 1, nprint) end if ! Print a clue about whether the solution looks OK. do j = 1, n w(j) = x(j) - xtrue(j) end do wnorm = dnrm2 ( n, w , 1 ) xnorm = dnrm2 ( n, xtrue, 1 ) enorm = wnorm / (one + xnorm) etol = 0.001_wp if (enorm <= etol) then write(me%nout, 3000) enorm else write(me%nout, 3100) enorm end if return 1000 format(1p & // 1x, 2a & / ' Least-Squares Test Problem P(', 4i5, e12.2, ' )' & // ' Condition no. =', e12.4, ' Residual function =', e17.9 & / 1x, 2a) 2000 format(1p & // ' We are solving min norm(Ax - b) with no damping.' & // ' Estimates from LSQR:' & / ' norm(x) =', e10.3, ' = xnorm' & / ' norm(r) =', e10.3, ' = rnorm' & / ' norm(A''r) =', e10.3, ' = arnorm') 2100 format(1p & // ' We are solving min norm(Ax - b) with damp =', e10.3 & / ' (damp*x)' & // ' Estimates from LSQR:' & / ' norm(x) =', e10.3, ' = xnorm' & / ' norm(rbar) =', e10.3, ' = rnorm' & / ' norm(Abar''rbar) =', e10.3, ' = arnorm') 2500 format(//' Solution x:' / 4(i6, g14.6)) 2600 format(/ ' Standard errors se:' / 4(i6, g14.6)) 3000 format(1p / ' LSQR appears to be successful.', & ' Relative error in x =', e10.2) 3100 format(1p / ' LSQR appears to have failed. ', & ' Relative error in x =', e10.2) 8000 format(/ ' XXX m or n is too large.') 9000 format(/ ' XXX Insufficient workspace.', & ' The length of rw should be at least', i6) end subroutine test