CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C                                                                    C
C     THIS FILE CONTAINS THE SOURCE CODE FOR FORTRAN 90D INTRINSIC   C
C     FUNCTIONS.                                                     C
C                                                                    C
C     VERSION 1.00, 10/11/92                                         C
C                                                                    C
C     COPYRIGHT (C) NORTHEAST PARALLEL ARCHITECTURES CENTER,         C
C     SYRACUSE UNIVERSITY, SYRACUSE, NY 13244, USA.                  C
C                                                                    C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      integer function MINVAL_1_I(A, a1, a2, A_INFO, proclist)
      integer a1, a2
      integer A(a1:a2), A_INFO(8,7), min, proclist(*)
      integer i, intsize, type, status, min_row, max_row
      data intsize, type /4, 23/
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .LT. min) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findintmin,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findintmin,intsize,1,proclist(1),
     &                proclist(2),type)
      end if

      MINVAL_1_I = min

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      integer function MINVAL_1_I_M(A, a1, a2, A_INFO, mask, m1, 
     &      m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), min, proclist(*)
      integer A(a1:a2), MASK_INFO(8,7)
      logical mask(m1:m2)
      integer i, intsize, type, status, min_row, max_row
      data intsize, type /4, 23/
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = 2147483647

      do i=min_row, max_row
         if ((A(i) .LT. min) .AND. mask(i)) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findintmin,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findintmin,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_1_I_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      integer function MINVAL_2_I_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), min, proclist(*)
      integer A(a1:a2,a3:a4)
      integer min_row, max_row, min_col, max_col
      integer i, intsize, type, status
      data intsize, type /4, 23/
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .LT. min) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findintmin,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findintmin,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_I_S = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      integer function MINVAL_2_I_S_M(A, a1, a2, a3, a4, A_INFO, 
     &   mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7)
      integer A(a1:a2,a3:a4), min, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, intsize, type, status
      data intsize, type /4, 23/
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = 2147483647
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .LT. min) .AND. mask(i,j)) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findintmin,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findintmin,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_I_S_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MINVAL_2_I_V(A, a1, a2, a3, a4, A_INFO, dim, min, 
     &   s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MIN_INFO(8,7)
      integer A(a1:a2,a3:a4), dim, min(s1:s2), proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer intsize, type
      data intsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .LT. min(i)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .LT. min(i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,findintmin,intsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(min,findintmin,intsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
      subroutine MINVAL_2_I_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, min, s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MIN_INFO(8,7) 
      integer A(a1:a2,a3:a4), dim, min(s1:s2), proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer intsize, type
      data intsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      integer findintmin
      external findintmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = 2147483647
            do j=min_col, max_col
               if ((A(i,j) .LT. min(i)) .AND. mask(i,j)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = 2147483647
            do j=min_row, max_row
               if ((A(j,i) .LT. min(i)) .AND. mask(j,i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,findintmin,intsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(min,findintmin,intsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end



CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      

      real function MINVAL_1_R(A, a1, a2, A_INFO, proclist)
      integer a1, a2, A_INFO(8,7), proclist(*)
      real A(a1:a2), min
      integer i, realsize, type, status, min_row, max_row
      data realsize, type /4, 23/
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .LT. min) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findrealmin,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findrealmin,realsize,1,proclist(1),
     &                proclist(2),type)
      end if

      MINVAL_1_R = min

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      real function MINVAL_1_R_M(A, a1, a2, A_INFO, mask, m1, 
     &      m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), MASK_INFO(8,7)
      integer proclist(*)
      real A(a1:a2), min
      logical mask(m1:m2)
      integer i, realsize, type, status, min_row, max_row
      data realsize, type /4, 23/
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = 2147483647.0

      do i=min_row, max_row
         if ((A(i) .LT. min) .AND. mask(i)) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findrealmin,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findrealmin,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_1_R_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      real function MINVAL_2_R_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), proclist(*)
      real A(a1:a2,a3:a4), min
      integer min_row, max_row, min_col, max_col
      integer i, realsize, type, status
      data realsize, type /4, 23/
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .LT. min) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findrealmin,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findrealmin,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_R_S = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      real function MINVAL_2_R_S_M(A, a1, a2, a3, a4, A_INFO, 
     &   mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7), proclist(*)
      real A(a1:a2,a3:a4), min
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, realsize, type, status
      data realsize, type /4, 23/
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = 2147483647.0
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .LT. min) .AND. mask(i,j)) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,findrealmin,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,findrealmin,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_R_S_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MINVAL_2_R_V(A, a1, a2, a3, a4, A_INFO, dim, min, 
     &   s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MIN_INFO(8,7)
      real A(a1:a2,a3:a4), min(s1:s2)
      integer dim, proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer realsize, type
      data realsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .LT. min(i)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .LT. min(i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,findrealmin,realsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(min,findrealmin,realsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
      subroutine MINVAL_2_R_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, min, s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MIN_INFO(8,7) 
      real A(a1:a2,a3:a4), min(s1:s2)
      integer dim, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer realsize, type
      data realsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      real findrealmin
      external findrealmin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = 2147483647.0
            do j=min_col, max_col
               if ((A(i,j) .LT. min(i)) .AND. mask(i,j)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = 2147483647.0
            do j=min_row, max_row
               if ((A(j,i) .LT. min(i)) .AND. mask(j,i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,findrealmin,realsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(min,findrealmin,realsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end



CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

C     FOR DOUBLE

      double precision function MINVAL_1_D(A, a1, a2, A_INFO, proclist)
      integer a1, a2, A_INFO(8,7), proclist(*)
      double precision A(a1:a2), min
      integer i, doublesize, type, status, min_row, max_row
      data doublesize, type /8, 23/
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .LT. min) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,finddoublemin,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,finddoublemin,doublesize,1,proclist(1),
     &                proclist(2),type)
      end if

      MINVAL_1_D = min

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      double precision function MINVAL_1_D_M(A, a1, a2, A_INFO, mask,
     &       m1, m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), MASK_INFO(8,7)
      integer proclist(*)
      double precision A(a1:a2), min
      logical mask(m1:m2)
      integer i, doublesize, type, status, min_row, max_row
      data doublesize, type /8, 23/
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min = 2147483647.0

      do i=min_row, max_row
         if ((A(i) .LT. min) .AND. mask(i)) then
            min = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,finddoublemin,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,finddoublemin,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_1_D_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      double precision function MINVAL_2_D_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), proclist(*)
      double precision A(a1:a2,a3:a4), min
      integer min_row, max_row, min_col, max_col
      integer i, doublesize, type, status
      data doublesize, type /8, 23/
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .LT. min) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,finddoublemin,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,finddoublemin,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_D_S = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      double precision function MINVAL_2_D_S_M(A, a1, a2, a3, a4, 
     &   A_INFO, mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7), proclist(*)
      double precision A(a1:a2,a3:a4), min
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, doublesize, type, status
      data doublesize, type /8, 23/
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      min = 2147483647.0
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .LT. min) .AND. mask(i,j)) then
               min = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(min,finddoublemin,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(min,finddoublemin,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MINVAL_2_D_S_M = min

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MINVAL_2_D_V(A, a1, a2, a3, a4, A_INFO, dim, min, 
     &   s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MIN_INFO(8,7)
      double precision A(a1:a2,a3:a4), min(s1:s2)
      integer dim, proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer doublesize, type
      data doublesize, type /8, 23/
      integer env(4), coord(2), nproc(2), size
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .LT. min(i)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .LT. min(i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,finddoublemin,doublesize,size,IALNOD,0,
     &     type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(min,finddoublemin,doublesize,size,
     &     nproc(3-dim),proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      

      subroutine MINVAL_2_D_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, min, s1, s2, MIN_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MIN_INFO(8,7) 
      double precision A(a1:a2,a3:a4), min(s1:s2)
      integer dim, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer doublesize, type
      data doublesize, type /8, 23/
      integer env(4), coord(2), nproc(2), size
      double precision finddoublemin
      external finddoublemin

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            min(i) = 2147483647.0
            do j=min_col, max_col
               if ((A(i,j) .LT. min(i)) .AND. mask(i,j)) then
                  min(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            min(i) = 2147483647.0
            do j=min_row, max_row
               if ((A(j,i) .LT. min(i)) .AND. mask(j,i)) then
                  min(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(min,finddoublemin,doublesize,size,IALNOD,0,
     &       type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(min,finddoublemin,doublesize,size,
     &      nproc(3-dim),proclist, type)
      end if

      return
      end




