/* glplpx.h */

/*----------------------------------------------------------------------
-- Copyright (C) 2000, 2001, 2002 Andrew Makhorin <mao@mai2.rcnet.ru>,
--               Department for Applied Informatics, Moscow Aviation
--               Institute, Moscow, Russia. All rights reserved.
--
-- This file is a part of GLPK (GNU Linear Programming Kit).
--
-- GLPK is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-- License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with GLPK; see the file COPYING. If not, write to the Free
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- 02111-1307, USA.
----------------------------------------------------------------------*/

#ifndef _GLPLPX_H
#define _GLPLPX_H

#include "glpinv.h"
#include "glpstr.h"

#define lpx_create_prob       _glp_lpx_create_prob
#define lpx_reset_parms       _glp_lpx_reset_parms
#define lpx_realloc_prob      _glp_lpx_realloc_prob
#define lpx_add_rows          _glp_lpx_add_rows
#define lpx_add_cols          _glp_lpx_add_cols
#define lpx_check_name        _glp_lpx_check_name
#define lpx_set_prob_name     _glp_lpx_set_prob_name
#define lpx_set_row_name      _glp_lpx_set_row_name
#define lpx_set_col_name      _glp_lpx_set_col_name
#define lpx_set_row_bnds      _glp_lpx_set_row_bnds
#define lpx_set_col_bnds      _glp_lpx_set_col_bnds
#define lpx_set_obj_dir       _glp_lpx_set_obj_dir
#define lpx_set_obj_c0        _glp_lpx_set_obj_c0
#define lpx_set_row_coef      _glp_lpx_set_row_coef
#define lpx_set_col_coef      _glp_lpx_set_col_coef
#define lpx_defrag_sva        _glp_lpx_defrag_sva
#define lpx_enlarge_cap       _glp_lpx_enlarge_cap
#define lpx_set_mat_row       _glp_lpx_set_mat_row
#define lpx_set_mat_col       _glp_lpx_set_mat_col
#define lpx_unmark_all        _glp_lpx_unmark_all
#define lpx_mark_row          _glp_lpx_mark_row
#define lpx_mark_col          _glp_lpx_mark_col
#define lpx_change_ordn       _glp_lpx_change_ordn
#define lpx_clear_mat         _glp_lpx_clear_mat
#define lpx_del_items         _glp_lpx_del_items
#define lpx_delete_prob       _glp_lpx_delete_prob
#define lpx_simplex           _glp_lpx_simplex
#define lpx_get_num_rows      _glp_lpx_get_num_rows
#define lpx_get_num_cols      _glp_lpx_get_num_cols
#define lpx_get_num_nz        _glp_lpx_get_num_nz
#define lpx_get_prob_name     _glp_lpx_get_prob_name
#define lpx_get_row_name      _glp_lpx_get_row_name
#define lpx_get_col_name      _glp_lpx_get_col_name
#define lpx_get_row_bnds      _glp_lpx_get_row_bnds
#define lpx_get_col_bnds      _glp_lpx_get_col_bnds
#define lpx_get_obj_dir       _glp_lpx_get_obj_dir
#define lpx_get_obj_c0        _glp_lpx_get_obj_c0
#define lpx_get_row_coef      _glp_lpx_get_row_coef
#define lpx_get_col_coef      _glp_lpx_get_col_coef
#define lpx_get_mat_row       _glp_lpx_get_mat_row
#define lpx_get_mat_col       _glp_lpx_get_mat_col
#define lpx_get_prim_stat     _glp_lpx_get_prim_stat
#define lpx_get_dual_stat     _glp_lpx_get_dual_stat

/*----------------------------------------------------------------------
-- The structure LPX defines a low-level LP problem object and includes
-- the following information:
--
--    LP problem data;
--    current basis;
--    factorization of the basis matrix;
--    basic solution components;
--    control parameters and statistics.
--
-- LP problem has the following formulation:
--
--    minimize (or maximize)
--
--       Z = c[1]*x[1] + c[2]*x[2] + ... + c[m+n]*x[m+n] + c[0]      (1)
--
--    subject to linear constraints
--
--       x[1] = a[1,1]*x[m+1] + a[1,2]*x[m+1] + ... + a[1,n]*x[m+n]
--       x[2] = a[2,1]*x[m+1] + a[2,2]*x[m+1] + ... + a[2,n]*x[m+n]  (2)
--                . . . . . .
--       x[m] = a[m,1]*x[m+1] + a[m,2]*x[m+1] + ... + a[m,n]*x[m+n]
--
--    and bounds of variables
--
--         l[1] <= x[1]   <= u[1]
--         l[2] <= x[2]   <= u[2]                                    (3)
--             . . . . . .
--       l[m+n] <= x[m+n] <= u[m+n]
--
-- where:
-- x[1], ..., x[m]      - rows (auxiliary variables);
-- x[m+1], ..., x[m+n]  - columns (structural variables);
-- Z                    - objective function;
-- c[1], ..., c[m+n]    - coefficients of the objective function;
-- c[0]                 - constant term of the objective function;
-- a[1,1], ..., a[m,n]  - constraint coefficients;
-- l[1], ..., l[m+n]    - lower bounds of variables;
-- u[1], ..., u[m+n]    - upper bounds of variables.
--
-- Using vector-matrix notations the LP problem (1)-(3) can be written
-- as follows:
--
--    minimize (or maximize)
--
--       Z = c * x + c[0]                                            (4)
--
--    subject to linear constraints
--
--       xR = A * xS                                                 (5)
--
--    and bounds of variables
--
--       l <= x <= u                                                 (6)
--
-- where:
-- xR                   - subvector of auxiliary variables (rows);
-- xS                   - subvector of structural variables (columns);
-- x = (xR, xS)         - vector of all variables;
-- c                    - vector of objective coefficients;
-- A                    - constraint matrix (has m rows and n columns);
-- l                    - vector of lower bounds of variables;
-- u                    - vector of upper bounds of variables.
--
-- The system of constraints (5) can be written in homogeneous form as
-- follows:
--
--    A~ * x = 0,                                                    (7)
--
-- where
--
--    A~ = (I | -A)                                                  (8)
--
-- is an augmented constraint matrix (has m rows and m+n columns), I is
-- the unity matrix of the order m. Note that in the structure LPX only
-- the original constraint matrix A is explicitly stored.
--
-- The current basis is defined by partitioning columns of the matrix
-- A~ into basic and non-basic ones, in which case the system (7) can
-- be written as
--
--    B * xB + N * xN = 0,                                           (9)
--
-- where B is a square non-sigular mxm matrix built of basic columns
-- and called the basis matrix, N is a mxn matrix built of non-basic
-- columns, xB is a subvector of basic variables, xN is a subvector of
-- non-basic variables.
--
-- Using the partitioning (9) the LP problem (4)-(6) can be written in
-- a form, which defines components of the corresponding basic solution
-- and is called the simplex table:
--
--    Z = d * xN + c[0]                                             (10)
--
--    xB = A~ * xN                                                  (11)
--
--    lB <= xB <= uB                                                (12)
--
--    lN <= xN <= uN                                                (13)
--
-- where:
--
--    A~ = (alfa[i,j]) = - inv(B) * N                               (14)
--
-- is the mxn matrix of influence coefficients;
--
--    d = (d[j]) = cN - N' * pi                                     (15)
--
-- is the vector of reduced costs of non-basic variables; and
--
--    pi = (pi[i]) = inv(B') * cB                                   (16)
--
-- is the vector of simplex (Lagrange) multipliers.
--
-- Note that signs of the reduced costs d are determined by the formula
-- (15) in both cases of minimization and maximization.
--
-- The structure LPX allows scaling the problem. In the scaled problem
-- the constraint matrix is scaled and has the form
--
--    A" = R * A * S,                                               (17)
--
-- where A is the constraint matrix of the original (unscaled) problem,
-- R and S are, respectively, diagonal scaling mxm and nxn matrices with
-- positive diagonal elements used to scale rows and columns of A.
--
-- Actually *all* components of the LP problem stored in the structure
-- LPX are in the scaled form (for example, the constraint matrix stored
-- in LPX is A" = R*A*S, not A), and if the scaling is not used, it just
-- means that the matrices R and S are unity. Each time when something
-- is entered into LPX (for example, bounds of variables or constraint
-- coefficients), it is automatically scaled and then stored, and vice
-- versa, if something is obtained from LPX (for example, components of
-- the current basic solution), it is automatically unscaled. Thus, on
-- API level the scaling process is invisible.
--
-- The connection between the original and scaled components is defined
-- by (17) and expressed by the following formulae:
--
--    cR" = inv(R) * cR    (obj. coefficients at auxiliary variables)
--
--    cS" = S * cR         (obj. coefficients at structural variables)
--
--    xR" = R * xR         (values of auxiliary variables)
--    lR" = R * lR         (lower bounds of auxiliary variables)
--    uR" = R * uR         (upper bounds of auxiliary variables)
--
--    xS" = inv(S) * xS    (values of structural variables)
--    lS" = inv(S) * lS    (lower bounds of structural variables)
--    uS" = inv(S) * uS    (upper bounds of structural variables)
--
--    A"  = R * A * S      (constraint matrix)
--
-- Note that substitution scaled components into (4)-(6) gives the same
-- LP problem. */

typedef struct LPX LPX;

struct LPX
{     /* LP problem object */
      int m_max;
      /* maximal number of rows (if necessary, this parameter is
         automatically increased) */
      int n_max;
      /* maximal number of columns (if necessary, this parameter is
         automatically increased) */
      int m;
      /* current number of rows (auxiliary variables) */
      int n;
      /* current number of columns (structural variables) */
      POOL *pool;
      /* memory pool for segmented character strings */
      char *buf; /* char buf[255+1]; */
      /* working buffer used to return character strings */
      /*--------------------------------------------------------------*/
      /* symbolic names, types, and bounds of variables */
      STR **name; /* STR *name[1+m+n]; */
      /* name[0] is a name of the LP problem object;
         name[k], 1 <= k <= m+n, is a name of the variable x[k] */
      int *typx; /* int typx[1+m_max+n_max]; */
      /* typx[0] is not used;
         typx[k], 1 <= k <= m+n, is the type of the variable x[k]: */
#define LPX_FR          10 /* free variable:    -inf <  x[k] < +inf  */
#define LPX_LO          11 /* lower bound:      l[k] <= x[k] < +inf  */
#define LPX_UP          12 /* upper bound:      -inf <  x[k] <= u[k] */
#define LPX_DB          13 /* double bound:     l[k] <= x[k] <= u[k] */
#define LPX_FX          14 /* fixed variable:   l[k]  = x[k]  = u[k] */
      double *lb; /* double lb[1+m_max+n_max]; */
      /* lb[0] is not used;
         lb[k], 1 <= k <= m+n, is an lower bound of the variable x[k];
         if x[k] has no lower bound, lb[k] is zero */
      double *ub; /* double ub[1+m_max+n_max]; */
      /* ub[0] is not used;
         ub[k], 1 <= k <= m+n, is an upper bound of the variable x[k];
         if x[k] has no upper bound, ub[k] is zero; if x[k] is of fixed
         type, ub[k] is equal to lb[k] */
      double *rs; /* double rs[1+m_max+n_max]; */
      /* rs[0] is not used;
         rs[i], 1 <= i <= m, is diagonal element r[i,i] of the row
         scaling matrix R (see (17));
         rs[m+j], 1 <= j <= n, is diagonal element s[j,j] of the column
         scaling matrix S (see (17)) */
      int *mark; /* int mark[1+m+max+n_max]; */
      /* mark[0] is not used;
         mark[k], 1 <= k <= m+n, is a marker of the variable x[k];
         these markers are used to mark rows and columns for various
         purposes */
      /*--------------------------------------------------------------*/
      /* objective function */
      int dir;
      /* optimization direction (sense of the objective function): */
#define LPX_MIN         20 /* minimization */
#define LPX_MAX         21 /* maximization */
      double *coef; /* double coef[1+m_max+n_max]; */
      /* coef[0] is a constant term of the objective function;
         coef[k], 1 <= k <= m+n, is a coefficient of the objective
         function at the variable x[k] (note that auxiliary variables
         also may have non-zero objective coefficients) */
      /*--------------------------------------------------------------*/
      /* constraint matrix in row/column-wise sparse format */
      int *aa_ptr; /* int aa_ptr[1+m_max+n_max]; */
      /* aa_ptr[0] is not used;
         aa_ptr[i], 1 <= i <= m, is a pointer to the first element of
         the i-th row in the sparse vector area;
         aa_ptr[m+j], 1 <= j <= n, is a pointer to the first element of
         the j-th column in the sparse vector area */
      int *aa_len; /* int aa_len[1+m_max+n_max]; */
      /* aa_len[0] is not used;
         aa_len[i], 1 <= i <= m, is number of (non-zero) elements in
         the i-th row, 0 <= aa_len[i] <= n;
         aa_len[m+j], 1 <= j <= n, is number of (non-zero) elements in
         the j-th column, 0 <= aa_len[m+j] <= m */
      int *aa_cap; /* int aa_cap[1+m_max+n_max]; */
      /* aa_cap[0] is not used;
         aa_cap[i], 1 <= i <= m, is capacity of the i-th row that is
         number of locations, which can be used without relocation the
         row, aa_cap[i] >= aa_len[i];
         aa_cap[m+j], 1 <= j <= n, is capacity of the j-th column that
         is number of locations, which can be used without relocation
         the column, aa_cap[m+j] >= aa_len[m+j] */
      /*--------------------------------------------------------------*/
      /* sparse vector area (SVA) is a set of locations intended to
         store sparse vectors that represent rows and columns of the
         constraint matrix; each location is a doublet (ndx, val),
         where ndx is an index and val is a numerical value of sparse
         vector element; in the whole each sparse vector is a set of
         adjacent locations defined by a pointer to the first element
         (aa_ptr[*]) and number of its non-zero elements (aa_len[*]) */
      int sv_size;
      /* total size of SVA, in locations; locations are numbered by
         integers 1, 2, ..., sv_size, and location with the number 0 is
         not used; if necessary, sv_size is automatically increased */
      int sv_used;
      /* locations with the numbers 1, 2, ..., sv_used are currently
         used by rows and columns of the constraint matrix (this extent
         may contain "holes" due to fragmentation);
         locations with the numbers sv_used+1, sv_used+2, ..., sv_size
         are currently free;
         total number of free locations is (sv_size - sv_used) */
      int *sv_ndx; /* int sv_ndx[1+sv_size]; */
      /* sv_ndx[0] is not used;
         sv_ndx[k], 1 <= k <= sv_size, is the index field of the k-th
         location */
      double *sv_val; /* double sv_val[1+sv_size]; */
      /* sv_val[0] is not used;
         sv_val[k], 1 <= k <= sv_size, is the value field of the k-th
         location */
      /*--------------------------------------------------------------*/
      /* in order to efficiently defragment SVA a doubly linked list of
         rows and columns of the constraint matrix is used, where rows
         have numbers 1, ..., m, and column have numbers m+1, ..., m+n,
         so each row and column can be uniquely identified by only one
         integer; in the list rows and columns are ordered by ascending
         their pointers aa_ptr[*] */
      int sv_head;
      /* the number of the leftmost (in SVA) row/column */
      int sv_tail;
      /* the number of the rightmost (in SVA) row/column */
      int *sv_prev; /* int sv_prev[1+m_max+n_max]; */
      /* sv_prev[k], 1 <= k <= m+n, is the number of a row/column that
         precedes (in SVA) the k-th row/column */
      int *sv_next; /* int sv_next[1+m_max+n_max]; */
      /* sv_next[k], 1 <= k <= m+n, is the number of a row/column that
         succedes (in SVA) the k-th row/column */
      /*--------------------------------------------------------------*/
      /* current basis */
      int b_stat;
      /* status of the current basis: */
#define LPX_B_UNDEF     30 /* the current basis is undefined */
#define LPX_B_VALID     31 /* the current basis is valid */
      int p_stat;
      /* status of the primal solution: */
#define LPX_P_UNDEF     40 /* the status is undefined */
#define LPX_P_FEAS      41 /* the solution is primal feasible */
#define LPX_P_INFEAS    42 /* the solution is primal infeasible */
#define LPX_P_NOFEAS    43 /* no primal feasible solution exists */
      int d_stat;
      /* status of the dual solution: */
#define LPX_D_UNDEF     50 /* the status is undefined */
#define LPX_D_FEAS      51 /* the solution is dual feasible */
#define LPX_D_INFEAS    52 /* the solution is dual infeasible */
#define LPX_D_NOFEAS    53 /* no dual feasible solution exists */
      int *tagx; /* int tagx[1+m_max+n_max]; */
      /* tagx[0] is not used;
         tagx[k], 1 <= k <= m+n, is the status of the variable x[k]
         (contents of this array is always defined independently on the
         status of the current basis): */
#define LPX_BS          60 /* basic variable */
#define LPX_NL          61 /* non-basic variable on its lower bound */
#define LPX_NU          62 /* non-basic variable on its upper bound */
#define LPX_NF          63 /* non-basic free variable */
#define LPX_NS          64 /* non-basic fixed variable */
      int *posx; /* int posx[1+m_max+n_max]; */
      /* posx[0] is not used;
         posx[k], 1 <= k <= m+n, is the position of the variable x[k]
         in the vector of basic variables xB or non-basic variables xN:
         posx[k] = i   means that x[k] = xB[i], 1 <= i <= m
         posx[k] = m+j means that x[k] = xN[j], 1 <= j <= n
         (if the current basis is undefined, contents of this array is
         undefined) */
      int *indx; /* int indx[1+m_max+n_max]; */
      /* indx[0] is not used;
         indx[i], 1 <= i <= m, is the original number of the basic
         variable xB[i], i.e. indx[i] = k means that posx[k] = i
         indx[m+j], 1 <= j <= n, is the original number of the non-basic
         variable xN[j], i.e. indx[m+j] = k means that posx[k] = m+j
         (if the current basis is undefined, contents of this array is
         undefined) */
      INV *inv; /* INV inv[m,m]; */
      /* an invertable (factorized) form of the current basis matrix */
      /*--------------------------------------------------------------*/
      /* basic solution components */
      double *bbar; /* double bbar[1+m_max]; */
      /* bbar[0] is not used;
         bbar[i], 1 <= i <= m, is a value of basic variable xB[i] */
      double *pi; /* double pi[1+m_max]; */
      /* pi[0] is not used;
         pi[i], 1 <= i <= m, is a simplex (Lagrange) multiplier, which
         corresponds to the i-th row (equality constraint) */
      double *cbar; /* double cbar[1+n_max]; */
      /* cbar[0] is not used;
         cbar[j], 1 <= j <= n, is a reduced cost of non-basic variable
         xN[j] */
      /*--------------------------------------------------------------*/
      /* control parameters and statistics */
      int msg_lev;
      /* level of messages output by the solver:
         0 - no output
         1 - error messages only
         2 - normal output
         3 - full output (includes informational messages) */
      int start;
      /* starting option:
         0 - use standard initial basis
         1 - use advanced initial basis
         2 - use current basis (warm start) */
      int dual;
      /* simplex method option:
         0 - use primal simplex
         1 - use dual simplex (requires the starting basis to be dual
             feasible) */
      int price;
      /* pricing option (for both primal and dual):
         0 - textbook pricing
         1 - steepest edge pricing */
      double relax;
      /* bound relaxation parameter used in the primal ratio test;
         if this parameter is zero, textbook ratio test is used;
         if this parameter is non-zero, Harris's ratio test is used;
         in the latter case on the first pass of the ratio test basic
         variables are allowed to slightly violate their bounds, but
         not more than relax * tol_bnd (thus, relax is a percentage of
         tol_bnd); typical value is 0.10--0.15 */
      double tol_bnd;
      /* relative tolerance used to check if the current basic solution
         is primal feasible */
      double tol_dj;
      /* absolute tolerance used to check if the current basic solution
         is dual feasible */
      double tol_piv;
      /* relative tolerance used to check pivotal elements in the ratio
         test */
      int it_lim;
      /* simplex iteration limit (maximal number of iterations allowed
         to the solver); negative value means no limit */
      int it_cnt;
      /* simplex iteration count; this count is reset to zero on entry
         to the solver and increased by one each time when the current
         basis is changed; thus, on exit it keeps the total number of
         simplex iterations performed by the solver */
};

/* exit codes returned by the routine lpx_simplex: */
#define LPX_E_OK        70 /* no errors */
#define LPX_E_EMPTY     71 /* empty problem (no rows/columns) */
#define LPX_E_BADB      72 /* bad initial basis (warm start only) */
#define LPX_E_ITLIM     73 /* iteration limit exceeded */
#define LPX_E_SING      74 /* numerical problems with basis matrix */

LPX *lpx_create_prob(void);
/* create LP problem object */

void lpx_reset_parms(LPX *lp);
/* reset control parameters to default values */

void lpx_realloc_prob(LPX *lp, int m_max, int n_max);
/* reallocate LP problem object */

void lpx_add_rows(LPX *lp, int nrs);
/* add new rows to LP problem object */

void lpx_add_cols(LPX *lp, int ncs);
/* add new columns to LP problem object */

int lpx_check_name(char *name);
/* check correctness of symbolic name */

void lpx_set_prob_name(LPX *lp, char *name);
/* assign (change) problem name */

void lpx_set_row_name(LPX *lp, int i, char *name);
/* assign (change) row name */

void lpx_set_col_name(LPX *lp, int j, char *name);
/* assign (change) column name */

void lpx_set_row_bnds(LPX *lp, int i, int typx, double lb, double ub);
/* set (change) row bounds */

void lpx_set_col_bnds(LPX *lp, int j, int typx, double lb, double ub);
/* set (change) column bounds */

void lpx_set_obj_dir(LPX *lp, int dir);
/* set (change) optimization direction */

void lpx_set_obj_c0(LPX *lp, double c0);
/* set (change) constant term of the obj. function */

void lpx_set_row_coef(LPX *lp, int i, double coef);
/* set (change) row objective coefficient */

void lpx_set_col_coef(LPX *lp, int j, double coef);
/* set (change) column objective coefficient */

void lpx_defrag_sva(LPX *lp);
/* defragment the sparse vector area */

int lpx_enlarge_cap(LPX *lp, int k, int cap);
/* enlarge capacity of row or column */

void lpx_set_mat_row(LPX *lp, int i, int len, int ndx[], double val[]);
/* set (replace) row of the constraint matrix */

void lpx_set_mat_col(LPX *lp, int j, int len, int ndx[], double val[]);
/* set (replace) column of the constraint matrix */

void lpx_unmark_all(LPX *lp);
/* unmark all rows and columns */

void lpx_mark_row(LPX *lp, int i, int mark);
/* assign mark to row */

void lpx_mark_col(LPX *lp, int j, int mark);
/* assign mark to column */

void lpx_change_ordn(LPX *lp);
/* change ordinal numbers of rows and columns */

void lpx_clear_mat(LPX *lp);
/* clear rows and columns of the constraint matrix */

void lpx_del_items(LPX *lp);
/* remove rows and columns from LP problem object */

void lpx_delete_prob(LPX *lp);
/* delete LP problem object */

int lpx_simplex(LPX *lp);
/* solve LP problem by means of the simplex method */

int lpx_get_num_rows(LPX *lp);
/* determine number of rows */

int lpx_get_num_cols(LPX *lp);
/* determine number of columns */

int lpx_get_num_nz(LPX *lp);
/* determine number of constraint coefficients */

char *lpx_get_prob_name(LPX *lp);
/* obtain problem name */

char *lpx_get_row_name(LPX *lp, int i);
/* obtain row name */

char *lpx_get_col_name(LPX *lp, int j);
/* obtain column name */

void lpx_get_row_bnds(LPX *lp, int i, int *typx, double *lb,
      double *ub);
/* obtain row bounds */

void lpx_get_col_bnds(LPX *lp, int j, int *typx, double *lb,
      double *ub);
/* obtain column bounds */

int lpx_get_obj_dir(LPX *lp);
/* determine optimization direction */

double lpx_get_obj_c0(LPX *lp);
/* obtain constant term of the obj. function */

double lpx_get_row_coef(LPX *lp, int i);
/* obtain row objective coefficient */

double lpx_get_col_coef(LPX *lp, int j);
/* obtain column objective coefficient */

int lpx_get_mat_row(LPX *lp, int i, int ndx[], double val[]);
/* get row of the constraint matrix */

int lpx_get_mat_col(LPX *lp, int j, int ndx[], double val[]);
/* get column of the constraint matrix */

int lpx_get_prim_stat(LPX *lp);
/* query primal status of basic solution */

int lpx_get_dual_stat(LPX *lp);
/* query dual status of basic solution */

#endif

/* eof */
