*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE AXLIMS (V, IDIM, NPT, NVECT, VMIN, VMAX,
*                        ATICK, NTICK, IAX, DMIN, DMAX)
*
*
* Purpose:
*     Find limits for a plot axis
*
*
* Description:
*     This routine finds the minimum and maximum values for an axis.
*     The minimum and maximum values are determined by from the
*     following (in the indicated order).
*       1. VMIN and VMAX (if these differ)
*       2. min(V(i,j)) and max(V(i,j)) (if these differ)
*       3. min(ATICK(i)) and max(ATICK(i)) (if these differ)
*       4. default values
*
*
* Parameters:
* R ->  V      - Two dimensional array of data values.  V(1,1) through
*                V(NPT,1) represent one data vector, V(1,2) through
*                Y(NPT,2) represent another data vector, and so on.
* I ->  IDIM   - First dimension of the input array V
* I ->  NPT    - Number of values per vector (less than or equal to
*                IDIM)
* I ->  NVECT  - Number of vectors contained in V
* R ->  VMIN   - Minimum data value
* R ->  VMAX   - Maximum data value
*                Note: Normally VMAX is not equal to VMIN.  If VMAX is
*                      equal to VMIN, the data range will be chosen to
*                      include this data value.
* R -> ATICK   - Array of data values corresponding to axis ticks.
*                For ITICK=1, this array is used to determine the data
*                range if the data range cannot be determined from
*                VMIN and VMAX, or the input data array.
* I ->  NTICK  - Number of values in the array ATICK.  This value is
*                used if ITICK=1.
* I <-> IAX    - Option value.  The option value has five components.
*                IAX = ILL + 4*IUL + 16*ITICK + 32*ILABEL + 64*ILOG
*                ILL    = 0 - default value.  On output, ILL will be
*                             set to to 1 (if (VMAX = VMIN) or 2 (if
*                             VMAX != VMIN).
*                         1 - The lower limit of the graph is to be a
*                             tick value less than or equal to VMIN
*                         2 - The lower limit of the graph is VMIN
*                IUL    = 0 - default value.  On output, IUL will be
*                             set to to 1 (if (VMAX = VMIN) or 2 (if
*                             VMAX != VMIN).
*                         1 - The upper limit of the graph is to be a
*                             tick value greater than or equal to VMAX
*                         2 - The upper limit of the graph is VMAX
*                ITICK  = 0 - Ticks are not supplied as input
*                         1 - Ticks are supplied as input
*                ILABEL = 0,1 not used
*                ILOG   = 0 - Linear scale
*                         1 - Logarithmic scale
* R <-  DMIN   - Lower limit for the graph
* R <-  DMAX   - Upper limit for the graph
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.8 $  $Date: 1995/03/08 15:30:19 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE AXLIMS (V, IDIM, NPT, NVECT, VMIN, VMAX,
     -                   ATICK, NTICK, IAX, DMIN, DMAX)


      INTEGER DEFAULT,TICKV,EXACTV,INP,LINS,LOGS
      PARAMETER (DEFAULT=0,TICKV=1,EXACTV=2,INP=1,LINS=0,LOGS=1)

      INTEGER IDIM,NPT,NVECT,NTICK,IAX
      INTEGER ILL,IUL,ITICK,ILABEL,ILOG,J
      INTEGER IFLORX,ICEILX

      REAL VMIN,VMAX,DMIN,DMAX
      REAL V(IDIM,*),ATICK(*)
      REAL D


* Separate the axis option codes
      ILL=MOD(IAX,4)
      IUL=MOD(IAX/4,4)
      ITICK=MOD(IAX/16,2)
      ILABEL=MOD(IAX/32,2)
      ILOG=MOD(IAX/64,2)

*==========
* Resolve the default limit options
      IF (ILL.EQ.DEFAULT) THEN
        IF (VMIN.EQ.VMAX) THEN
          ILL=TICKV
        ELSE
          ILL=EXACTV
        END IF
      END IF
      IF (IUL.EQ.DEFAULT) THEN
        IF (VMIN.EQ.VMAX) THEN
          IUL=TICKV
        ELSE
          IUL=EXACTV
        END IF
      END IF

*==========
* If data limits are undefined, search the data array
      DMIN=VMIN
      DMAX=VMAX
      IF (DMIN.EQ.DMAX) THEN
        DO 120 J=1,NVECT
          CALL AMINMX(V(1,J),NPT,DMIN,DMAX)
 120    CONTINUE
      END IF

* If data limits are still undefined, try to get the limits from
* the tick array
      IF (DMIN.EQ.DMAX .AND. ITICK.EQ.INP) THEN
        CALL AMINMX(ATICK,NTICK,DMIN,DMAX)
      END IF

*==========
* Check log scale limits, warn and fix up
      IF (ILOG.NE.LINS) THEN
        IF (DMIN.LE.0.0) THEN
          DMIN=MAX(0.1*DMAX,0.1)
          CALL WARN('AXLIMS - Log scale, nonpositive value')
        END IF
        IF (DMAX.LE.0.0) THEN
          DMAX=10.*DMIN
          CALL WARN('AXLIMS - Log scale, nonpositive value')
        END IF
      END IF

* Limits still undefined, set the limits
      IF (DMIN.EQ.DMAX) THEN
        IF (ILOG.EQ.LINS) THEN

          IF (ILL.EQ.EXACTV) THEN
            IF (DMIN.LT.0.0) THEN
              DMAX=0.0
            ELSE IF (DMIN.GT.0.0) THEN
              DMIN=0.0
            ELSE
              DMIN=0.0
              DMAX=+1.
            END IF
          ELSE
            IF (DMIN.LT.0.0) THEN
              DMIN=1.5*DMIN
              DMAX=0.0
            ELSE IF (DMIN.GT.0.0) THEN
              DMIN=0.0
              DMAX=1.5*DMAX
            ELSE
              DMIN=0.0
              DMAX=+1.
            END IF
          END IF

        ELSE
          D=LOG10(DMIN)
          DMIN=10.**IFLORX(D)
          IF (ILL.EQ.EXACTV) THEN
            IF (DMIN.EQ.DMAX) DMAX=10.*DMIN
          ELSE
            DMAX=10.**ICEILX(D)
            IF (DMIN.EQ.DMAX) THEN
              DMIN=0.1*DMIN
              DMAX=10.*DMAX
            END IF
          END IF

        END IF
      END IF

*==========
* Reconstruct the axis option code
      IAX=ILL+4*IUL+16*ITICK+32*ILABEL+64*ILOG


      RETURN

      END
