*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

      subroutine mimps ( imps, maxm, maxn, maxnb, maxne,
     $                   nncon, nnjac, nnobj,
     $                   m, n, nb, ne, nint,
     $                   iobj, objadd, names,
     $                   a, ha, ka, bl, bu, name1, name2,
     $                   hint, hs, xn, pi,
     $                   inform, ns, z, nwcore )

      implicit           double precision (a-h,o-z)
      character*8        names(5)
      integer*4          ha(maxne) , hint(maxn)  , hs(maxnb)
      integer            ka(maxn+1), name1(maxnb), name2(maxnb)
      double precision   a(maxne)  , bl(maxnb)   , bu(maxnb)
      double precision   xn(maxnb) , pi(maxm)    , z(nwcore)

*     ------------------------------------------------------------------
*     mimps  inputs constraint data for a linear or nonlinear program
*     in MPS format, consisting of NAME, ROWS, COLUMNS, RHS, RANGES and
*     BOUNDS sections in that order.  The RANGES and BOUNDS sections are
*     optional.
*
*     In the LP case, MPS format defines a set of constraints of the
*     form
*              l <= x <= u,      b1 <=  Ax  <= b2,
*     where l and u are specified by the BOUNDS section, and b1 and b2
*     are defined somewhat indirectly by the ROWS, RHS and RANGES
*     sections.  mimps converts these constraints into the equivalent
*     form
*              Ax + s = 0,       bl <= ( x ) <= bu,
*                                      ( s )
*     where s is a set of slack variables.  This is the way MINOS deals
*     with the data.  The first n components of bl and bu are the same
*     as l and u.  The last m components are -b2 and -b1.
*
*     MPS format gives 8-character names to the rows and columns of A.
*     One of the rows of A may be regarded as a linear objective row.
*     This will be row iobj, where iobj = 0 means there is no such row.
*
*     The data defines a linear program if nncon = nnjac = nnobj = 0.
*     The nonlinear case is the same except for a few details.
*     1. If nncon = nnjac = 0 but nnobj > 0, the first nnobj columns
*        are associated with a nonlinear objective function.
*     2. If nncon > 0, then nnjac > 0 and nnobj may be zero or positive.
*        The first nncon rows and the first nnjac columns are associated
*        with a set of nonlinear constraints.
*     3. Let nn = max( nnjac, nnobj ).  The first nn columns correspond
*        to "nonlinear variables".
*     4. If an objective row is specified (iobj > 0), then it must be
*        such that iobj > nncon.
*     5. "Small" elements (below the Aij tolerance) are ignored only if
*        they lie outside the nncon by nnjac Jacobian, i.e. outside
*        the top-left corner of A.
*     6. No warning is given if some of the first nn columns are empty.
*
*
*     ON ENTRY
*     ========
*     imps   is the unit containing the MPS file.  On some systems, it
*            may be necessary to open file imps before calling mimps.
*
*     maxm   is an overestimate of the number of rows in the ROWS
*            section of the MPS file.
*
*     maxn   is an overestimate of the number of columns in the COLUMNS
*            section of the MPS file.
*
*     maxnb  is maxm + maxn.
*
*     maxne  is an overestimate of the number of elements (matrix
*            coefficients) in the COLUMNS section.
*
*     nncon  is the no. of nonlinear constraints in the problem.
*            These must be the FIRST rows in the ROWS section.
*
*     nnjac  is the no. of nonlinear Jacobian variables in the problem.
*            These must be the FIRST columns in the COLUMNS section.
*
*     nnobj  is the no. of nonlinear objective variables in the problem.
*            These must be the FIRST columns in the COLUMNS section,
*            overlapping where necessary with the Jacobian variables.
*
*     names  is an array of five 8-character names.
*            names(1) need not be specified... it will be changed to
*            the name on the NAME card of the MPS file.
*            names(2) is the name of the objective row to be selected
*            from the ROWS section, or blank if mimps should select
*            the first type N row encountered.
*            Similarly,
*            names(3), names(4) and names(5) are the names of the
*            RHS, RANGES and BOUNDS to be selected from the
*            RHS, RANGES and BOUNDS sections respectively, or blank
*            if mimps should select the first ones encountered.
*
*     z(*)   is a workspace array of length nwcore.  It is needed to
*            hold the row-name hash table and a few other things.
*
*     nwcore is the length of z(*).  It should be at least 4*maxm.
*
*
*     ON EXIT
*     =======
*     m      is the number of rows in the ROWS section.
*
*     n      is the number of columns in the COLUMNS section.
*
*     nb     is n + m.
*
*     ne     is the number of matrix coefficients in COLUMNS section.
*
*     nint   is the number of integer variables detected.
*
*     iobj   is the row number of the specified objective row,
*            or zero if no such row was found.
*
*     objadd is a real constant extracted from row iobj of the RHS.
*            It is zero if the RHS contained no objective entry.
*            MINOS adds objadd to the objective function.
*
*     names(1)-names(5) contain the names of the
*               Problem, Objective row, RHS, RANGES and BOUNDS
*            respectively.
*
*     a(*)   contains the ne entries for each column of the matrix
*            specified in the COLUMNS section.
*
*     ha(*)  contains the corresponding row indices.
*
*     ka(j)  (j = 1 to n) points to the beginning of column j
*            in the parallel arrays a(*), ha(*).
*     ka(n+1) = ne+1.
*
*     bl(*)  contains nb lower bounds for the columns and slacks.
*            If there is no lower bound on x(j), then bl(j) = - 1.0d+20.
*
*     bu(*)  contains nb lower bounds for the columns and slacks.
*            If there is no upper bound on x(j), then bu(j) = + 1.0d+20.
*
*     name1(*), name2(*) contain nb column and row names in 2a4 format.
*            The j-th column name is stored in name1(j) and name2(j).
*            The i-th row    name is stored in name1(k) and name2(k),
*            where k = n + i.  
*
*     hint(*) contains nint entries.  The j-th integer variable is
*            column number hint(j), j = 1, nint.
*
*     hs(*)  contains an initial state for each column and slack.
*
*     xn(*)  contains an initial value for each column and slack.
*
*            If there is no INITIAL bounds set,
*               xn(j) = 0 if that value lies between bl(j) and bu(j),
*                     = the bound closest to zero otherwise,
*               hs(j) = 0 if xn(j) < bu(j),
*                     = 1 if xn(j) = bu(j).
*
*            If there is an INITIAL bounds set, xn(j) and hs(j) are
*            set as follows.  Suppose the j-th variable has the name Xj,
*            and suppose any numerical value specified happens to be 3.
*                                                   xn(j)    hs(j)
*             FR INITIAL   Xj         3.0           3.0       -1
*             FX INITIAL   Xj         3.0           3.0        2
*             LO INITIAL   Xj                       bl(j)      4
*             UP INITIAL   Xj                       bu(j)      5
*             MI INITIAL   Xj         3.0           3.0        4
*             PL INITIAL   Xj         3.0           3.0        5
*
*     pi(*)  contains a vector defined by a special RHS called LAGRANGE.
*            If the MPS file contains no such RHS, pi(i) = 0.0, i=1:m.
*
*     inform =  0 if no fatal errors were encountered,
*            = 40 if the ROWS or COLUMNS sections were empty
*                 or iobj > 0 but iobj <= nncon,
*            = 41 if maxm, maxn or maxne were too small.
*
*     ns     is the no. of FX INITIAL entries in the INITIAL bounds set.
*              
*
*     19 Apr 1992: Original version, derived from m3inpt.
*     22 Jul 1993: Updated to match MINOS 5.4 Dec 1992.
*     17 Feb 1995: Fixed bug.  iobj is now output correctly.
*     16 May 1997: nint, hint(*) now output if 'INTORG' and 'INTEND'
*                  markers are found in the COLUMNS section.
*     ------------------------------------------------------------------

      common    /m1file/ iread,iprint,isumm
      common    /m1word/ nwordr,nwordi,nwordh
      common    /m2len / mrows,mcols,melms
      common    /m3mps3/ aijtol,bstruc(2),mlst,mer,
     $                   aijmin,aijmax,na0,line,ier(20)
      common    /m3mps4/ name(2),mobj(2),mrhs(2),mrng(2),mbnd(2),minmax
****  Note: iobjx is used in the next common block to avoid a clash
****        with the output parameter iobj (which returns the value
****        that m3mpsa gives to iobjx).
      common    /m5lobj/ sinf,wtobj,minimz,ninf,iobjx,jobj,kobj
      common    /m5log1/ idebug,ierr,lprint

      integer            ncard(6)
      character*4        key
      character*4        lenda
      character*5        f1
      data               lenda /'ENDA'/, f1 /'(2a4)'/

*     Copy maximum dimensions into the global variables.

      mrows  = maxm
      mcols  = maxn
      melms  = maxne

*     The SPECS file has been read.
*     Make sure the MPS file is read from unit imps, and
*     make sure m3dflt knows if the problem is nonlinear.
*     The parameter 0 stops these two lines from being printed.

      nn     = max( nnjac, nnobj )
      call miopti( 'MPS file           ', imps  , 0, isumm, inform )
      call miopti( 'Nonlinear variables', nn    , 0, isumm, inform )

*     Set unspecified options to default values but don't print them
*     since minoss gets a chance later.

      iprnt  = iprint
      iprint = 0
      call m3dflt( 2 )
      iprint = iprnt

*     Load the specified obj, rhs, range and bound names into names(*).

      read (names(2), f1) mobj
      read (names(3), f1) mrhs
      read (names(4), f1) mrng
      read (names(5), f1) mbnd

*     key    retains the first 4 characters of the NAME, ROWS, COLUMNS
*            RHS, RANGES and BOUNDS cards.
*     ncard  counts the number of data records in each section.
*     m3getp finds a prime number for the length of the row hash table.
                                      
      ierr   = 0
      ncoll  = 0
      key    = '    '
      call iload ( 6, ncoll, ncard, 1 )
      call m3getp( maxm, lenh )

*     ------------------------------------------------------------------
*     Allocate workspace for the MPS input routines.
*     ------------------------------------------------------------------
      lhrtyp = 1
      lkb    = lhrtyp + 1 + (maxm/nwordh)
      lkeynm = lkb    + 1 + (maxm/nwordi)
      minmps = lkeynm + lenh
      if (nwcore .lt. minmps) go to 600

*     ------------------------------------------------------------------
*     Input ROWS.
*     lrow   is the location of the first rowname in name1, name2.
*            The column names will later go at the front.
*     lennm  is the initial length of name1, name2,
*            i.e. the maximum no. of names allowed for.
*     ------------------------------------------------------------------
      lrow   = maxn + 1
      lennm  = maxnb
      call m3mpsa( maxm, maxn, maxne, ncoll, m,
     $             lrow, lennm, lenh, nn, nncon, key, ncard,
     $             z(lhrtyp), name1, name2, z(lkeynm) )
      if (ierr .eq. 40) go to 400
      if (ierr .eq. 41) go to 600

*     ------------------------------------------------------------------
*     m  is now known.
*     Input COLUMNS, RHS, RANGES.
*     ------------------------------------------------------------------
      nb     = maxn + m 
      nka    = maxn + 1
      call m3mpsb( maxn, maxne, lrow, lennm, lenh, ncoll, objadd,
     $             m, n, nb, ne, nka, nint,
     $             nn, nncon, nnjac, nnobj, njac, key, ncard,
     $             hint, z(lhrtyp), name1, name2, z(lkeynm),
     $             ka, ha, a, bl, bu, z(lkb), pi )
      if (ierr .eq. 40) go to 400
      if (ierr .eq. 41) go to 600

*     ------------------------------------------------------------------
*     n  and  ne  are now known.
*     Move the row names to be contiguous with the column names.
*     Input BOUNDS.
*     ------------------------------------------------------------------
      call m3imov( lennm, lrow, m, n, name1 )
      call m3imov( lennm, lrow, m, n, name2 )
      nb     = n + m
      call m3mpsc( m, n, nb, ne, ns, lennm,
     $             key, ncard, name1, name2,
     $             bl, bu, hs, xn )

      if (iprint .gt. 0) then
         if (lprint .gt. 0) write(iprint, 1300) lenh, ncoll
         if (na0    .gt. 0) write(iprint, 1320) na0
         if (nncon  .gt. 0) write(iprint, 1350) njac
         if (nn     .gt. 0  .or.  ncard(6) .gt. 0)
     $                      write(iprint, 1400) ncard(6), ns
      end if

      go to 900

*     ---------------------------
*     Fatal error in MPS file.
*     ---------------------------
  400 call m1page( 2 )
      if (iprint .gt. 0) write(iprint, 1100)
      if (isumm  .gt. 0) write(isumm , 1100)
      go to 900

*     ------------------------------------
*     Not enough storage to read MPS file.
*     ------------------------------------
  600 call m1page(2)
      if (iprint .gt. 0) write(iprint, 1110)
      if (isumm  .gt. 0) write(isumm , 1110)

*     Exit.
*     Set iobj from m3mpsa.
*     Copy the various MPS names into the array names(*).

  900 inform = ierr
      iobj   = iobjx
      write(names, f1) name, mobj, mrhs, mrng, mbnd
      return

 1100 format(' EXIT -- fatal errors in the MPS file')
 1110 format(' EXIT -- not enough storage to read the MPS file')
 1300 format(/ ' Length of row-name hash table  ', i12
     $       / ' Collisions during table lookup ', i12)
 1320 format(  ' No. of rejected coefficients   ', i12)
 1350 format(  ' No. of Jacobian entries specified', i10)
 1400 format(  ' No. of INITIAL  bounds  specified', i10
     $       / ' No. of superbasics specified   ', i12)

*     end of mimps
      end
