NAG Library Manual, Mark 30.2
Interfaces:  FL   CL   CPP   AD 

NAG FL Interface Introduction
Example description
    Program f08ztfe

!     F08ZTF Example Program Text

!     Mark 30.2 Release. NAG Copyright 2024.

!     .. Use Statements ..
      Use nag_library, Only: dznrm2, nag_wp, zgemv, zggrqf, ztrmv, ztrtrs,     &
                             zunmqr, zunmrq
!     .. Implicit None Statement ..
      Implicit None
!     .. Parameters ..
      Complex (Kind=nag_wp), Parameter :: one = (1.0E0_nag_wp,0.0E0_nag_wp)
      Integer, Parameter               :: nb = 64, nin = 5, nout = 6
!     .. Local Scalars ..
      Real (Kind=nag_wp)               :: rnorm
      Integer                          :: i, info, lda, ldb, lwork, m, n, p
!     .. Local Arrays ..
      Complex (Kind=nag_wp), Allocatable :: a(:,:), b(:,:), c(:), d(:),        &
                                          taua(:), taub(:), work(:), x(:)
!     .. Intrinsic Procedures ..
      Intrinsic                        :: min
!     .. Executable Statements ..
      Write (nout,*) 'F08ZTF Example Program Results'
      Write (nout,*)
!     Skip heading in data file
      Read (nin,*)
      Read (nin,*) m, n, p
      lda = m
      ldb = p
      lwork = nb*(p+n)
      Allocate (a(lda,n),b(ldb,n),c(m),d(p),taua(n),taub(n),work(lwork),x(n))

!     Read A, B, C and D from data file

      Read (nin,*)(a(i,1:n),i=1,m)
      Read (nin,*)(b(i,1:n),i=1,p)
      Read (nin,*) c(1:m)
      Read (nin,*) d(1:p)

!     Compute the generalized RQ factorization of (B,A) as
!     B = (0 T12)*Q,   A = Z*(R11 R12)*Q, where T12 and R11
!                            ( 0  R22)
!     are upper triangular
!     The NAG name equivalent of zggrqf is f08ztf
      Call zggrqf(p,m,n,b,ldb,taub,a,lda,taua,work,lwork,info)

!     Set Qx = y. The problem then reduces to:
!                 minimize (Ry - Z^Hc) subject to Ty = d
!     Update c = Z^H*c -> minimize (Ry-c)
!     The NAG name equivalent of zunmqr is f08auf
      Call zunmqr('Left','Conjugate transpose',m,1,min(m,n),a,lda,taua,c,m,    &
        work,lwork,info)

!     Putting y = (y1), solve T12*w = d for w, storing result in d
!                 (w )
!     The NAG name equivalent of ztrtrs is f07tsf
      Call ztrtrs('Upper','No transpose','Non-unit',p,1,b(1,n-p+1),ldb,d,p,    &
        info)

      If (info>0) Then
        Write (nout,*) 'The upper triangular factor of B is singular, '
        Write (nout,*) 'the least squares solution could not be computed'
        Go To 100
      End If

!     From first n-p rows of (Ry-c) we have
!     R11*y1 + R12*w = c(1:n-p) = c1
!     Form c1 = c1 - R12*w = R11*y1

!     The NAG name equivalent of zgemv is f06saf
      Call zgemv('No transpose',n-p,p,-one,a(1,n-p+1),lda,d,1,one,c,1)

!     Solve R11*y1 = c1 for y1, storing result in c(1:n-p)
!     The NAG name equivalent of ztrtrs is f07tsf
      Call ztrtrs('Upper','No transpose','Non-unit',n-p,1,a,lda,c,n-p,info)

      If (info>0) Then
        Write (nout,*) 'The upper triangular factor of A is singular, '
        Write (nout,*) 'the least squares solution could not be computed'
        Go To 100
      End If

!     Copy y into x (first y1, then w)
      x(1:n-p) = c(1:n-p)
      x(n-p+1:n) = d(1:p)

!     Compute x = (Q**H)*y
!     The NAG name equivalent of zunmrq is f08cxf
      Call zunmrq('Left','Conjugate transpose',n,1,p,b,ldb,taub,x,n,work,      &
        lwork,info)

!     The least squares solution is in x, the remainder here is to compute
!     the residual, which equals c2 - R22*w.

!     Upper triangular part of R22 first
!     The NAG name equivalent of ztrmv is f06sff
      Call ztrmv('Upper','No transpose','Non-unit',min(m,n)-n+p,               &
        a(n-p+1,n-p+1),lda,d,1)
      Do i = 1, min(m,n) - n + p
        c(n-p+i) = c(n-p+i) - d(i)
      End Do

      If (m<n) Then

!       Additional rectangular part of R22
!       The NAG name equivalent of zgemv is f06saf
        Call zgemv('No transpose',m-n+p,n-m,-one,a(n-p+1,m+1),lda,d(m-n+p+1),  &
          1,one,c(n-p+1),1)

      End If

!     Compute norm of residual sum of squares.
!     The NAG name equivalent of dznrm2 is f06jjf
      rnorm = dznrm2(m-(n-p),c(n-p+1),1)

!     Print least squares solution x
      Write (nout,*) 'Constrained least squares solution'
      Write (nout,99999) x(1:n)

!     Print estimate of the square root of the residual sum of
!     squares
      Write (nout,*)
      Write (nout,*) 'Square root of the residual sum of squares'
      Write (nout,99998) rnorm

100   Continue

99999 Format (4(' (',F7.4,',',F7.4,')',:))
99998 Format (1X,1P,E10.2)
    End Program f08ztfe