      SUBROUTINE H12(MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV)
C
C     C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUNE 12
C     TO APPEAR IN ^SOLVING LEAST SQUARES PROBLEMS^, PRENTICE-HALL, 1974
C
C     CONSTRUCTION AND/OR APPLICATION OF A SINGLE
C     HOUSEHOLDER TRANSFORMATION     Q = I + U*(U**T)/B
C
C     MODE  = 1 OR 2  TO SELECT ALGORITHM H1 OR H2
C     LPIVOT IS THE INDEX OF THE PIVOT ELEMENT
C     L1,M  IF L1.LE.M THE TRANSFORMATION WILL BE CONSTRUCTED TO
C           ZERO ELEMENTS INDEXED FROM L1 THROUGH M. IF L1.GT.M
C           THE SUBROUTINE DOES AN IDENTITY TRANSFORMATION
C     U(),IUE,UP  ON ENTRY TO H1 U() CONTAINS THE PIVOT VECTOR
C                 IUE IS THE STORAGE INCREMENT BETWEEN ELEMENTS.
C                 ON EXIT FROM H1 U() AND UP CONTAIN QUANTITIES
C                 DEFINING THE VECTOR U OF THE HOUSEHOLDER
C                 TRANSFORMATION. ON ENTRY TO H2 U() AND UP SHOULD
C                 CONTAIN QUANTITIES PREVIOUSLY COMPUTED BY H1.
C                 THESE WILL NOT BE MODIFIED BY H2.
C     C()  ON ENTRY TO H1 OR H2 C() CONTAINS A MATRIX WHICH WILL BE
C          REGARDED AS A SET OF VECTORS TO WHICH THE HOUSEHOLDER
C          TRANSFORMATION IS TO BE APPLIED. ON EXIT C() CONTAINS THE
C          SET OF TRANSFORMED VECTORS.
C     ICE  STORAGE INCREMENT BETWEEN ELEMENTS IN C ()
C     ICV  STORAGE INCREMENT BETWEEN VECTORS IN C ()
C     NCV  NUMBER OF VECTORS IN C() TO BE TRANSFORMED. IF NCV.LE.0
C          NO OPERATIONS WILL BE DONE ON C()
C
      IMPLICIT REAL*8(A-H,O-Z)
      IMPLICIT INTEGER(I-N)
C
      DIMENSION U(IUE,M),C(1)
      ONE = 1.
C
      IF(0.GE.LPIVOT.OR.LPIVOT.GE.L1.OR.L1.GT.M) RETURN
      CL = ABS(U(1,LPIVOT))
      IF(MODE.EQ.2) GO TO 60
C
C     CONSTRUCT THE TRANSFORMATION
C
      DO 10 J=L1,M
   10 CL = MAX(ABS(U(1,J)),CL)
      IF(CL) 130,130,20
   20 CONTINUE
C
C     ****** THIS IS A VAX TEST FOR D_FLOATING REAL*8 ARITHMETIC
C            IT PREVENTS AN OVERFLOW ON INVERSION
C
      IF(CL.LT.5.9D-39) GO TO 130
C
      CLINV = ONE/CL
      SM = (U(1,LPIVOT)*CLINV)**2
      DO 30 J=L1,M
   30 SM = SM + (U(1,J)*CLINV)**2
C
C     CONVERT DBLE PREC. SM TO SNGL PREC. SM1
C
      SM1 = SM
      CL = CL*SQRT(SM1)
      IF(U(1,LPIVOT)) 50,50,40
   40 CL = -CL
   50 UP = U(1,LPIVOT) - CL
      U(1,LPIVOT) = CL
      GO TO 70
C
C     APPLY THE TRANSFORMATION 1+U*U(T)/B TO C
C
   60 IF(CL) 130,130,70
   70 IF(NCV.LE.0) RETURN
      B = UP*U(1,LPIVOT)
C
C     B MUST BE NONPOSITIVE HERE. IF B=0 RETURN
C
      IF(B) 80,130,130
   80 CONTINUE
C
C     ****** THIS IS A VAX TEST FOR D_FLOATING REAL*8 ARITHMETIC
C            IT PREVENTS AN OVERFLOW ON INVERSION
C
      IF(-B.LT.5.9D-39) GO TO 130
C
      B = ONE/B
      I2 = 1 - ICV+ICE*(LPIVOT-1)
      INCR = ICE*(L1-LPIVOT)
      DO 120 J=1,NCV
      I2 = I2 + ICV
      I3 = I2 + INCR
      I4 = I3
      SM = C(I2)*UP
      DO 90 I=L1,M
      SM = SM + C(I3)*U(1,I)
   90 I3 = I3 + ICE
      IF(SM) 100,120,100
  100 SM = SM*B
      C(I2) = C(I2) + SM*UP
      DO 110 I=L1,M
      C(I4) = C(I4) + SM*U(1,I)
  110 I4 = I4 + ICE
  120 CONTINUE
  130 RETURN
      END

