/* glprfi.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 _GLPRFI_H
#define _GLPRFI_H

#include "glpduff.h"
#include "glpeta.h"
#include "glpmat.h"

#define create_rfi            _glp_create_rfi
#define build_rfi             _glp_build_rfi
#define rfi_btran             _glp_rfi_btran
#define rfi_ftran             _glp_rfi_ftran
#define update_rfi            _glp_update_rfi
#define delete_rfi            _glp_delete_rfi

/*----------------------------------------------------------------------
-- The structure RFI defines Reid's Form of the Inverse which is the
-- following representation of the current basis matrix B:
--
--    B = H * V,
--
-- where H is the eta-matrix, V is the implicit upper triangular matrix.
--
-- The eta-matrix H has the form of eta-file:
--
--    H = H(1) * H(2) * ... * H(t),
--
-- where H(1), H(2), ..., H(t) are elementary matrix multipliers or
-- eta-terms, t is the total number of terms (size of eta-file).
--
-- The matrix V differs from an upper triangular matrix only by order of
-- rows and columns. This means that
--
--    U = P * V * Q,
--
-- where U is the upper triangular matrix, P and Q are known permutation
-- matrices.
--
-- It's understood that RFI is some variety of LU-factorization, where
-- L is represented by the eta-file H, and U is represented implicitly
-- by the matrices V, P and Q. */

typedef struct RFI RFI;

struct RFI
{     /* Reid's form of the inverse (RFI) */
      int m;
      /* order of basis matrix */
      HFILE *H;
      /* eta-matrix in the form of eta-file */
      MAT *V;
      /* implicit upper triangular matrix */
      PER *P;
      /* left permutation matrix */
      PER *Q;
      /* right permutation matrix */
      int nzH0;
      /* size of the eta-file H at once after the last reinversion */
      int nzV0;
      /* number of non-zeros of the matrix V at once after the last
         reinversion */
      int reid;
      /* if this flag is set, Reid's technique will be used to minimize
         the bump of the matrix U = P*V*Q */
      int tech;
      /* updating technique flag: */
#define RFI_BG    0  /* Bartels & Golub updating technique */
#define RFI_FT    1  /* Forrest & Tomlin updating technique */
      double *col;
      /* partially transformed column corresponding to that non-basis
         variable which has been chosen to enter the basis */
      int flag;
      /* transformed column flag:
         0 - column is not prepared yet
         1 - column is ready for updating */
      DUFF *rs, *cs; /* DUFF rs[1:m,1:m], cs[1:m,1:m]; */
      /* auxiliary Duff's schemes */
      double *work; /* double work[1+m]; */
      /* auxiliary array */
};

extern RFI *create_rfi(int m);
/* create RFI */

extern int build_rfi(RFI *rfi, MAT *A, int indb[]);
/* build RFI for given basis matrix */

extern double *rfi_ftran(RFI *rfi, double z[], int save);
/* perform forward transformation (FTRAN) using RFI */

extern double *rfi_btran(RFI *rfi, double z[]);
/* perform backward transformation (BTRAN) using RFI */

extern int update_rfi(RFI *rfi, int p);
/* update RFI for adjacent basis matrix */

extern void delete_rfi(RFI *rfi);
/* delete RFI */

#endif

/* eof */
