\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename libref
@settitle GLPK 1.1 Library Reference
@setchapternewpage odd
@exampleindent 0
@c %**end of header
@syncodeindex fn cp
@syncodeindex tp cp
@syncodeindex vr cp

@ifinfo
Sorry, this document is not intended to be formatted as @samp{info}.
@bye
@end ifinfo

@ifhtml
Sorry, this document is not intended to be formatted as @samp{html}.
@bye
@end ifhtml

@titlepage
@title GLPK
@subtitle GNU Linear Programming Kit
@subtitle Version 1.1
@subtitle Library Reference
@subtitle December 2000
@author Andrew Makhorin
@page
@vskip 0pt plus 1filll
The GLPK package is a part of the GNU project, released under the aegis of GNU.

Copyright @copyright{} 2000 Andrew Makhorin, Department for Applied
Informatics, Moscow Aviation Institute, Moscow, Russia. All rights reserved.

Free Software Foundation, Inc., 59 Temple Place --- Suite 330, Boston, MA
02111, USA.

Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on all
copies.

Permission is granted to copy and distribute modified versions of this manual
under the conditions for verbatim copying, provided also that the entire
resulting derived work is distributed under the terms of a permission notice
identical to this one.

Permission is granted to copy and distribute translations of this manual into
another language, under the above conditions for modified versions.
@end titlepage

@contents

@chapter Introduction

GLPK (GNU Linear Programming Kit) is a set of routines written in the ANSI C
programming language and organized in the form of a library. This package is
intended for solving large scale linear programming and other related problems.

This document describes GLPK routines, which implement some important
algorithms and data structures (for example, operations on sparse matrices) and
which may be used independently.

For the sake of convenience all GLPK routines are splitted into partitions.
Each partition has a name, which is identical to the corresponding header file
in the library. For example, declarations of data structures and routines
related to operations on sparse matrices are contained in the header file
@code{glpmat.h}, therefore the name of that partition is GLPMAT.

Some GLPK routines (for example, routines that implement AVL search trees) are
not related directly to solving LP problems. However, those routines play
important role on preparing input data in case of large scale problems.

Descriptions of some routines include @dfn{time complexity}. This
characteristic shows how the time of an operation depends on the size of data.
For example, the @code{find_by_key} routine, which searches for a node with the
given key in AVL tree, has time complexity @i{O}(log@i{n}), where @i{n} is
current number of nodes in the AVL tree. This means that if this operation
takes @i{t} time units in case of @i{n} nodes, it will take 10@i{t} time units
in case of 1000@i{n} nodes, i.e. increasing number of nodes in 1000 times
involves increasing the time of operation approx. in 10 times, because
@tex
$\log 1000 \approx 10$
@end tex
(the logarithm base is not essential). Time complexity @i{O}(1) means that an
operation takes the constant time, i.e. the time of operation doesn't depend
on the size of data. Knowing time complexity of GLPK routines the user can
estimate this characteristic of its own routines based on GLPK routines.

@chapter GLPAVL: AVL Search Trees

@section Prelude

@dfn{Adelson-Velsky and Landis search tree (AVL tree)} is a well known data
structure, which is intended mainly for organizing symbol tables
@footnote{Another approach for organizing symbol tables is based on
@emph{hash tables}.}.

The user can consider AVL tree just as an ordered set of @dfn{nodes} (or table
entries), where each node has a @dfn{key}, i.e. some value, which identifies
the node. Data type, which is used for representing keys of a particular AVL
tree, should be supplied by the user and may be of arbitrary nature. However,
all keys should be comparable on "less than", "equal to", and "greater than".

AVL trees allow performing main operations (inserting a new node, searching for
a node, and deleting a node) for logarithmic time and, thus, combine advantages
of linked lists and binary search.

AVL trees are based on binary trees. @dfn{Binary tree} is a recursive data
structure, where one node is a @dfn{root}, and other nodes are divided into two
parts: the @dfn{left subtree} and the @dfn{right subtree}, thereto each subtree
also have the same structure of binary tree. The ordering of nodes of a binary
tree is defined in the following way: if some node has the key @i{K}, then all
nodes in the left subtree have keys that are less than @i{K}, and all nodes in
the right subtree have keys that are greater than @i{K}. Example of a binary
tree is shown on Fig. 2.1.

@sp 1
@image{doc/fig/glpavl01}
@center{Fig. 2.1. Example of a binary tree}
@sp 1

The ordering nodes by keys allows efficient searching for a node with the given
key @i{K}. In order to find that node we should start from the root of a binary
tree and go to the left if @i{K} is less than the key of the current node or to
the right if @i{K} is greater than the key of the current node. The same way
may be used in order to find the point for inserting a new node.

The main characteristic of a binary tree is its @dfn{height}, which is a
maximal number of nodes in a path from the root to any other node. It is
understood that the height of a binary tree is a crucial parameter, since it
determines the number of elementary steps needed for performing main operations
on a binary tree. If there are no additional limitations on the structure of a
binary tree, its height may change from
@tex
$\log_2(N+1)$
@end tex
(ideal case) to @i{N} (degenerative case), where @i{N} is total number of
nodes. Therefore if a binary tree approaches to the degenerative case, all
main operations become inefficient as in the case of ordinary linear linked
lists.

In order to avoid the degeneracy of a binary tree Adelson-Velsky and Landis [1]
proposed the following limitation on its structure: the difference between
heights of the left and the right subtrees for each node of a binary tree
should be not greater than one. The binary tree, which is satisfied to such
limitation, is called @dfn{AVL tree}. (Note that the binary tree shown on
@w{fig. 2.1} is not AVL tree.) In [1] it also was shown that the height of any
AVL tree can't exceed @i{O}(log@i{N}), therefore AVL trees allow all main
operations to be efficient as in the case of the binary search.

For more detailed discussion of AVL and binary trees see the excellent book
[2].

In order to represent AVL tree on the whole the @code{AVLTREE} structure is
used:

@tpindex{AVLTREE}
@example
      typedef struct AVLTREE AVLTREE;
      struct AVLTREE
      @{     POOL *pool;
            int (*comp)(void *, void *);
            int size;
            AVLNODE *root;
            int height;
      @};
@end example

@noindent
where:

@table @code
@item pool
memory pool (see Section 10.3) that holds all nodes of the tree;
@item comp
user-supplied routine for comparing node keys. If this pointer is @code{NULL},
the ordering by keys is not used;
@item size
tree size (total number of nodes in the tree);
@item root
pointer to the root node;
@item height
total height of the tree.
@end table

The representation of a particular node is defined by the @code{AVLNODE}
structure:

@tpindex{AVLNODE}
@example
      typedef struct AVLNODE AVLNODE;
      struct AVLNODE
      @{     void *key;
            int rank;
            int type;
            void *link;
            AVLNODE *up;
            short int flag;
            short int bal;
            AVLNODE *left;
            AVLNODE *right;
      @};
@end example

@noindent
where:

@table @code
@item key
pointer to the key (data type used for representing keys is supplied by the
user);
@item rank
node rank (the relative position of the node in its own subtree = number of
nodes in the left subtree plus one);
@item type
node type (this field is intended for the user);
@item link
pointer to the node extension (this field is intended for the user);
@item up
pointer to the parent node or @code{NULL} (if this node is the root of the
entire tree and has no parent node);
@item flag
node flag:
@table @code
@item 0
this node is the left child of its parent (or this node is the root of the
entire tree and has no parent node);
@item 1
this node is the right child of its parent.
@end table
@item bal
balance flag (the difference between heights of the right and the left
subtrees):
@table @code
@item -1
the left subtree is higher than the right one;
@item @ 0
the left and the right subtrees has equal heights;
@item +1
the left subtree is lower that the right one.
@end table
@item left
pointer to the root of the left subtree;
@item right
pointer to the root of the right subtree.
@end table

@section @code{create_avl} --- create AVL tree
@fnindex{create_avl}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLTREE *create_avl(int (*comp)(void *, void *));
@end example

@subsubheading Description

The @code{create_avl} routine creates an empty AVL tree, which has no nodes.

The parameter @code{comp} specifies a routine for comparing node keys (data
type representing keys should be supplied by the user). The comparing routine
should have the following heading:

@example
      int comp(void *key1, void *key2);
@end example

@noindent
where @code{key1} and @code{key2} are pointers to the first key and to the
second key respectively. This routine should return one of the following
values depending on the result of comparison (below [@code{p}] denotes a value
of the object, which @code{p} points to):

@table @code
@item < 0
if [@code{key1}] is less than [@code{key2}];
@item = 0
if [@code{key1}] and [@code{key2}] are identical;
@item > 0
if [@code{key1}] is greater than [@code{key2}].
@end table

If node keys are character strings, the following statement may be used for
creating AVL tree:

@example
      ... = create_avl((int (*)(void *, void *))strcmp);
@end example

If node keys are not used, it is allowed to specify @code{NULL} instead the
comparing routine. This case assumes inserting, searching, and deleting nodes
by their positions (sequential numbers).

@subsubheading Returns

The @code{create_avl} routine returns a pointer to the created AVL tree.

@section @code{insert_by_key} --- insert new node with given key
@fnindex{insert_by_key}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *insert_by_key(AVLTREE *tree, void *key);
@end example

@subsubheading Description

The @code{insert_by_key} routine creates a new node with the given @code{key}
and inserts this node into the AVL @code{tree}. (This operation requires key
nodes, therefore the key comparing routine should be defined on creating the
tree; see Section 2.2.)

The insertion is performed independently on whether there are nodes with the
same keys in the tree or not. In order to check that a node with the same key
already exists the @code{find_by_key} routine may be used (see Section 2.6).

It is assumed that the object, which @code{key} points to, has yet been
allocated. This allocation should be kept at least while the node is in the
tree or while the tree exists.

On exit the fields @code{type} and @code{link} of the structure @code{AVLNODE},
that represents the inserted node, will contain binary zeros. These fields are
available through the pointer returned by the routine and may be used for
arbitrary purposes.

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

The @code{insert_by_key} routine returns a pointer to the inserted node.

@subsubheading Algorithm

At first the routine searches for the point, where a new node with the given
key @i{K} should be inserted. In order to do that the routine starts from the
root of the tree. If @w{@i{K} @math{@leq{}} @i{K}'}, where @i{K}' is the key of
the current node, the routine goes to its left child; otherwise, if
@w{@i{K} > @i{K}'}, the routine goes to its right child. Such descent is
continued until the routine has found an empty left or right subtree, instead
which it inserts new node.

After insertion the tree may become disbalanced. It is obvious that only those
subtrees can be disbalanced, which were visited on inserting the node. So, the
routine rises from the new node up to the root of the tree and restores the
balance of each visited node (now these nodes are visited in the reverse
order).

Let us assume that the routine visits a node, the left subtree of which was
increased as the result of the insertion. Depending on the difference between
heights of subtrees of that node the following three cases can take a place
(see Fig. 2.2):

a) before insertion @i{bal} = +1, after insertion @i{bal} = 0. Since in this
case the height of the subtree, the root of which is the visited node, was not
changed, further movement up to the tree is terminated;

b) before insertion @i{bal} = 0, after insertion @i{bal} = @minus{}1. Since in
this case the height of the subtree, the root of which is the visited node, was
increased, further movement up to the tree should be continued;

c) before insertion @i{bal} = @minus{}1, after insertion @i{bal} = @minus{}2.
In this case the routine performs the auxiliary transformation called
@dfn{rotation}. This transformation, keeping the order of nodes, restores the
balance (for details see Section 2.11). After rotation the height of the
subtree, the root of which is the visited node, remains unchanged, so further
movement up to the tree is terminated.

Now let us assume that the routine visits a node, the right subtree of which
was increased as the result of the insertion. The corresponding cases are
mirror reflections of cases described above (see Fig. 2.3).

@section @code{next_node} --- search for the next node
@fnindex{next_node}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *next_node(AVLTREE *tree, AVLNODE *node);
@end example

@subsubheading Description

The @code{next_node} routine searches for the next node of the AVL @code{tree},
which follows the given @code{node}. If the parameter node is @code{NULL}, the
routine searches for the first node of the tree. The key of the next node is
always not less than the key of the given node.

The following statement may be used for visiting all nodes of the tree in the
sequence of non-decreasing their keys:

@example
      for (n = next_node(t, NULL); n != NULL; n = next_node(t, n)) ...
@end example

@sp 1
@image{doc/fig/glpavl02}
@center{Fig. 2.2. New node was inserted into the left subtree}
@sp 1

Note that if the tree has nodes with identical keys, these nodes will be also
visited only once, however, the order of visiting these indistinguishable nodes
is undefined.

This operation is applicable if nodes has no keys. In such case the next node
is that one, which has the next sequential number (see Algorithm).

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

If the parameter @code{node} is @code{NULL}, the @code{next_node} routine
returns a pointer to the first node of the tree, or @code{NULL}, if the tree is
empty. If the parameter @code{node} points to the given node, the
@code{next_node} routine returns a pointer to the next node or @code{NULL}, if
the next node does not exist.

@sp 1
@image{doc/fig/glpavl03}
@center{Fig. 2.3. New node was inserted into the right subtree}
@sp 1

@subsubheading Algorithm

Visiting all nodes of AVL tree in the straight sequence may be explained by the
following recursive procedure:

1) visit all nodes of the left subtree using the same procedure;

2) visit the root;

3) visit all nodes of the right subtree using the same procedure.

However, the @code{next_node} routine uses non-recursive version of this
procedure. Two cases, which may take a place, are schematically shown on
Fig. 2.4.

@page
@image{doc/fig/glpavl04}
@center{Fig. 2.4. Searching for a node, which follows the given node}
@sp 1

@section @code{prev_node} --- search for the previous node
@fnindex{prev_node}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *prev_node(AVLTREE *tree, AVLNODE *node);
@end example

@subsubheading Description

The @code{prev_node} routine searches for the previous node of the AVL
@code{tree}, which precedes the given @code{node}. If the parameter @code{node} is
@code{NULL}, the routine searches for the last node of the tree. The key of the
previous node is always not greater that the key of the given node.

The following statement may be used for visiting all nodes of the tree in the
sequence of non-increasing their keys:

@example
      for (n = prev_node(t, NULL); n != NULL; n = prev_node(t, n)) ...
@end example

Note that if the tree has nodes with identical keys, these nodes will be also
visited only once, however, the order of visiting these indistinguishable nodes
is undefined.

This operation is applicable if nodes has no keys. In such case the next node
is that one, which has the previous sequential number (see Algorithm).

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is the current
number of nodes in the tree.

@subsubheading Returns

If the parameter @code{node} is @code{NULL}, the @code{prev_node} routine
returns a pointer to the last node of the tree, or @code{NULL}, if the tree is
empty. If the parameter @code{node} points to the given node, the
@code{prev_node} routine returns a pointer to the previous node or @code{NULL},
if the previous node does not exist.

@subsubheading Algorithm

Visiting all nodes of AVL tree in the reverse order may be explained by the
following recursive procedure:

1) visit all nodes of the right subtree using the same procedure;

2) visit the root;

3) visit all nodes of the left subtree using the same procedure.

However, the @code{prev_node} routine uses non-recursive version of this
procedure. Two cases, which may take a place, are schematically shown on
Fig. 2.5.

@sp 1
@image{doc/fig/glpavl05}
@center{Fig. 2.5. Searching for a node, which precedes the given node}
@sp 1

@section @code{find_by_key} --- search for the first node with given key
@fnindex{find_by_key}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *find_by_key(AVLTREE *tree, void *key);
@end example

@subsubheading Description

The @code{find_by_key} routine searches for the first node in the AVL
@code{tree}, which has the given @code{key}. (This operation requires key
nodes, therefore the key comparing routine should be defined on creating
the tree; see Section 2.2.)

In order to find all other nodes with the same key the @code{next_by_key}
routine may be used (see Section 2.7).

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

The @code{find_by_key} routine returns a pointer to the first node with the
given key, or @code{NULL}, if the tree has no nodes with the given key.

@subsubheading Algorithm

At first the @code{find_by_key} routine finds arbitrary node with the given key
using the same descent on the tree as in the case of inserting new node (see
Section 2.8). If a node with the given key has been found, the
@code{find_by_key} routine calls the @code{prev_node} routine (see Section 2.5)
in order to find the first node with the given key.

@section @code{next_by_key} --- search for the next node with the same key
@fnindex{next_by_key}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *next_by_key(AVLTREE *tree, void *key);
@end example

@subsubheading Description

The @code{next_by_key} routine searches for the next node in the AVL tree,
which has the same key as the given node. (This operation requires key nodes,
therefore the key comparing routine should be defined on creating the tree;
see Section 2.2.)

In order to find the first node with the given key the @code{find_by_key}
routine may be used (see Section 2.6).

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

The @code{next_by_key} routine returns a pointer to the next node with the same
key as the given node, or @code{NULL}, if the next node with the same key does
not exist.

@subsubheading Algorithm

In order to find the next node the @code{next_by_key} routine calls the
@code{next_node} routine (see Section 2.4). If the next node has the same key
as the given node, the routine returns a pointer to the next node, otherwise
the routine returns @code{NULL}.

@section @code{insert_by_pos} --- insert new node to given position
@fnindex{insert_by_pos}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *insert_by_pos(AVLTREE *tree, int pos);
@end example

@subsubheading Description

The @code{insert_by_pos} routine creates a new node and inserts it to the given
position @code{pos} of the AVL @code{tree}. It is necessary that
@w{@math{1 @leq{} pos @leq{} n+1}}, where @i{n} = @code{tree->size} is total
number of nodes in the AVL tree before insertion.

If we renumber all nodes of the AVL tree by numbers
@w{@math{1, 2, @dots{}, n}} in that order, in which nodes would be visited by
the next_node routine (see Section 2.4), then new node is placed between nodes
with numbers @code{pos}@minus{}1 and @code{pos} (if @code{pos} = 1, new node is
placed before the first node, and if @code{pos} = @i{n}+1, new node is placed
after the last node). Thus, after insertion the new node will have the number
@code{pos}.

On exit the fields @code{type} and @code{link} of the structure @code{AVLNODE},
that represents the inserted node, will contain binary zeros. These fields are
available through the pointer returned by the routine and may be used for
arbitrary purposes.

It is not recommended to use the @code{insert_by_pos} routine together with
routines, which assume keyed nodes (@code{insert_by_key}, @code{find_by_key},
@code{next_by_key}), because incorrect insertion may invalidate the order of
nodes.

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

The @code{insert_by_pos} routine returns a pointer to the inserted node.

@subsubheading Algorithm

At first the routine searches for the point, where a new should be inserted.
In order to do that the routine starts from the root of the tree. If
@w{@math{pos @leq{} rank}}, where @i{rank} is the relative position of the
current node in its own subtree (number of nodes in the left subtree plus one),
the routine goes to the left child of the current node; otherwise, if
@w{@math{pos > rank}}, the routine goes to the right child of the current node.
Thereto in the latter case the routine decreases @i{pos} by the @i{rank} value
of the current node. The descent is continued until the routine has found an
empty left or right subtree, instead which it inserts new node. Then the
routine restores the balance of all subtrees in the same way as in case of
insertion by keys (see Section 2.3).

@section @code{find_by_pos} --- search for node placed in given position
@fnindex{find_by_pos}

@subsubheading Synopsis

@example
#include "glpavl.h"
AVLNODE *find_by_pos(AVLTREE *tree, int pos);
@end example

@subsubheading Description

The @code{find_by_pos} routine searches for a node, which is placed in the
given position @code{pos} of the AVL @code{tree}.

Do not use this routine for visiting all nodes of the AVL tree, because this
is inefficient. It's better to use the @code{next_node} or the @code{prev_node}
routines (see Sections 2.4 and 2.5).

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

If @w{@math{1 @leq{} pos @leq{} n}}, where @w{@i{n} = @code{tree->size}} is
total number of nodes in the AVL tree, the routine returns a pointer to the
node placed in the given position @code{pos}. Otherwise the routine returns
@code{NULL}.

@section @code{delete_node} --- delete given node
@fnindex{delete_node}

@subsubheading Synopsis

@example
#include "glpavl.h"
void delete_node(AVLTREE *tree, AVLNODE *node);
@end example

@subsubheading Description

The @code{delete_node} routine deletes the given @code{node} from the AVL
@code{tree}. It is assumed (without any checking) that the given node belongs
to the given tree; otherwise the behavior is undefined. (This operation is
applicable independently of whether nodes have keys or not, since the order of
nodes is preserved.)

Note that the @code{delete_node} routine deletes exactly the specified node,
therefore all references to other nodes from the user's data structures (if
such references exist) will remain valid after deletion.

Actually the routine doesn't free the memory allocated to the deleted node. It
just returns that memory to the memory pool, so that memory can be reused in
the future for the same tree.

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Algorithm

If both subtrees of the deleted node are not empty, the routine exchanges the
deleted node with the next node, the left subtree of which is empty. It is
important to note that the routine exchanges nodes themselves (i.e. structures
of @code{AVLNODE} type), but not data placed in nodes. Therefore all references
to other nodes from the user's data structures (if such references exist) will
remain valid after deletion.

In order to delete node, which has one non-empty subtree, the routine connects
that subtree to the parent of the deleted node. If the deleted node has no
subtrees, the routine just disconnect the node from its parent.

After deletion the tree may become disbalanced. So, the routine rises from the
deleted node up to the root of the tree and restores the balance of each
visited node similarly to the case of insertion (see Section 2.3).

Let us assume that the routine visits a node, the left subtree of which was
decreased as the result of the deletion. Depending on the difference between
heights of subtrees of that node the following three cases can take a place
(see Fig. 2.6):

a) before deletion @i{bal} = @minus{}1, after deletion @i{bal} = 0. Since in
this case the height of the subtree, the root of which is the visited node, was
decreased, further movement up to the tree should be continued;

b) before deletion @i{bal} = 0, after deletion bal = +1. Since in this case the
height of the subtree, the root of which is the visited node, was not changed,
further movement up to the tree is terminated;

c) before deletion bal = +1, after deletion bal = +2. In this case the routine
performs the auxiliary transformation called @dfn{rotation}. This
transformation, keeping the order of nodes, restores the balance (for details
see Section 2.11). After rotation the routine analyzes the balance flag of that
node, which has replaced the visited node. If @i{bal} = @minus{}1 (the height
of subtree was not changed), the movement is terminated. If @i{bal} = 0 (the
height of subtree was decreased), the movement is continued.

Now let us assume that the routine visits a node, the right subtree of which
was decreased as the result of the deletion. The corresponding cases are mirror
reflections of cases described above (see Fig. 2.7).

@page
@image{doc/fig/glpavl06}
@center{Fig. 2.6. Node was deleted from the left subtree}
@sp 1

@section @code{rotate_avl} --- restore balance of AVL subtree
@fnindex{rotate_avl}

@subsubheading Synopsis

@example
#include "glpavl.h"
void delete_node(AVLTREE *tree, AVLNODE *node);
@end example

@subsubheading Description

The @code{rotate_avl} routine restores balance of the subtree (of the AVL
@code{tree}) specified by its root, which the parameter @code{node} points to.

The @code{rotate_avl} routine is auxiliary, it is not intended for independent
usage.

@sp 1
@image{doc/fig/glpavl07}
@center{Fig. 2.7. Node was deleted from the right subtree}
@sp 1

@subsubheading Complexity

This operation has time complexity @i{O}(log@i{n}), where @i{n} is current
number of nodes in the tree.

@subsubheading Returns

The @code{rotate_avl} routine returns a pointer to the node, which replaces
the root of the specified subtree.

@subsubheading Algorithm

If the height of the left subtree of the given key is higher that the height of
the right subtree, the routine performs single or double clockwise rotation
depending on cases shown on Fig. 2.8. Analogously, if the height of the left
subtree of the given key is lower that the height of the right subtree, the
routine performs single or double counterclockwise rotation depending on cases
shown on Fig. 2.9.

@sp 1
@image{doc/fig/glpavl08}
@center{Fig. 2.8. Single (a, b) and double (c) clockwise rotation}
@sp 1


@section @code{delete_avl} --- delete AVL tree
@fnindex{delete_avl}

@subsubheading Synopsis

@example
#include "glpavl.h"
void delete_avl(AVLTREE *tree);
@end example

@sp 1
@image{doc/fig/glpavl09}
@center{Fig. 2.9. Single (a, b) and double (c) counterclockwise rotation}
@sp 1

@subsubheading Description

The @code{delete_avl} routine deletes the AVL @code{tree}, freeing all memory
allocated to this object. Note that the routine doesn't free any memory
allocated to the user's data structures.

@unnumberedsec References

@enumerate 1
@item
@i{G. M. Adelson-Velsky, E. M. Landis.} Odin algoritm organizacii informacii.
DAN SSSR, 146, 1962, @w{s. 263---66} (in Russian).
@item
@i{Donald E. Knuth.} The Art of Computer Programming. @w{Vol. 3}. Sorting and
Searching. Addison-Wesley, 1973.
@end enumerate

@chapter GLPDUFF: Duff Search Technique

@section Prelude

Let us consider a set of @i{n} objects numbered by integers
@w{@math{1, 2, @dots{}, n}}, where a particular object with the number @i{k}
can posses the length @math{@lambda{}l(k)}. @dfn{Duff search technique} allows
efficient (i.e. for a fixed time) performing the following two main operations:

determining numbers of all objects that have the given length;

changing the length of an object.

These operations appear mainly in implementations of sparse gaussian
elimination based on Markowitz strategy for pivoting. The considered search
technique was proposed by @w{I. Duff} [1].

This implementation of Duff search technique is based on @dfn{Duff scheme},
which is a set of unordered double linked lists. A particular linked list
contains numbers of objects that have the same length.

Duff scheme is represented by the DUFF structure:

@tpindex{DUFF}
@example
      typedef struct DUFF DUFF;
      struct DUFF
      @{     int n;
            int maxlen;
            int len[1:n];
            int head[0:maxlen];
            int prev[1:n];
            int next[1:n];
      @};
@end example

@noindent
where:

@table @code
@item n
total number of objects, @i{n} > 0;
@item maxlen
maximal length of each object, @math{maxlen @geq{} 0};
@item len
array of object lengths. Location @code{len}[0] is not used. Location
@code{len}[@i{k}] contains the length of @i{k}th object
@w{@math{(1 @leq{} k @leq{} n)}} in the range from 0 to @code{maxlen}. The case
@w{@code{len}[@i{k}] < 0} means that @i{k}th object is not in the scheme and
its length is undefined;
@item head
array of initial pointers. Location @code{head}[@i{len}]
@w{@math{(0 @leq{} len @leq{} maxlen)}} contains number of the first object,
which has the length @i{len};
@item prev
array of predecessors. Location @code{prev}[0] is not used. Location
@code{prev}[@i{k}] @w{@math{(1 @leq{} k @leq{} n)}} contains number of the
preceding object, which has the same length as @i{k}th object
(@code{prev}[@i{k}] = 0 means that @i{k}th object is the first in the list);
@item next
array of successors. Location @code{next}[0] is not used. Location
@code{next}[@i{k}] @w{@math{(1 @leq{} k @leq{} n)}} contains number of the
succeeding object, which has the same length as @i{k}th object
(@code{next}[@i{k}] = 0 means that @i{k}th object is the last in the list).
@end table

@section @code{create_duff} --- create Duff scheme
@fnindex{create_duff}

@subsubheading Synopsis

@example
#include "glpduff.h"
DUFF *create_duff(int n, int maxlen);
@end example

@subsubheading Description

The @code{create_duff} routine creates Duff scheme that can contain up to
@code{n} objects, where the length of each object may be in the range from 0 to
@code{maxlen}. Initially the scheme contains no objects.

@subsubheading Returns

The @code{create_duff} routine returns a pointer to the created scheme.

@section @code{include_obj} --- include object into scheme
@fnindex{include_obj}

@subsubheading Synopsis

@example
#include "glpduff.h"
void include_obj(DUFF *duff, int k, int len);
@end example

@subsubheading Description

The @code{include_obj} routine includes the object with number @code{k}
@w{@math{(1 @leq{} k @leq{} n)}} into the Duff scheme @code{duff}. The
parameter @code{len} specifies the object length
@w{@math{(1 @leq{} len @leq{} maxlen)}}. It is assumed that before inclusion
the object doesn't belong the scheme.

@subsubheading Complexity

This operation has time complexity @i{O}(1).

@section @code{exclude_obj} --- exclude object from scheme
@fnindex{exclude_obj}

@subsubheading Synopsis

@example
#include "glpduff.h"
void exclude_obj(DUFF *duff, int k);
@end example

@subsubheading Description

The @code{exclude_obj} routine excludes the object with number @code{k}
@w{@math{(1 @leq{} k @leq{} n)}} from the Duff scheme @code{duff}. It is
assumed that before exclusion the object does belong to the scheme.

@subsubheading Complexity

This operation has time complexity @i{O}(1).

@section Determining all objects with given length

In order to determine all objects that have the given length @i{len} the
following for statement may be used:

@example
      for (k = duff->head[len]; k; k = duff->next[k])
      @{
         /* processing the object with number k */
      @}
@end example

@section Determining length of given object

The length of the object with number @i{k} can be obtained from the location
@code{duff->len[k]}. The case @code{duff->len[k]} < 0 means, that the object
with number @i{k} doesn't belong to the Duff scheme, therefore its length is
undefined.

@section Changing length of given object

In order to change the length of the object with number @i{k} it is necessary
to exclude this object from the Duff scheme and to include it back into the
scheme using its new length:

@example
      len = duff->len[k];        /* determine current length */
      exclude_obj(duff, k);      /* exclude object from scheme */
      len = ...                  /* set new length */
      include_obj(duff, k, len); /* include object into scheme */
@end example

@section @code{reset_duff} --- remove all objects from scheme
@fnindex{reset_duff}

@subsubheading Synopsis

@example
#include "glpduff.h"
void reset_duff(DUFF *duff);
@end example

@subsubheading Description

The @code{reset_duff} routine removes all objects from the Duff scheme
@code{duff}, so the scheme becomes empty.

@subsubheading Complexity

This operation has time complexity @i{O}(max(@i{n}, @i{maxlen})).

@section @code{delete_duff} --- delete Duff scheme
@fnindex{delete_duff}

@subsubheading Synopsis

@example
#include "glpduff.h"
void delete_duff(DUFF *duff);
@end example

@subsubheading Description

The @code{delete_duff} routine deletes the Duff scheme @code{duff}, freeing all
the memory allocated to this object.

@unnumberedsec References

@enumerate 1
@item
@i{I. S. Duff.} MA28 --- a set of FORTRAN subroutines for sparse unsymmetric
linear equations. Harwell Report AERE, @w{R. 8730}, 1977.
@end enumerate

@chapter GLPETA: Implementation of Eta File

@section Prelude

@dfn{Product form} of (square) matrix @i{H}, which is also called eta file
@footnote{The name "eta file" appeared in the beginning of 1960s, when terms of
the form (5.1) used to be stored as records on a magnetic tape and the
corresponding sequential file was often denoted by the letter @i{H} (Greek
"eta").}, is the representation of this matrix in the following multiplication
form:
@tex
$$H = H_1 H_2 \dots H_N = \sum_{k=1}^N H_k \eqno (5.1)$$
@end tex
(in case of @i{n} = 0 it is assumed that @i{H} is unity matrix).

Each term
@tex
$H_k$
@end tex
has the form:
@tex
$$ H_k =
\pmatrix
{
1 \cr
& \ddots \cr
& & 1 \cr
& & & 1 \cr
& \eta_{ij} & & & 1 \cr
& & & & & \ddots \cr
& & & & & & 1 \cr
}, \eqno (5.2)
$$
@end tex
i.e. each term of eta file differs from the unity matrix only in one element
@tex
$\eta_{ij},$
@end tex
which may be placed out of the main diagonal (@math{i @neq{} j}) as well as on
the main diagonal (@i{i} = @i{j}).

In order to represent eta file on the whole the @code{HFILE} structure is used:

@tpindex{HFILE}
@example
      typedef struct HFILE HFILE;
      struct HFILE
      @{     int n;
            POOL *pool;
            HTERM *head;
            HTERM *tail;
      @};
@end example

@noindent
where:

@table @code
@item n
the order of matrix @i{H} (all eta terms have the same order), @i{n} > 0;
@item pool
memory pool (see Section 10.3) that holds all eta terms;
@item head
pointer to the first eta term
@tex
$H_1;$
@end tex
@item tail
pointer to the last eta term
@tex
$H_N.$
@end tex
@end table

The representation of a particular eta term is defined by the @code{HTERM}
structure:

@tpindex{HTERM}
@example
      typedef struct HTERM HTERM;
      struct HTERM
      @{     int i;
            int j;
            double val;
            HTERM *prev;
            HTERM *next;
      @};
@end example

@noindent
where:

@table @code
@item i
row index of element
@tex
$\eta_{ij};$
@end tex
@item j
column index of element
@tex
$\eta_{ij};$
@end tex
@item val
numerical value of element
@tex
$\eta_{ij};$
@end tex
@item prev
pointer to the previous eta term
@tex
$H_{k-1}$
@end tex
or @code{NULL}, if this eta term is
@tex
$H_1;$
@end tex
@item next
pointer to the next eta term
@tex
$H_{k+1}$
@end tex
or @code{NULL}, if this eta term is
@tex
$H_N.$
@end tex
@end table

@section @code{create_eta} --- create eta file
@fnindex{create_eta}

@subsubheading Synopsis

@example
#include "glpeta.h"
HFILE *create_eta(int n);
@end example

@subsubheading Description

The @code{create_eta} routine creates eta file (5.1) of order @i{n}. Initially
the created eta file has no terms and therefore it formally corresponds to
unity matrix.

@subsubheading Returns

The @code{create_eta} routine returns a pointer to the created eta file.

@section @code{app_term} --- append new eta term
@fnindex{app_term}

@subsubheading Synopsis

@example
#include "glpeta.h"
HTERM *app_term(HFILE *eta, int i, int j, double val);
@end example

@subsubheading Description

The @code{app_term} routine appends new eta term
@tex
$H_{N+1} = (\eta_{ij})$
@end tex
to the end of the eta file @code{eta}, where @code{i} and @code{j} are
respectively row and column indices of element
@tex
$\eta_{ij},$
@end tex
@code{val} is its numerical value.

If @i{i} = @i{j} and @i{val} = 1.0 or if @math{i @neq{} j} and @i{val} = 0.0,
the new eta term formally corresponds to unity matrix. Therefore in this two
cases the routine actually doesn't append the eta term.

@subsubheading Complexity

This operation has time complexity @i{O}(1).

@subsubheading Returns

The @code{app_term} routine returns a pointer to the new eta term or
@code{NULL}, if the eta term was not appended because of two cases mentioned
above.

@section @code{h_solve} --- solve system @i{Hx} = @i{b}
@fnindex{h_solve}

@subsubheading Synopsis

@example
#include "glpeta.h"
double *h_solve(HFILE *eta, double x[]);
@end example

@subsubheading Description

The @code{h_solve} routine solves the system @i{Hx} = @i{b}, where @i{H} is the
matrix represented by the eta file, which @code{eta} points to, @i{x} is dense
vector of unknowns, @i{b} is dense vector of right hand sides.

On entry the array @code{x} should contain elements of the vector @i{b} in
locations @code{x[1]}, @code{x[2]}, @dots{}, @code{x[n]}. On exit the array
@code{x} contains elements of the vector @i{x} in the same locations.

The matrix @i{H} should be non-singular, i.e. all
@tex
$\eta_{ii}$
@end tex
should be non-zero.

@subsubheading Complexity

This operation has time complexity @i{O}(@i{N}), where @i{N} is total number of
eta terms.

@subsubheading Returns

The @code{h_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

From (5.1) it follows that
@tex
$$x = H^{-1}b = H_{N}^{-1} \dots H_2^{-1}H_1^{-1}b,$$
@end tex
therefore solving the system @i{Hx} = @i{b} involves sequential solving systems
with trivial matrices
@tex
$H_1, H_2, \dots, H_N$
@end tex
of the form (5.2).

@section @code{ht_solve} --- solve system @i{H}'@i{x} = @i{b}
@fnindex{ht_solve}

@subsubheading Synopsis

@example
#include "glpeta.h"
double *ht_solve(HFILE *eta, double x[]);
@end example

@subsubheading Description

The @code{ht_solve} routine solves the system
@tex
$H^Tx = b,$
@end tex
where @i{H} is the matrix represented by the eta file, which @code{eta} points
to, @i{x} is dense vector of unknowns, @i{b} is dense vector of right hand
sides.

On entry the array @code{x} should contain elements of the vector @code{b} in
locations @code{x[1]}, @code{x[2]}, @dots{}, @code{x[n]}. On exit the array
@code{x} contains elements of the vector @i{x} in the same locations.

The matrix @i{H} should be non-singular, i.e. all
@tex
$\eta_{ii}$
@end tex
should be non-zero.

@subsubheading Complexity

This operation has time complexity @i{O}(@i{N}), where @i{N} is total number of
eta terms.

@subsubheading Returns

The @code{ht_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

From (5.1) it follows that
@footnote{
@tex
$H^{-T}$ means $(H^T)^{-1}$.
@end tex
}
@tex
$$x = H^{-T}b = H_1^{-T}H_2^{-T} \dots H_N{-T},$$
@end tex
therefore solving the system
@tex
$H^Tx = b$
@end tex
involves sequential solving systems with trivial matrices
@tex
$H_N^T, \dots, H_2^T, H_1^T$
@end tex
of the form (5.2).

@section @code{reset_eta} --- reset eta file
@fnindex{reset_eta}

@subsubheading Synopsis

@example
#include "glpeta.h"
void reset_eta(HFILE *eta);
@end example

@subsubheading Description

The @code{reset_eta} routine removes all eta terms from the eta file
@code{eta}. After this operation the eta file formally corresponds to unity
matrix.

Actually the routine doesn't free the memory allocated to eta terms. It just
returns that memory to the memory pool, so that memory can be reused in the
future for the same eta file.

@section @code{delete_eta} --- delete eta file
@fnindex{delete_eta}

@subsubheading Synopsis

@example
#include "glpeta.h"
void delete_eta(HFILE *eta);
@end example

@subsubheading Description

The @code{delete_eta} routine deletes the eta file @code{eta}, freeing all the
memory allocated to this object.

@chapter GLPGEL: Sparse Gaussian Elimination

This chapter describes a set of routines related to sparse gaussian
elimination.

@section Unsymmetric Gaussian Elimination

This section describes routines, which implement general version of sparse
unsymmetric gaussian elimination as well as some specific versions of this
technique assuming the special structure of transformed matrix.

@subsection @code{gel} --- transform sparse matrix to upper triangular form using gaussian elimination
@fnindex{gel}

@subsubheading Synopsis

@example
#include "glpgel.h"
int gel(MAT *V, PER *P, PER *Q,
   void (*func)(int i, int k, double f), double tol, double lim,
   int *Unz, double *Umax, double *Ubig, DUFF *rs, DUFF *cs,
   double rmax[], double work[]);
@end example

@subsubheading Description

The @code{gel} routine transforms the sparse matrix @i{U}, which initially is
the given sparse matrix @i{V}, to the upper triangular form using gaussian
elimination technique. The result of transformation is the upper triangular
matrix @i{U}' = @i{PV}'@i{Q}, where @i{V}' is the resultant matrix placed
instead the input matrix @i{V}, @i{P} and @i{Q} are resultant permutation
matrices.

The matrix @i{U}, which is transformed to the final upper triangular matrix
@i{U}', has implicit representation, i.e. all operations are actually performed
on the matrix @i{V}, which differs from @i{U} only in the order of rows and
columns determined by permutation matrices @i{P} and @i{Q}. This implicit
representation allows not to explicitly permute rows and columns during
elimination and thereby allows improving the efficiency of computational
process.

The example of transformation of the test matrix @math{D(100, 30)} (see
Section 7.28) performed by means of the gel routine is shown on Fig. 6.1.

In order to eliminate subdiagonal elements of the matrix @i{U} = @i{PVQ} the
routine applies to the matrix @i{U} elementary transformations of the following
three kinds: row permutation, column permutation, and subtraction one row
multiplied by a number from other row (gaussian transformation). Each time,
when gaussian transformation is applied to the matrix @i{U} (in order to
eliminate one of its subdiagonal elements), the @code{gel} routine calls the
formal routine @code{func} in order to allow the calling program accumulating
information about all performed gaussian transformations (information about
row and column permutations is accumulated in the matrices @i{P} and @i{Q} by
the @code{gel} routine and also available to the calling program). (This
feature of the @code{gel} routine allows accommodating it to any context, which
needs transformation to the upper triangular form, unlike other existing
gaussian elimination routines, which usually accumulate information about
performed gaussian transformations in some particular form: in the form of
lower triangular matrix in case of LU factorization, in the form of eta file,
etc.)

@sp 1
@image{doc/fig/glpgel01}
@center{Fig. 6.1. Example of transformation performed by the @code{gel} routine}
@center{(a) input matrix @i{U} = @i{V}; (b) resultant matrix @i{V}'; (c) resultant matrix @i{U}' = @i{PV}'@i{Q}.}
@sp 1

The point, where the @code{func} routine is called, and the meaning of
parameters passed to that routine can be explained with the following model
scheme of the elimination process:

@example
      for (k = 1; k <= n; k++)
      @{  /* k-th elimination step starts here */
         /* choose the pivot element u[p,q] */
         p = ...; assert(k <= p <= n);
         q = ...; assert(k <= q <= n);
         /* permute rows of the matrix U with numbers k and p */
         ...;
         /* permute columns of the matrix U with numbers k and q */
         ...;
         /* now the pivot element is u[k,k] */
         assert(u[k,k] != 0.0);
         /* eliminate non-zero subdiagonal elements of the matrix U that
            are placed in k-th column */
         for (i = k+1; i <= n; i++)
         @{  /* eliminate subdiagional element u[i,k] */
            if (u[i,k] == 0.0) continue;
            /* compute gaussian multiplier */
            f = u[i,k] / u[k,k];
            /* (i-th row of U) := (i-th row of U) - f * (k-th row of U) */
            ...;
            assert(u[i,k] == 0.0);
            /* i-th row of the matrix U has been transformed */
            func(i, k, f);
         @}
      @}
@end example


Note that row numbers passed to the @code{func} routine correspond to the
matrix @i{U}, not to @i{V}. The correspondence between row and column numbers
of the matrices @i{U} = @i{PVQ} and @i{V} is determined by the row permutation
matrix @i{P} and the column permutation matrix @i{Q}. Thus, if an element
@math{u[i,j]} of the matrix @i{U} corresponds to an element @math{v[i',j']} of
the matrix @i{V}, the following formulae may be used:

@example
      i' = P->row[i], j' = Q->col[j];
      i = P->col[i'], j = Q->row[j'];
@end example

@noindent
(these formulae are valid on exit as well as during all the elimination
process).

The control parameter @i{tol} is a relative tolerance used for threshold
pivoting. Its value should be in the range 0 < @i{tol} < 1. For more details
see the method description below.

The control parameter @i{lim} is intended for checking numerical stability and
specifies maximal allowable growth of elements of the matrix @i{U} during
elimination process. For more details see the method description below.

On entry the location @code{Unz} should contain the total number of non-zeros
in the matrix @i{U} = @i{V}. On exit this location contains total number of
non-zeros in the final matrix @i{U}' = @i{PV}'@i{Q}. (If on entry the location
@code{Unz} contains zero, on exit it contains the fill-in count, i.e. the
difference between numbers of non-zeros in the matrices @i{U}' and @i{U}.)

On entry contents of the locations @code{Umax} and @code{Ubig} are ignored. On
exit the location @code{Umax} contains maximal of absolute values of elements
of the initial matrix @i{U} = @i{V}. The location @code{Ubig} contains maximal
of absolute values of elements of the matrix @i{U}, which appeared in this
matrix during entire elimination process (i.e.
@tex
$Ubig = max|u_{ij}^k|,$
@end tex
where @i{k} is number of the elimination step). Thus, the ratio
@math{Ubig/Umax} may be used to measure the numerical "quality" of
transformation.

The parameters @code{rs} and @code{cs} should specify Duff schemes (see
Chapter 3), which are used by the @code{gel} routine to keep lists of active
rows and columns. On entry contents of these schemes is ignored. In the case of
error (see below) on exit these schemes contain active rows and columns of the
matrix @i{V} (not @i{U}!) and define the final active submatrix (this
information may be used for further analysis). These schemes should be created
by statements @w{@code{rs = create_duff(n, n)}} and
@w{@code{cs = create_duff(n, n)}}, where @i{n} is order of the matrix @i{V}.

The arrays @code{rmax} and @code{work} are working storage. They should have at
least @math{1+n} locations, where @i{n} is order of the matrix @i{V}.

@subsubheading Returns

The @code{gel} routine returns one the following error codes:

@table @asis
@item 0
no errors;
@item @math{-k}
on @i{k}th elimination step all elements of the active submatrix are equal to
zero;
@item @math{+k}
on @i{k}th elimination step the numerical stability condition is violated (see
below the method description).
@end table

@subsubheading Method

In order to transform the given matrix @i{U} to the upper triangular form the
@code{gel} routine uses gaussian elimination with partial pivoting based on
Markowitz strategy and Duff search technique (see, for example, [1]).

Before @i{k}th elimination step the partially transformed matrix @i{U} has the
form:
@tex
$$
U =
\pmatrix
{
u_{11} & \dots & u_{1,k-1}  & u_{1k}   & u_{1,k+1} & \dots & u_{1n} \cr
       & \dots & \dots      & \dots    & \dots     & \dots & \dots  \cr
       &       & u_{k-1,k-1}& u_{k-1,k}&u_{k-1,k+1}&\dots&u_{k-1,n} \cr
       &       &            & u_{kk}   & u_{k,k+1} & \dots & u_{kn} \cr
       &       &            & \dots    & \dots     & \dots & \dots  \cr
       &       &            & u_{nk}   & u_{n,k+1} & \dots & u_{nn} \cr
}
, \eqno (6.1)
$$
@end tex
where rows and columns with numbers @i{k}, @i{k}+1, @dots{}, @i{n} form the
active submatrix.

The goal of the @i{k}th elimination step is to eliminate (nullify) subdiagonal
elements of the @i{k}th column
@tex
$u_{k+1,k}, \dots, u_{nk}.$
@end tex

At first the @code{gel} routine chooses the pivot element in the active
submatrix. Let's assume that the pivot element chosen on the @i{k}th
elimination step is
@tex
$u_{pq}, k \leq p, q \leq n.$
@end tex
So, it is necessary to permute rows of the matrix @i{U} with numbers @i{k} and
@i{p} and columns with numbers @i{k} and @i{q} in order to move the pivot
element to the position
@tex
$u_{kk}.$
@end tex
Since the matrix @i{U} has implicit representation @i{U} = @i{PVQ}, no actual
permutations are performed. Instead that the routine actually permutes @i{k}th
and @i{p}th rows of the matrix @i{P}, and @i{k}th and @i{q}th columns of the
matrix @i{Q}. Note that the order of rows and columns of the matrix @i{V}
remain unchanged from the beginning to the end of elimination process.

In order to eliminate a particular subdiagonal element
@tex
$u_{ik}, k+1 \leq i \leq n$
@end tex
the routine applies elementary gaussian transformation to the matrix @i{U},
which consists of subtracting @i{k}th (pivot) row multiplied by gaussian factor
@tex
$f_{ik} = u_{ik}/u_{kk}$
@end tex
from @i{i}th (transformed) row. Thus, elements of ith row of the matrix @i{U}
are transformed using the formula:
@tex
$$\overline{u}_{ij} = u_{ij} - f_{ik} u_{kj} =
u_{ij} - {u_{ik} u_{kj} \over u_{kk}}, \ \ j = 1, \dots, n, \eqno (6.2)$$
@end tex
that gives
@tex
$\overline{u}_{ik} = 0.$
@end tex
After last elimination step (@i{k} = @i{n}) the matrix @i{U} becomes upper
triangular.

The process of gaussian elimination is completely defined, if pivot elements
are known on each elimination step. It is well known that pivoting is
determined by two main factors:

a) small pivot element may cause numerical instability;

b) pivoting affects on appearance of new non-zeros in the matrix @i{U}.

Since the @code{gel} routine is intended for general case (when a priori
numerical properties of the matrix @i{U} is unknown), it uses so called dynamic
pivoting --- the next pivot element is determined directly before the
corresponding elimination step.

In order to provide numerical stability the @code{gel} routine chooses the next
pivot element only among those elements of the active submatrix, which are
satisfied to the following numerical stability condition:
@tex
$$|u_{ij}| \geq tol \cdot \max_l |u_{il}|, \eqno (6.3)$$
@end tex
where 0 < @i{tol} < 1 is a given relative tolerance (see below). This
condition guarantees that the pivot element is not very small among other
elements in the same row (of the active submatrix).

The choice of the pivot element also affects on appearence of new @w{non-zeros}
in the matrix @i{U}. Locally this affection can be estimated in the following
way. Let
@tex
$\nu_r(i)$
@end tex
is number of @w{non-zeros} in @i{i}th row and
@tex
$\nu_c(j)$
@end tex
is number of @w{non-zeros} in @i{j}th column. If the pivot element is
@tex
$u_{ij},$
@end tex
number of @w{non-zeros} apperaing in the matrix @i{U} after @i{k}th elimination
step is not greater than
@tex
$$c(i,j) = [\nu_r(i)-1][\nu_c(j)-1], \eqno (6.4)$$
@end tex
where @math{c(i,j)} is so called @dfn{Markowitz cost} of the element
@tex
$u_{ij}$
@end tex
[1] (see Fig. 6.2).

The @code{gel} routine uses heuristic rule called @dfn{Markowitz strategy} [1].
It chooses that element of the active submatrix, which satisfies to the
numerical stability condition (6.3) and has possibly minimal Markowitz cost
(6.4).

The relative tolerance @i{tol} in the condition (6.3) is so called Markowitz
parameter. Generally this parameter allows improving numerical stability at the
expense of sparsity and vice versa. If @i{tol} is close to 1, the pivot element
is close to the maximal element of the pivot row, that provides good numerical
stability but decreases freedom for choosing good pivot element to keep
sparsity. On the contrary, if @i{tol} is close to 0, it is possible to choose
pivot element for minimizing fill-in, however, such element may be very small
that may involve numerical instability.

@sp 1
@image{doc/fig/glpgel02}
@center{Fig. 6.2. Appearence of new non-zeros in the matrix @i{U} on @i{k}th elimination step}
@center{@math{ukk} is the pivot element, @samp{bullet} is new non-zero}
@sp 1

In practice good results can be obtained using @i{tol} = 0.1---0.01. However,
if the computational process becomes numerically unstable (see below), the
tolerance @i{tol} should be increased.

In order to look after numerical stability the @code{gel} routine uses some
heuristic test. The computational process is considered as stable, if the
following condition is satisfied on each elimination step:
@tex
$$Ubig \leq lim \cdot Umax, \eqno (6.5)$$
@end tex
where @i{Umax} is maximal of absolute values of elements of the initial matrix
@i{U}, @i{Ubig} is maximal of absolute values of elements of the matrix @i{U},
which appeared in this matrix during entire elimination process (i.e.
@tex
$Ubig = max|u_{ij}^k|,$
@end tex
where @i{k} is the number of elimination step), @i{lim} is the specified
parameter.

If on @i{k}th elimination step the condition (6.5) is violated, the @code{gel}
routine returns error code @math{+k}.

The choice of the parameter @i{lim} depends on the working precision of a
particular computer. If @code{DBL_DIG} is approximately 15 decimal places, the
recommended value is
@tex
$lim = 10^{10}$---$10^{12}.$
@end tex

Now let's consider some important details of implementation of Markowitz
strategy.

In order to find the pivot element, which satisfies to the stability condition
(6.3) and has smallest Markowitz cost (6.4) it is necessary to examine all
elements of the active submatrix. Although the matrix @i{U} is assumed to be
sparse, such full pivoting may be very expensive. Therefore the @code{gel}
routine uses partial pivoting based on the search technique proposed by
@w{I. Duff} [2].

The main idea of @dfn{Duff search technique} is based on the reasonable
thought that pivot element with smallest Markowitz cost should be probably
placed in row and column, which have small number of non-zeros. So, the
@code{gel} routine examines rows and columns of the active submatrix in the
order of increasing their counts
@tex
$\nu_r(i)$ and $\nu_c(i).$
@end tex
In order to organize efficient examining all active rows and columns the
routine splits them into sets (active lists)
@tex
$R(n) = {i|\nu_r(i) = n}$ and $C(n) = {j|\nu_c(j) = n},$
@end tex
which are implemented as Duff schemes. The @code{gel} routine builds these
sets @footnote{Actually sets @math{R(n)} and @math{C(n)} contain numbers of
rows and columns of the matrix @i{V}, not of the matrix @i{U}, in order to
avoid explicit permutations of rows and columns.} before the first elimination
step and corrects them each time, when new non-zero is appeared in some row or
column or some element becomes zero.

The choice of the pivot element using Duff search technique is performed in the
following way. If
@tex
$C(1) \neq$\ \O,
@end tex
@i{j}th column of the active
submatrix, where @math{j @in{} C(1)}, has the only non-zero element (column
singleton), which the routine immediately chooses as the pivot element.
Similarly, if
@tex
$R(1) \neq$\ \O,
@end tex
@i{i}th row of the active submatrix, where @math{i @in{} R(1)}, has the only
non-zero element (row singleton), which the routine immediately chooses as the
pivot element. (Note that singletons give no fill-in.) Otherwise, if
@tex
$C(1) =$\ \O and $R(1) =$\ \O,
@end tex
the @code{gel} routine continues examining elements in rows and columns from
sets @i{C}(2), @i{R}(2), @i{C}(3), @i{R}(3), etc., storing those element, which
satisfies to the stability condition (6.3) and has the smallest Markowitz cost
among other examined elements. In order not to examine all rows and columns
from sets up to @math{C(n)} and @math{R(n)} the routine uses the following
termination heuristics proposed by @w{I. Duff} [2]: the examination is
terminated if all columns from the set @math{C(@nu{})} have been examined and
@tex
$c^* \leq \nu(\nu-1),$
@end tex
or all rows from the set @math{R(@nu{})} have been examined and
@tex
$c^* \leq (\nu-1)^2,$
@end tex
where
@tex
$c^*$
@end tex
is best Markowitz cost that has been reached for some examined element, which
is also satisfied to the stability condition. This heuristics can be easily
grounded. In fact, if one of mentioned conditions for
@tex
$c^*$
@end tex
is satisfied, it is doubtful that there is other element with better Markowitz
cost.

@subsection @code{gel_bg} --- transform sparse matrix of special structure to upper triangular form using Bartels and Golub technique
@fnindex{gel_bg}

@subsubheading Synopsis

@example
#include "glpgel.h"
int gel_bg(PER *P, MAT *V, PER *Q, int k1, int k2,
   void (*func)(int i, int k, double f), double tol, double eps,
   int *Unz, double work[]);
@end example

@subsubheading Description

The @code{gel_bg} routine transforms the sparse matrix @math{U = PVQ} of
special structure (see below), where @i{V} is the given sparse matrix, @i{P}
and @i{Q} are given permutation matrices, to the upper triangular form using
the version of gaussian elimination proposed by @w{R. H. Bartels} and
@w{G. H. Golub} [3, 4]. The result of transformation is the upper triangular
matrix @math{U' = P'V'Q'}, where @i{P}', @i{V}', and @i{Q}' are resultant
matrices placed instead matrices @i{P}, @i{V}, and @i{Q} respectively.

The @code{gel_bg} routine assumes that the initial matrix @math{U = PVQ} has
the special structure @footnote{Such matrices usually appear in the simplex
method of linear programming after replacing a column of upper triangular
matrix by other column.} shown on Fig. 6.3. Thus, only the submatrix of @i{U}
formed by rows
@tex
$k_1, k_1+1, \dots, k_2$ and columns $k_1, k_1+1, \dots, n$
@end tex
should be transformed (elements of this submatrix are marked by @math{@ast{}},
other elements of the initial matrix @i{U}, are marked by @math{@times{}}).

@sp 1
@image{doc/fig/glpgel03}
@center{Fig 6.3. The special structure of the initial matrix @math{U = PVQ}}
@sp 1

The matrix @i{U}, which is transformed to the final upper triangular matrix
@i{U}', has implicit representation, i.e. all operations are actually performed
on the matrix @i{V}, which differs from @i{U} only in the order of rows and
columns determined by permutation matrices @i{P} and @i{Q} (cf. also
Subsection 6.1.1). This implicit representation allows not to explicitly
permute rows and columns during elimination and thereby allows improving the
efficiency of computational process.

The example of transformation of a sparse matrix (@i{n} = 97) performed by
means of the @i{gel_bg} routine is shown on Fig. 6.4.

@sp 1
@image{doc/fig/glpgel04}
@center{Fig 6.4. Example of transformation performed by the @code{gel_bg} routine}
@center{(input matrix @math{U = PVQ} and resultant matrix @math{U' = P'V'Q'}).}
@sp 1

In order to eliminate subdiagonal elements of the matrix @math{U = PVQ} the
routine applies to the matrix @i{U} elementary transformations of the following
three kinds: row permutation, column permutation, and subtraction one row
multiplied by a number from other row (gaussian transformation). Each time,
when gaussian transformation is applied to the matrix @i{U} (in order to
eliminate one of its subdiagonal elements), the @code{gel_bg} routine calls the
formal routine @code{func} in order to allow the calling program accumulating
information about all performed gaussian transformations (information about
row and column permutations is accumulated in the matrices @i{P} and @i{Q} by
the @code{gel_bg} routine and also available to the calling program).

The point, where the func routine is called, and the meaning of parameters
passed to that routine are explained below in the method description.

The control parameter @i{tol} is a relative tolerance used for threshold
pivoting. Its value should be in the range 0 < @i{tol} < 1. For more details
see the method description below.

The control parameter @i{eps} is a relative tolerance for diagonal elements of
the matrix @i{U}'. For more details see the method description below.

On entry the location @code{Unz} should contain total number of non-zeros in
the initial matrix @i{U}. On exit this location contains total number of
non-zeros in the resultant matrix @i{U}'. (If on entry the location @code{Unz}
contains zero, on exit it contains the fill-in count, i.e. the difference
between numbers of non-zeros in the matrices @i{U}' and @i{U}.)

The array @code{work} is working storage. It should have at least @math{1+n}
locations, where @i{n} is order of the matrix @i{V}.

@subsubheading Returns

The @code{gel_bg} routine returns one the following error codes:

@table @asis
@item 0
no errors;
@item @math{-k}
@tex
if $k_1 \leq k < k_2$, on $k$th elimination step elements $u_{kk}$ and
$u_{k+1,k}$ are equal to zero. If $k = k_2$, after last elimination step
element $u_{k_2,k_2}$ is equal to zero;
@end tex
@item @math{+k}
@tex
if $k_1 \leq k < k_2$, on $k$th elimination step the numerical stability
condition is violated (see below the method description). If $k = k_2$, this
condition is violated for element $u_{k_2,k_2}$.
@end tex
@end table

@subsubheading Method

The @code{gel_bg} routine is based on the version of gaussian elimination
proposed by @w{R. H. Bartels} and @w{G. H. Golub} [3, 4], which exploits the
special structure of the matrix @i{U}.

Before elimination the routine shifts columns
@tex
$k_1+1, k_1+2, \dots, k_2$
@end tex
by one position to the left and also moves the column
@tex
$k_1$
@end tex
to the position
@tex
$k_2$
@end tex
(in the original Bartels & Golub version
@tex
$k_2 = n,$
@end tex
because
@tex
$k_2 < n$
@end tex
reduces the freedom of pivoting and thereby involves worsening numerical
stability). Due to these column permutations the matrix @i{U} becomes upper
Hessenberg matrix shown on Fig. 6.5 (elements that should be eliminated are
marked by @samp{bullet}).

In order to fully exploit the special structure of the matrix @i{U} the
@code{gel_bg} routine uses partial pivoting only in the active column. So far
as on each elimination step the active column contain the only non-zero
subdiagonal element, the choice is limited by two elements:
@tex
$u_{kk}$ and $u_{k+1,k}.$
@end tex

@sp 1
@image{doc/fig/glpgel05}
@center{Fig 6.5. The matrix @i{U} after column permutations}
@sp 1

In the original Bartels & Golub version the largest (in absolute value) element
is used as the pivot element, because this guarantees good numerical stability.
However, the @code{gel_bg} routine tries to reduce fill-in at the expense of
some worsening numerical stability. The pivoting rule, which is used in the
@code{gel_bg} routine, is based on the following heuristics @footnote{This
heuristics is Markowitz strategy applied to this particular case.}, where the
parameter @i{tol} (0 < @i{tol} < 1) is the given relative tolerance:

a) if
@tex
$|u_{k+1,k}| < tol \cdot |u_{kk}|,$
@end tex
the routine chooses the element
@tex
$u_{kk};$
@end tex

b) if
@tex
$|u_{kk}| < tol \cdot |u_{k+1,k}|,$
@end tex
the routine chooses the element
@tex
$u_{k+1,k};$
@end tex

c) in other cases the routine chooses that element, which is placed in the row
with smaller number of non-zeros.

(Note that in the original Bartels & Golub version @i{tol} = 1.)

Thus, the model scheme of the elimination process is the following:

@example
      /* permute columns of the matrix U */
      ...;
      for (k = k1; k < k2; k++)
      @{  /* k-th elimination step starts here */
         /* choose the pivot element u[k,k] or u[k+1,k] */
         ...;
         /* if u[k+1,k] has been chosen, permute rows k and k+1 of the
            matrix U */
         if (...) ...;
         /* now the pivot element is u[k,k] */
         assert(u[k,k] != 0.0);
         /* eliminate non-zero subdiagonal element u[k+1,k] */
         i = k+1;
         if (u[i,k] == 0.0) continue;
         /* compute gaussian multiplier */
         f = u[i,k] / u[k,k];
         /* (i-th row of U) := (i-th row of U) - f * (k-th row of U) */
         ...;
         assert(u[i,k] == 0.0);
         /* i-th row of the matrix U has been transformed */
         func(i, k, f);
      @}
      assert(u[k2,k2] != 0.0);
@end example

Note that row numbers passed to the @code{func} routine correspond to the
matrix @i{U}, not to @i{V}. The correspondence between row and column numbers
of the matrices @i{U} = @i{PVQ} and @i{V} is determined by the row permutation
matrix @i{P} and the column permutation matrix @i{Q}. Thus, if an element
@math{u[i,j]} of the matrix @i{U} corresponds to an element @math{v[i',j']} of
the matrix @i{V}, the following formulae may be used:

@example
      i' = P->row[i], j' = Q->col[j];
      i = P->col[i'], j = Q->row[j'];
@end example

@noindent
(these formulae are valid on exit as well as during all the elimination
process).

In order to look after numerical stability the @code{gel_bg} routine checks the
following condition on each elimination step, where @i{eps} is the given
relative tolerance:
@tex
$$u_{k,k}' \geq eps \cdot \max_j |u_{k,j}'| > 0,$$
@end tex
i.e. each diagonal element should be non-zero and should not be very small
among other elements in the same row. (Note that this condition is checked only
for rows
@tex
$k_1, k_1+1, \dots, k_2).$
@end tex

Some experimental results show that:

1. Fairly good numerical stability (even in case of bad scaled matrices) can
be provided using @i{tol} = 0.2---0.5. Lower values of @i{tol} usually involve
excessive round-off errors and as a consequence numerical instability.

2. The choice of the parameter @i{eps} depends on the working precision of a
particular computer. If @code{DBL_DIG} is approximately 15 decimal places, the
recommended value is
@tex
$eps = 10^4$---$10^6.$
@end tex

@subsection @code{gel_ft} --- transform sparse matrix of special structure to upper triangular form using Forrest and Tomlin technique
@fnindex{gel_ft}

@subsubheading Synopsis

@example
#include "glpgel.h"
int gel_ft(PER *P, MAT *V, PER *Q, int k1, int k2,
   void (*func)(int i, int k, double f), double eps, int *Unz,
   double work[]);
@end example

@subsubheading Description

The @code{gel_ft} routine transforms the sparse matrix @math{U = PVQ} of
special structure (see below), where @i{V} is the given sparse matrix, @i{P}
and @i{Q} are given permutation matrices, to the upper triangular form using
the version of gaussian elimination proposed by @w{J. J. H. Forrest} and
@w{J. A. Tomlin} [5]. The result of transformation is the upper triangular
matrix @w{@math{U' = P'V'Q'}}, where @math{P'}, @math{V'}, and @math{Q'} are
resultant matrices placed instead matrices @i{P}, @i{V}, and @i{Q}
respectively.

The @code{gel_ft} routine assumes that the initial matrix @math{U = PVQ} has
the special structure @footnote{Such matrices usually appear in the simplex
method of linear programming after replacing a column of upper triangular
matrix by other column.} shown on Fig. 6.6. Thus, only the submatrix of @i{U}
formed by rows
@tex
$k_1, k_1+1, \dots, k_2$ and columns $k_1, k_1+1, \dots, n$
@end tex
should be transformed (elements of this submatrix are marked by @math{@ast{}},
other elements of the initial matrix @i{U}, are marked by @math{@times{}}).

@sp 1
@image{doc/fig/glpgel06}
@center{Fig 6.6. The special structure of the initial matrix @math{U = PVQ}}
@sp 1

The matrix @i{U}, which is transformed to the final upper triangular matrix
@math{U'}, has implicit representation, i.e. all operations are actually
performed on the matrix @i{V}, which differs from @i{U} only in the order of
rows and columns determined by permutation matrices @i{P} and @i{Q} (cf. also
Subsection 6.1.1). This implicit representation allows not to explicitly
permute rows and columns during elimination and thereby allows improving the
efficiency of computational process.

The example of transformation of a sparse matrix (@i{n} = 97) performed by
means of the @code{gel_ft} routine is shown on Fig. 6.7.

(Obviously, the @code{gel_ft} routine solves the same problem as the
@code{gel_bg} routine described in Subsection 6.1.2.)

In order to eliminate subdiagonal elements of the matrix @math{U = PVQ} the
routine applies to the matrix @i{U} elementary transformations of the following
three kinds: row permutation, column permutation, and subtraction one row
multiplied by a number from other row (gaussian transformation). Each time,
when gaussian transformation is applied to the matrix @i{U} (in order to
eliminate one of its subdiagonal elements), the @code{gel_ft} routine calls the
formal routine @code{func} in order to allow the calling program accumulating
information about all performed gaussian transformations (information about
row and column permutations is accumulated in the matrices @i{P} and @i{Q} by
the @code{gel_ft} routine and also available to the calling program).

@sp 1
@image{doc/fig/glpgel07}
@center{Fig 6.7. Example of transformation performed by the @code{gel_ft} routine}
@center{(input matrix @math{U = PVQ} and resultant matrix @math{U' = P'V'Q'}).}
@sp 1

The point, where the @code{func} routine is called, and the meaning of
parameters passed to that routine are explained below in the method
description.

The control parameter @i{eps} is a relative tolerance for diagonal elements of
the matrix @math{U'}. For more details see the method description below.

On entry the location @code{Unz} should contain total number of non-zeros in
the initial matrix @i{U}. On exit this location contains total number of
non-zeros in the resultant matrix @math{U'}. (If on entry the location
@code{Unz} contains zero, on exit it contains the fill-in count, i.e. the
difference between numbers of non-zeros in the matrices @math{U'} and @i{U}.)

The array @code{work} is working storage. It should have at least @math{1+n}
locations, where @i{n} is order of the matrix @i{V}.

@subsubheading Returns

The @code{gel_ft} routine returns one the following error codes:

@table @asis
@item 0
no errors;
@item @math{-k}
@tex
if $k_1 \leq k < k_2,$ on $k$th elimination step elements $u_{kk}$ and
$u_{k+1,k}$ are equal to zero. If $k = k_2,$ after last elimination step
element $u_{k_2,k_2}$ is equal to zero;
@end tex
@item @math{+k}
@tex
if $k_1 \leq k < k_2,$ on $k$th elimination step the numerical stability
condition is violated (see below the method description). If $k = k_2,$ this
condition is violated for element $u_{k_2,k_2}.$
@end tex
@end table

@subsubheading Method

The @code{gel_ft} routine is based on the version of gaussian elimination
proposed by @w{J. J. H. Forrest} and @w{J. A. Tomlin} [5], which exploits the
special structure of the matrix @i{U}.

Before elimination the routine shifts columns
@tex
$k_1+1, k_1+2, \dots, k_2$
@end tex
by one position to the left and upwards, and also moves the row and column
@tex
$k_2$
@end tex
to the position
@tex
$k_1.$
@end tex
Due to these row and column permutations the matrix @i{U} acquires the form
shown on Fig. 6.8. Then the routine applies gaussian elimination in order to
eliminate (nullify) subdiagonal elements of the matrix @i{U}.

@sp 1
@image{doc/fig/glpgel08}
@center{Fig 6.8. The matrix @i{U} after row and column permutations}
@sp 1

Forrest & Tomlin version of gaussian elimination assumes no pivoting. This
means that on @i{k}th elimination step
@tex
$(k = k_1, k_1+1, \dots, k_2-1)$
@end tex
the pivot element is always
@tex
$u_{kk},$
@end tex
which is used to eliminate the only subdiagonal element
@tex
$u_{k_2,k}$
@end tex
(of course, if it is non-zero).

Thus, Forrest---Tomlin technique makes no fill-in of the matrix @i{U}. On the
other hand this involves worsening numerical stability in contrast to other
methods, which use pivoting.

Note that no pivoting is a key idea in Forrest---Tomlin technique, because this
allows keeping the special structure of the matrix @i{U} during entire
elimination process. In fact, if we would provide Forrest---Tomlin technique
with, for example, partial pivoting in the active column, it would turn into
Bartels---Golub technique (see Subsection 6.1.2). May note that
Forrest---Tomlin technique can be considered as a version of Bartels---Golub
technique, where rows @i{k} and @math{k+1} are permuted on each elimination
step.

Thus, the model scheme of the elimination process is the following:

@example
      /* permute symmetrically rows and columns of the matrix U */
      ...;
      for (k = k1; k < k2; k++)
      @{  /* k-th elimination step starts here */
         /* the pivot element is always u[k,k] */
         assert(u[k,k] != 0.0);
         /* eliminate non-zero subdiagonal element u[k2,k] */
         i = k2;
         if (u[i,k] == 0.0) continue;
         /* compute gaussian multiplier */
         f = u[i,k] / u[k,k];
         /* (i-th row of U) := (i-th row of U) - f * (k-th row of U) */
         ...;
         assert(u[i,k] == 0.0);
         /* elementary transformation of i-th row of the matrix U has been
            performed */
         func(i, k, f);
      @}
      assert(u[k2,k2] != 0.0);
@end example

Note that row numbers passed to the @code{func} routine correspond to the
matrix @i{U}, not to @i{V}. The correspondence between row and column numbers
of the matrices @i{U} = @i{PVQ} and @i{V} is determined by the row permutation
matrix @i{P} and the column permutation matrix @i{Q}. Thus, if an element
@math{u[i,j]} of the matrix @i{U} corresponds to an element @math{v[i',j']} of
the matrix @i{V}, the following formulae may be used:

@example
      i' = P->row[i], j' = Q->col[j];
      i = P->col[i'], j = Q->row[j'];
@end example

@noindent
(these formulae are valid on exit as well as during all the elimination
process).

So far as the only row
@tex
$k_2$
@end tex
is being changed in Forrest---Tomlin version, in order to check for numerical
stability the @code{gel_ft} routine uses simplified test. The transformation is
considered as satisfactory if the following condition is true after the
transformation has been finished:
@tex
$$|u{k_2,k_2}| \geq eps \cdot big,$$
@end tex
where @i{eps} is the given relative tolerance,
@tex
$big = \max_{k,j}|u_{k_2,j}^k|$
@end tex
is maximal of absolute values of elements, which appeared in the matrix @i{U}
during entire elimination process (k is number of the elimination step).

Note that the @code{gel_ft} routine detects zero diagonal element
@tex
$u_{kk}$
@end tex
only in that case if
@tex
$u_{k_2,k} \neq 0,$
@end tex
i.e. if elementary gaussian transformation is actually needed.

The choice of the tolerance @i{eps} depends on the working precision of a
particular computer. If @code{DBL_DIG} is approximately 15 decimal places, the
value
@tex
$eps = 10^{-4}$---$10^{-6}$
@end tex
may be recommended.

@page
@subsection @code{min_bump} --- minimize bump of sparse matrix using Reid technique
@fnindex{min_bump}

@subsubheading Synopsis

@example
#include "glpgel.h"
void *min_bump(PER *P, MAT *V, PER *Q, int *k1, int *k2,
   DUFF *rs, DUFF *cs, int prev[], int next[]);
@end example

@subsubheading Description

The @code{min_bump} routine minimizes the bump of the sparse matrix
@math{U = PVQ} of special structure (see below), where @i{V} is the given
sparse matrix, @i{P} and @i{Q} are given permutation matrices, implicitly
permuting its rows and columns by means of the structural transformation
proposed by @w{J. K. Reid} [6]. The result of transformation is the matrix
@math{U' = P'VQ'} with minimal bump, where @math{P'} and @math{Q'} are
resultant permutation matrices placed instead matrices @i{P} and @i{Q}
respectively (the matrix @i{V} is not changed on exit).

This transformation may be used before subsequent transforming the matrix
@math{U = PVQ} using Bartels---Golub or Forrest---Tomlin methods (see
Subsections 6.1.2 and 6.1.3) in order to improve sparsity.

The @code{min_bump} routine assumes that the initial matrix @math{U = PVQ} has
the special structure shown on Fig. 6.9, where submatrix formed by rows and
columns
@tex
$k_1, k_1+1, . . ., k_2$
@end tex
is so called @dfn{bump}. Thus, the matrix @i{U} differs from upper triangular
matrix only in the column
@tex
$k_1,$
@end tex
which is called @dfn{spike}. Additionally it is assumed that all diagonal
elements of the matrix @i{U} (except may be the element
@tex
$u_{k_1,k_1})$
@end tex
are non-zero. The element
@tex
$u_{k_2,k_1}$
@end tex
also should be non-zero, otherwise the bump could be decreased. (On Fig. 6.9
elements of bump are marked by @math{@ast{}}, other elements are marked by
@math{@times{}}.)

@sp 1
@image{doc/fig/glpgel09}
@center{Fig 6.9. The initial matrix @math{U = PVQ}}
@sp 1

The @code{min_bump} routine performs symmetric row and column permutations in
order that the final matrix @math{U = P'VQ'} of the same special structure has
the bump of minimal size (the routine accumulates these permutations in
matrices @i{P} and @i{Q}, so the matrix @i{V} remain unchanged). On exit the
routine stores bounds of the final bump
@tex
$k_1$ and $k_2$
@end tex
to the locations @code{k1} and @code{k2} respectively (the case
@tex
$k_1 = k_2$
@end tex
means that the final matrix @math{U'} became of upper triangular form with
non-zero diagonal elements, except may be the element
@tex
$u_{k_1,k_1},$
@end tex
which is the final bump in this case).

The example of structural transformation of a sparse matrix (@i{n} = 97)
performed by means of the @code{min_bump} routine is shown on Fig. 6.10.

@sp 1
@image{doc/fig/glpgel10}
@center{Fig 6.10. Example of structural transformation performed by the @code{min_bump} routine}
@center{input matrix @math{U = PVQ} and resultant matrix @math{U' = P'VQ'}.}
@sp 1

The parameters @code{rs} and @code{cs} should specify Duff schemes (see
Chapter 3), which are used by the @code{min_bump} routine to keep lists of
active (i.e. that belong to the bump) rows and columns (see the method
description). On entry contents of these schemes is ignored. On exit these
schemes contain rows and columns of the matrix @i{U} (not @i{V}!) that belong
to the final bump. These schemes should be created by statements
@code{@w{rs = create_duff(n, n)}} and @code{@w{cs = create_duff(n, n)}}, where
@i{n} is order of the matrix @i{U} (which is the same as of the matrix @i{V}).

The arrays @code{prev} and @code{next} are working storage. They should have at
least @math{1+n} locations, where @i{n} is order of the matrix @i{U}.

@subsubheading Method

Let the current bump contains a column, which is not the spike and which has
the only non-zero element
@tex
$u_{kk}$
@end tex
(column singleton). Obviously, this non-zero element is on the main diagonal.
Therefore the @code{min_bump} routine shifts rows and columns
@tex
$k_1, k_1+1, \dots, k-1$
@end tex
to the right and downward by one position and moves row and column @i{k} to the
position
@tex
$k_1.$
@end tex
Such symmetric transformation keeps the special structure of the matrix U and
decreases its bump size by one (Fig. 6.11).

@sp 1
@image{doc/fig/glpgel11}
@center{Fig 6.11. Symmetric transformation in case of column singleton}
@sp 1

Similarly, if the current bump contains a row, which is not symmetric to the
spike and has the only non-zero element
@tex
$u_{kk}$
@end tex
(row singleton) on the main diagonal, the @code{min_bump} routine shifts rows
and columns
@tex
$k+1, k+2, \dots, k_2$
@end tex
to the left and upward by one position and moves row and column @i{k} to the
position
@tex
$k_2.$
@end tex
Such symmetric transformation also keeps special structure of the matrix @i{U}
and again decreases its bump size by one (Fig. 6.12).

@sp 1
@image{doc/fig/glpgel12}
@center{Fig 6.12. Symmetric transformation in case of row singleton}
@sp 1

So far as removing row or column from the bump may cause new singletons to
appear in the bump, the @code{min_bump} routine repeats these structural
transformations until it is possible. It may be easily shown that in fact the
final bump has the smallest possible size.

Now let's consider some important implementation details. Explicit row and
columns permutations of the matrix @i{U} (which has implicit representation
@math{U = PVQ}) is very expensive, because one shift of row or column requires
up to @i{n} transpositions, i.e. up to @i{n} movements of elements of matrices
@i{P} and @i{Q}. Therefore the @code{min_bump} routine performs all elementary
transformations using other matrix @math{@overline{U}}, which differs from the
matrix @i{U} only in the order of rows and columns. For representing the matrix
@math{@overline{U}} the routine doesn't use permutation matrices (like @i{P}
and @i{Q}); instead that it uses double linked list, elements of which are
numbers of rows and columns of the matrix @i{U}. In the linked list these
elements are placed in the order, which reflects the order of the corresponding
rows and columns in the matrix @i{U}. (Only one linked list is needed, because
all performed structural transformations are symmetric.) Initially
@math{@overline{U}} is identical to @i{U}. After the matrix @i{U} has been
completely transformed, the @code{min_bump} routine uses the linked list for
reordering rows and columns of the matrix @i{U}. This technique allows
performing one movement of rows and columns (of the matrix @math{@overline{U}})
for a fixed time, because one movement is equivalent to one exclusion from and
one inclusion to the linked list. This gives time estimation @i{O}(@i{nz}),
where @i{nz} is number of non-zeros in the matrix @i{U}.

In order to find row or column singleton for a fixed time the routine uses
Duff search technique (see Chapter 3).

@section LU Factorization

This section describes a set of routines, which are based on sparse gaussian
elimination routines (see Section 6.1) and implement the following LU
factorization of a given (quadratic) matrix @i{A}:
@tex
$$A = PLUQ, \eqno (6.6)$$
@end tex
where @i{L} is lower triangular matrix with unit main diagonal, @i{U} is upper
triangular matrix, @i{P} and @i{Q} are permutation matrices.

Permutation matrices @i{P} and @i{Q} are introduced in order to allow permuting
row and column during factorization for improving numerical stability by means
of partial pivoting. Being computed the factorization (6.6) may be considered
as if it would be computed for the matrix
@tex
$\overline{A} = P^{-1}AQ^{-1}$
@end tex
(which differs from the original matrix @i{A} only in the order of rows and
columns) with no row and column permutations, because
@tex
$\overline{A} = LU.$
@end tex

LU factorization (6.6) is represented by the LU structure:

@tpindex{LU}
@example
      typedef struct LU LU;
      struct LU
      @{     int n;
            PER *P;
            MAT *L;
            MAT *U;
            PER *Q;
      @};
@end example

@noindent
where:

@table @code
@item n
order of matrices @i{P}, @i{L}, @i{U}, and @i{Q} (@i{n} > 0);
@item P
left permutation matrix @i{P};
@item L
lower triangular matrix @i{L} with unit main diagonal;
@item U
upper triangular matrix @i{U};
@item Q
right permutation matrix @i{Q}.
@end table

@subsection @code{create_lu} --- create LU factorization
@fnindex{create_lu}

@subsubheading Synopsis

@example
#include "glpgel.h"
LU *create_lu(int n);
@end example

@subsubheading Description

The @code{create_lu} routine creates LU factorization of order @i{n} > 0.
Initially the factorization corresponds to unity matrix, i.e.
@math{P = L = U = Q = I}.

@subsubheading Returns

The @code{create_lu} routine returns a pointer to the created LU factorization.

@subsection @code{build_lu} --- compute LU factorization of given sparse matrix

@subsubheading Synopsis

@example
#include "glpgel.h"
int build_lu(LU *lu, MAT *A, double tol, double lim,
   void (*monit)(LU *lu, int kase, int i, int k, double f),
   double *Amax, double *Ubig);
@end example

@subsubheading Description

The @code{build_lu} routine computes LU factorization (6.6) of the given sparse
matrix @i{A}. In order to compute LU factorization the @code{build_lu} routine
uses the @code{gel} routine, which performs sparse gaussian elimination (see
Subsection 6.1.1).

The LU factorization, which @code{lu} points to, should be created before by
the @code{create_lu} routine (see Subsection 6.2.1) and may be used several
times for different matrices of the same order to factorize them by means of
the @code{build_lu} routine.

It is allowed to pass the matrix @code{lu->U} as the input matrix @i{A}.
Otherwise the matrix @i{A} remains unchanged on exit.

The control parameter @i{tol} is a relative tolerance (Markowitz parameter)
used for threshold pivoting. Its value should be in the range 0 < @i{tol} < 1.
An element
@tex
$u_{ij}$
@end tex
of the active submatrix fits to be the pivot element (from the point of view of
numerical stability) if
@tex
$u_{ij} \geq tol \cdot \max_l |u_{il}|$
@end tex
on some elimination step. Decreasing @i{tol} usually involves improving
sparsity at the expense of accuracy and vice versa. If the input matrix @i{A}
is expected to be well conditioned, the value @i{tol} = 0.1---0.01 may be
recommended in most cases. For more hard matrices the value of tol should be
increased. For details see the description of the @code{gel} routine
(Subsection 6.2.1).

The control parameter @i{lim} specifies maximal allowable growth of elements of
the matrix @i{U} during factorization process. The process is considered as
numerically stable if on each step the condition
@tex
$Ubig \leq lim \cdot Amax$
@end tex
is satisfied (@i{Amax} and @i{Ubig} are described below). If @code{DBL_DIG} is
approximately 15 decimal places, the recommended value is
@tex
$lim = 10^{10}$---$10^{12}.$
@end tex
For details see the description of the @code{gel} routine (Subsection 6.2.1).

The formal routine @code{monit} is intended for monitoring purposes. The
@code{build_lu} routine calls the @code{monit} routine in the following cases
(recognized by the parameter @code{kase}):

@table @code
@item kase = 0
once before the beginning of factorization (parameters @code{i}, @code{k}, and
@code{f} should be ignored);

@item kase = 1
each time when the next elementary gaussian transformation is applied to the
matrix @i{U} using the following formula:

(@i{i}th row of @i{U}) := (@i{i}th row of @i{U}) @minus{} @i{f} @math{@times{}}
(@i{k}th row of @i{U}),

where @i{i} is number of transformed row, @i{k} is number of pivot row. As a
result of this elementary transformation the next non-zero element appears in
the matrix @i{L}. Note that during factorization matrices @code{lu->L} and
@code{lu->U} differ from matrices @i{L} and @i{U} as declared by (6.6) in the
order of rows and columns, which is determined by permutation matrices @i{P}
and @i{Q}. This is used to avoid explicit permutations of rows and columns of
matrices @i{L} and @i{U}. For details see the method description;

@item kase = 2
once after the end of factorization (parameters @code{i}, @code{k}, and
@code{f} should be ignored);
@end table

There is standard monitoring routine @code{monit_lu} (see Subsection 6.2.3),
which may be passed to the @code{build_lu} routine. Every second the
@code{monit_lu} routine prints the following information: @i{n} (order of the
matrix @i{A}), @i{k} (number of elimination step), @math{nz(L)} (current number
of non-zeros in the matrix @i{L}), and @math{nz(U)} (current number of
non-zeros in the matrix @i{U}).

If the parameter @code{monit} is @code{NULL}, no monitoring is performed.

On entry contents of the locations @code{Amax} and @code{Ubig} are ignored. On
exit the location @code{Amax} contains maximal of absolute values of elements
of the input matrix @i{A}. The location @code{Ubig} contains maximal of
absolute values of elements of the matrix @i{U}, which appeared in this matrix
during entire elimination process (i.e.
@tex
$Ubig = \max |u_{ij}^{(k)}|,$
@end tex
where @i{k} is number of the elimination step). Thus, the ratio
@math{Ubig/Amax} may be used to measure the numerical "quality" of computed
factorization.

Factorization process may fail if the input matrix @i{A} is singular or ill
conditioned. In this case matrices @i{L} and @i{U} correspond to partial
factorization and look like shown on @w{Fig. 6.13} (where @i{k} is number of
factorization step, @math{@ast{}} marks the active submatrix that causes a
problem).

Note that the equality @math{A = PLUQ} is valid even in case of error,
therefore this partial factorization may be used for performing further
analysis of the matrix @i{A}.

@sp 1
@image{doc/fig/glpgel13}
@center{Fig 6.13. Matrices @i{L} and @i{U} in case of error (partial factorization)}
@sp 1

@subsubheading Returns

The @code{build_lu} routine returns one of the following error codes:

@table @asis
@item 0
no errors, factorization has been successfully computed;
@item @math{-k}
on @i{k}th elimination step all elements of the active submatrix are equal to
zero;
@item @math{+k}
on @i{k}th elimination step the numerical stability condition is violated.
@end table

@subsubheading Method

In order to factorize the input matrix @i{A} the @code{build_lu} routine calls
the @code{gel} routine, which allows transforming matrix to upper triangular
form using gaussian elimination (see Subsection 6.1.1).

If the @code{build_lu} routine would use the form (6.6) directly, it should
explicitly permute rows and columns of @i{L} each time when the @code{build_lu}
routine (implicitly) permute rows and columns of @i{U}. Explicit permutations
of rows and columns are undesirable because of low efficiency. Therefore during
factorization process the @code{build_lu} routine instead (6.6) uses the
following form:
@tex
$$A = MV, \eqno (6.7)$$
where $M = PLP^{-1}$ and $V = PUQ.$
@end tex
Thus, (6.7) is equivalent to (6.6), where @i{M} and @i{V} differ from @i{L} and
@i{U} in the order of rows and columns determined by permutation matrices @i{P}
and @i{Q}. After the factorization (6.7) has been computed the @code{build_lu}
routine replaces matrices @i{M} and @i{V} by matrices @i{L} and @i{U}, that
gives the final factorization (6.6). Note that during the factorization process
matrices
@tex
$\overline{P} = P^{-1}$ and $\overline{Q} = Q^{-1}$
@end tex
are actually used instead matrices @i{P} and @i{Q}, because the @code{gel}
needs the form
@tex
$U = \overline{P}V\overline{Q}$
@end tex
instead @math{V = PUQ}. These permutation matrices are inverted after the
factorization is finished.

At first the @code{build_lu} routine sets @math{M = I} and @math{V = A}, and
then calls the @code{gel} routine in order to transform the matrix
@tex
$U = \overline{P}V\overline{Q}$
@end tex
to upper triangular form (the @code{gel} routine initially sets
@tex
$\overline{P} = \overline{Q} = I,$
@end tex
so the equation (6.7) is kept). During factorization the @code{build_lu}
routine accumulates all inverted elementary transformation, which the
@code{gel} routine applies to the matrix @i{U} (actually to the matrix @i{V},
because @i{U} has implicit representation), in the form of the matrix @i{M}
through the routine @code{func} passed to the @code{gel} routine as formal
parameter. Finally the @code{build_lu} routine inverts permutation matrices
@tex
$\overline{P}$ and $\overline{Q}$
@end tex
computed by the @code{gel} routine that gives matrices @i{P} and @i{Q}, and
builds resultant matrices
@tex
$L = P^{-1}MP$ and $U = P^{-1}VQ^{-1}$
@end tex

Let's assume that the @code{gel} routine applies to the matrix @code{U}
elementary gaussian transformation using the formula (6.2) in order to
eliminate the subdiagonal element
@tex
$u_{ik}.$
@end tex
This elementary transformation may be written as
@tex
$\overline{U} = \Phi U,$
@end tex
where
@tex
$$\Phi =
\pmatrix
{
1 \cr
& \ddots \cr
& & 1 \cr
& & & 1 \cr
& -f_{ik} & & & 1 \cr
& & & & & \ddots \cr
& & & & & & 1 \cr
}, \eqno (6.8)
$$
@end tex
is a transforming matrix,
@tex
$f_{ik}$
@end tex
is gaussian multiplier. In order to keep the equality (6.6) it is necessary to
apply the corresponding inverted transformation to the matrix @i{L}, i.e.
@tex
$\overline{L} = L \Phi^{-1},$
@end tex
where
@tex
$$\Phi^{-1} =
\pmatrix
{
1 \cr
& \ddots \cr
& & 1 \cr
& & & 1 \cr
& +f_{ik} & & & 1 \cr
& & & & & \ddots \cr
& & & & & & 1 \cr
}, \eqno (6.9)
$$
@end tex

It is well known that if gaussian elimination is performed by rows (as the
@code{gel} routine does), the transformation (6.9) involves appearing the only
new non-zero element
@tex
$l_{ik} = f_{ik}$
@end tex
in the matrix @i{L}, i.e. no actual matrix multiplication is needed.

As it was said above the @code{build_lu} works with matrices @i{M} and @i{V},
which differ from matrices @i{L} and @i{U} only in the order of rows and
columns. Obviously, transforming @i{L} and @i{U} using (6.8) and (6.9) is
equivalent to transforming @i{M} and @i{V} using transforming matrices, which
has the same structure as (6.8) and (6.9) and differ only in the order of rows
and columns. Therefore each time when the @code{gel} routine applies elementary
gaussian transformation, the @code{build_lu} routine just adds the next
non-zero element
@tex
$f_{ik}$
@end tex
to the matrix @i{M}, determining its position in the matrix @i{M} by means of
current permutation matrices @math{@overline{P}} and @math{@overline{Q}}.

The example of LU factorization of the test matrix @math{D(100, 30)} (see
Section 7.28) performed by means of the @code{build_lu} routine is shown on
@w{Fig. 6.14}.

@page
@image{doc/fig/glpgel14}
@center{Fig 6.14. Example of LU factorization performed by the @code{build_lu} routine}
@center{(a) input matrix @i{A}; (b) matrices @i{M} and @i{V}; (c) matrices @i{L} and @i{U}.}
@sp 1

@subsection @code{monit_lu} --- standard monitoring routine
@fnindex{monit_lu}

@subsubheading Synopsis

@example
#include "glpgel.h"
void monit_lu(LU *lu, int kase, int i, int k, double f);
@end example

@subsubheading Description

The @code{monit_lu} routine is the standard monitoring routine, which can be
passed to the @code{build_lu} routine (see Subsection 6.2.2). It also can be
used as an example for user-written monitoring routine.

For details see Subsection 6.2.2.

@subsection @code{solve_lu} --- solve linear system using LU factorization
@fnindex{solve_lu}

@subsubheading Synopsis

@example
#include "glpgel.h"
void solve_lu(LU *lu, int flag, double x[], double work[]);
@end example

@subsubheading Description

The @code{solve_lu} routine solves either the system @math{Ax = b} or the
system
@tex
$A^Tx = b,$
@end tex
where @i{A} is given non-singular coefficient matrix, @i{x} is dense vector of
unknowns, @i{b} is dense vector of right hand sides.

The parameter @code{lu} should specify LU factorization of the coefficient
matrix computed by the @code{build_lu} routine (see Subsection 6.2.2). If the
@code{build_lu} routine reported an error, LU factorization should not be used.

The parameter @code{flag} specifies what system has to be solved. If
@w{@code{flag} = 0}, the routine solves the system @math{Ax = b}. Otherwise the
routine solves the transposed system
@tex
$A^Tx = b.$
@end tex

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The array @code{work} is auxiliary storage. It should have at least @math{1+n}
locations, where @i{n} is the order of the matrix @i{A}.

LU factorization, which @code{lu} points to, is not changed. Therefore it may
be used several times for solving systems with the same coefficient matrix and
different right hand sides.

@subsubheading Complexity

The @code{solve_lu} routine has time complexity @math{O[nz(L)+nz(U)]}, where
@math{nz(L)} is number of non-zeros in the matrix @i{L}, @math{nz(U)} is number
of non-zeros in the matrix @i{U}.

@subsubheading Method

From (6.6) it follows that
@tex
$$A^{-1} = Q^{-1}U^{-1}L^{-1}P^{-1}$$
@end tex

@noindent
and
@footnote{
@tex
$A^{-T}$ means $(A^T)^{-1}$.
@end tex
}

@tex
$$A^{-T} = PL^{-T}U^{-T}Q.$$
@end tex

Therefore solving systems @math{Ax = b} and
@tex
$A^Tx = b$
@end tex
may be performed through solving systems with triangular matrices @i{L} and
@i{U} and additionally permuting elements of vectors @i{x} and @i{b} as
determined by permutation matrices @i{P} and @i{Q}.

@subsection @code{delete_lu} --- delete LU factorization
@fnindex{delete_lu}

@subsubheading Synopsis

@example
#include "glpgel.h"
void delete_lu(LU *lu);
@end example

@subsubheading Description

The @code{delete_lu} routine deletes the LU factorization @code{lu}, freeing
all the memory allocated to this object.

@unnumberedsec References

@enumerate 1
@item
@i{Sergio Pissanetzky.} Sparse Matrix Technology. Academic Press Inc., 1984.
@item
@i{I. S. Duff.} MA28 --- a set of FORTRAN subroutines for sparse unsymmetric
linear equations. Harwell Report AERE, @w{R. 8730}, 1977.
@item
@i{R. H. Bartels.} A Numerical Investigation of the Simplex Method. Tech.
Report. Computer Science Department, Stanford University, California, 1968.
@item
@i{R. H. Bartels, G. H. Golub.} The Simplex Method of Linear Programming
Using @w{LU-decomposition}. Comm. ACM, 12, @w{pp. 266---68}, 1969.
@item
@i{J. J. H. Forrest, J. A. Tomlin.} Updating Triangular Factors of the Basis
to Maintain Sparsity in the Product Form Simplex Method. Mathematical
Programming, 2, @w{pp. 263---78}, 1972.
@item
@i{J. K. Reid.} A Sparsity Exploiting Variant of the Bartels---Golub
Decomposition for Linear Programming Bases. Mathematical Programming, 24,
@w{pp. 55---69}, 1982.
@end enumerate

@chapter GLPMAT: Operations on Vectors and Matrices

@section Prelude

This chapter describes a set of routines, which operates on vectors and
matrices. All routines are given in the alphabetical order.

@subsubheading Vectors

Vectors are stored using dense format. There is no specific data structure for
representing vectors. In order to represent a vector
@tex
$x = (x_1, x_2, \dots, x_n)$
@end tex
of length @i{n} the ordinary array of @code{double} type should be used:

@example
      double x[1+n];
@end example

Note that the array should have @math{n+1} locations, since the location
@code{x[0]} is not used. This convention provides natural correspondence:
@code{x[1]} =
@tex
$x_1,$
@end tex
@code{x[2]} =
@tex
$x_2,$
@end tex
@dots{}, @code{x[n]} =
@tex
$x_n.$
@end tex

@subsubheading Sparse matrices

@dfn{Sparse matrix} is a matrix, most of elements of which are equal to zero.

Sparse matrices are stored using so called @dfn{sparse rowwise/columnwise
unordered} format. This means that:

only non-zero elements are explicitly stored @footnote{It is allowed to store
zero elements. Therefore "non-zero element" means "element, which is explicitly
stored in the memory".} ("sparse");

for each row and each column of matrix the corresponding elements are linked
into linked lists ("rowwise/columnwise");

as a rule the ordering of elements inside row and column lists is undefined
("unordered").

In order to represent sparse matrix on the whole the @code{MAT} structure is
used:

@tpindex{MAT}
@example
      typedef struct MAT MAT;
      struct MAT
      @{     int m;
            int n;
            POOL *pool;
            ELEM row[1+m];
            ELEM col[1+n];
      @};
@end example

@noindent
where:

@table @code
@item m
number of rows, @i{m} > 0;
@item n
number of columns, @i{n} > 0;
@item pool
memory pool (see Section 10.3) that holds all elements of the matrix;
@item row
array of row lists. The location @code{row[0]} is not used. The location
@code{row[i]} is a pointer to the first element placed in @i{i}th row
@math{(1 @leq{} i @leq{} m)};
@item col
array of column lists. The location @code{col[0]} is not used. The location
@code{col[j]} is a pointer to the first element placed in @i{j}th column
@math{(1 @leq{} j @leq{} n)}.
@end table

The representation of a particular element of sparse matrix is defined by the
following @code{ELEM} structure:

@tpindex{ELEM}
@example
      typedef struct struct ELEM;
      struct ELEM
      @{     int i;
            int j;
            double val;
            ELEM *row;
            ELEM *col;
      @};
@end example

@noindent
where:

@table @code
@item i
row number @math{(1 @leq{} i @leq{} m)};
@item j
column number @math{(1 @leq{} j @leq{} n)};
@item val
numerical value of element (usually non-zero, but zero is allowed);
@item row
pointer to the next element in the same row or @code{NULL}, if there is no the
next element (this linked list is unordered);
@item col
pointer to the next element in the same column or @code{NULL}, if there is no
the next element (this linked list is unordered).
@end table

Let's consider the following example of sparse matrix:
@tex
$$
\pmatrix
{
   0 &  0 & 2.5 &    0 & -1.7 \cr
   0 &  0 &   0 &    0 &    0 \cr
 3.2 &  0 &   1 &    0 &    0 \cr
   1 & -1 &   0 & -4.1 &    0 \cr
}
.$$
@end tex
The corresponding data structure of this matrix is shown on Fig. 7.1.

Note that the format used for representing sparse matrices allows
@dfn{multiplets}, i.e. sets of elements, which have identical row and column
indices. Above it was also said that this format allows explicit zeros. In some
cases it is desirable to keep multiplets and/or explicit zeros (for example,
when a matrix describes the structure of directed multigraph, where multiplets
represent multiarcs, or when a matrix is the result of symbolic factorization,
where explicit zeros determine matrix elements, which might become non-zero for
other matrix with the same pattern). However, multiplets and explicit zeros
should be considered as special cases. Therefore, it is assumed everywhere that
@emph{normally a sparse matrix has neither multiplets nor explicit zeros}. If
some routine allows multiplets or/and explicit zeros in a sparse matrix, this
will be declared explicitly in the description of the corresponding routine. It
is very important, because some matrix routines are not able to work correctly,
if input matrices have multiplets and/or explicit zeros. Note also that some
matrix routines may produce matrices with multiplets and/or explicit zeros.

@sp 1
@image{doc/fig/glpmat01}
@center{Fig 7.1. Example of sparse matrix representation}
@sp 1

@subsubheading Permutation matrices

@dfn{Permutation matrix} is a quadratic matrix, which is a result of permuting
columns (or rows) of unity matrix. (Permutation matrix can be also defined as a
quadratic matrix, each row and each column of which contains only one non-zero
element, which is equal to one.)

Permutation matrices are described by the PER structure:

@tpindex{PER}
@example
      typedef struct PER PER;
      struct PER
      @{     int n;
            int row[1+n];
            int col[1+n];
      @};
@end example

@noindent
where:

@table @code
@item n
order of permutation matrix, @math{n > 0};
@item row
rowwise representation. The location @code{row[0]} is not used. The location
@code{row[i]} contains column number of unity element, which is placed in
@i{i}th row, @math{1 @leq{} i @leq{} n}. In other words, @code{row[i]} =
@code{j} if
@tex
$p_{ij} = 1;$
@end tex
@item col
columnwise representation. The location @code{col[0]} is not used. The location
@code{col[j]} contains row number of unity element, which is placed in @i{j}th
column, @math{1 @leq{} j @leq{} n}. In other words, @code{col[j] = i} if
@tex
$p_{ij} = 1.$
@end tex
@end table

Let's consider the following example of permutation matrix:
@tex
$$
\pmatrix
{
0 & 0 & 1 & 0 \cr
0 & 1 & 0 & 0 \cr
0 & 0 & 0 & 1 \cr
1 & 0 & 0 & 0 \cr
}
.$$
@end tex
Representation of this matrix is the following:

@example
      row[1] = 3, row[2] = 2, row[3] = 4, row[4] = 1,
      col[1] = 4, col[2] = 2, col[3] = 1, col[4] = 3.
@end example

It is seen that the representation of permutation matrices is superfluous,
since @w{@code{row[col[j]]} @math{@equiv{}} @code{j}} and @w{@code{col[row[i]]}
@math{@equiv{}} @code{i}}. However, on practice it is convenient to have both
arrays at the same time.

@section @code{check_mat} --- check sparse matrix for correctness
@fnindex{check_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
void check_mat(MAT *A);
@end example

@subsubheading Description

The @code{check_mat} routine checks representation of the sparse matrix @i{A}
for correctness. In case of incorrect representation the routine reports an
error and abnormally terminates the program.

Sparse matrix is correct if all its elements have correct row and column
indices and there are no "lost" elements, i.e. elements which being presented
in row (column) linked list are missing from the corresponding column (row)
linked list.

The normal return from the @code{check_mat} routine guarantees that the matrix
@i{A} is correct. (Note that sparse matrix is considered as correct even if it
has multiplets and explicit zeros.)

@subsubheading Complexity

This operation is extremely inefficient and intended only for debugging
purposes.

@section @code{check_per} --- check permutation matrix for correctness
@fnindex{check_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
void check_per(PER *P);
@end example

@subsubheading Description

The @code{check_per} routine checks the representation of the permutation
matrix @i{P} for correctness. In case of incorrect representation the routine
reports an error and abnormally terminates the program.

The normal return from the @code{check_per} routine guarantees that the matrix
@i{P} is correct.

@subsubheading Complexity

This operation has time complexity @math{O(n)}, where @i{n} is the order of
permutation matrix.

@section @code{clear_line} --- clear row or column of sparse matrix
@fnindex{clear_line}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *clear_line(MAT *A, int k);
@end example

@subsubheading Description

The @code{clear_line} routine performs one of the following operations:

if @i{k} > 0, the routine clears @i{k}th row of the sparse matrix @i{A};

if @i{k} < 0, the routine clears @i{k}th column of the sparse matrix @i{A};

if @i{k} = 0, the routine clears the entire sparse matrix @i{A}.

To clear row, column, or entire matrix means to remove all elements from the
row, column, or matrix (all removed elements are returned to the corresponding
memory pool).

The @code{clear_line} routine works correctly if the matrix @i{A} has
multiplets and/or explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is total number
of non-zero elements of sparse matrix (in all three cases).

@subsubheading Returns

The @code{clear_line} routine returns a pointer to the matrix @i{A}.

@section @code{clear_mat} --- clear sparse matrix @w{(@i{A} := 0)}
@fnindex{clear_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *clear_mat(MAT *A);
@end example

@subsubheading Description

The @code{clear_mat} routine clears the sparse matrix @i{A}, making its row and
column lists be empty.

Note that the routine doesn't free the memory allocated to the matrix @i{A}. It
just returns all its elements to the corresponding memory pool.

The @code{clear_mat} routine works correctly if the matrix @i{A} has multiplets
and/or explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is total number
of non-zero elements of sparse matrix.

@subsubheading Returns

The @code{clear_mat} routine returns a pointer to the matrix @i{A}.

@section @code{copy_mat} --- copy sparse matrix @w{(@i{B} := @i{A})}
@fnindex{copy_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *copy_mat(MAT *B, MAT *A);
@end example

@subsubheading Description

The @code{copy_mat} routine copies the sparse matrix @i{A} to the sparse matrix
@i{B}. The matrices @i{A} and @i{B} should be of identical size.

The @code{copy_mat} performs verbatim copying. Therefore if the matrix @i{A}
has multiplets and/or explicit zeros, the matrix @i{B} inherits exactly the
same structure.

If @i{A} and @i{B} is the same matrix, no copying is performed.

@subsubheading Complexity

This operation has time complexity @math{O[nz(A), nz(B)]}, where @math{nz(A)}
and @math{nz(B)} are number of non-zero elements of the matrices @i{A} and
@i{B} (before copying) respectively.

@subsubheading Returns

The @code{copy_mat} routine returns a pointer to the matrix @i{B}.

@section @code{copy_per} --- copy permutation matrix (@i{Q} := @i{P})
@fnindex{copy_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
PER *copy_per(PER *Q, PER *P);
@end example

@subsubheading Description

The @code{copy_per} routine copies the permutation matrix @i{P} to the
permutation matrix @i{Q}. The matrices @i{P} and @i{Q} should be of identical
order.

If @i{P} and @i{Q} is the same matrix, no copying is performed.

@subsubheading Complexity

This operation has time complexity @math{O(n)}, where @i{n} is the order of
permutation matrices.

@subsubheading Returns

The @code{copy_per} routine returns a pointer to the matrix @i{Q}.

@section @code{count_nz} --- count non-zeros of sparse matrix
@fnindex{count_nz}

@subsubheading Synopsis

@example
#include "glpmat.h"
int count_nz(MAT *A, int k);
@end example

@subsubheading Description

If @i{k} = 0, the @code{count_nz} routine returns total number of non-zeros in
the entire sparse matrix @i{A}.

If @i{k} > 0, the routine returns number of non-zeros in @i{k}th row of the
matrix @i{A}.

If @i{k} < 0, the routine returns number of non-zeros in @i{k}th column of the
matrix @i{A}.

Each element is counted once even if it belongs to multiplet (i.e. if there are
other elements with the same row and column indices) or if it is explicit zero.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is the returned
value.

@subsubheading Returns

The @code{count_nz} routine returns the number of non-zero elements.

@section @code{create_mat} --- create sparse matrix
@fnindex{create_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *create_mat(int m, int n);
@end example

@subsubheading Description

The @code{create_mat} routine creates a sparse matrix with @i{m} rows and
@i{n} columns (@i{m}, @i{n} > 0). Initially the created matrix is null matrix,
i.e. its row and column lists are empty.

@subsubheading Returns

The @code{create_mat} routine returns a pointer to the created matrix.

@section @code{create_per} --- create permutation matrix
@fnindex{create_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
PER *create_per(int n);
@end example

@subsubheading Description

The @code{create_per} routine creates a permutation matrix of order @i{n}
(@i{n} > 0). Initially the created matrix is identity matrix.

@subsubheading Returns

The @code{create_per} routine returns a pointer to the created matrix.

@section @code{delete_mat} --- delete sparse matrix
@fnindex{delete_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
void delete_mat(MAT *A);
@end example

@subsubheading Description

The @code{delete_mat} routine deletes the sparse matrix @i{A}, freeing the
memory allocated to this object.

@section @code{delete_per} --- delete permutation matrix
@fnindex{delete_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
void delete_per(PER *P);
@end example

@subsubheading Description

The @code{delete_per} routine deletes the permutation matrix @i{P}, freeing the
memory allocated to this object.

@section @code{eq_scaling} --- implicit equilibration scaling
@fnindex{eq_scaling}

@subsubheading Synopsis

@example
#include "glpmat.h"
void eq_scaling(MAT *A, double R[], double S[], int ord);
@end example

@subsubheading Description

The @code{eq_scaling} routine performs implicit equilibration scaling of the
matrix @math{RAS}, where @i{A} is the given sparse matrix (remains unchanged on
exit), @i{R} and @i{S} are given diagonal scaling matrices.

The result of scaling is the matrix @math{R'AS'}, where @math{R'} and @math{S'}
are new scaling matrices computed by the routine.

Diagonal elements of the matrix @i{R} should be placed in locations
@code{R[1]}, @code{R[2]}, @dots{}, @code{R[m]}, where @i{m} is number of rows
of the matrix @i{A}. Analogously, diagonal elements of the matrix @i{S} should
be placed in locations @code{S[1]}, @code{S[2]}, @dots{}, @code{S[n]}, where
@i{n} is number of columns of the matrix @i{A}. Diagonal elements of new
scaling matrices @math{R'} and @math{S'} are placed in the same manner on exit.

If the matrix @i{A} is not scaled on entry, @i{R} and @i{S} should be unity
matrices, i.e. all their diagonal elements should be set to 1.

The parameter @code{ord} specifies the order of scaling:

if @code{ord} = 0, at first the routine scales rows, then columns;

if @code{ord} = 1, at first the routine scales columns, then rows.

@subsubheading Method

In order to perform equilibration scaling the routine divide all elements of
each row (column) of the matrix @math{RAS} by the largest absolute value of
elements in the corresponding row (column).

@section @code{gm_scaling} --- implicit geometric mean scaling
@fnindex{gm_scaling}

@subsubheading Synopsis

@example
#include "glpmat.h"
void gm_scaling(MAT *A, double R[], double S[], int ord,
   double eps, int itmax);
@end example

@subsubheading Description

The @code{gm_scaling} routine performs implicit geometric mean scaling of the
matrix @math{RAS}, where @i{A} is the given sparse matrix (remains unchanged on
exit), @i{R} and @i{S} are given diagonal scaling matrices.

The result of scaling is the matrix @math{R'AS'}, where @math{R'} and @math{S'}
are new scaling matrices computed by the routine.

Diagonal elements of the matrix @i{R} should be placed in locations
@code{R[1]}, @code{R[2]}, @dots{}, @code{R[m]}, where @i{m} is number of rows
of the matrix @i{A}. Analogously, diagonal elements of the matrix @i{S} should
be placed in locations @code{S[1]}, @code{S[2]}, @dots{}, @code{S[n]}, where
@i{n} is number of columns of the matrix @i{A}. Diagonal elements of new
scaling matrices @math{R'} and @math{S'} are placed in the same manner on exit.

If the matrix @i{A} is not scaled on entry, @i{R} and @i{S} should be unity
matrices, i.e. all their diagonal elements should be set to 1.

The parameter @code{ord} specifies the order of scaling:

if @code{ord} = 0, at first the routine scales rows, then columns;

if @code{ord} = 1, at first the routine scales columns, then rows.

Description of parameters @code{eps} and @code{itmax} are given below (see
method description).

@subsubheading Method

In order to perform geometric mean scaling the routine divides all elements of
each row (column) by
@tex
$(\beta/\alpha)^{1/2},$
@end tex
where @math{@alpha{}} and @math{@beta{}} are, respectively, smallest and
largest absolute values of non-zero elements of the corresponding row (column).
For improving the scaling "quality" the routine performs scaling rows and
columns several times.

The parameter @i{eps} specifies a termination criterion. The iterative scaling
process is terminated, if
@tex
$t^{(k-1)} - t^{(k)} < eps \cdot t^{(k-1)}$,
where $t^{(k)} = \beta^{(k)} / \alpha^{(k)}$
is the scaling "quality",
$\alpha^{(k)}$ and $\beta^{(k)}$
@end tex
are, respectively, smallest and largest absolute elements of the matrix
@math{R'AS'} on @i{k}th iteration. In most cases the value
@i{eps} = 0.01---0.1 may be recommended.

The parameter @i{itmax} specifies maximal number of scaling iterations. In most
cases the value @i{itmax} = 10---50 may be recommended.

On each iteration the @code{gm_scaling} routine prints the scaling "quality"
(see above).

@section @code{inv_per} --- invert permutation matrix (@i{P} := @i{P}')
@fnindex{inv_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
PER *inv_per(PER *P);
@end example

@subsubheading Description

The @code{inv_per} routine inverts (transposes) the permutation matrix @i{P}.

@subsubheading Complexity

This operation has time complexity @math{O(1)}.

@subsubheading Returns

The @code{inv_per} routine returns a pointer to the matrix @i{P}.

@section @code{iper_vec} --- permute vector elements in reverse order @w{(@i{y} := @i{P}'@i{x})}
@fnindex{iper_vec}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *iper_vec(double y[], PER *P, double x[]);
@end example

@subsubheading Description

The @code{iper_vec} routine computes the product
@tex
$y = P^{-1}x,$
@end tex
where @i{P} is permutation matrix, @i{x} and @i{y} are dense vectors.

The arrays @code{x} and @code{y} should not overlap. The matrix @i{P} and the
vector @i{x} remain unchanged on exit.

@subsubheading Complexity

This operation has time complexity @math{O(n)}, where @i{n} is order of the
matrix @i{P}.

@subsubheading Returns

The @code{iper_vec} routine returns a pointer to the array @i{y}.

@section @code{l_solve} --- solve lower triangular system @i{Lx} = @i{b}
@fnindex{l_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *l_solve(MAT *L, double x[]);
@end example

@subsubheading Description

The @code{l_solve} routine solves the system @math{Lx = b}, where @i{L} is
non-singular lower triangular matrix, @i{x} is dense vector of unknowns, @i{b}
is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The matrix @i{L} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{L}.

@subsubheading Returns

The @code{l_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

Since @i{i}th equation of the system @math{Lx = b} has the form:
@tex
$$\sum_{j=1}^i {l_{ij} x_j} =
l_{i1}x_1 + l_{i2}x_2 + \dots + l_{i,i-1}x_{i-1} + l_{ii}x_i = b_i,$$
@end tex
the unknown
@tex
$x_i$
@end tex
can be computed using the formula:
@tex
$$x_i = (b_i - l_{i1}x_1 - l_{i2}x_2 - \dots - l_{i,i-1}x_{i-1}) / l_{ii} =
{{1 \over l_{ii}} (b_i - \sum_{j=1}^{i-1}{l_{ij}x_j})},$$
@end tex
assuming that
@tex
$x_1, x_2, \dots, x_{i-1}$
@end tex
have been computed yet.

@section @code{lt_solve} --- solve transposed lower triangular system @w{@i{L}'@i{x} = @i{b}}
@fnindex{lt_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double lt_solve(MAT *L, double x[]);
@end example

@subsubheading Description

The @code{lt_solve} routine solves the system
@tex
$L^Tx = b,$
@end tex
where @i{L} is non-singular lower triangular matrix, @i{x} is dense vector of
unknowns, @i{b} is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The matrix @i{L} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{L}.

@subsubheading Returns

The @code{lt_solve} routine returns a pointer to the array @i{x}.

@subsubheading Method

Since @i{i}th equation of the system
@tex
$L^Tx = b$
@end tex
has the form:
@tex
$$\sum_{j=i}^n {l_{ji} x_j} =
l_{ii}x_i + l_{i+1,i}x_{i+1} + \dots + l_{n-1,i}x_{n-1} + l_{ni}x_n = b_i,$$
@end tex
the unknown
@tex
$x_i$
@end tex
can be computed using the formula:
@tex
$$x_i = (b_i - l_{i+1,i}x_{i+1} - \dots - l_{n-1,i}x_{n-1} - l_{ni}x_n) / l_{ii} =
{{1 \over l_{ii}} (b_i - \sum_{j=i+1}^{n}{l_{ji}x_j})},$$
@end tex
assuming that
@tex
$x_{i+1}, \dots, x_{n-1}, x_n$
@end tex
have been computed yet.

@section @code{mat_per} --- permute matrix columns (@i{A} := @i{AP})
@fnindex{mat_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *mat_per(MAT *A, PER *P, void *work[]);
@end example

@subsubheading Description

The @code{mat_per} routine computes the product @math{A' = AP}, where @i{A} is
sparse matrix, @i{P} is permutation matrix, and stores the resultant matrix
@math{A'} instead the input matrix @i{A}.

The auxiliary array @code{work} should have at least @math{1+n} locations,
where @i{n} is number of columns of the matrix @i{A}.

Since the @code{mat_per} routine just permutes columns of the matrix @i{A}, the
latter may have multiplets and explicit zeros, which are retained.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{mat_per} routine returns a pointer to the matrix @i{A}.

@section @code{mat_vec} --- multiply sparse matrix on vector (@i{y} := @i{Ax})
@fnindex{mat_vec}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *mat_vec(double y[], MAT *A, double x[]);
@end example

@subsubheading Description

The @code{mat_vec} routine computes the product @math{y = Ax}, where @i{A} is
sparse matrix, @i{x} and @i{y} are dense vectors.

The arrays @code{x} and @code{y} should not overlap. The matrix @i{A} and the
vector @i{x} remain unchanged on exit.

The matrix @i{A} may have explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros @i{A}.

@subsubheading Returns

The @code{mat_vec} routine returns a pointer to the array @code{y}.

@section @code{new_elem} --- create new element of sparse matrix
@fnindex{new_elem}

@subsubheading Synopsis

@example
#include "glpmat.h"
ELEM *new_elem(MAT *A, int i, int j, double val);
@end example

@subsubheading Description

The @code{new_elem} routine creates new element of the sparse matrix @i{A},
which is placed in @i{i}th row and @i{j}th column and has the value @code{val}.

Note that the @code{new_elem} routine doesn't check whether such element
already exists. It just appends new element to the corresponding row and column
lists. Therefore multiple calls to the @code{new_elem} routine with the same
@i{i} and @i{j} indices involve appearance of multiplets. The routine also
allows creating explicit zeros, if @code{val} is set to 0.

@subsubheading Complexity

This operation has time complexity @math{O(1)}.

@subsubheading Returns

The @code{new_elem} routine returns a pointer to the created element.

@section @code{per_mat} --- permute matrix rows (@i{A} := @i{PA})
@fnindex{per_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *per_mat(PER *P, MAT *A, void *work[]);
@end example

@subsubheading Description

The @code{per_mat} routine computes the product @math{A' = PA}, where @i{A} is
sparse matrix, @i{P} is permutation matrix, and stores the resultant matrix
@math{A'} instead the input matrix @i{A}.

The auxiliary array work should have at least @math{1+m} locations, where @i{m}
is number of rows of the matrix @i{A}.

Since the @code{per_mat} routine just permutes rows of the matrix @i{A}, the
latter may have multiplets and explicit zeros, which are retained.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{per_mat} routine returns a pointer to the matrix @i{A}.

@section @code{per_vec} --- permute vector elements (@i{y} := @i{Px})
@fnindex{per_vec}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *per_vec(double y[], PER *P, double x[]);
@end example

@subsubheading Description

The @code{per_vec} routine computes the product @math{y = Px}, where @i{P} is
permutation matrix, @i{x} and @i{y} are dense vectors.

The arrays @code{x} and @code{y} should not overlap. The matrix @i{P} and the
vector @i{x} remain unchanged on exit.

@subsubheading Complexity

This operation has time complexity @math{O(n)}, where @i{n} is order of the
matrix @i{P}.

@subsubheading Returns

The @code{per_vec} routine returns a pointer to the array @code{y}.

@section @code{reset_per} --- reset permutation matrix (@i{P} := @i{I})
@fnindex{reset_per}

@subsubheading Synopsis

@example
#include "glpmat.h"
PER *reset_per(PER *P);
@end example

@subsubheading Description

The @code{reset_per} routine resets the permutation matrix @i{P} to unity
matrix.

@subsubheading Complexity

This operation has time complexity @math{O(n)}, where @i{n} is order of the
matrix @i{P}.

@subsubheading Returns

The @code{reset_per} routine returns a pointer to the matrix @i{P}.

@section @code{scrape_mat} --- remove tiny elements from sparse matrix
@fnindex{scrape_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
int scrape_mat(MAT *A, double eps);
@end example

@subsubheading Description

The @code{scrape_mat} routine removes from the sparse matrix @i{A} all
elements, whose absolute value is not greater than @i{eps}. If @math{eps = 0},
the routine removes only explicit zeros.

The matrix @i{A} may contain multiplets and explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{scrape_mat} routine returns number of elements, which have been
removed.

@section @code{sort_mat} --- sort row and column lists of sparse matrix
@fnindex{sort_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *sort_mat(MAT *A);
@end example

@subsubheading Description

The @code{sort_mat} routine sorts row and column lists of the sparse matrix
@i{A} in order that in row lists all its elements follow in the order of
increasing column indices and in column lists all its elements follow in the
order of increasing row indices.

The matrix may contain multiplets and explicit zeros, which are retained.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{sort_mat} routine returns a pointer to the matrix @i{A}.

@section @code{submatrix} --- copy submatrix of sparse matrix
@fnindex{submatrix}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *submatrix(MAT *B, MAT *A, int i1, int i2, int j1, int j2);
@end example

@subsubheading Description

The @code{submatrix} routine copies a submatrix of the sparse matrix @i{A} to
the sparse matrix @i{B}. The submatrix consists of rows with numbers @code{i1}
to @code{i2} and columns with numbers @code{j1} to @code{j2}. The matrix @i{B}
should have @code{i2-i1+1} rows and @code{j2-j1+1} columns. The matrix @i{A}
remains unchanged.

If the submatrix has explicit zeros, they are retained in the matrix @i{B}.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of A.

@subsubheading Returns

The @code{submatrix} routine returns a pointer to the matrix @i{B}.

@section @code{test_mat_d} --- create test sparse matrix of @i{D}(@i{n},@i{c}) class
@fnindex{test_mat_d}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *test_mat_d(int n, int c);
@end example

@subsubheading Description

The @code{test_mat_d} routine creates a test sparse matrix of @math{D(n, c)}
class (for details see [1]).

Matrix of @math{D(n, c)} class is a quadratic matrix of order @i{n}. It has
unit main diagonal, three codiagonals above main diagonal in the distance of
@i{c}, which are cyclically continued below main diagonal, and a triangle of
@math{10 @times{} 10} elements in the upper right corner. An example of
@math{D(100, 30)} test matrix is shown on Fig. 7.2.

It is necessary that @math{n @geq{} 14} and @math{1 @leq{} c @leq{} n-13}.

@sp 1
@image{doc/fig/glpmat02}
@center{Fig 7.2. The pattern of @math{D(100,30)} test matrix}
@sp 1

@subsubheading Returns

The @code{test_mat_d} routine returns a pointer to the created test matrix.

@section @code{test_mat_e} --- create test sparse matrix of @i{E}(@i{n},@i{c}) class
@fnindex{test_mat_e}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *test_mat_e(int n, int c);
@end example

@subsubheading Description

The @code{test_mat_e} routine creates a test sparse matrix of @math{E(n, c)}
class (for details see [1]).

Matrix of @math{E(n, c)} class is a symmetric positive definite matrix of order
@i{n}. It has the number 4 on its main diagonal and the number @math{-1} on its
four codiagonals, two of which neighbor with main diagonal and two others are
away from main diagonal in the distance @i{c}. An example of @math{E(100, 30)}
test matrix is shown on Fig. 7.3.

It is necessary that @math{n @geq{} 3} and @math{2 @leq{} c @leq{} n-1}.

@sp 1
@image{doc/fig/glpmat03}
@center{Fig 7.3. The pattern of @math{E(100,30)} test matrix}
@sp 1

@subsubheading Returns

The @code{test_mat_e} routine returns a pointer to the created test matrix.

@section @code{tmat_vec} --- multiply transposed sparse matrix on vector @w{(@i{y} := @i{A}'@i{x})}
@fnindex{tmat_vec}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *tmat_vec(double y[], MAT *A, double x[]);
@end example

@subsubheading Description

The @code{tmat_vec} routine computes the product
@tex
$y = A^Tx,$
@end tex
where @i{A} is sparse matrix, @i{x} and @i{y} are dense vectors.

The arrays @code{x} and @code{y} should not overlap. The matrix @i{A} and the
vector @i{x} remain unchanged on exit.

The matrix @i{A} may have explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{tmat_vec} routine returns a pointer to the array @code{y}.

@section @code{trn_mat} --- transpose sparse matrix (@i{A} := @i{A}')
@fnindex{trn_mat}

@subsubheading Synopsis

@example
#include "glpmat.h"
MAT *trn_mat(MAT *A);
@end example

@subsubheading Description

The @code{trn_mat} routine transposes the sparse matrix @i{A}.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{A}.

@subsubheading Returns

The @code{trn_mat} routine returns a pointer to the matrix @i{A}.

@section @code{u_solve} --- solve upper triangular system @i{Ux} = @i{b}
@fnindex{u_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *u_solve(MAT *U, double x[]);
@end example

@subsubheading Description

The @code{u_solve} routine solves the system @math{Ux = b}, where @i{U} is
non-singular upper triangular matrix, @i{x} is dense vector of unknowns, @i{b}
is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The matrix @i{U} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{U}.

@subsubheading Returns

The @code{u_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

Since @i{i}th equation of the system @math{Ux = b} has the form:
@tex
$$\sum_{j=i}^n {u_{ij} x_j} =
u_{ii}x_i + u_{i,i+1}x_{i+1} + \dots + u_{i,n-1}x_{n-1} + u_{in}x_n = b_i,$$
@end tex
the unknown
@tex
$x_i$
@end tex
can be computed using the formula:
@tex
$$x_i = (b_i - u_{i,i+1}x_{i+1} - \dots - u_{i,n-1}x_{n-1} - u_{i,n}x_n) / u_{ii} =
{{1 \over u_{ii}} (b_i - \sum_{j=i+1}^n{u_{ij}x_j})},$$
@end tex
assuming that
@tex
$x_{i+1}, \dots, x_{n-1}, x_n$
@end tex
have been computed yet.

@section @code{ut_solve} --- solve transposed upper triangular system @w{@i{U}'@i{x} = @i{b}}
@fnindex{ut_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *u_solve(MAT *U, double x[]);
@end example

@subsubheading Description

The @code{ut_solve} routine solves the system
@tex
$U^Tx = b,$
@end tex
where @i{U} is non-singular upper triangular matrix, @i{x} is dense vector of
unknowns, @i{b} is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The matrix @i{U} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{U}.

@subsubheading Returns

The @code{ut_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

Since @i{i}th equation of the system
@tex
$U^Tx = b$
@end tex
has the form:
@tex
$$\sum_{j=1}^i {u_{ji} x_j} =
u_{1i}x_1 + u_{2i}x_2 + \dots + u_{i-1,i}x_{i-1} + u_{ii}x_i = b_i,$$
@end tex
the unknown
@tex
$x_i$
@end tex
can be computed using the formula:
@tex
$$x_i = (b_i - u_{1i}x_1 - u_{2i}x_2 - \dots - u_{i-1,i}x_{i-1}) / u_{ii} =
{{1 \over u_{ii}} (b_i - \sum_{j=1}^{i-1}{u_{ji}x_j})},$$
@end tex
assuming that
@tex
$x_1, x_2, \dots, x_{i-1}$
@end tex
have been computed yet.

@section @code{v_solve} --- solve implicit upper triangular system @w{@i{Vx} = @i{b}}
@fnindex{v_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *v_solve(PER *P, MAT *V, PER *Q, double x[], double work[]);
@end example

@subsubheading Description

The @code{v_solve} routine solves the system @math{Vx = b}, where
@math{U = PVQ} is implicit non-singular upper triangular matrix, @i{V} is the
given sparse matrix, @i{P} and @i{Q} are permutation matrices, @i{x} is dense
vector of unknowns, @i{b} is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector of unknowns @i{x}.

The matrix @i{V} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{V}.

@subsubheading Returns

The @code{v_solve} routine returns a pointer to the array @code{x}.

@subsubheading Method

The @code{v_solve} routine uses the same formulae as the @code{u_solve} routine
(see Section 7.32), determining elements of the implicit upper triangular
matrix @math{U = PVQ} each time, when it is necessary.

@section @code{vt_solve} --- solve implicit transposed upper triangular system @w{@i{V}'@i{x} = @i{b}}
@fnindex{vt_solve}

@subsubheading Synopsis

@example
#include "glpmat.h"
double *vt_solve(PER *P, MAT *V, PER *Q, double x[], double work[]);
@end example

@subsubheading Description

The @code{vt_solve} routine solves the system
@tex
$V^Tx = b,$
@end tex
where @math{U = PVQ} is implicit non-singular upper triangular matrix, @i{V} is
the given sparse matrix, @i{P} and @i{Q} are permutation matrices, @i{x} is
dense vector of unknowns, @i{b} is dense vector of right hand sides.

On entry the array @code{x} should contain the vector of right hand sides
@i{b}. On exit this array contains the vector @i{x}.

The matrix @i{V} may contain explicit zeros.

@subsubheading Complexity

This operation has time complexity @math{O(nz)}, where @i{nz} is number of
non-zeros of @i{V}.

@subsubheading Returns

The @code{vt_solve} routine returns a pointer to the array @i{x}.

@subsubheading Method

The @code{vt_solve} routine uses the same formulae as the @code{ut_solve}
routine (see Section 7.33), determining elements of the implicit upper
triangular matrix @math{U = PVQ} each time, when it is necessary.

@unnumberedsec References

@enumerate 1
@item
Ole @O{}sterby, Zahari Zlatev. Direct Methods for Sparse Matrices.
Springer-Verlag, 1983.
@end enumerate

@chapter GLPMPS: Processing LP Problems Using MPS Format

@section Linear programming (LP) problem

The MPS format @footnote{The MPS format was proposed in 1960's by IBM as input
format for their mathematical programming system MPS/360. To-day the MPS format
became most widely used format, which is understood by most packages that are
intended for solving mathematical programming problems. This chapter describes
only those features of the MPS format, which are supported by GLPK routines.}
is intended for coding LP problem data.

This format assumes the following linear programming (LP) problem formulation:

@noindent
@tex
\ \ \ \ \ \ \ \ \ \ minimize (or maximize)
$$Z = x_{obj} \eqno (8.1)$$
\ \ \ \ \ \ \ \ \ \ subject to linear constraints
$$
\matrix
{
x_1 = a_{11}x_{m+1} + a_{12}x_{m+2} + \dots + a_{1n}x_{m+n} \cr
x_2 = a_{21}x_{m+1} + a_{22}x_{m+2} + \dots + a_{2n}x_{m+n} \cr
\dots \dots \dots \cr
x_m = a_{m1}x_{m+1} + a_{m2}x_{m+2} + \dots + a_{mn}x_{m+n} \cr
}
\eqno (8.2)
$$
\ \ \ \ \ \ \ \ \ \ and bounds of variables
$$
\matrix
{
l_1 \leq x_1 \leq u_1 \cr
l_2 \leq x_2 \leq u_2 \cr
\dots \dots \dots \cr
l_{m+n} \leq x_{m+n} \leq u_{m+n} \cr
}
\eqno (8.3)
$$
where
$x_1, x_2, \dots, x_m$ are rows or auxiliary variables;
$x_{m+1}, x_{m+2}, \dots, x_{m+n}$ are columns or structural variables;
$Z$ is the objective function;
$obj$ is number of row, which defines the objective function;
$a_{11}, a_{12}, \dots, a_{mn}$ are constraint coefficients;
$l_1, l_2, \dots, l_{m+n}$ are lower bounds of variables;
$u_1, u_2, \dots, u_{m+n}$ are upper bounds of variables.
@end tex

Auxiliary variables are called @dfn{rows}, because they correspond to rows of
the constraint matrix (i.e. matrix formed by constraint coefficients). Note
that the value of an auxiliary variable is the value of the corresponding
linear form. Analogously, structural variables are called @dfn{columns},
because they correspond to columns of the constraint matrix.

Bounds of variables can be finite as well as infinite. Besides, a lower bound
can be equal to an upper bound. Thus, the following types of variables are
possible:

@tex
$$\vbox
{
\settabs 3 \columns
\+ \hfil Bounds of variable & Type of variable \cr
\+ \hrulefill & \hrulefill & \cr
\+ \hfil $-\infty < x_k < +\infty$ & Free (unbounded) variable & \cr
\+ \hfil $l_k \leq x_k < +\infty$ & Variable with lower bound & \cr
\+ \hfil $-\infty < x_k \leq u_k$ & Variable with upper bound & \cr
\+ \hfil $l_k \leq x_k \leq u_k$ & Double-bounded variable & \cr
\+ \hfil $l_k = x_k = u_k$ & Fixed variable & \cr
}
$$
@end tex

@noindent
Note that types of variables shown above are applicable to structural as well
as to auxiliary variables.

@section MPS Format Specification

A file in the MPS format is a text file, which contains two types of cards
@footnote{In 1960's MPS file was a deck of 80-column punching cards. The
author decided to keep the word "card", which is to be understood as "line of
text file".}: indicator cards and data cards.

Indicator cards determine a kind of following data. Each indicator card has
one word in uppercase letters beginning at the column 1.

Data cards contain LP problem data. Each data card is divided into six fixed
fields:
@tex
$$\vbox
{
\settabs 8 \columns
\+ & \hfil Field 1 & \hfil Field 2 & \hfil Field 3 & \hfil Field 4 &
    \hfil Field 5 & \hfil Field 6 & \cr
\+ \hrulefill & \hrulefill & \hrulefill & \hrulefill & \hrulefill &
    \hrulefill & \hrulefill & \cr
\+ \hfil Columns & \hfil 2---3 & \hfil 5---12 & \hfil 15---22 &
    \hfil 25---36 & \hfil 40---47 & \hfil 50---61 & \cr
\+ \hfil Contents & \hfil Code & \hfil Name & \hfil Name &
    \hfil Number & \hfil Name & \hfil Number & \cr
}
$$
@end tex

On a particular data card some fields may be optional.

Names are used for identifying LP rows, LP columns, and some vectors (see
below).

Aligning the indicator code to the left margin of the field 1 is optional.

All names specified in fields 2, 3, and 5 should contain from 1 to 8 arbitrary
characters (except control characters). If a name is placed in the field 3 or
5, its first character should not be the dollar sign @samp{$}. If a name
contains spaces, these spaces are ignored.

All numerical values placed in fields 4 and 6 should be coded in the form
@i{sxx}@code{E}@i{syy}, where @i{s} is the plus @samp{+} or the minus
@samp{-} sign, @i{xx} is a real number with optional decimal point, @i{yy} is
an integer decimal exponent. Any number should contain up to 12 characters. If
the sign @i{s} is omitted, the plus sign is assumed. The exponent part is
optional. If a number contains spaces, these spaces are ignored.

If a card has the asterisk @samp{*} in the column 1, this card is considered
as a comment and ignored. Besides, if the first character in the field 3 or 5
is the dollar sign @samp{$}, all characters from the dollar sign to the end of
the card are considered as comment and ignored.

MPS file should contain cards in the following order:

@itemize @bullet
@item
the NAME indicator card;
@item
the ROWS indicator card;
@item
data cards specifying LP rows (constraints or auxiliary variables);
@item
the COLUMNS indicator card;
@item
data cards specifying LP columns (structural variables) and constraint
coefficients;
@item
the RHS indicator card;
@item
data cards specifying right-hand sides of constraints;
@item
the RANGES indicator card;
@item
data cards specifying double-sided constraints;
@item
the BOUNDS indicator card;
@item
data cards specifying types and bounds of LP columns;
@item
the ENDATA indicator card.
@end itemize

@dfn{Section} is a group of cards consisting of an indicator card and data
cards following that indicator card. For example, the ROWS section consists of
the ROWS indicator card and data cards specifying LP rows.

Sections RHS, RANGES, and BOUNDS are optional and may be omitted.

@subheading NAME indicator card

The NAME indicator card should be the first card of MPS file (except optional
comment  cards). This card should contain the word @samp{NAME} in columns
1---4 and the problem name in the field 3. The problem name is optional and
may be omitted.

@subheading ROWS section

The ROWS section should start with the indicator card, which contains the word
@samp{ROWS} in columns 1---3.

Each data card of the ROWS section specifies one row (constraint) of the LP
problem. These data cards have the following format.

The filed 1 specifies the row type (see (8.2), Section 8.1):

@samp{N} in the filed 1 means that the row is free (unbounded), i.e. the
corresponding constraint has the form:
@tex
$$ -\infty < x_i = a_{m1} x_{m+1} + a_{m2} x_{m+2} + \dots \ + a_{mn} x_{m+n}
< +\infty; $$
@end tex

@samp{L} in the field 1 means that the constraint is of "less than or equal to"
type:
@tex
$$ -\infty < x_i = a_{m1} x_{m+1} + a_{m2} x_{m+2} + \dots \ + a_{mn} x_{m+n}
\leq b_i; $$
@end tex

@samp{G} in the field 1 means that the constraint is of "greater than or equal
to" type:
@tex
$$ b_i \leq x_i = a_{m1} x_{m+1} + a_{m2} x_{m+2} + \dots \ + a_{mn} x_{m+n}
< +\infty; $$
@end tex

@samp{E} in the field 1 means that the row is the constraint of "equal to"
type:
@tex
$$ x_i = a_{m1} x_{m+1} + a_{m2} x_{m+2} + \dots \ + a_{mn} x_{m+n} = b_i. $$
where $b_i$ is the right hand side. Note that each constraint is connected with
the corresponding auxiliary variable ($x_i$ above), therefore bounds of the
linear form can be understood as bounds of such auxiliary variable.
@end tex

The field 2 specifies the row name (i.e. the name of the corresponding
auxiliary variable).

Fields 3, 4, 5, and 6 are not used and should be empty.

Numerical values of all non-zero right-hand sides
@tex
$b_i$
@end tex
should be specified in the RHS section. All double-sided constraints should be
specified in the RANGES section.

@subheading COLUMNS section

The COLUMNS section should start with the indicator card that contains the word
@samp{COLUMNS} in columns 1---7.

Each data card of the COLUMNS section specifies one or two constraint
coefficients and introduces names of LP columns, i.e. names of structural
variables. These data cards have the following format.

The field 1 is not used and should be empty.

The field 2 specifies the column name. If this field is empty, the name from
the previous data card is used.

The field 3 specifies the row name defined in the ROWS section.

The field 4 specifies the numerical value of the constraint coefficient
@tex
$a_{ij},$
@end tex
which is placed in the corresponding row and column.

Fields 5 and 6 are optional. If they are used, they should contain the second
pair "row name---constraint coefficient" for the same column.

Elements of constraint matrix (i.e. constraint coefficients) should follow in
the column wise manner: all elements for the current column should be specified
before specifying elements for the next column. However, the order of rows in
the COLUMNS section may differ from the order of rows in the ROWS section.

Constraint coefficients not specified in the COLUMNS section, are considered as
zeros. Therefore zero coefficients may be omitted, although it's allowed to
specify them.

Bounds of columns should be specified in the BOUNDS section.

@subheading RHS section

The RHS section should start with the indicator card, which contains the word
@samp{RHS} in columns 1---3.

Each data card of the RHS section specifies one or two right-hand sides
@tex
$b_i$
@end tex
(see the description of the ROWS section).

The field 1 is not used and should be empty.

The field 2 specifies the name of the right-hand side (RHS) vector
@footnote{This allows the user to specify several RHS vectors in the same MPS
file. However, for solving the problem the user should choose the particular
RHS vector.}. If this field is empty, the name from the previous data card is
used.

The field 3 specifies the row name defined in the ROWS section.

The field 4 specifies the right-hand side
@tex
$b_i$
@end tex
for the row, whose name is specified in the field 3. Depending on the row type
@tex
$b_i$
@end tex
defines the lower bound (in case of G type), or the upper bound (in case of L
type), or the fixed value (in case of E type).

Fields 5 and 6 are optional. If they are used, they should contain the second
pair "row name---right hand side value" for the same RHS vector.

All right hand sides for the current RHS vector should be specified before
right hand sides for the next RHS vector. However, the order of rows in the
COLUMNS section may differ from the order of rows in the ROWS section. Each
RHS vector should have unique name.

Right-hand sides not specified in the RHS section are considered as zeros.
Therefore zero right hand sides may be omitted, although it's allowed to
specify them.

@subheading RANGES section

The RANGES section should start with the indicator card, which contains the
word @samp{RANGES} in columns 1---6.

Each data card of the RANGES section specifies one or two ranges for
double-sided constraints, i.e. for constraints that have types L and G at the
same time:
@tex
$$ l_i \leq x_i = a_{i1} x_{m+1} + a_{i2} x_{m+2} + \dots + a_{in} x_{m+n}
\leq u_i, $$
where $x_i$ is an auxiliary variable, $l_i$ is a lower bound, $u_i$ is an upper
bound.
@end tex

The field 1 is not used and should be empty.

The field 2 specifies the name of the range vector @footnote{This allows the
user to specify several range vectors in the same MPS file. However, for
solving the problem the user should choose the particular range vector.}. If
this field is empty, the name from the previous data card is used.

The field 3 specifies the row name defined in the ROWS section.

The field 4 specifies the range value ri for the row, whose name is specified
in the field 3.

Fields 5 and 6 are optional. If they are used, they should contain the second
pair "row name---range value" for the same range vector.

All range values for the current range vector should be specified before range
values for the next range vector. However, the order of rows in the RANGES
section may differ from the order of rows in the ROWS section. Each range
vector should have unique name.

Lower and upper bounds are determined by the following table:

@tex
$$\vbox
{
\settabs 5 \columns
\+ \hfil Row type & \hfil Sign of $r_i$ & \hfil Lower Bound &
    \hfil Upper Bound & \cr
\+ \hrulefill & \hrulefill & \hrulefill & \hrulefill & \cr
\+ \hfil G & \hfil + or -- & \hfil $b_i$ & \hfil $b_i + |r_i|$ & \cr
\+ \hfil L & \hfil + or -- & \hfil $b_i - |r_i|$ & \hfil $b_i$ & \cr
\+ \hfil E & \hfil + & \hfil $b_i$ & \hfil $b_i + |r_i|$ & \cr
\+ \hfil E & \hfil -- & \hfil $b_i - |r_i|$ & \hfil $b_i$ & \cr
}
$$
@end tex

@noindent
@tex
where $b_i$ is the right-hand side specified in the RHS section (if $b_i$ is
not specified, it is considered to be equal to zero), $r_i$ is the range value
specified in the RANGES section).
@end tex

@subheading BOUNDS section

The BOUNDS section should start with the indicator card, which contains the
word @samp{BOUNDS} in columns 1---6.

Each data card of the BOUNDS section specifies one bound of one column
(structural variable).

The field 1 specifies the bound type:
@table @samp
@item LO
lower bound;
@item UP
upper bound;
@item FX
fixed variable (lower bound equal to upper bound);
@item FR
free variable (no bounds);
@item MI
no lower bound (lower bound is "minus infinity");
@item PL
no upper bound (upper bound is "plus infinity").
@end table

The field 2 contains the name of the bound vector @footnote{This allows the
user to specify several bound vectors in the same MPS file. However, for
solving the problem the user should choose the particular bound vector.}. If
this field is empty, the name from the previous data card is used.

The field 3 contains the column name defined in the COLUMNS section.

The field 4 specifies the bound value. If the bound type in the field 1 differs
from LO, UP, or FX, this value is ignored and may be omitted.

Fields 5 and 6 are not used and should be empty.

All bound values for the current bound vector should be specified before bound
values for the next bound vector. However, the order of columns in the BOUNDS
section may differ from the order of columns in the COLUMNS section. Each bound
vector should have unique name. The specification of the lower bound should
precede the specification of the upper bound for the same column (if both they
are explictly specified).

By default all columns (structural variables) are considered as non-negative,
i.e. with lower bound equal to zero and upper bound equal to
@tex
$+\infty$. Lower ($l_j$) or/and upper ($u_j$) bounds of each column (i.e.
structural variable $x_j$) specified in the BOUNDS section are set in the
following way ($s_j$ denotes the corresponding bound value):
@end tex

@table @samp
@item LO
@tex
sets $l_j$ to $s_j$;
@end tex
@item UP
@tex
sets $u_j$ to $s_j$;
@end tex
@item FX
@tex
sets both $l_j$ and $u_j$ to $s_j$;
@end tex
@item FR
@tex
sets $l_j$ to $-\infty$ and $u_j$ to $+\infty$;
@end tex
@item MI
@tex
sets $l_j$ to $-\infty$;
@end tex
@item PL
@tex
sets $u_j$ to $+\infty$.
@end tex
@end table

If only zero upper bound is specified, it is the same as if FX type would be
specified.

@subheading ENDATA indicator card

The ENDATA indicator card should be the last card of MPS file (except optional
comment cards). This card should contain the word @samp{ENDATA} in columns
1---6.

It is impossible to specify the objective function and the optimization
direction explicitly in the MPS file. However, the following rule is used by
default in all cases: the first row of N type is considered as the row of the
objective function (i.e. the objective function is the same as the
corresponding auxiliary variable), which should be minimized.

@subheading Example of MPS file

In order to illustrate what the MPS format is, let us consider the following
example LP problem:

@sp 1
@example
   minimize

      Z = COST

   subject to linear constraints

COST = 0.03 MIX1 + 0.08 MIX2 + 0.17 MIX3 + 0.12 MIX4 + 0.15 MIX5 + 0.21 ALUM
     + 0.38 SILC
SUM  =      MIX1 +      MIX2 +      MIX3 +      MIX4 +      MIX5 +      ALUM
     + SILC
FE   = 0.15 MIX1 + 0.04 MIX2 + 0.02 MIX3 + 0.04 MIX4 + 0.02 MIX5 + 0.01 ALUM
     + 0.03 SILC
CU   = 0.03 MIX1 + 0.05 MIX2 + 0.08 MIX3 + 0.02 MIX4 + 0.06 MIX5 + 0.01 ALUM
MN   = 0.02 MIX1 + 0.04 MIX2 + 0.01 MIX3 + 0.02 MIX4 + 0.02 MIX5
MG   = 0.02 MIX1 + 0.03 MIX2 + 0.01 MIX5
AL   = 0.70 MIX1 + 0.75 MIX2 + 0.80 MIX3 + 0.75 MIX4 + 0.80 MIX5 + 0.97 ALUM
SI   = 0.02 MIX1 + 0.06 MIX2 + 0.08 MIX3 + 0.12 MIX4 + 0.02 MIX5 + 0.01 ALUM
     + 0.97 SILC

   and bounds of (auxiliary and structural) variables

      -inf <  COST < +inf        0 <= MIX1 <=  200
              SUM  =  200        0 <= MIX2 <= 2500
      -inf <  FE   <=  60      400 <= MIX3 <=  800
      -inf <  CU   <= 100      100 <= MIX4 <=  700
      -inf <  MN   <=  40        0 <= MIX3 <= 1500
      1500 <= AL   < +inf        0 <= ALUM <  +inf
       250 <= SI   <= 300        0 <= SILC <  +inf
@end example
@sp 1

The MPS file, which specifies data for this example LP problem, is shown
below (two top comment lines show card positions).

@sp 1
@example
*000000001111111111222222222233333333334444444444555555555566
*234567890123456789012345678901234567890123456789012345678901
NAME          PLAN
ROWS
 N  COST
 E  SUM
 L  FE
 L  CU
 L  MN
 L  MG
 G  AL
 L  SI
COLUMNS
    MIX1      COST            .03000   SUM            1.00000
              FE              .15000   CU              .03000
              MN              .02000   MG              .02000
              AL              .70000   SI              .02000
    MIX2      COST            .08000   SUM            1.00000
              FE              .04000   CU              .05000
              MN              .04000   MG              .03000
              AL              .75000   SI              .06000
    MIX3      COST            .17000   SUM            1.00000
              FE              .02000   CU              .08000
              MN              .01000   AL              .80000
              SI              .08000
    MIX4      COST            .12000   SUM            1.00000
              FE              .04000   CU              .02000
              MN              .02000   AL              .75000
              SI              .12000
    MIX5      COST            .15000   SUM            1.00000
              FE              .02000   CU              .06000
              MN              .02000   MG              .01000
              AL              .80000   SI              .02000
    ALUM      COST            .21000   SUM            1.00000
              FE              .01000   CU              .01000
              AL              .97000   SI              .01000
    SILC      COST            .38000   SUM            1.00000
              FE              .03000   SI              .97000
RHS
    RHS1      SUM         2000.00000   FE            60.00000
              CU           100.00000   MN            40.00000
              SI           300.00000
              MG            30.00000   AL          1500.00000
RANGES
    RNG1      SI            50.00000
BOUNDS
 UP BND1      MIX1         200.00000
 UP           MIX2        2500.00000
 LO           MIX3         400.00000
 UP           MIX3         800.00000
 LO           MIX4         100.00000
 UP           MIX4         700.00000
 UP           MIX5        1500.00000
ENDATA
@end example
@sp 1

@page
@section MPS data structures

MPS data structures are internal representation of MPS file.

The structure @code{MPS} is a root structure, which contains initial pointers
to other structures:

@tpindex{MPS}
@example
      typedef struct MPS MPS;
      struct MPS
      @{     POOL *pool;
            char *name;
            int n_row;
            int n_col;
            int n_rhs;
            int n_rng;
            int n_bnd;
            MPSROW *row[1+n_row];
            MPSCOL *col[1+n_col];
            MPSCOL *rhs[1+n_rhs];
            MPSCOL *rng[1+n_rng];
            MPSBND *bnd[1+n_bnd];
            MPSQFE *quad;
      @};
@end example

@noindent
where:
@table @code
@item pool
memory pool (see Section 10.3) that holds all other data structures;
@item name
problem name (1 to 8 characters);
@item n_row
number of rows, @code{n_row} @math{@geq{}} 1;
@item n_col
number of columns, @code{n_col} @math{@geq{}} 1;
@item n_rhs
number of right hand side vectors, @code{n_rhs} @math{@geq{}} 0;
@item n_rng
number of range vectors, @code{n_rng} @math{@geq{}} 0;
@item n_bnd
number of bound vectors, @code{n_bnd} @math{@geq{}} 0;
@item row
array of rows. Location @code{row[0]} is not used. Location
@code{row[}@i{k}@code{]} is a pointer to @i{k}th row
@math{(1 @leq{} k @leq{}} @code{n_row}). The order of rows is the same as in
MPS file;
@item col
array of columns. Location @code{col[0]} is not used. Location
@code{col[}@i{k}@code{]} is a pointer to @i{k}th column
@math{(1 @leq{} k @leq{}} @code{n_col}). The order of columns is the same as in
MPS file;
@item rhs
array of RHS vectors. Location @code{rhs[0]} is not used. Location
@code{rhs[}@i{k}@code{]} is a pointer to @i{k}th RHS vector
@math{(1 @leq{} k @leq{}} @code{n_rhs}). The order of RHS vectors is the same
as in MPS file;
@item rng
array of range vectors. Location @code{rng[0]} is not used. Location
@code{rng[}@i{k}@code{]} is a pointer to @i{k}th range vector
@math{(1 @leq{} k @leq{}} @code{n_rng}). The order of range vectors is the same
as in MPS file;
@item bnd
array of bound vectors. Location @code{bnd[0]} is not used. Location
@code{bnd[}@i{k}@code{]} is a pointer to @i{k}th bound vector
@math{(1 @leq{} k @leq{}} @code{n_bnd}). The order of bound vectors is the same
as in MPS file;
@item quad
reserved for future use.
@end table

The structure @code{MPSROW} defines a particular row (constraint):

@tpindex{MPSROW}
@example
      typedef struct MPSROW MPSROW;
      struct MPSROW
      @{     char *name;
            char type[2+1];
      @};
@end example

@noindent
where:
@table @code
@item name
row name (1 to 8 characters);
@item type
row type (left justified):
@table @samp
@item N
free (unbounded) row;
@item L
row of "less than or equal to" type;
@item G
row of "greater than or equal to" type;
@item E
row of "equal to" type.
@end table
@end table

The structure @code{MPSCOL} defines a particular column (structural variable),
right hand sides vector, or range vector:

@tpindex{MPSCOL}
@example
      typedef struct MPSCOL MPSCOL;
      struct MPSCOL
      @{     char *name;
            int flag;
            MPSCQE *ptr;
      @};
@end example

@noindent
where:
@table @code
@item name
column or vector name (1 to 8 characters);
@item flag
reserved for future use;
@item ptr
pointer to the linked list of column or vector elements. The order of elements
is the same as in MPS file.
@end table

The structure @code{MPSCQE} defines a particular element of column, right hand
sides vector, or range vector:

@tpindex{MPSCQE}
@example
      typedef struct MPSCQE MPSCQE;
      struct MPSCQE
      @{     int ind;
            double val;
            MPSCQE *next;
      @};
@end example

@noindent
where:
@table @code
@item ind
row number @math{(1 @leq} @code{ind} @math{@leq{}} @code{n_row});
@item val
numeric value of the element;
@item next
pointer to the next element of the same column, RHS vector, or range vector.
@end table

The structure @code{MPSBND} defines a particular bound vector:

@tpindex{MPSBND}
@example
      typedef struct MPSBND MPSBND;
      struct MPSBND
      @{     char *name;
            MPSBQE *ptr;
      @};
@end example

@noindent
where:
@table @code
@item name
vector name (1 to 8 characters);
@item ptr
pointer to the linked list of bound vector elements. The order of elements is
the same as in MPS file.
@end table

The structure @code{MPSBQE} defines a particular element of bound vector:

@tpindex{MPSBQE}
@example
      typedef struct MPSBQE MPSBQE;
      struct MPSBQE
      @{     char type[2+1];
            int ind;
            double val;
            MPSBQE *next;
      @};
@end example

@noindent
where:
@table @code
@item type
bound type:
@table @samp
@item LO
lower bound;
@item UP
upper bound;
@item FX
fixed variable;
@item FR
free variable;
@item MI
no lower bound (lower bound is @math{-@infty{}});
@item PL
no upper bound (upper bound is @math{+@infty{}}).
@end table
@item ind
column number @math{(1 @leq{}} @code{ind} @math{@leq{}} @code{n_col});
@item val
numeric value of element;
@item ptr
pointer to the next element of the same bound vector.
@end table

@section @code{load_mps} --- load MPS file
@fnindex{load_mps}

@subsubheading Synopsis

@example
#include "glpmps.h"
MPS *load_mps(char *fname);
@end example

@subsubheading Description

The @code{load_mps} routine reads linear programming problem data using MPS
format from the text file, whose name is the character string @code{fname}.

@subsubheading Returns

The @code{load_mps} routine returns a pointer to the object of MPS type, which
is internal representation of MPS file. In case of error the @code{load_mps}
routine prints an appropriate error message to @code{stderr} and returns
@code{NULL}.

@section @code{free_mps} --- free MPS file
@fnindex{free_mps}

@subsubheading Synopsis

@example
#include "glpmps.h"
void free_mps(MPS *mps);
@end example

@subsubheading Description

The @code{free_mps} routine deletes the object of MPS type, which @code{mps}
points to, freeing all memory allocated to this object.

@chapter GLPPFI: Product Form of the Inverse (PFI)

@section Prelude

One of the most essential components of any implementation of the revised
simplex method for linear programming is the representation of the basis
matrix @footnote{@dfn{Basis matrix} or just @dfn{basis} is a quadratic
non-singular matrix formed by columns of basis variables.}, which allow
performing the following four main operations:

@itemize @bullet
@item
building the representation of a given basis matrix @i{B};
@item
updating the representation if one column of @i{B} has been replaced by other
column;
@item
forward transformation of a given vector @i{z} by means of solving the system
@w{@math{Bz' = z}};
@item
backward transformation of a given vector @i{z} by means of solving the system
@tex
$B^Tz' = z.$
@end tex
@end itemize

This chapter describes routines implementing so called @dfn{Product Form of
the Inverse (PFI)}, which is the following representation of the basis matrix:
@tex
$$ B = B_0H, \eqno (4.1)$$
@end tex
@noindent
where
@tex
$B_0$
@end tex
is an initial basis matrix, @i{H} is a matrix represented in the form of eta
file (see Section 5.1).

Let there is the current basis matrix @i{B} of order @i{m}, for which the
representation (4.1) is known. Let also @math{@overline{B}} is the adjacent
basis matrix, which differs from @i{B} only in one column
@tex
$B_p.$
@end tex
Since @i{B} is assumed to be non-singular and
@tex
$B^{-1}B = I,$
@end tex
therefore
@tex
$$B^{-1}\overline{B} = \overline{H}, \eqno (4.2)$$
@end tex
where @math{@overline{H}} also differs from unity matrix only in one @i{p}th
column.

Let @i{p}th column of @math{@overline{H}} is @math{@eta{}}. Then from (4.2) it
follows that
@tex
$$B^{-1}B_p = \eta, \eqno (4.3)$$
@end tex
i.e. @i{p}th column of @math{@overline{H}} may be determined by solving the
system
@tex
$B\eta = B_p$.
@end tex

It is well known that the matrix @math{@overline{H}} can be represented in the
product form
@tex
$$\overline{H} = H^{(p)}H^{(1)} \dots H^{(p-1)}H^{(p+1)} \dots H^{(m)},
\eqno (4.4)$$
@end tex
where each term
@tex
$H^{(i)}$
@end tex
on the right hand side has the form of eta term (5.2), and non-trivial elements
of
@tex
$H^{(p)}, H^{(1)}, \dots, H^{(m)}$
@end tex
are, respectively,
@tex
$\eta_p, \eta_1, \dots, \eta_m.$
@end tex
In other words each element of the column @math{@eta{}} (that is @i{p}th
column of the matrix @math{@overline{H}}) gives a particular eta term
@tex
$H^{(i)},$
@end tex
which has
@tex
$\eta_i$
@end tex
placed in @i{i}th row and @i{p}th column. Note that the eta term
@tex
$H^{(p)},$
@end tex
which corresponds to the diagonal element
@tex
$\eta_p,$
@end tex
should follow first, other eta terms
@tex
$H^{(i)} \ (i \neq p)$
@end tex
may follow in arbitrary order @footnote{If
@tex
$\eta_i = 0,$
@end tex
it is understood that eta term
@tex
$H^{(i)}$
@end tex
is unity matrix and may be omitted.}.

Thus, if (4.1) represents the current basis matrix @i{B}, the adjacent basis
matrix @math{@overline{B}} may be represented in the same form:
@tex
$$\overline{B} = B\overline{H} = B_0(H\overline{H}), \eqno (4.5)$$
@end tex
i.e. replacing the current matrix @i{B} to the adjacent matrix
@math{@overline{B}} just involves new eta terms to be appended to the eta file
@i{H}.

The initial basis matrix
@tex
$B_0$
@end tex
is represented in decomposed form using LU factorization (see also Section
6.2):
@tex
$$B_0 = PLUQ, \eqno (4.6)$$
@end tex
where @i{L} is lower triangular matrix with unit diagonal, @i{U} is upper
triangular matrix, @i{P} and @i{Q} are permutation matrices.

If the representation (4.1) becomes inaccurate or the eta file @i{H} becomes
too large, PFI routines allows reinverting the current basis matrix, i.e. set
@tex
$B_0 = B$
@end tex
and @i{H} = @i{I} and compute LU factorization of
@tex
$B_0.$
@end tex
Of course, PFI may be built also for other given basis matrix.

From (4.1) it follows that
@tex
$B^{-1} = H^{-1}$
@end tex
and @footnote{
@tex
$B^{-T}$ means $(B^T)^{-1}.$
@end tex
}
@tex
$B^{-T} = B_0^{-T}H^{-T}$
@end tex
Therefore forward and backward transformations can be efficiently performed by
solving systems with matrices
@tex
$B_0$
@end tex
and @i{H}.

Note that PFI has a minor disadvantage, because in some cases column
@math{@eta{}} may be quite dense, and there is no freedom for improving its
sparsity. On the other hand PFI provides good numerical stability.

PFI is defined by the following structure:

@tpindex{PFI}
@example
      typedef struct PFI PFI;
      struct PFI
      @{     int m;
            LU *lu;
            HFILE *eta;
            double col[1+m];
            int flag;
            double work[1+m];
      @};
@end example

@noindent
where:
@table @code
@item m
order of basis matrix @i{B};
@item lu
representation of initial basis matrix
@tex
$B_0$
@end tex
in the form of LU factorization;
@item eta
representation of matrix @i{H} in the form of eta file;
@item col
column @math{@eta{}}, which has to be used on updating PFI for adjacent basis
matrix @math{@overline{B}};
@item flag
column flag (this flag is reset to 0 after each updating PFI):
@table @code
@item 0
column @math{@eta{}} is not ready yet;
@item 1
column @math{@eta{}} is ready for updating.
@end table
@item work
working storage.
@end table

(It is understood that the column @math{@eta{}} is transformed column of that
non-basis variable, which enters the adjacent basis. In case of the primal
simplex method this column is used on choosing basis variable that leaves the
current basis, therefore keeping this column after forward transformation
allows not to perform this operation on subsequent updating PFI.)

@section @code{create_pfi} --- create PFI
@fnindex{create_pfi}

@subsubheading Synopsis

@example
#include "glppfi.h"
PFI *create_pfi(int m);
@end example

@subsubheading Description

The @code{create_pfi} routine creates PFI (4.1) for representing basis matrix
of order @code{m}. Initially PFI corresponds to unity basis matrix, i.e.
@tex
$B_0 = H = I.$
@end tex

@subsubheading Returns

The @code{create_pfi} routine returns a pointer to the created PFI.

@section @code{build_pfi} --- build PFI for given basis matrix
@fnindex{build_pfi}

@subsubheading Synopsis

@example
#include "glppfi.h"
int build_pfi(PFI *pfi, MAT *A, int indb[]);
@end example

@subsubheading Description

The @code{build_pfi} routine builds PFI for the given basis matrix @i{B} (see
below) in the form (4.1). It sets
@tex
$B_0 = B$
@end tex
and @i{H} = @i{I} (unity matrix) and then computes LU factorization (4.6) by
means of the @code{build_lu} routine (see Subsection 6.2.2). This operation is
usually performed if the current PFI becomes inaccurate or too large, or the
basis matrix is completely changed.

The basis matrix @i{B} is specified implicitly by means of the sparse matrix
@code{A} and the list of basis columns @code{indb}. The matrix @i{A} should
have @i{m} rows, where @i{m} is order of basis matrix. Locations
@code{indb[1]}, @code{indb[2]}, @dots{}, @code{indb[m]} should contain numbers
of basis columns of the matrix @i{A}, which specify the basis matrix @i{B}.

@subsubheading Returns

If PFI has been successfully built, the @code{build_pfi} routine returns zero.
Otherwise, if the matrix @i{B} is singular or ill conditioned, the routine
returns non-zero. In the latter case partial LU factorization can be used for
further analysis of the matrix @i{B} (for details see Chapter 6).

@section @code{update_pfi} --- update PFI for adjacent basis matrix
@fnindex{update_pfi}

@subsubheading Synopsis

@example
#include "glppfi.h"
int update_pfi(PFI *pfi, int p);
@end example

@subsubheading Description

The @code{update_pfi} routine recomputes PFI, which @code{pfi} points to and
which corresponds to the current basis matrix @i{B}, in order that it
corresponds to the adjacent basis matrix @math{@overline{B}} (see Subsection
4.1).

The parameter @code{p} specifies the number of column of the basis matrix
@i{B}, which is replaced by new column if the adjacent basis matrix
@math{@overline{B}}.

New basis column is passed implicitly. The @code{update_pfi} routine assumes
that new basis column was prepared before by means of the @code{pfi_ftran}
routine (see Section 4.5).

@subsubheading Returns

The @code{update_pfi} routine returns one of the following error codes:

@table @asis
@item 0
PFI has been successfully updated;
@item 1
PFI is inaccurate;
@item 2
PFI is too large.
@end table

In case of non-zero error code the calling program should reinvert the basis
matrix by means of the @code{build_pfi} routine (see Section 4.3).

@section @code{pfi_ftran} --- perform forward transformation (FTRAN)
@fnindex{pfi_ftran}

@subsubheading Synopsis

@example
#include "glppfi.h"
double *pfi_ftran(PFI *pfi, double z[], int save);
@end example

@subsubheading Description

The @code{pfi_ftran} routine performs so called @emph{forward transformation
(FTRAN)} of a given vector, i.e. it solves the system @math{Bz' = z}, where
@i{B} is the current basis matrix represented by PFI, which @code{pfi} points
to.

On entry the array @code{z} should contain elements of the input vector @i{z}
in locations @code{z[1]}, @code{z[2]}, @dots{}, @code{z[m]}, where @i{m} is
order of the basis matrix. On exit the array @code{z} contains elements of the
transformed vector @math{z'} in the same locations.

The parameter @code{save} is a flag. If this flag is set, it means that the
input vector @i{z} is a column corresponding to that non-basis variable, which
has been chosen to enter the basis. In this case the @code{pfi_ftran} routine
saves the transformed column @math{z'} (that is column @math{@eta{}}; see
(4.3)) in order that it could be used later by the @code{update_pfi} routine
(see Section 4.4) on updating PFI. It is assumed that the calling program
performs at least one call to the @code{pfi_ftran} routine with the @code{save}
flag set.

@subsubheading Returns

The @code{pfi_ftran} routine returns a pointer to the array @code{z}.

@section @code{pfi_btran} --- perform backward transformation (BTRAN)
@fnindex{pfi_btran}

@subsubheading Synopsis

@example
#include "glppfi.h"
double *pfi_btran(PFI *pfi, double z[]);
@end example

@subsubheading Description

The @code{pfi_btran} routine performs so called @emph{backward transformation
(BTRAN)} of a given vector, i.e. it solves the system
@tex
$B^Tz' = z,$
@end tex
where @i{B} is the current basis matrix represented by PFI, which @code{pfi}
points to.

On entry the array @code{z} should contain elements of the input vector @i{z}
in locations @code{z[1]}, @code{z[2]}, @dots{}, @code{z[m]}, where @i{m} is
order of the basis matrix. On exit the array @code{z} contains elements of the
transformed vector @math{z'} in the same locations.

@subsubheading Returns

The @code{pfi_ftran} routine returns a pointer to the array @code{z}.

@section @code{delete_pfi} --- delete PFI
@fnindex{delete_pfi}

@subsubheading Synopsis

@example
#include "glppfi.h"
void delete_pfi(PFI *pfi);
@end example

@subsubheading Description

The @code{delete_pfi} routine deletes PFI, which @code{pfi} points to, freeing
all the memory allocated to this object.

@chapter GLPRFI: Reid Form of the Inverse (RFI)

@section Prelude

One of the most essential components of any implementation of the revised
simplex method for linear programming is the representation of the basis
matrix @footnote{@dfn{Basis matrix} or just @dfn{basis} is a quadratic
non-singular matrix formed by columns of basis variables.}, which allow
performing the following four main operations:
@itemize @bullet
@item
building the representation of a given basis matrix @i{B};
@item
updating the representation if one column of @i{B} has been replaced by other
column;
@item
forward transformation of a given vector @i{z} by means of solving the system
@math{Bz' = z};
@item
backward transformation of a given vector @i{z} by means of solving the system
@tex
$B^Tz' = z.$
@end tex
@end itemize

This chapter describes routines implementing @dfn{Reid Form of the Inverse
(RFI)}, which is the representation of basis matrix proposed by @w{J. K. Reid}
[1]. (See also Chapter 4, which describes other representation of basis
matrix.)

RFI is the following four:
@tex
$$B = (H, V, P, Q), \eqno (9.1)$$
@end tex
where @i{B} is the current basis matrix, @i{H} is a matrix in the form of eta
file (see Section 5.1), @i{V} is sparse matrix, @i{P} and @i{Q} are permutation
matrices.

Also it is assumed that
@tex
$$B = HV \eqno (9.2)$$
and
$$PVQ = U, \eqno (9.3)$$
@end tex
where @i{U} is upper triangular matrix (@i{U} is not stored explicitly).

(It should be understood that (9.1)---(9.3) is some variant of LU
factorization. In fact,
@tex
$B = HV = HP^{-1}UQ^{-1},$ i.e. $PBQ = (PHP^{-1})U,$
@end tex
and it may be shown that
@tex
$PHP^{-1}$
@end tex
is lower triangular matrix.)

Let's assume that the matrix @i{U} is not upper triangular. In this case we can
apply gaussian elimination procedure in order to restore its upper triangular
form.

Gaussian elimination procedure includes elementary transformations of the
following three kinds: row permutation, column permutation, and subtraction one
row multiplied by a number from other row (gaussian transformation). Row and
column permutations are used for pivoting, gaussian transformations are used
for eliminating subdiagonal elements. (See also Chapter 6.)

Each time when RFI routines apply elementary transformations to the matrix
@i{U}, they also apply corresponding inverted transformations to the matrices
@i{H}, @i{V}, @i{P}, and @i{Q} in order to keep main equalities (9.2) and
(9.3). Note that the matrix @i{U} has implicit representation. This means that
all transformations are actually applied to the matrix @i{V}, which differs
from @i{U} only in the order of rows and columns determined by permutation
matrices @i{P} and @i{Q}.

Let's assume that @i{k}th and @i{p}th rows of the matrix @i{U} have been
permuted. In order to compensate this permutation and to keep the equality
(9.3) we should also permute @i{k}th and @i{p}th rows of the permutation matrix
@i{P}. Similarly, if @i{k}th and @i{q}th columns of the matrix @i{U} have been
permuted, @i{k}th and @i{q}th columns of the permutation matrix @i{Q} should be
permuted. Note that rows and columns permutations don't affect on the matrix
@i{V}, i.e. the order of rows and columns of @i{V} is not changed.

Now let's assume that in order to eliminate subdiagonal element
@tex
$u_{ki}$
@end tex
@i{k}th row of the matrix @i{U} multiplied by
@tex
$f = u_{ki}/u_{kk}$
@end tex
(gaussian multiplier) has been subtracted from its @i{i}th row. Because the
matrix @i{U} has implicit representation, this transformation should be
actually applied to the matrix @i{V}, i.e. it is necessary to subtract row
@math{k'} multiplied by @i{f} from row @math{i'}, where row numbers @math{k'}
and @math{i'} can be determined by row numbers @i{k} and @i{i} through
permutation matrices @i{P} and @i{Q}.

This elementary gaussian transformation of the matrix @i{V} is equivalent to
multiplying the following elementary matrix
@tex
$\Phi$
@end tex
from the left on the matrix @i{V}:
@tex
$$\Phi =
\pmatrix
{
1 \cr
& \ddots \cr
& & 1 \cr
& & & 1 \cr
& -f_{i'k'} & & & 1 \cr
& & & & & \ddots \cr
& & & & & & 1 \cr
}, \eqno (9.4)
$$
@end tex
At the same time in order to keep the equality (9.2) we should multiply the
matrix
@tex
$\Phi^{-1}$
@end tex
from the right on the matrix @i{H}, where
@tex
$\Phi^{-1}$
@end tex
is the following:
@tex
$$\Phi^{-1} =
\pmatrix
{
1 \cr
& \ddots \cr
& & 1 \cr
& & & 1 \cr
& +f_{i'k'} & & & 1 \cr
& & & & & \ddots \cr
& & & & & & 1 \cr
}, \eqno (9.5)
$$
@end tex
And so far the matrix @i{H} has the from of eta file, this multiplication is
equivalent to adding new eta term, which
@tex
$\Phi^{-1}$
@end tex
is (for details see Chapter 5).

If it is required to initially compute RFI for the given basis matrix @i{B},
RFI routines just set @math{H = P = Q = I, V = B}, and apply general gaussian
elimination procedure in order to transform the matrix @math{U = V} to upper
triangular form.

Now let there is the current basis matrix @i{B}, for which the RFI
representation (9.1)---(9.3) is already known. Let also @math{@overline{B}} is
the adjacent basis matrix, which differs from @i{B} only in @i{p}th column
@tex
$B_p.$
@end tex
From (9.2) it follows that
@tex
$$\overline{B} = H\overline{V}, \eqno (9.6)$$
@end tex
where @math{@overline{V}} also differs from @i{V} only in one @i{p}th column
@tex
$V_p.$
@end tex
Moreover,
@tex
$B_p = HV_p,$
@end tex
therefore
@tex
$$V_p = H^{-1}B_p. \eqno (9.7)$$
@end tex

Thus, replacing @i{p}th column of the matrix @i{V} on new column
@tex
$V_p$
@end tex
(9.7) automatically gives the representation (9.1)---(9.3) for the adjacent
basis matrix @math{@overline{B}}. However, it also involves that the matrix
@i{U} becomes not upper triangular. In order to restore upper triangular form
of @i{U} the general gaussian elimination procedure could be used. On the other
hand, it is obvious that new matrix @i{U} has the special structure, because it
differs from upper triangular matrix only in one column (in fact, this matrix
has the same rows and columns as the matrix @i{V}, only in other order). Due to
this updating RFI can be performed more efficiently if to use special versions
of gaussian elimination like Bartels---Golub or Forrest---Tomlin techniques
(see Subsections 6.1.2 and 6.1.3).

Comparing RFI and PFI (see Chapter 4) it may be noted that RFI is generally
able to producesparser representation, because it allows pivoting on
reinverting as well as on updating the representation unlike PFI, which allows
pivoting only on reinverting the representation.

From (9.2)---(9.3) it follows that
@tex
$B^{-1} = V^{-1}H^{-1}$
@end tex
and @footnote{
@tex
$B^{-T}$ means $(B^T)^{-1}$
@end tex
}
@tex
$B^{-T} = H^{-T}V^{-T},$ where $V^{-1} = QU^{-1}P$ and
$V^{-T} = P^{-1}U^{-T}Q^{-1}.$
@end tex
Therefore forward and backward transformations can be efficiently performed by
solving systems with matrices of easy structures.

RFI is defined by the following structure:

@tpindex{RFI}
@example
      typedef struct RFI RFI;
      @{     int m;
            HFILE *H;
            MAT *V;
            PER *P;
            PER *Q;
            int nzH0;
            int nzV0;
            int reid;
            int tech;
            double col[1+m];
            int flag;
            DUFF *rs, cs;
            double work[1+m];
      @};
@end example

@noindent
where:
@table @code
@item m
order of basis matrix @i{B};
@item H
matrix @i{H} in the form eta file;
@item V
matrix @i{V} in the sparse format;
@item P
left permutation matrix @i{P};
@item Q
right permutation matrix @i{Q};
@item nzH0
size of the matrix @i{H} (number of eta terms) at the last reinversion;
@item nzV0
size of the matrix @i{V} (number of non-zeros) at the last reinversion;
@item reid
if this flag is set, Reid's technique is used in order to minimize the bump of
the matrix @math{U = PVQ} on updating the representation (see Subsection
6.1.4);
@item tech
updating technique flag:
@table @code
@item RFI_BG
use Bartels---Golub updating technique (see Subsection 6.1.3);
@item RFI_FT
use Forrest---Tomlin updating technique (see Subsection 6.1.4).
@end table
@item col
partially transformed column
@tex
$V_p$
@end tex
(9.7), which has to be used on updating RFI for adjacent basis matrix
@math{@overline{B}};
@item flag
column flag (this flag is reset to 0 after each updating RFI):
@table @asis
@item 0
column
@tex
$V_p$
@end tex
is not ready yet;
@item 1
column
@tex
$V_p$
@end tex
is ready for updating.
@end table
@item rs, cs
Duff schemes used on building the representation by means of the @code{gel}
routine (see Subsection 6.1.2).
@item work
working storage.
@end table

(The column
@tex
$V_p$
@end tex
is an intermediate result, which appears on performing forward transformation
of column of that non-basis variable, which enters the adjacent basis. In case
of the primal simplex method that transformed column is used on choosing basis
variables that leaves the current basis, therefore keeping
@tex
$V_p$
@end tex
after forward transformation allows not to compute this column on subsequent
updating RFI.)

@section @code{create_rfi} --- create RFI
@fnindex{create_rfi}

@subsubheading Synopsis

@example
#include "glprfi.h"
RFI *create_rfi(int m);
@end example

@subsubheading Description

The @code{create_rfi} routine creates RFI (9.1)---(9.3) for representing basis
matrix of order @i{m}. Initially RFI corresponds to unity matrix, i.e.
@math{H = V = P = Q = I}.

@subsubheading Returns

The @code{create_rfi} routine returns a pointer to the created RFI.

@section @code{build_rfi} --- build RFI for given basis matrix
@fnindex{build_rfi}

@subsubheading Synopsis

@example
#include "glprfi.h"
int build_rfi(RFI *rfi, MAT *A, indb[]);
@end example

@subsubheading Description

The @code{build_rfi} routine builds RFI for the given basis matrix @i{B} (see
below) in the form (9.1)---(9.3). It sets @math{H = P = Q = I} (unity matrix)
and @math{V = B} and then calls the @code{gel} routine (see Subsection 6.1.1)
in order to transform the matrix @math{U = PVQ} to upper triangular form by
means of gaussian elimination. This operation is usually performed if the
current RFI becomes inaccurate or too large, or the basis matrix is completely
changed.

The basis matrix @i{B} is specified implicitly by means of the sparse matrix
@i{A} and the list of basis columns @code{indb}. The matrix @i{A} should have
@i{m} rows, where @i{m} is order of basis matrix. Locations @code{indb[1]},
@code{indb[2]}, @dots{}, @code{indb[m]} should contain numbers of basis columns
of the matrix @i{A}, which specify the basis matrix @i{B}.

@subsubheading Returns

If RFI has been successfully built, the @code{build_rfi} routine returns zero.
Otherwise, if the matrix @i{B} is singular or ill conditioned, the routine
returns non-zero. In the latter case partial LU factorization can be used for
further analysis of the matrix @i{B} (for details see Chapter 6).

@section @code{update_rfi} --- update RFI for adjacent basis matrix
@fnindex{update_rfi}

@subsubheading Synopsis

@example
#include "glprfi.h"
int update_rfi(RFI *rfi, int p);
@end example

@subsubheading Description

The @code{update_rfi} routine recomputes RFI, which @code{rfi} points to and
which corresponds to the current basis matrix @i{B}, in order that it
corresponds to the adjacent basis matrix @math{@overline{B}} (see Subsection
9.1).

The parameter @code{p} specifies the number of column of the basis matrix
@i{B}, which is replaced by new column of the adjacent basis matrix
@math{@overline{B}}.

New basis column is passed implicitly. The @code{update_rfi} routine assumes
that new basis column was prepared before by means of the @code{rfi_ftran}
routine (see Section 4.5).

@subsubheading Returns

The @code{update_rfi} routine returns one of the following error codes:
@table @asis
@item 0
RFI has been successfully updated;
@item 1
RFI is inaccurate;
@item 2
RFI is too large.
@end table

In case of non-zero error code the calling program should reinvert the basis
matrix by means of the @code{build_rfi} routine (see Section 9.3).

@section @code{rfi_ftran} --- perform forward transformation (FTRAN)
@fnindex{rfi_ftran}

@subsubheading Synopsis

@example
#include "glprfi.h"
double *rfi_ftran(RFI *rfi, double z[], int save);
@end example

@subsubheading Description

The @code{rfi_ftran} routine performs so called @dfn{forward transformation
(FTRAN)} of a given vector, i.e. it solves the system @math{Bz' = z}, where
@i{B} is the current basis matrix represented by RFI, which @code{rfi} points
to.

On entry the array @code{z} should contain elements of the input vector @i{z}
in locations @code{z[1]}, @code{z[2]}, @dots{}, @code{z[m]}, where @i{m} is
order of the basis matrix. On exit the array @code{z} contains elements of the
transformed vector @math{z'} in the same locations.

The parameter @code{save} is a flag. If this flag is set, it means that the
input vector @i{z} is a column corresponding to non-basis variable, which has
been chosen to enter the basis. In this case the @code{rfi_ftran} routine saves
the partially transformed column
@tex
$V_p$
@end tex
(see (9.7)) in order that it could be used later by the @code{update_rfi}
routine (see Section 9.4) on updating RFI. It is assumed that the calling
program performs at least one call to the @code{rfi_ftran} routine with the
@code{save} flag set.

@subsubheading Returns

The @code{rfi_ftran} routine returns a pointer to the array @code{z}.

@section @code{rfi_btran} --- perform backward transformation (BTRAN)
@fnindex{rfi_btran}

@subsubheading Synopsis

@example
#include "glprfi.h"
double *rfi_btran(RFI *rfi, double z[]);
@end example

@subsubheading Description

The @code{rfi_btran} routine performs so called @dfn{backward transformation
(BTRAN)} of a given vector, i.e. it solves the system
@tex
$B^Tz' = z,$
@end tex
where @i{B} is the current basis matrix represented by RFI, which @code{rfi}
points to.

On entry the array @code{z} should contain elements of the input vector @i{z}
in locations @code{z[1]}, @code{z[2]}, @dots{}, @code{z[m]}, where @i{m} is
order of the basis matrix. On exit the array @code{z} contains elements of the
transformed vector @math{z'} in the same locations.

@subsubheading Returns

The @code{rfi_ftran} routine returns a pointer to the array @i{z}.

@section @code{delete_rfi} --- delete RFI
@fnindex{delete_rfi}

@subsubheading Synopsis

@example
#include "glprfi.h"
void delete_rfi(RFI *rfi);
@end example

@subsubheading Description

The @code{delete_rfi} routine deletes RFI, which @code{rfi} points to, freeing
all the memory allocated to this object.

@unnumberedsec References

@enumerate 1
@item
@i{J. K. Reid.} A Sparsity Exploiting Variant of the Bartels---Golub
Decomposition for Linear Programming Bases. Mathematical Programming, 24,
@w{pp. 55---69}, 1982.
@end enumerate

@chapter GLPSET: Auxiliary Routines

This chapter describes auxiliary routines, which are used by most other GLPK
routines. However, these routines may be useful from the user's point of view.

@section Communicative Routines

GLPK includes three communicative routines, which are used by all other GLPK
routines. The communicative routines were introduced to the package mainly in
order to provide its portability on other platforms that differ from the
standard C environment. For example, all GLPK routines report error messages by
means of the @code{error} routine, which in case of the standard C environment
sends an error message to @code{stderr}. Therefore the user can easily change
such behavior of GLPK routines replacing the @code{error} routine by its own
version, which, for example, sends a message to the error window instead
@code{stderr}. Of course, if the user makes such replacement, it should keep
the external behavior of the original communicative routines.

@subsection @code{print} --- print informative message
@fnindex{print}

@subsubheading Synopsis

@example
#include "glpset.h"
void print(char *fmt, ...);
@end example

@subsubheading Description

The @code{print} routine sends an informative message specified by the format
control string @code{fmt} and variable parameter list to the standard output
(@code{stdout}). Note that the @code{print} routine automatically appends
@code{LF} control character to the end of output.

@subsection @code{error} --- print error message and continue program execution
@fnindex{error}

@subsubheading Synopsis

@example
#include "glpset.h"
void error(char *fmt, ...);
@end example

@subsubheading Description

The @code{error} routine sends an error message specified by the format control
string @code{fmt} and variable parameter list to @code{stderr} and returns to
the calling program. Note that the error routine automatically appends
@code{LF} control character to the end of output.

@page
@subsection @code{fault} --- print error message and terminate program execution
@fnindex{fault}

@subsubheading Synopsis

@example
#include "glpset.h"
void fault(char *fmt, ...);
@end example

@subsubheading Description

The @code{fault} routine sends an error message specified by the format control
string @code{fmt} and variable parameter list to @code{stderr} and abnormally
terminates execution of the program. Note that the @code{fault} routine
automatically appends @code{LF} control character to the end of output.

@section Memory Management Routines

GLPK includes three low level memory management routines @code{umalloc},
@code{ucalloc}, and @code{ufree}, which are used by all other GLPK routines
instead the standard C routines @code{malloc}, @code{calloc}, and @code{free}
respectively. These routines were introduced to the package in order to:
a) simplify error handling (if there is no free memory, @code{umalloc} and
@code{ucalloc} just report an error and abnormally terminate execution of the
program); and b) provide some additional features (see below), which are not
supported by the standard C routines.

Each memory block allocated by @code{umalloc} and @code{ucalloc} routines
includes a prefix, which is called @dfn{memory block descriptor}. This
descriptor has the following format:

@tpindex{mem_desc}
@example
      struct mem_desc
      @{     int size;
            int flag;
            /* actual data */
      @};
@end example

@noindent
where:
@table @code
@item size
total size of a memory block (including descriptor) in bytes;
@item flag
descriptor flag (a value, which is used by the @code{ufree} routine for
checking whether a pointer to memory block is valid).
@end table

Actual data of variable size, a pointer to which is returned by the
@code{umalloc} and @code{ucalloc} routines, are placed immediately after the
memory block descriptor.

There are also several external variables that are related to dynamic memory
allocation. These variables are the following:

@table @code
@item int mem_flag;
@vrindex{mem_flag}
a value used as the memory block descriptor flag;
@item int mem_limit;
@vrindex{mem_limit}
maximal amount of memory (in bytes), which is available for dynamic allocation.
Initially this variable is set to @code{INT_MAX}. The user may decrease this
value, for example, in order to prevent abnormal page swapping on virtual
memory systems if the storage required by the program exceeds amount of the
real memory (in this case @code{mem_limit} should be set to 80-90% of amount of
available real memory);
@item int mem_total;
@vrindex{mem_total}
total amount of memory (in bytes), which is currently allocated. This value is
the sum of @code{size} fields of all memory block descriptors and may be used
for statistics;
@item int mem_tpeak;
@vrindex{mem_tpeak}
peak value of @code{mem_total} reached during program execution. This value may
be used for statistics;
@item int mem_count;
@vrindex{mem_count}
total number of currently allocated memory block. This value may be used for
statistics;
@item int mem_cpeak;
@vrindex{mem_cpeak}
peak value of @code{mem_count} reached during program execution. This value may
be used for statistics.
@end table

The application program should not change these external variables (except
@code{mem_limit}).

@subsection @code{umalloc} --- allocate memory block
@fnindex{umalloc}

@subsubheading Synopsis

@example
#include "glpset.h"
void *umalloc(int size);
@end example

@subsubheading Description

The @code{umalloc} routine allocates a memory block of @code{size} bytes long
and clears this block by binary zeros. Failure of the operation involves
abnormal program termination.

@subsubheading Returns

The @code{umalloc} routine returns a pointer to the allocated memory block. In
order to free this block the @code{ufree} routine (not @code{free}!) should be
used (see Subsection 10.2.3).

@subsection @code{ucalloc} --- allocate memory block
@fnindex{ucalloc}

@subsubheading Synopsis

@example
#include "glpset.h"
void *ucalloc(int nmemb, int size);
@end example

@subsubheading Description

The @code{ucalloc} routine allocates a memory block of
@code{nmemb}@math{@times{}}@code{size} bytes long and clears this block by
binary zeros. Failure of the operation involves abnormal program termination.

@subsubheading Returns

The @code{umalloc} routine returns a pointer to the allocated memory block. In
order to free this block the @code{ufree} routine (not @code{free}!) should be
used (see Subsection 10.2.3).

@subsection @code{ufree} --- free memory block
@fnindex{ufree}

@subsubheading Synopsis

@example
#include "glpset.h"
void ufree(void *ptr);
@end example

@subsubheading Description

The @code{ufree} routine frees the memory block, which @code{ptr} points to and
which was previously allocated by the @code{umalloc} or the @code{ucalloc}
routine (see Subsections 10.2.1 and 10.2.2).

@section Memory Pools

In many applications it is necessary to organize information in the form of
linked lists. Such data structures require specific memory allocation, because
they usually consist of a lot of elementary data blocks of small size (several
tens of bytes or even less). This makes use of the standard routines like
@code{malloc} and @code{free} to be inefficient, because small size of data
blocks involves high overhead expenses and may cause pathological fragmentation
of the main memory. Therefore in order to avoid this negative phenomenon many
GLPK routines organize data structures using so called memory pools.

@dfn{Memory pool} is an auxiliary data structure, which allows allocating and
freeing atoms (i.e. elementary data blocks) of fixed size for a fixed time.

Each memory pool includes three linked lists:

the list of free atoms;

the list of free blocks;

the list of used blocks.

In order to allocate an atom the memory pool routine looks through the list of
free atoms. This operation requires a fixed time, because all atoms have the
same size, so the first free atom is fitted. If the list of free atoms is
empty, the routine pulls the first free block (all blocks have the same large
enough size) and splits it into free atoms. Free blocks are drawn from the list
of free blocks or, if it is empty, allocated by means of the @code{umalloc}
routine (see Subsection 10.2.1). In both cases the routine pushes the block to
the list of used blocks. In order to free an atom the memory pool routine just
returns it to the list of free atoms. Note that the total amount of memory
allocated to a pool always increases and never decreases (until the pool will
be deleted).

Memory pools give the following two main advantages: allocating and freeing
atoms require a fixed time, because all atoms have the same size; overhead
expenses and memory fragmentation remain low, because all blocks allocated by
the control program (operating system) have the same large enough size.

Memory pools also may hold atoms of variable (different) size. However, in this
case atoms can't be freed separately; it is allowed freeing only all atoms at
the same time. Such pools may be used in that cases, when information is only
added to data structures, but not removed.

Memory pools are described by the @code{POOL} structure:

@tpindex{POOL}
@example
      typedef struct POOL POOL;
      struct POOL
      @{     int size;
            void *avail;
            void *link;
            int used;
            void *stock;
            int count;
      @};
@end example

@noindent
where:
@table @code
@item size
if atoms are of fixed size, this field contains the size of atom
@math{(1 @leq{} size @leq{} 256)}. If atoms are of variable size, this field
contains zero;
@item avail
pointer to the list of free atoms;
@item link
pointer to the list of used blocks (it points to the last recently allocated
block, which may have free space for allocating free atoms);
@item used
number of bytes used in the block, which @code{link} points to;
@item stock
pointer to the list of free blocks;
@item count
total number of allocated atoms (i.e. of atoms, which belong to this pool, but
missing from the list of free atoms).
@end table

@noindent
Remarks.
@enumerate 1
@item
The first @code{sizeof(void *)} bytes of each free atom contain a pointer to
the previous free atom.
@item
The first @code{sizeof(void *)} bytes of each used (free) block contain a
pointer to the previous used (free) block.
@item
All blocks have the same size defined by the preprocessor variable
@code{POOL_SIZE}.
@end enumerate

@subsection @code{create_pool} --- create memory pool
@fnindex{create_pool}

@subsubheading Synopsis

@example
#include "glpset.h"
POOL *create_pool(int size);
@end example

@subsubheading Description

The @code{create_pool} routine creates an empty memory pool, which holds no
atoms. The parameter @code{size} specifies size of atoms in bytes. If
@math{1 @leq{}} @code{size} @math{@leq{} 256}, all atoms are of @code{size}
bytes long. If @code{size} = 0, atoms may have different size.

@subsubheading Returns

The @code{create_pool} routine returns a pointer to the created memory pool.

@subsection @code{get_atom} --- allocate atom of fixed size
@fnindex{get_atom}

@subsubheading Synopsis

@example
#include "glpset.h"
void *get_atom(POOL *pool);
@end example

@subsubheading Description

The @code{get_atom} routine allocate an atom from the specified memory
@code{pool} and clears the atom by binary zeros. The size of atom should be
specified on creating the pool (see Subsection 10.3.1).

@subsubheading Complexity

This operation has time complexity @math{O(1)}.

@subsubheading Returns

The @code{get_atom} routine returns a pointer to the allocated atom.

@subsection @code{free_atom} --- free atom
@fnindex{free_atom}

@subsubheading Synopsis

@example
#include "glpset.h"
void free_atom(POOL *pool, void *ptr);
@end example

@subsubheading Description

The @code{free_atom} routine frees the atom, which @code{ptr} points to,
returning it to the list of free atoms of the specified memory @code{pool}. It
is assumed that the atom was allocated from the same memory pool by means of
the @code{get_atom} routine (see Subsection 10.3.2); otherwise the behavior is
undefined.

@subsubheading Complexity

This operation has time complexity @math{O(1)}.

@subsection @code{get_atomv} --- allocate atom of variable size
@fnindex{get_atomv}

@subsubheading Synopsis

@example
#include "glpset.h"
void *get_atomv(POOL *pool, int size);
@end example

@subsubheading Description

The @code{get_atomv} routine allocates an atom from the specified memory
@code{pool} and clears the atom by binary zeros. The pool should be created by
the @code{create_pool} routine (see Subsection 10.3.1) with @code{size} = 0.
The actual size of atom in bytes is specified by the parameter @code{size},
which should be positive and not greater than 256.

@subsubheading Complexity

This operation has time complexity @math{O(1)}.

@subsubheading Returns

The @code{get_atomv} routine returns a pointer to the allocated atom.

@subsection @code{clear_pool} --- free all atoms
@fnindex{clear_pool}

@subsubheading Synopsis

@example
#include "glpset.h"
void clear_pool(POOL *pool);
@end example

@subsubheading Description

The @code{clear_pool} routine free all atoms that belong to the specified
memory @code{pool} and were allocated by means of the routines
@code{get_atom} or @code{get_atomv} (see Subsection 10.3.2 and 10.3.4).

Note that the routine performs this operation just moving all used (allocated)
blocks to the list of free blocks, hence no memory block are returned to the
control program (operating system).

@subsection @code{delete_pool} --- delete memory pool
@fnindex{delete_pool}

@subsubheading Synopsis

@example
#include "glpset.h"
void delete_pool(POOL *pool);
@end example

@subsubheading Description

The @code{clear_pool} routine deletes the specified memory @code{pool}, freeing
all the memory allocated to this object.

@chapter GLPSTR: Operations on Charater Strings

@section Ordinary Character Strings

This section describes routines, which perform some operations on ordinary
character strings and complement standard C routines.

@subsection @code{str2int} --- convert character string to value of integer type
@fnindex{str2int}

@subsubheading Synopsis

@example
#include "glpstr.h"
int str2int(char *str, int *val);
@end example

@subsubheading Description

The @code{str2int} routine converts the character string @code{str} to a value
of integer type and stores this value to the location, which @code{val} points
to. In case of error the location remains unchanged.

@subsubheading Returns

The @code{str2int} routine returns one of the following error codes:
@table @asis
@item 0
no error;
@item 1
value is out of range;
@item 2
character string is syntactically incorrect.
@end table

@subsection @code{str2dbl} --- convert character string to value of double type
@fnindex{str2dbl}

@subsubheading Synopsis

@example
#include "glpstr.h"
int str2dbl(char *str, double *val);
@end example

@subsubheading Description

The @code{str2dbl} routine converts the character string @code{str} to a value
of double type and stores this value to the location, which @code{val} points
to. In case of error the location remains unchanged.

@subsubheading Returns

The @code{str2dbl} routine returns one of the following error codes:
@table @asis
@item 0
no error;
@item 1
value is out of range;
@item 2
character string is syntactically incorrect.
@end table

@subsection @code{strspx} --- remove all spaces from character string
@fnindex{strspx}

@subsubheading Synopsis

@example
#include "glpstr.h"
char *strspx(char *str);
@end example

@subsubheading Description

The @code{strspx} routine removes all space characters from the character
string @code{str}.

@subsubheading Examples

@example
      strspx("   Errare   humanum   est   ") => "Errarehumanumest"
      strspx("      ")                       => ""
@end example

@subsubheading Returns

The @code{strspx} routine returns a pointer to the character string @code{str}.

@subsection @code{strtrim} --- remove trailing spaces from character string
@fnindex{strtrim}

@subsubheading Synopsis

@example
#include "glpstr.h"
char *strtrim(char *str);
@end example

@subsubheading Description

The @code{strtrim} routine removes trailing space characters from the character
string @code{str}.

@subsubheading Examples

@example
      strtrim("Errare humanum est   ") => "Errare humanum est"
      strtrim("      ")                => ""
@end example

@subsubheading Returns

The @code{strtrim} routine returns a pointer to the character string
@code{str}.

@section Segmented Character Strings

@dfn{Segmented character string} is a character string, which is represented in
the form of linked list, where each element of linked list represents a
particular segment of string.

In cases of intensive creating, modifying and deleting character strings during
program execution this data structure allows greatly decreasing loadness on the
system mechanism of dynamic memory allocation. However, this data structure
involves some overhead expenses of main memory, because each linked list
element needs a pointer to the next element.

In order to represent segmented character string on the whole the @code{STR}
structure is used:

@tpindex{STR}
@example
      typedef struct STR STR;
      struct STR
      @{     POOL *pool;
            int len;
            SQE *head;
            SQE *last;
      @};
@end example

@noindent
where:
@table @code
@item pool
memory pool (see Section 10.3) that holds all elements of the string. Note that
the same pool can be shared between several strings;
@item len
current string length, len @math{@geq{}} 0;
@item head
pointer to the first string element;
@item tail
pointer to the last string element.
@end table

A particular element of segmented character string is defined by the structure
@code{SQE}:

@tpindex{SQE}
@example
      typedef struct SQE SQE;
      struct SQE
      @{     char data[SQE_SIZE];
            SQE *next;
      @};
@end example

@noindent
where:
@table @code
@item data
characters allocated in this element;
@item next
pointer to the next string element.
@end table

@noindent
Remarks.
@enumerate 1
@item
Segmented character string may contain any control characters including
@code{NUL} control character (@samp{\0}). This allows representing text data as
well as binary data.
@item
Number of characters allocated in one string element is defined by the
preprocessor variable @code{SQE_SIZE}.
@item
Only the last element of segmented character string can be partially filled,
i.e. there are no "holes" or unnecessary elements.
@item
All freed elements are returned to the memory pool, which is connected with the
corresponding segmented character string.
@end enumerate

@subsection @code{clear_str} --- clear segmented character string
@fnindex{clear_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
STR *clear_str(STR *str);
@end example

@subsubheading Description

The @code{clear_str} routine makes the segmented character string @code{str} be
empty.

@subsubheading Returns

The @code{clear_str} routine returns a pointer to the string @code{str}.

@subsection @code{compare_str} --- compare segmented character strings
@fnindex{compare_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
int compare_str(STR *str1, STR *str2);
@end example

@subsubheading Description

The @code{compare_str} routine lexicographically compares the segmented
character string @code{str1} and @code{str2}. If compared strings have
different length, shorter string is considered as if it would be padded by
binary zeros to the length of longer string.

@subsubheading Returns

The @code{compare_str} returns one of the following values:
@table @asis
@item < 0
@code{str1} lexicographically less than @code{str2};
@item = 0
@code{str1} and @code{str2} are identical;
@item > 0
@code{str1} lexicographically greater than @code{str2}.
@end table

@subsection @code{create_str} --- create segmented character string
@fnindex{create_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
STR *create_str(POOL *pool);
@end example

@subsubheading Description

The @code{create_str} routine creates empty segmented character string.

The parameter @code{pool} should specify a memory pool (see Section 10.3),
which is created by the @code{create_str_pool} routine (see Subsection 11.2.4).
The @code{create_str} routine connects this pool with the created string,
therefore this pool will be used in all subsequent operations on this string.
Note that several strings may use the same memory pool.

@subsubheading Returns

The @code{create_str} routine returns a pointer to the created string.

@page
@subsection @code{create_str_pool} --- create pool for segmented character strings
@fnindex{create_str_pool}

@subsubheading Synopsis

@example
#include "glpstr.h"
POOL *create_str_pool(void);
@end example

@subsubheading Description

The @code{create_str_pool} routine creates a memory pool (see Section 10.3),
which may be used to hold elements of segmented character strings.

In order to free all memory allocated to memory pool the @code{delete_pool}
routine should be used (see Subsection 10.3.6). Note that deleting memory pool
involves deleting all segmented character string, which refer to this pool.

@subsubheading Returns

The @code{create_str_pool} routine returns a pointer to the created memory
pool.

@subsection @code{delete_str} --- delete segmented character string
@fnindex{delete_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
void delete_str(STR *str);
@end example

@subsubheading Description

The @code{delete_str} routine deletes the segmented character string
@code{str}, returning all memory allocated to this string to the corresponding
memory pool.

Note that allocated memory is not returned to the control program (operating
system) while the corresponding memory pool exists.

@subsection @code{get_str} --- extract value of segmented character string
@fnindex{get_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
char *get_str(char *to, STR *str);
@end example

@subsubheading Description

The @code{get_str} routine copies data from the segmented character string
@code{str} to the ordinary character string @code{to}. The array of @code{char}
type, which @code{to} points to, should have at least @math{len+1} characters,
where @i{len} is the current length of the string @code{str}.

@subsubheading Returns

The @code{get_str} routine returns a pointer to the string @code{to}.

@subsection @code{set_str} --- assign value to segmented character string
@fnindex{set_str}

@subsubheading Synopsis

@example
#include "glpstr.h"
STR *set_str(STR *str, char *from);
@end example

@subsubheading Description

The @code{set_str} routine copies data from the ordinary character string
@code{from} to the segmented character string @code{str}.

@subsubheading Returns

The @code{set_str} routine returns a pointer to the string @code{str}.

@unnumbered Index
@printindex cp

@bye
