LCOV - code coverage report
Current view: top level - bnmin1/src/f77 - pda_qrsolv.f (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 62 0.0 %
Date: 2024-10-12 00:35:29 Functions: 0 1 0.0 %

          Line data    Source code
       1           0 :       subroutine pda_qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa)
       2             :       integer n,ldr
       3             :       integer ipvt(n)
       4             :       double precision r(ldr,n),diag(n),qtb(n),x(n),sdiag(n),wa(n)
       5             : c     **********
       6             : c
       7             : c     subroutine pda_qrsolv
       8             : c
       9             : c     given an m by n matrix a, an n by n diagonal matrix d,
      10             : c     and an m-vector b, the problem is to determine an x which
      11             : c     solves the system
      12             : c
      13             : c           a*x = b ,     d*x = 0 ,
      14             : c
      15             : c     in the least squares sense.
      16             : c
      17             : c     this subroutine completes the solution of the problem
      18             : c     if it is provided with the necessary information from the
      19             : c     qr factorization, with column pivoting, of a. that is, if
      20             : c     a*p = q*r, where p is a permutation matrix, q has orthogonal
      21             : c     columns, and r is an upper triangular matrix with diagonal
      22             : c     elements of nonincreasing magnitude, then pda_qrsolv expects
      23             : c     the full upper triangle of r, the permutation matrix p,
      24             : c     and the first n components of (q transpose)*b. the system
      25             : c     a*x = b, d*x = 0, is then equivalent to
      26             : c
      27             : c                  t       t
      28             : c           r*z = q *b ,  p *d*p*z = 0 ,
      29             : c
      30             : c     where x = p*z. if this system does not have full rank,
      31             : c     then a least squares solution is obtained. on output pda_qrsolv
      32             : c     also provides an upper triangular matrix s such that
      33             : c
      34             : c            t   t               t
      35             : c           p *(a *a + d*d)*p = s *s .
      36             : c
      37             : c     s is computed within pda_qrsolv and may be of separate interest.
      38             : c
      39             : c     the subroutine statement is
      40             : c
      41             : c       subroutine pda_qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa)
      42             : c
      43             : c     where
      44             : c
      45             : c       n is a positive integer input variable set to the order of r.
      46             : c
      47             : c       r is an n by n array. on input the full upper triangle
      48             : c         must contain the full upper triangle of the matrix r.
      49             : c         on output the full upper triangle is unaltered, and the
      50             : c         strict lower triangle contains the strict upper triangle
      51             : c         (transposed) of the upper triangular matrix s.
      52             : c
      53             : c       ldr is a positive integer input variable not less than n
      54             : c         which specifies the leading dimension of the array r.
      55             : c
      56             : c       ipvt is an integer input array of length n which defines the
      57             : c         permutation matrix p such that a*p = q*r. column j of p
      58             : c         is column ipvt(j) of the identity matrix.
      59             : c
      60             : c       diag is an input array of length n which must contain the
      61             : c         diagonal elements of the matrix d.
      62             : c
      63             : c       qtb is an input array of length n which must contain the first
      64             : c         n elements of the vector (q transpose)*b.
      65             : c
      66             : c       x is an output array of length n which contains the least
      67             : c         squares solution of the system a*x = b, d*x = 0.
      68             : c
      69             : c       sdiag is an output array of length n which contains the
      70             : c         diagonal elements of the upper triangular matrix s.
      71             : c
      72             : c       wa is a work array of length n.
      73             : c
      74             : c     subprograms called
      75             : c
      76             : c       fortran-supplied ... dabs,dsqrt
      77             : c
      78             : c     argonne national laboratory. minpack project. march 1980.
      79             : c     burton s. garbow, kenneth e. hillstrom, jorge j. more
      80             : c
      81             : c     **********
      82             :       integer i,j,jp1,k,kp1,l,nsing
      83             :       double precision cos,cotan,p5,p25,qtbpj,sin,sum,tan,temp,zero
      84             :       data p5,p25,zero /5.0d-1,2.5d-1,0.0d0/
      85             : c
      86             : c     copy r and (q transpose)*b to preserve input and initialize s.
      87             : c     in particular, save the diagonal elements of r in x.
      88             : c
      89           0 :       do 20 j = 1, n
      90           0 :          do 10 i = j, n
      91           0 :             r(i,j) = r(j,i)
      92           0 :    10       continue
      93           0 :          x(j) = r(j,j)
      94           0 :          wa(j) = qtb(j)
      95           0 :    20    continue
      96             : c
      97             : c     eliminate the diagonal matrix d using a givens rotation.
      98             : c
      99           0 :       do 100 j = 1, n
     100             : c
     101             : c        prepare the row of d to be eliminated, locating the
     102             : c        diagonal element using p from the qr factorization.
     103             : c
     104           0 :          l = ipvt(j)
     105           0 :          if (diag(l) .eq. zero) go to 90
     106           0 :          do 30 k = j, n
     107           0 :             sdiag(k) = zero
     108           0 :    30       continue
     109           0 :          sdiag(j) = diag(l)
     110             : c
     111             : c        the transformations to eliminate the row of d
     112             : c        modify only a single element of (q transpose)*b
     113             : c        beyond the first n, which is initially zero.
     114             : c
     115           0 :          qtbpj = zero
     116           0 :          do 80 k = j, n
     117             : c
     118             : c           determine a givens rotation which eliminates the
     119             : c           appropriate element in the current row of d.
     120             : c
     121           0 :             if (sdiag(k) .eq. zero) go to 70
     122           0 :             if (dabs(r(k,k)) .ge. dabs(sdiag(k))) go to 40
     123           0 :                cotan = r(k,k)/sdiag(k)
     124           0 :                sin = p5/dsqrt(p25+p25*cotan**2)
     125           0 :                cos = sin*cotan
     126           0 :                go to 50
     127             :    40       continue
     128           0 :                tan = sdiag(k)/r(k,k)
     129           0 :                cos = p5/dsqrt(p25+p25*tan**2)
     130           0 :                sin = cos*tan
     131             :    50       continue
     132             : c
     133             : c           compute the modified diagonal element of r and
     134             : c           the modified element of ((q transpose)*b,0).
     135             : c
     136           0 :             r(k,k) = cos*r(k,k) + sin*sdiag(k)
     137           0 :             temp = cos*wa(k) + sin*qtbpj
     138           0 :             qtbpj = -sin*wa(k) + cos*qtbpj
     139           0 :             wa(k) = temp
     140             : c
     141             : c           accumulate the tranformation in the row of s.
     142             : c
     143           0 :             kp1 = k + 1
     144           0 :             if (n .lt. kp1) go to 70
     145           0 :             do 60 i = kp1, n
     146           0 :                temp = cos*r(i,k) + sin*sdiag(i)
     147           0 :                sdiag(i) = -sin*r(i,k) + cos*sdiag(i)
     148           0 :                r(i,k) = temp
     149           0 :    60          continue
     150             :    70       continue
     151           0 :    80       continue
     152             :    90    continue
     153             : c
     154             : c        store the diagonal element of s and restore
     155             : c        the corresponding diagonal element of r.
     156             : c
     157           0 :          sdiag(j) = r(j,j)
     158           0 :          r(j,j) = x(j)
     159           0 :   100    continue
     160             : c
     161             : c     solve the triangular system for z. if the system is
     162             : c     singular, then obtain a least squares solution.
     163             : c
     164           0 :       nsing = n
     165           0 :       do 110 j = 1, n
     166           0 :          if (sdiag(j) .eq. zero .and. nsing .eq. n) nsing = j - 1
     167           0 :          if (nsing .lt. n) wa(j) = zero
     168           0 :   110    continue
     169           0 :       if (nsing .lt. 1) go to 150
     170           0 :       do 140 k = 1, nsing
     171           0 :          j = nsing - k + 1
     172           0 :          sum = zero
     173           0 :          jp1 = j + 1
     174           0 :          if (nsing .lt. jp1) go to 130
     175           0 :          do 120 i = jp1, nsing
     176           0 :             sum = sum + r(i,j)*wa(i)
     177           0 :   120       continue
     178             :   130    continue
     179           0 :          wa(j) = (wa(j) - sum)/sdiag(j)
     180           0 :   140    continue
     181             :   150 continue
     182             : c
     183             : c     permute the components of z back to components of x.
     184             : c
     185           0 :       do 160 j = 1, n
     186           0 :          l = ipvt(j)
     187           0 :          x(l) = wa(j)
     188           0 :   160    continue
     189           0 :       return
     190             : c
     191             : c     last card of subroutine pda_qrsolv.
     192             : c
     193             :       end

Generated by: LCOV version 1.16