**********************************************************************
C
C     Copyright (C) 1992  Roland W. Freund and Noel M. Nachtigal
C     All rights reserved.
C
C     This code is part of a copyrighted package.  For details, see the
C     file `cpyrit.doc' in the top-level directory.
C
C     *****************************************************************
C     ANY USE OF  THIS CODE CONSTITUTES ACCEPTANCE OF  THE TERMS OF THE
C                             COPYRIGHT NOTICE
C     *****************************************************************
C
C**********************************************************************
C
      SUBROUTINE CAXPBY (N,CZ,CA,CX,CB,CY)
C
C     Purpose:
C     This subroutine computes CZ = CA * CX + CB * CY.  Several special
C     cases are handled separately:
C        CA =  0.0, CB =  0.0 => CZ = 0.0
C        CA =  0.0, CB =  1.0 => CZ = CY  (this is COPY)
C        CA =  0.0, CB = -1.0 => CZ = -CY
C        CA =  0.0, CB =   CB => CZ = CB * CY  (this is SCAL)
C        CA =  1.0, CB =  0.0 => CZ = CX  (this is COPY)
C        CA =  1.0, CB =  1.0 => CZ = CX + CY
C        CA =  1.0, CB = -1.0 => CZ = CX - CY
C        CA =  1.0, CB =   CB => CZ = CX + CB * CY (this is AXPY)
C        CA = -1.0, CB =  0.0 => CZ = -CX
C        CA = -1.0, CB =  1.0 => CZ = -CX + CY
C        CA = -1.0, CB = -1.0 => CZ = -CX - CY
C        CA = -1.0, CB =   CB => CZ = -CX + CB * CY
C        CA =   CA, CB =  0.0 => CZ = CA * CX  (this is SCAL)
C        CA =   CA, CB =  1.0 => CZ = CA * CX + CY  (this is AXPY)
C        CA =   CA, CB = -1.0 => CZ = CA * CX - CY
C        CA =   CA, CB =   CB => CZ = CA * CX + CB * CY
C     CZ may be the same as CX or CY.
C
C     Parameters:
C     N  = the dimension of the vectors (input).
C     CZ = the vector result (output).
C     CA = scalar multiplier for CX (input).
C     CX = one of the vectors (input).
C     CB = scalar multiplier for CY (input).
C     CY = the other vector (input).
C
C     Noel M. Nachtigal
C     March 23, 1993
C
C**********************************************************************
C
      INTRINSIC AIMAG, REAL
C
      INTEGER N
      COMPLEX CA, CB, CX(N), CY(N), CZ(N)
C
C     Local variables.
C
      INTEGER I
      REAL SAI, SAR, SBI, SBR
C
      IF (N.LE.0) RETURN
C
      SAI = AIMAG(CA)
      SAR = REAL(CA)
      SBI = AIMAG(CB)
      SBR = REAL(CB)
      IF ((SAR.EQ.0.0E0).AND.(SAI.EQ.0.0E0)) THEN
         IF ((SBR.EQ.0.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 0.0, CB = 0.0 => CZ = 0.0.
            DO 10 I = 1, N
               CZ(I) = (0.0E0,0.0E0)
 10         CONTINUE
         ELSE IF ((SBR.EQ.1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 0.0, CB = 1.0 => CZ = CY (this is COPY).
            DO 20 I = 1, N
               CZ(I) = CY(I)
 20         CONTINUE
         ELSE IF ((SBR.EQ.-1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 0.0, CB = -1.0 => CZ = -CY.
            DO 30 I = 1, N
               CZ(I) = -CY(I)
 30         CONTINUE
         ELSE
C           CA = 0.0, CB = CB => CZ = CB * CY (this is SCAL).
            DO 40 I = 1, N
               CZ(I) = CB * CY(I)
 40         CONTINUE
         END IF
      ELSE IF ((SAR.EQ.1.0E0).AND.(SAI.EQ.0.0E0)) THEN
         IF ((SBR.EQ.0.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 1.0, CB = 0.0 => CZ = CX (this is COPY).
            DO 50 I = 1, N
               CZ(I) = CX(I)
 50         CONTINUE
         ELSE IF ((SBR.EQ.1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 1.0, CB = 1.0 => CZ = CX + CY.
            DO 60 I = 1, N
               CZ(I) = CX(I) + CY(I)
 60         CONTINUE
         ELSE IF ((SBR.EQ.-1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = 1.0, CB = -1.0 => CZ = CX - CY.
            DO 70 I = 1, N
               CZ(I) = CX(I) - CY(I)
 70         CONTINUE
         ELSE
C           CA = 1.0, CB = CB => CZ = CX + CB * CY (this is AXPY).
            DO 80 I = 1, N
               CZ(I) = CX(I) + CB * CY(I)
 80         CONTINUE
         END IF
      ELSE IF ((SAR.EQ.-1.0E0).AND.(SAI.EQ.0.0E0)) THEN
         IF ((SBR.EQ.0.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = -1.0, CB = 0.0 => CZ = -CX
            DO 90 I = 1, N
               CZ(I) = -CX(I)
 90         CONTINUE
         ELSE IF ((SBR.EQ.1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = -1.0, CB = 1.0 => CZ = -CX + CY
            DO 100 I = 1, N
               CZ(I) = -CX(I) + CY(I)
 100        CONTINUE
         ELSE IF ((SBR.EQ.-1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = -1.0, CB = -1.0 => CZ = -CX - CY.
            DO 110 I = 1, N
               CZ(I) = -CX(I) - CY(I)
 110        CONTINUE
         ELSE
C           CA = -1.0, CB = CB => CZ = -CX + CB * CY
            DO 120 I = 1, N
               CZ(I) = -CX(I) + CB * CY(I)
 120        CONTINUE
         END IF
      ELSE
         IF ((SBR.EQ.0.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = CA, CB = 0.0 => CZ = CA * CX (this is SCAL).
            DO 130 I = 1, N
               CZ(I) = CA * CX(I)
 130        CONTINUE
         ELSE IF ((SBR.EQ.1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = CA, CB = 1.0 => CZ = CA * CX + CY (this is AXPY)
            DO 140 I = 1, N
               CZ(I) = CA * CX(I) + CY(I)
 140        CONTINUE
         ELSE IF ((SBR.EQ.-1.0E0).AND.(SBI.EQ.0.0E0)) THEN
C           CA = CA, CB = -1.0 => CZ = CA * CX - CY.
            DO 150 I = 1, N
               CZ(I) = CA * CX(I) - CY(I)
 150        CONTINUE
         ELSE
C           CA = CA, CB = CB => CZ = CA * CX + CB * CY.
            DO 160 I = 1, N
               CZ(I) = CA * CX(I) + CB * CY(I)
 160        CONTINUE
         END IF
      END IF
C
      RETURN
      END
C
C**********************************************************************