Determine an N1-vector W, and an N2-vector Z which minimizes the Euclidean length of W subject to GW+HZ >= Y. This is the least projected distance problem, LPDP. The matrices G and H are of respective dimensions M by N1 and M by N2.
Called by subprogram DLSI.
The matrix
(G H Y)
occupies rows 1,...,M and cols 1,...,N1+N2+1 of A(*,*).
The solution (W) is returned in X(*).
(Z)
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp) | :: | a(mda,*) |
|
|||
integer, | intent(in) | :: | mda | |||
integer | :: | m | ||||
integer, | intent(in) | :: | n1 | |||
integer, | intent(in) | :: | n2 | |||
real(kind=wp) | :: | prgopt(*) | ||||
real(kind=wp) | :: | x(*) |
|
|||
real(kind=wp) | :: | wnorm | ||||
integer, | intent(out) | :: | mode |
The value of MODE indicates the status of the computation after returning to the user.
|
||
real(kind=wp) | :: | ws(*) |
|
|||
integer | :: | is(*) |
|
subroutine dlpdp (a, mda, m, n1, n2, prgopt, x, wnorm, mode, ws, is) integer,intent(in) :: mda integer :: m integer,intent(in) :: n1 integer,intent(in) :: n2 real(wp) :: a(mda,*) !! `A(MDA,N+1)`, where `N=N1+N2`. real(wp) :: prgopt(*) real(wp) :: x(*) !! `X(N)`, where `N=N1+N2`. real(wp) :: wnorm integer,intent(out) :: mode !! The value of MODE indicates the status of !! the computation after returning to the user. !! !! * `MODE=1` The solution was successfully obtained. !! * `MODE=2` The inequalities are inconsistent. real(wp) :: ws(*) !! `WS((M+2)*(N+7))`, where `N=N1+N2`. This is a slight overestimate for WS(*). integer :: is(*) !! `IS(M+N+1)`, where `N=N1+N2`. integer :: i, iw, ix, j, l, modew, n, np1 real(wp) :: rnorm, sc, ynorm real(wp),parameter :: zero = 0.0_wp real(wp),parameter :: one = 1.0_wp real(wp),parameter :: fac = 0.1_wp n = n1 + n2 mode = 1 if (m <= 0) then if (n > 0) then x(1) = zero call dcopy(n,x,0,x,1) end if wnorm = zero return end if np1 = n + 1 ! SCALE NONZERO ROWS OF INEQUALITY MATRIX TO HAVE LENGTH ONE. do i = 1, m sc = dnrm2(n,a(i,1),mda) if (sc /= zero) then sc = one/sc call dscal(np1,sc,a(i,1),mda) end if end do ! SCALE RT.-SIDE VECTOR TO HAVE LENGTH ONE (OR ZERO). ynorm = dnrm2(m,a(1,np1),1) if (ynorm /= zero) then sc = one/ynorm call dscal(m,sc,a(1,np1),1) end if ! SCALE COLS OF MATRIX H. j = n1 + 1 do if (j > n) exit sc = dnrm2(m,a(1,j),1) if (sc /= zero) sc = one/sc call dscal(m,sc,a(1,j),1) x(j) = sc j = j + 1 end do if (n1 > 0) then ! COPY TRANSPOSE OF (H G Y) TO WORK ARRAY WS(*). iw = 0 do i = 1, m ! MOVE COL OF TRANSPOSE OF H INTO WORK ARRAY. call dcopy(n2,a(i,n1+1),mda,ws(iw+1),1) iw = iw + n2 ! MOVE COL OF TRANSPOSE OF G INTO WORK ARRAY. call dcopy(n1,a(i,1),mda,ws(iw+1),1) iw = iw + n1 ! MOVE COMPONENT OF VECTOR Y INTO WORK ARRAY. ws(iw+1) = a(i,np1) iw = iw + 1 end do ws(iw+1) = zero call dcopy(n,ws(iw+1),0,ws(iw+1),1) iw = iw + n ws(iw+1) = one iw = iw + 1 ! SOLVE EU=F SUBJECT TO (TRANSPOSE OF H)U=0, U>=0. THE ! MATRIX E = TRANSPOSE OF (G Y), AND THE (N+1)-VECTOR ! F = TRANSPOSE OF (0,...,0,1). ix = iw + 1 iw = iw + m ! DO NOT CHECK LENGTHS OF WORK ARRAYS IN THIS USAGE OF ! DWNNLS( ). is(1) = 0 is(2) = 0 call dwnnls(ws,np1,n2,np1-n2,m,0,prgopt,ws(ix),rnorm, & modew,is,ws(iw+1)) ! COMPUTE THE COMPONENTS OF THE SOLN DENOTED ABOVE BY W. sc = one - ddot(m,a(1,np1),1,ws(ix),1) if (one + fac*abs(sc) == one .or. rnorm <= zero) then mode = 2 return end if sc = one/sc do j = 1, n1 x(j) = sc*ddot(m,a(1,j),1,ws(ix),1) end do ! COMPUTE THE VECTOR Q=Y-GW. OVERWRITE Y WITH THIS ! VECTOR. do i = 1, m a(i,np1) = a(i,np1) - ddot(n1,a(i,1),mda,x,1) end do end if if (n2 > 0) then ! COPY TRANSPOSE OF (H Q) TO WORK ARRAY WS(*). iw = 0 do i = 1, m call dcopy(n2,a(i,n1+1),mda,ws(iw+1),1) iw = iw + n2 ws(iw+1) = a(i,np1) iw = iw + 1 end do ws(iw+1) = zero call dcopy(n2,ws(iw+1),0,ws(iw+1),1) iw = iw + n2 ws(iw+1) = one iw = iw + 1 ix = iw + 1 iw = iw + m ! SOLVE RV=S SUBJECT TO V>=0. THE MATRIX R =(TRANSPOSE ! OF (H Q)), WHERE Q=Y-GW. THE (N2+1)-VECTOR S =(TRANSPOSE ! OF (0,...,0,1)). ! ! DO NOT CHECK LENGTHS OF WORK ARRAYS IN THIS USAGE OF ! DWNNLS( ). is(1) = 0 is(2) = 0 call dwnnls(ws,n2+1,0,n2+1,m,0,prgopt,ws(ix),rnorm,modew, & is,ws(iw+1)) ! COMPUTE THE COMPONENTS OF THE SOLN DENOTED ABOVE BY Z. sc = one - ddot(m,a(1,np1),1,ws(ix),1) if (one + fac*abs(sc) == one .or. rnorm <= zero) then mode = 2 return end if sc = one/sc do j = 1, n2 l = n1 + j x(l) = sc*ddot(m,a(1,l),1,ws(ix),1)*x(l) end do end if ! ACCOUNT FOR SCALING OF RT.-SIDE VECTOR IN SOLUTION. call dscal(n,ynorm,x,1) wnorm = dnrm2(n1,x,1) end subroutine dlpdp