diff --git a/contrib/kbipack/compute_normal_form.c b/contrib/kbipack/compute_normal_form.c
deleted file mode 100644
index f86e043cc27e27144738acbffcbe7eafd6e7a6b3..0000000000000000000000000000000000000000
--- a/contrib/kbipack/compute_normal_form.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* 
-   COMPUTE_NORMAL_FORM
-
-   Hermite and Smith normal forms of integer matrices. 
-
-   Implementation: Dense matrix with GMP-library's mpz_t elements to 
-                   hold huge integers. 
-
-   Algorithm: Kannan - Bachem algorithm with improvement by
-              Chou and Collins. Expects a large number of unit invariant 
-	      factors and takes advantage of them as they appear.
-
-   References: 
-    [1] Ravindran Kannan, Achim Bachem: 
-        "Polynomial algorithms for computing the Smith and Hermite normal 
-	forms of an integer matrix", 
-	SIAM J. Comput., vol. 8, no. 5, pp. 499-507, 1979.
-    [2] Tsu-Wu J.Chou, George E. Collins: 
-        "Algorithms for the solution of systems of linear Diophantine 
-	equations", 
-	SIAM J. Comput., vol. 11, no. 4, pp. 687-708, 1982.
-    [3] GMP homepage http://www.swox.com/gmp/
-    [4] GNU gmp page http://www.gnu.org/software/gmp/
-
-   Copyright (C) 3.11.2003 Saku Suuriniemi TUT/CEM
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   Saku Suuriniemi, TUT/Electromagetics
-   P.O.Box 692, FIN-33101 Tampere, Finland
-   saku.suuriniemi@tut.fi
-   
-   $Id: compute_normal_form.c,v 1.1 2009-03-30 14:10:57 matti Exp $
-*/
-
-
-#include<stdlib.h>
-#include<stdio.h>
-#include<string.h>
-#include"gmp_matrix_io.h"
-#include"gmp_normal_form.h"
-
-typedef enum {HERMITE, SMITH}     nf_flag;
-typedef enum {NOT_WANTED, WANTED} w_flag;
-
-static int nf_parse_options(int arg_counter, char ** args, 
-			    char ** p_infile_name, char ** p_outfile_name, 
-			    nf_flag *       p_normal_form_requested, 
-			    inverted_flag * p_left_inverted, 
-			    inverted_flag * p_right_inverted, 
-			    w_flag *        p_help_wanted, 
-			    w_flag *        p_verbose_wanted)
-{
-  size_t ind1, ind2;
-  size_t outfilename_length;
-  
-  /* If no infile is specified, the error is indisputable. 
-      => Print help and exit. 
-     Infile should be the last argument. */
-
-  if(strncmp(args[arg_counter-1], "-", 1) == 0)
-    {
-      *(p_help_wanted) = WANTED;
-      return EXIT_SUCCESS;
-    }
-
-  /* Should I find arguments? */
-  if(arg_counter > 2)
-    {
-      for(ind1 = 1; ind1 < arg_counter-1; ind1++)
-	{
-	  /* No multiple infile names ! */
-	  if(strncmp(args[ind1], "-", 1) != 0)
-	    {
-	      *(p_help_wanted) = WANTED;
-	      return EXIT_SUCCESS;
-	    }
-
-	  /* Parse the option letters after '-' one by one */
-	  for(ind2 = 1; ind2 < strlen(args[ind1]); ind2++)
-	    {
-	      switch(args[ind1][ind2])
-		{
-		case 'h':
-		  *(p_help_wanted) = WANTED;
-		  return EXIT_SUCCESS;
-		  break;
-		case 'H':
-		  *(p_normal_form_requested) = HERMITE;
-		  break;
-		case 'S':
-		  *(p_normal_form_requested) = SMITH;
-		  break;
-		case 'l':
-		  *(p_left_inverted) = INVERTED;
-		  break;
-		case 'r':
-		  *(p_right_inverted) = INVERTED;
-		  break;
-		case 'v':
-		  *(p_verbose_wanted) = WANTED;
-		  break;
-		}
-	    }	  
-	}
-    }
-
-  /* Get the infile name */
-  * p_infile_name = (char *) calloc(strlen(args[arg_counter-1]) + 1, 
-				    sizeof(char));
-  if(* p_infile_name == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  strcpy(* p_infile_name, args[arg_counter-1]);
-
-  /* Create the outfile name */
-  outfilename_length = strcspn( * p_infile_name, ".");
-  * p_outfile_name = (char *) calloc(outfilename_length + 1, 
-				     sizeof(char));
-  if( * p_outfile_name == NULL)
-    {
-      free( * p_infile_name);
-      return EXIT_FAILURE;
-    }
-
-  strncpy(* p_outfile_name, * p_infile_name, outfilename_length);
-  (* p_outfile_name)[outfilename_length] = '\0';
-
-  return EXIT_SUCCESS;
-}
-
-static int nf_print_help(void)
-{
-  fprintf(stdout, "Usage: compute_normal_form [-hHSlrv] infile\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Description: Compute the Hermite/Smith normal form of an integer matrix.\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Input: \"infile\" is an ascii file, which contains an integer matrix\n");
-  fprintf(stdout, "       in the sparse coordinate format:\n"); 
-  fprintf(stdout, "\n");
-  fprintf(stdout, "        # All comments before the data\n");
-  fprintf(stdout, "        rows columns nonzeros\n");
-  fprintf(stdout, "        row1 col1    value1\n");
-  fprintf(stdout, "        row2 col2    value2\n");
-  fprintf(stdout, "        ...\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "       No multiple infiles, please.\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Options: -h This help\n");
-  fprintf(stdout, "         -H Compute the Hermite normal form (default)\n");
-  fprintf(stdout, "         -S Compute the Smith normal form\n");
-  fprintf(stdout, "         -l Left factor inverted (A = P^(T)LU instead of PA = LU for Hermite, \n");
-  fprintf(stdout, "                                  U^(-1)A = SV instead of A = USV for Smith)\n");
-  fprintf(stdout, "         -r Right factor inverted (PAU^(-1) = L instead of PA = LU for Hermite, \n");
-  fprintf(stdout, "                                   AV^(-1) = US instead of A = USV for Smith)\n");
-  fprintf(stdout, "         -v Verbose. Print the matrix and the decomposition to sdtout, \n");
-  fprintf(stdout, "                     so that the user may check that the problem is read and written\n");
-  fprintf(stdout, "                     correctly.\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Output: For inpur matrix in e.g. \"infile.coord\", writes ascii files\n");
-  fprintf(stdout, "        \"infile.left\", \"infile.can\", and \"infile.right\", which \n");
-  fprintf(stdout, "        contain the left factor, canonical form, and the right factor, \n");
-  fprintf(stdout, "        respectively. The matrices are written in the sparse coordinate\n");
-  fprintf(stdout, "        format.\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Note: The return values may be big enough to not fit the standard integer types.\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Copyright (C) 3.11.2003 Saku Suuriniemi, Tampere University of Technology/Electromagnetics\n");
-  fprintf(stdout, "                        P.O.Box 692, FIN-33101 Tampere, Finland. saku.suuriniemi@tut.fi\n");
-  fprintf(stdout, "\n");
-  fprintf(stdout, "Licenced under GNU General Public Licence (GPL) version 2 or later, ABSOLUTELY NO WARRANTY.\n");
-
-  return EXIT_SUCCESS;
-}
-
-
-static char* append_suffix(const char * file_base_name, const char * suffix)
-{
-  char * filename;
-
-  if((file_base_name == NULL) || (suffix == NULL))
-    {
-      return NULL;
-    }
-
-  filename = 
-    (char*) calloc(strlen(file_base_name)+strlen(suffix)+2,
-		   sizeof(char));
-
-  if(filename == NULL)
-    {
-      return NULL;
-    }
-
-  strcpy(filename, file_base_name);
-  strcat(filename, ".");
-  strcat(filename, suffix);
-
-  return filename;
-}
-
-
-
-int main(int argc, char * argv[])
-{
-  char            * infile_name;
-  char            * file_base_name;
-  char            * outfile_name;
-  gmp_matrix      * A;
-  gmp_normal_form * normal_form;
-  w_flag            help_wanted;
-  w_flag            verbose_wanted;
-  nf_flag           normal_form_requested;
-  inverted_flag     left_inverted;
-  inverted_flag     right_inverted;
-
-  if(argc == 1)
-    {
-      fprintf(stdout, "Please try \"compute_normal_form -h\" for help.\n");
-      return EXIT_SUCCESS;
-    }
-
-  /* Default settings before option parsing */
-  normal_form_requested = HERMITE;
-  left_inverted         = NOT_INVERTED;
-  right_inverted        = NOT_INVERTED;
-  help_wanted           = NOT_WANTED;
-  verbose_wanted        = NOT_WANTED;
-
-  if( nf_parse_options(argc, argv, 
-		       &infile_name, &file_base_name, 
-		       &normal_form_requested, 
-		       &left_inverted, &right_inverted, 
-		       &help_wanted, 
-		       &verbose_wanted) 
-      == EXIT_FAILURE )
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* In this case, no dynamical memory has been allocated by 
-     nf_parse_options ! */
-  if(help_wanted == WANTED)
-    {
-      return nf_print_help();
-    }
-
-  if(verbose_wanted == WANTED)
-    {
-      fprintf(stdout, "Computing ");
-      if(normal_form_requested == HERMITE)
-	{
-	  fprintf(stdout, "Hermite");
-	}
-      else
-	{
-	  fprintf(stdout, "Smith");
-	}
-      fprintf(stdout, " normal form\n");
-      if(left_inverted == INVERTED)
-	{
-	  fprintf(stdout, "The left factor will be inverted.\n");
-	}
-      if(right_inverted == INVERTED)
-	{
-	  fprintf(stdout, "The right factor will be inverted.\n");
-	}
-      fprintf(stdout, "Matrix read from file %s\n", infile_name);
-    }
-
-  /*************************************************************/
-  /* We have all we need to get to the computational business: */
-  /*************************************************************/
-
-  /* Read the matrix */
-  A = gmp_matrix_read_coord(infile_name);
-  free(infile_name);
-
-  if(verbose_wanted == WANTED)
-    {
-      fprintf(stdout, "Input matrix:\n");
-      gmp_matrix_fprintf(stdout, A);
-    }
-
-  /* Compute the requested normal form */
-  switch(normal_form_requested)
-    {
-    case SMITH:
-      normal_form = create_gmp_Smith_normal_form(A, left_inverted, right_inverted);
-      break;
-
-    default:
-      normal_form = create_gmp_Hermite_normal_form(A, left_inverted, right_inverted);
-      break;
-    }
-
-
-  if(verbose_wanted == WANTED)
-    {
-      fprintf(stdout, "Left factor:\n");
-      gmp_matrix_fprintf(stdout, normal_form->left);
-      fprintf(stdout, "Canonical form:\n");
-      gmp_matrix_fprintf(stdout, normal_form->canonical);
-      fprintf(stdout, "Right factor:\n");
-      gmp_matrix_fprintf(stdout, normal_form->right);
-    }
-
-  /* Save the result to the output files */
-  outfile_name = append_suffix(file_base_name, "left");
-  if( gmp_matrix_write_coord(outfile_name, normal_form -> left) 
-      == EXIT_SUCCESS)
-    {
-      if(verbose_wanted == WANTED)
-	fprintf(stdout, "Left factor successfully writen to file     %s\n", outfile_name);
-    }
-
-  free(outfile_name);
-
-  outfile_name = append_suffix(file_base_name, "can");
-  if( gmp_matrix_write_coord(outfile_name, normal_form -> canonical)
-      == EXIT_SUCCESS)
-    {
-      if(verbose_wanted == WANTED)
-	fprintf(stdout, "Canonical form successfully writen to file  %s\n", outfile_name);
-    }
-  free(outfile_name);
-
-  outfile_name = append_suffix(file_base_name, "right");
-  if( gmp_matrix_write_coord(outfile_name, normal_form -> right)
-      == EXIT_SUCCESS)
-    {
-      if(verbose_wanted == WANTED)
-	fprintf(stdout, "Right factor successfully writen to file    %s\n", outfile_name);
-    }
-  free(outfile_name);
-
-  free(file_base_name);
-  destroy_gmp_normal_form(normal_form);
-  
-  return EXIT_SUCCESS;
-}
diff --git a/contrib/kbipack/gmp_blas.c b/contrib/kbipack/gmp_blas.c
deleted file mode 100644
index 6003888d5b67598c71dd23a44d50e5702f2c0feb..0000000000000000000000000000000000000000
--- a/contrib/kbipack/gmp_blas.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* 
-   Source file for integer-oriented elementary versions of some 
-   subroutines of BLAS. There routines are chosen to facilitate the 
-   computation of Hermite and Smith normal forms of matrices of 
-   modest size. 
-
-   Copyright (C) 28.10.2003 Saku Suuriniemi TUT/CEM
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   Saku Suuriniemi, TUT/Electromagetics
-   P.O.Box 692, FIN-33101 Tampere, Finland
-   saku.suuriniemi@tut.fi
-
-   $Id: gmp_blas.c,v 1.1 2009-03-30 14:10:57 matti Exp $
-*/
-
-/* #include<stdio.h> */
-#include"gmp_blas.h"
-
-void gmp_blas_swap(size_t n, mpz_t* x, size_t incx, mpz_t* y, size_t incy)
-{
-  mpz_t  elbow;
-  size_t ind;
-
-  mpz_init(elbow);
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_set(elbow      , x[ind*incx]);
-      mpz_set(x[ind*incx], y[ind*incy]);
-      mpz_set(y[ind*incy], elbow);
-    }
-  mpz_clear(elbow);
-
-  return;
-}
-
-void gmp_blas_scal(size_t n, mpz_t a, mpz_t* x, size_t incx)
-{
-  size_t ind;
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_mul (x[ind*incx], x[ind*incx], a);
-    }
-
-  return;
-}
-
-void gmp_blas_copy(size_t n, const mpz_t* x, size_t incx, mpz_t* y, size_t incy)
-{
-  size_t ind;
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_set(y[ind*incy], x[ind*incx]);
-    }
-
-  return;
-}
-
-void gmp_blas_axpy(size_t n, mpz_t a, const mpz_t* x, size_t incx, 
-		   mpz_t* y, size_t incy)
-{
-  size_t ind;
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_addmul (y[ind*incy], a, x[ind*incx]);
-    }
-
-  return;
-}
-
-void
-gmp_blas_dot(mpz_t * d, size_t n, 
-	     const mpz_t* x, size_t incx, 
-	     const mpz_t* y, size_t incy)
-{
-  size_t ind;
-
-  mpz_set_si(*d,0);
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_addmul (*d, x[ind*incx], y[ind*incy]);
-    }
-
-  return;  
-}
-
-/* x <- ax + by 
-   y <- cx + dy */
-void gmp_blas_rot(size_t n, 
-		  mpz_t a, mpz_t b, mpz_t* x, size_t incx, 
-		  mpz_t c, mpz_t d, mpz_t* y, size_t incy)
-{
-  mpz_t  ax;
-  mpz_t  by;
-  mpz_t  cx;
-  mpz_t  dy;
-
-  size_t ind;
-
-  mpz_init(ax);
-  mpz_init(by);
-  mpz_init(cx);
-  mpz_init(dy);
-
-  for(ind = 0; ind < n; ind++)
-    {
-      mpz_mul (ax, a, x[ind*incx]);
-      mpz_mul (by, b, y[ind*incy]);
-      mpz_mul (cx, c, x[ind*incx]);
-      mpz_mul (dy, d, y[ind*incy]);
-      mpz_add (x[ind*incx], ax, by);
-      mpz_add (y[ind*incy], cx, dy);
-    }
-
-  mpz_clear(ax);
-  mpz_clear(by);
-  mpz_clear(cx);
-  mpz_clear(dy);
-
-  return;
-}
-
-
-/* Returns k such that x[(k-1)*incx] != 0 holds for the first time. 
-   If none found, returns n+1. */
-size_t gmp_blas_inz  (size_t n, const mpz_t* x, size_t incx)
-{
-  size_t ind;
-
-  for(ind = 0; ind < n; ind++)
-    {
-      if(mpz_sgn (x[ind*incx]) != 0)
-	{  
-	  return ind+1; 
-	}
-    }
-
-  /* No nonzeros found */
-  return n+1; 
-}
-
-size_t gmp_blas_iamax(size_t n, const mpz_t* x, size_t incx)
-{
-  size_t ind;
-  size_t ind_so_far;
-  mpz_t  max_so_far;
-
-  mpz_init(max_so_far);
-  mpz_set_si(max_so_far, 0);
-  ind_so_far = 0;
-
-  for(ind = 0; ind < n; ind++)
-    {
-      if(mpz_cmpabs (x[ind*incx], max_so_far) > 0)
-	{  
-	  mpz_set(max_so_far, x[ind*incx]);
-	  ind_so_far = ind;
-	}
-    }
-
-  /* No nonzeros found */
-  if(mpz_sgn (max_so_far) == 0)
-    {
-      mpz_clear(max_so_far);
-      return n + 1; 
-    }
-
-  /* Nonzero maximal by modulus element found */
-  mpz_clear(max_so_far);
-  return ind_so_far + 1; 
-}
-
-
-size_t gmp_blas_iamin(size_t n, const mpz_t* x, size_t incx)
-{
-  size_t ind;
-  size_t ind_so_far;
-  mpz_t  min_so_far;
-
-  ind_so_far = gmp_blas_inz (n, x, incx);
-
-  /* No nonzeros found? */
-  if(ind_so_far == n+1)
-    {
-      return n+1;
-    }
-
-  /* OK, There is at leat one nonzero element */
-  mpz_init(min_so_far);
-  mpz_set(min_so_far, x[(ind_so_far-1)*incx]);
-
-  /* Scan through te rest of the elements to see if smaller  
-     elements by modulus are found */
-  for(ind = ind_so_far-1; ind < n; ind++)
-    {
-      if(mpz_sgn (x[ind*incx]) != 0)
-	{
-	  if(mpz_cmpabs (x[ind*incx], min_so_far) < 0)
-	    { 
-	      mpz_set(min_so_far, x[ind*incx]);
-	      ind_so_far = ind + 1;
-	    }
-	}
-    }
-
-  /* Nonzero minimal by modulus element found */
-  mpz_clear(min_so_far);
-  return ind_so_far;
-}
diff --git a/contrib/kbipack/gmp_matrix.c b/contrib/kbipack/gmp_matrix.c
deleted file mode 100644
index a9a4f9eeee77aef68f069eb842ed68f63895c769..0000000000000000000000000000000000000000
--- a/contrib/kbipack/gmp_matrix.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/* 
-   Source file for integer-oriented matrix, relying on the arbitrary 
-   precision integers from the GNU gmp package. 
-
-   Copyright (C) 28.10.2003 Saku Suuriniemi TUT/CEM
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   Saku Suuriniemi, TUT/Electromagetics
-   P.O.Box 692, FIN-33101 Tampere, Finland
-   saku.suuriniemi@tut.fi
-
-   $Id: gmp_matrix.c,v 1.5 2009-05-05 11:35:01 matti Exp $
-*/
-
-
-#include<stdlib.h>
-#include"gmp_matrix.h"
-
-gmp_matrix * 
-create_gmp_matrix(size_t r, size_t c, 
-		  const mpz_t * e)
-{
-  gmp_matrix * new_matrix;
-  size_t       ind;
-
-  new_matrix = (gmp_matrix * ) malloc(sizeof(gmp_matrix));
-  if(new_matrix == NULL)
-    {
-      return NULL;
-    }
-
-  new_matrix -> storage = (mpz_t *) calloc(r*c, sizeof(mpz_t));
-  if(new_matrix -> storage == NULL)
-    {
-      free(new_matrix);
-      return NULL;
-    }
-
-  new_matrix -> rows = r;
-  new_matrix -> cols = c;
-
-  for(ind = 0; ind < r*c; ind ++)
-    {
-      mpz_init (new_matrix -> storage[ind]);
-      mpz_set  (new_matrix -> storage[ind], e[ind]);
-    }
-
-  return new_matrix;
-}
-
-gmp_matrix * 
-create_gmp_matrix_int(size_t r, size_t c, 
-		  const long int * e)
-{
-  gmp_matrix * new_matrix;
-  size_t       ind;
-
-  new_matrix = (gmp_matrix * ) malloc(sizeof(gmp_matrix));
-  if(new_matrix == NULL)
-    {
-      return NULL;
-    }
-
-  new_matrix -> storage = (mpz_t *) calloc(r*c, sizeof(mpz_t));
-  if(new_matrix -> storage == NULL)
-    {
-      free(new_matrix);
-      return NULL;
-    }
-
-  new_matrix -> rows = r;
-  new_matrix -> cols = c;
-
-  for(ind = 0; ind < r*c; ind ++)
-    {
-      mpz_init    (new_matrix -> storage[ind]);
-      mpz_set_si  (new_matrix -> storage[ind], e[ind]);
-    }
-
-  return new_matrix;
-}
-
-
-gmp_matrix * 
-create_gmp_matrix_identity(size_t dim)
-{
-  gmp_matrix * new_matrix;
-  size_t       ind;
-
-  new_matrix = (gmp_matrix * ) malloc(sizeof(gmp_matrix));
-  if(new_matrix == NULL)
-    {
-      return NULL;
-    }
-
-  new_matrix -> storage = (mpz_t *) calloc(dim*dim, sizeof(mpz_t));
-  if(new_matrix -> storage == NULL)
-    {
-      free(new_matrix);
-      return NULL;
-    }
-
-  new_matrix -> rows = dim;
-  new_matrix -> cols = dim;
-
-  for(ind = 0; ind < dim*dim; ind ++)
-    {
-      mpz_init_set_si (new_matrix -> storage[ind], 0);
-    }
-
-  for(ind = 0; ind < dim; ind ++)
-    {
-      mpz_set_ui(new_matrix -> storage[ind*(dim+1)], 1);
-    }
-
-  return new_matrix;
-}
-
-
-gmp_matrix * 
-create_gmp_matrix_zero(size_t rows, size_t cols)
-{ 
-  gmp_matrix * new_matrix;
-  size_t       ind;
-
-  new_matrix = (gmp_matrix * ) malloc(sizeof(gmp_matrix));
-  if(new_matrix == NULL)
-    {
-      return NULL;
-    }
-
-  new_matrix -> storage = (mpz_t *) calloc(rows*cols, sizeof(mpz_t));
-  if(new_matrix -> storage == NULL)
-    {
-      free(new_matrix);
-      return NULL;
-    }
-
-  new_matrix -> rows = rows;
-  new_matrix -> cols = cols;
-
-  for(ind = 0; ind < rows*cols; ind ++)
-    {
-      mpz_init_set_si (new_matrix -> storage[ind], 0);
-    }
-  return new_matrix;
-}
-
-gmp_matrix * 
-copy_gmp_matrix(const gmp_matrix * matrix, 
-		  const size_t start_row, const size_t start_col, 
-		  const size_t end_row, const size_t end_col)
-{
-  gmp_matrix * new_matrix;
-  size_t       ind;
-  size_t       r;
-  size_t       c;
-  size_t       old_rows;
-  size_t       old_cols;
-  size_t       i;
-  size_t       j;
-
-  new_matrix = (gmp_matrix * ) malloc(sizeof(gmp_matrix));
-  if(new_matrix == NULL)
-    {
-      return NULL;
-    }
-
-  r = end_row-start_row+1;
-  c = end_col-start_col+1;
-  if(r < 1 || c < 1) return NULL;
-  
-  new_matrix -> storage = (mpz_t *) calloc(r*c, sizeof(mpz_t));
-  if(new_matrix -> storage == NULL)
-    {
-      free(new_matrix);
-      return NULL;
-    }
-
-  new_matrix -> rows = r;
-  new_matrix -> cols = c;
-
-  old_rows = matrix -> rows;
-  old_cols = matrix -> cols;
-
-  ind = 0;
-  for(j = 1; j <= old_cols; j++){
-    if(j >= start_col && j <= end_col){
-      for(i = 1; i <= old_rows; i++){
-        if(i >= start_row && i <= end_row){
-          mpz_init (new_matrix -> storage[ind]);
-          mpz_set  (new_matrix -> storage[ind], matrix -> storage[(j-1)*old_rows+(i-1)]);
-          ind++;
-        }
-      }
-    }
-  }
-     
-  return new_matrix;
-}
-
-int 
-destroy_gmp_matrix(gmp_matrix * m)
-{
-  size_t       ind, nmb_storage;;
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  if(m -> storage == NULL)
-    {
-      free(m);
-      return EXIT_FAILURE;
-    }
-
-  nmb_storage = (m -> rows)*(m -> cols);
-
-  for(ind = 0; ind < nmb_storage; ind++)
-    {
-      mpz_clear(m -> storage[ind]);
-    }
-
-  free(m -> storage);
-  free(m);
-  return EXIT_SUCCESS;
-}
-
-
-size_t
-gmp_matrix_rows(const gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return 0;
-    }
-
-  return m -> rows;
-}
-
-
-size_t
-gmp_matrix_cols(const gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return 0;
-    }
-
-  return m -> cols;
-}
-
-/* elem <- (matrix(row, col)) */
-int
-gmp_matrix_get_elem(mpz_t elem, size_t row, size_t col,
-		    const gmp_matrix * m)
-{
-#ifdef DEBUG
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-#endif
-
-  mpz_set(elem, m -> storage[(col-1)*(m -> rows)+row-1]);
-  return EXIT_SUCCESS;
-}
-
-/* (matrix(row, col)) <- elem */
-int
-gmp_matrix_set_elem(mpz_t elem, size_t row, size_t col,
-		    const gmp_matrix * m)
-{
-#ifdef DEBUG
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-#endif
-
-  mpz_set(m -> storage[(col-1)*(m -> rows)+row-1], elem);
-  return EXIT_SUCCESS;
-}
-
-int  
-gmp_matrix_swap_rows(size_t row1, size_t row2, gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((row1 < 1) || (row1 > m->rows) || (row2 < 1) || (row2 > m->rows))
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* printf("Swapping rows %i %i\n", row1, row2); */
-  gmp_blas_swap(m -> cols,
-		&(m -> storage[row1-1]), m -> rows, 
-		&(m -> storage[row2-1]), m -> rows);
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_swap_cols(size_t col1, size_t col2, gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((col1 < 1) || (col1 > m->cols) || (col2 < 1) || (col2 > m->cols))
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* printf("Swapping cols %i %i\n", col1, col2); */
-  gmp_blas_swap(m -> rows, 
-		&(m -> storage[(m->rows)*(col1-1)]), 1, 
-		&(m -> storage[(m->rows)*(col2-1)]), 1);
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_negate_row(size_t row, gmp_matrix * m)
-{
-  mpz_t minus_one;
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((row < 1) || (row > m->rows))
-    {
-      return EXIT_FAILURE;
-    }
-
-  mpz_init(minus_one);
-  mpz_set_si(minus_one, -1);
-  gmp_blas_scal(m -> cols, minus_one, (&m -> storage[row-1]), m -> rows); 
-  mpz_clear(minus_one);
-  return EXIT_SUCCESS; 
-}
-
-int
-gmp_matrix_negate_col(size_t col, gmp_matrix * m)
-{
-  mpz_t minus_one;
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((col < 1) || (col > m->cols))
-    {
-      return EXIT_FAILURE;
-    }
-  mpz_init(minus_one);
-  mpz_set_si(minus_one, -1);
-  gmp_blas_scal(m -> rows, minus_one, 
-		&(m -> storage[(m->rows)*(col-1)]), 1); 
-  mpz_clear(minus_one);
-  return EXIT_SUCCESS;
-}
-
-/* row2 <- a*row1 + row2*/
-int
-gmp_matrix_add_row(mpz_t a, size_t row1, size_t row2,
-		   gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((row1 < 1) || (row1 > m->rows) || (row2 < 1) || (row2 > m->rows))
-    {
-      return EXIT_FAILURE;
-    }
-
-  gmp_blas_axpy(m->cols, a, 
-		(const mpz_t *) &(m->storage[row1-1]), m->rows, 
-		&(m->storage[row2-1]), m->rows); 
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_add_col(mpz_t a, size_t col1, size_t col2,
-		   gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((col1 < 1) || (col1 > m->cols) || (col2 < 1) || (col2 > m->cols))
-    {
-      return EXIT_FAILURE;
-    }
-
-  gmp_blas_axpy(m->rows, a, 
-		(const mpz_t *) &(m -> storage[(m->rows)*(col1-1)]), 1, 
-		&(m -> storage[(m->rows)*(col2-1)]), 1); 
-
-  return EXIT_SUCCESS;
-}
-
-/* row1 <- a*row1 + b*row2
-   row2 <- c*row1 + d*row2 */
-int
-gmp_matrix_row_rot(mpz_t a, mpz_t b, size_t row1,
-		   mpz_t c, mpz_t d, size_t row2,
-		   gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((row1 < 1) || (row1 > m->rows) || (row2 < 1) || (row2 > m->rows))
-    {
-      return EXIT_FAILURE;
-    }
-
-  gmp_blas_rot(m->cols, 
-	       a, b, &(m->storage[row1-1]), m->rows, 
-	       c, d, &(m->storage[row2-1]), m->rows); 
-
-  return EXIT_SUCCESS;
-}
-int
-gmp_matrix_col_rot(mpz_t a, mpz_t b, size_t col1,
-		   mpz_t c, mpz_t d, size_t col2,
-		   gmp_matrix * m)
-{
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  if((col1 < 1) || (col1 > m->cols) || (col2 < 1) || (col2 > m->cols))
-    {
-      return EXIT_FAILURE;
-    }
-
-/*   printf("a: %i b: %i c: %i d:%i col1: %i col2: %i\n", */
-/* 	 mpz_get_si(a), */
-/* 	 mpz_get_si(b), */
-/* 	 mpz_get_si(c), */
-/* 	 mpz_get_si(d), */
-/* 	 col1, col2); */
-
-  gmp_blas_rot(m->rows, 
-	       a, b, &(m -> storage[(m->rows)*(col1-1)]), 1, 
-	       c, d, &(m -> storage[(m->rows)*(col2-1)]), 1); 
-
-  return EXIT_SUCCESS;
-}
-
-size_t
-gmp_matrix_col_inz (size_t r1, size_t r2, size_t c, 
-		    gmp_matrix * m)
-{
-  size_t result;
-
-  if(m == NULL)
-    {
-      return 0;
-    }
-  if((r1 < 1) || (r1 > m->rows) || 
-     (r2 < 1) || (r2 > m->rows) ||
-     (r2 < r1) || (c < 1) || (c > m->cols))
-    {
-      return 0;
-    }
-
-  result = gmp_blas_inz(r2-r1+1, 
-			(const mpz_t *) &(m->storage[(c-1)*(m->rows)+r1-1]), 
-			1);
-
-  if(result > r2-r1+1)
-    {
-      return 0;
-    }
-
-  return result;
-}
-
-size_t
-gmp_matrix_row_inz (size_t r, size_t c1, size_t c2, 
-		    gmp_matrix * m)
-{
-  size_t result;
-
-  if(m == NULL)
-    {
-      return 0;
-    }
-  if((r  < 1) || (r  > m->rows) || 
-     (c1 < 1) || (c1 > m->cols) ||
-     (c2 < c1) || (c2 < 1) || (c2 > m->cols))
-    {
-      return 0;
-    }
-
-  result = gmp_blas_inz(c2-c1+1, 
-			(const mpz_t *) &(m->storage[(c1-1)*(m->rows)+r-1]), 
-			m->rows);
-
-  if(result > c2-c1+1)
-    {
-      return 0;
-    }
-
-  return result;
-}
-
-
-int
-gmp_matrix_is_diagonal(const gmp_matrix * M)
-{
-  size_t i,j;
-  size_t rows, cols;
-
-  if(M == NULL)
-    {
-      return 0;
-    }
-  
-  rows = M->rows;
-  cols = M->cols;
-
-  for(j = 1; j <= cols; j ++)
-    {
-      for(i = 1; i <= rows; i ++)
-	{
-	  if((mpz_cmp_si(M->storage[(i-1)+(j-1)*rows], 0) != 0) && 
-	     (i != j))
-	    {
-	      return 0;
-	    }
-	}
-    }
-
-  return 1;
-}
-
-
-int
-gmp_matrix_transp(gmp_matrix * M)
-{
-  mpz_t * new_storage;
-  size_t i,j;
-  size_t rows, cols;
-
-  if(M == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-  
-  rows = M->rows;
-  cols = M->cols;
-
-  new_storage = (mpz_t *) calloc(rows*cols, sizeof(mpz_t));
-  if(new_storage == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  if(rows == 1){
-    for(i = 1; i <= cols; i++)
-    {
-      mpz_init_set(new_storage[i-1], 
-		       M-> storage[i-1]);
-	    mpz_clear(M-> storage[i-1]);
-    }
-  } 
-  else if(cols == 1){
-    for(i = 1; i <= rows; i++)
-    {
-      mpz_init_set(new_storage[i-1], 
-		       M-> storage[i-1]);
-	    mpz_clear(M-> storage[i-1]);
-    }
-  }
-  else{
-  for(i = 1; i <= rows; i++)
-    {
-      for(j = 1; j <= cols; j++)
-	{
-	  mpz_init_set(new_storage[(j-1)+(i-1)*cols], 
-		       M-> storage[(i-1)+(j-1)*rows]);
-	  mpz_clear(M-> storage[(i-1)+(j-1)*rows]);
-	}
-    }
-  }
-  
-  free(M->storage);
-
-  M -> storage = new_storage;
-  M -> rows = cols;
-  M -> cols = rows;
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_sum(gmp_matrix * A, const gmp_matrix * B)
-{
-  size_t i,j;
-  size_t rows_A, cols_A, rows_B, cols_B;
-
-  if((A == NULL) || (B == NULL))
-    {
-      return EXIT_FAILURE;
-    }
-  
-  rows_A = A->rows;
-  cols_A = A->cols;
-  rows_B = B->rows;
-  cols_B = B->cols;
-
-  if(cols_A != cols_B || rows_A != rows_B)
-    {
-      return EXIT_FAILURE;
-    }
-  mpz_t a;
-  mpz_init_set_si(a, 1);
-  /* Compute the sum */
-  for(i = 1; i <= rows_A; i++)
-    {
-    
-    }
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_right_mult(gmp_matrix * A, const gmp_matrix * B)
-{
-  mpz_t * new_storage;
-  size_t i,j;
-  size_t rows_A, cols_A, rows_B, cols_B;
-
-  if((A == NULL) || (B == NULL))
-    {
-      return EXIT_FAILURE;
-    }
-  
-  rows_A = A->rows;
-  cols_A = A->cols;
-  rows_B = B->rows;
-  cols_B = B->cols;
-
-  if(cols_A != rows_B)
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* Create new storage for the product */
-  new_storage = (mpz_t *) calloc(rows_A*cols_B, sizeof(mpz_t));
-  if(new_storage == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* Compute the product to the storage */
-  for(j = 1; j <= cols_B; j++)
-    {
-      for(i = 1; i <= rows_A; i++)
-	{
-	  mpz_init (new_storage[(i-1)+(j-1)*rows_A]);
-	  gmp_blas_dot(&(new_storage[(i-1)+(j-1)*rows_A]),
-		       cols_A,
-		       (const mpz_t *) &(A->storage[i-1]),          rows_A,
-		       (const mpz_t *) &(B->storage[(j-1)*rows_B]), 1);
-	}
-    }
-
-  /* Get rid of the old storage */
-  for(i = 1; i <= rows_A*cols_A; i++)
-    {
-      mpz_clear (A->storage[i-1]);
-    }
-  free(A->storage);
-
-  /* Update A */
-  A -> storage = new_storage;
-  A -> cols    = cols_B;
-
-  return EXIT_SUCCESS;
-}
-
-int
-gmp_matrix_left_mult(const gmp_matrix * A, gmp_matrix * B)
-{
-  mpz_t * new_storage;
-  size_t i,j;
-  size_t rows_A, cols_A, rows_B, cols_B;
-
-  if((A == NULL) || (B == NULL))
-    {
-      return EXIT_FAILURE;
-    }
-  
-  rows_A = A->rows;
-  cols_A = A->cols;
-  rows_B = B->rows;
-  cols_B = B->cols;
-
-  if(cols_A != rows_B)
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* Create new storage for the product */
-  new_storage = (mpz_t *) calloc(rows_A*cols_B, sizeof(mpz_t));
-  if(new_storage == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* Compute the product to the storage */
-  for(j = 1; j <= cols_B; j++)
-    {
-      for(i = 1; i <= rows_A; i++)
-	{
-	  mpz_init (new_storage[(i-1)+(j-1)*rows_A]);
-	  gmp_blas_dot(&(new_storage[(i-1)+(j-1)*rows_A]),
-		       cols_A,
-		       (const mpz_t *) &(A->storage[i-1]),          rows_A,
-		       (const mpz_t *) &(B->storage[(j-1)*rows_B]), 1);
-	}
-    }
-
-  /* Get rid of the old storage */
-  for(i = 1; i <= rows_B*cols_B; i++)
-    {
-      mpz_clear (B->storage[i-1]);
-    }
-  free(B->storage);
-
-  /* Update A */
-  B -> storage = new_storage;
-  B -> rows    = rows_A;
-
-  return EXIT_SUCCESS;
-}
-
-
-int gmp_matrix_printf(const gmp_matrix * m)
-{
-
-  mpz_t        outz;
-  size_t rows, cols, i, j;
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  rows = m->rows;
-  cols = m->cols;
-  mpz_init(outz);
-  for(i = 1; i <= rows ; i++)
-    {
-      for(j = 1; j <= cols ; j++)
-	{
-	  gmp_matrix_get_elem(outz, i, j, m);
-	  mpz_out_str (stdout, 10, outz);
-	  printf(" ");
-	}
-      printf("\n");
-    }
-
-  mpz_clear(outz);
-
-  return EXIT_SUCCESS;
-}
-
-int gmp_matrix_fprintf(FILE* stream, const gmp_matrix * m)
-{
-  mpz_t        outz;
-  size_t rows, cols, i, j;
-
-  if(m == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  rows = m->rows;
-  cols = m->cols;
-  mpz_init(outz);
-  for(i = 1; i <= rows ; i++)
-    {
-      for(j = 1; j <= cols ; j++)
-	{
-	  gmp_matrix_get_elem(outz, i, j, m);
-	  mpz_out_str (stream, 10, outz);
-	  printf(" ");
-	}
-      printf("\n");
-    }
-
-  mpz_clear(outz);
-
-  return EXIT_SUCCESS;
-}
diff --git a/contrib/kbipack/gmp_matrix_io.c b/contrib/kbipack/gmp_matrix_io.c
deleted file mode 100644
index ca1c6e48778d682500163b4934ecd981949da23d..0000000000000000000000000000000000000000
--- a/contrib/kbipack/gmp_matrix_io.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-  IO-routines for gmp integer matrices in coordinate format.
-
-  Copyright (C) 19.11.2003 Saku Suuriniemi TUT/CEM
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  any later version.
-   
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-  Saku Suuriniemi, TUT/Electromagetics
-  P.O.Box 692, FIN-33101 Tampere, Finland
-  saku.suuriniemi@tut.fi
-
-  $Id: gmp_matrix_io.c,v 1.1 2009-03-30 14:10:57 matti Exp $
- */
-
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#include "gmp_matrix_io.h"
-
-gmp_matrix * gmp_matrix_read_coord(char* filename)
-{
-  FILE *  p_file;
-  size_t  read_values;
-  size_t  row, col, nrows, ncols, dummy;
-  int     val;
-  char    buffer[1000];
-  gmp_matrix * new_matrix;
-  
-  p_file = fopen(filename, "r");
-  if(p_file == NULL)
-    return NULL;
-
-  /* Matlab and Octave typically include comments on ascii files. */
-  /* They start with # */
-  fgets(buffer, 999, p_file);
-  while(strncmp(buffer, "#",1) == 0)
-    {
-      fgets(buffer, 999, p_file);
-    }
-
-  /* First read the size of the matrix */
-  read_values = sscanf(buffer, "%lu %lu %lu", &nrows, &ncols, &dummy);
-
-  /* Create the matrix */
-  new_matrix = create_gmp_matrix_zero(nrows, ncols);
-  if(new_matrix == NULL)
-    {
-      fclose(p_file);
-      return NULL;
-    }
-
-  /* Read the values to the matrix */
-  while(read_values != EOF)
-    {
-      read_values = fscanf(p_file, "%u %u %i\n", &row, &col, &val);
-      if( (row <= nrows) && (row > 0) && (col <= ncols) && (col > 0) )
-	{
-	  mpz_set_si ( new_matrix->storage[(row-1)+(col-1)*nrows], val );
-	}
-    }
-  fclose(p_file);
-
-  return new_matrix;
-}
-
-int gmp_matrix_write_coord(char* filename, const gmp_matrix * M)
-{
-
-  FILE *  p_file;
-  size_t  written_values;
-  size_t  row, col, nrows, ncols, nnz;
-  mpz_t   outz;
-
-  if(M == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  nrows = M->rows;
-  ncols = M->cols;
-
-  p_file = fopen(filename, "w");
-  if(p_file == NULL)
-    return 0;
-
-  nnz = 0;
-  /* Compute the number of nonzeros for coordinate format */
-  mpz_init(outz);
-  for(col = 1; col <= ncols ; col++)
-    {
-      for(row = 1; row <= nrows ; row++)
-	{
-	  gmp_matrix_get_elem(outz, row, col, M);
-	  if( mpz_cmp_si (outz, 0) != 0)
-	    {
-	      nnz++;
-	    }
-	}
-    }
-
-  /* First write the size of the matrix */
-  written_values = fprintf(p_file, "%u %u %u\n", nrows, ncols, nnz);
-
-  /* Write the values to the matrix */
-  for(col = 1; col <= ncols ; col++)
-    {
-      for(row = 1; row <= nrows ; row++)
-	{
-	  gmp_matrix_get_elem(outz, row, col, M);
-	  if( mpz_cmp_si (outz, 0) != 0)
-	    {
-	      fprintf(p_file, "%u %u ", row, col);
-	      mpz_out_str (p_file, 10, outz);
-	      fprintf(p_file, "\n");
-	    }
-	}
-    }
-  mpz_clear(outz);  
-
-  fclose(p_file);
-
-  return EXIT_SUCCESS;
-}
diff --git a/contrib/kbipack/gmp_normal_form.c b/contrib/kbipack/gmp_normal_form.c
deleted file mode 100644
index 42785337e7e54cf85e1bc82b1dc0ea52b14ed925..0000000000000000000000000000000000000000
--- a/contrib/kbipack/gmp_normal_form.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/* 
-   Implementation for integer computation of Hermite and Smith normal 
-   forms of matrices of modest size. 
-
-   Implementation: Dense matrix with GMP-library's mpz_t elements to 
-                   hold huge integers. 
-
-   Algorithm: Kannan - Bachem algorithm with improvement by
-              Chou and Collins. Expects a large number of unit invariant 
-	      factors and takes advantage of them as they appear. 
-
-   References: 
-    [1] Ravindran Kannan, Achim Bachem: 
-        "Polynomial algorithms for computing the Smith and Hermite normal 
-	forms of an integer matrix", 
-	SIAM J. Comput., vol. 8, no. 5, pp. 499-507, 1979.
-    [2] Tsu-Wu J.Chou, George E. Collins: 
-        "Algorithms for the solution of systems of linear Diophantine 
-	equations", 
-	SIAM J. Comput., vol. 11, no. 4, pp. 687-708, 1982.
-    [3] GMP homepage http://www.swox.com/gmp/
-    [4] GNU gmp page http://www.gnu.org/software/gmp/
-
-   Copyright (C) 30.10.2003 Saku Suuriniemi TUT/CEM
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   Saku Suuriniemi, TUT/Electromagetics
-   P.O.Box 692, FIN-33101 Tampere, Finland
-   saku.suuriniemi@tut.fi
-
-   $Id: gmp_normal_form.c,v 1.1 2009-03-30 14:10:57 matti Exp $
-*/
-
-#include<stdlib.h>
-#include"gmp_blas.h"
-#include"gmp_matrix.h"
-#include"gmp_normal_form.h"
-
-
-/* The unaltered matrix and identity left and right factors */
-static gmp_normal_form *
-create_gmp_trivial_normal_form(gmp_matrix * A, 
-			       inverted_flag left_inverted,
-			       inverted_flag right_inverted)
-{
-  size_t rows, cols;
-
-  gmp_normal_form * new_nf;
-  if(A == NULL)
-    {
-      return NULL;
-    }
-
-  new_nf = (gmp_normal_form *) malloc(sizeof(gmp_normal_form));
-  if(new_nf == NULL)
-    {
-      destroy_gmp_matrix(A);
-      return NULL;
-    }
-
-  rows = A -> rows;
-  cols = A -> cols;
-
-  if((rows == 0) || (cols == 0))
-    {
-      destroy_gmp_matrix(A);
-      return NULL;
-    }
-
-  new_nf->left = create_gmp_matrix_identity(rows);
-  if(new_nf->left == NULL)
-    {
-      destroy_gmp_matrix(A);
-      free(new_nf);
-      return NULL;
-    }
-
-  new_nf->right = create_gmp_matrix_identity(cols);
-  if(new_nf->right == NULL)
-    {
-      destroy_gmp_matrix(A);
-      destroy_gmp_matrix(new_nf->left);
-      free(new_nf);
-      return NULL;
-    }
-
-  new_nf -> canonical = A;
-  new_nf -> left_inverted  = left_inverted;
-  new_nf -> right_inverted = right_inverted;
-
-  return new_nf;
-}
-
-static int
-gmp_Hermite_eliminate_step(gmp_matrix * L, gmp_matrix * U, 
-			   size_t col, inverted_flag right_inverted)
-{
-  size_t ind, row_limit;
-  mpz_t  pivot, elem;
-  mpz_t  bez1, bez2, gc_div;
-  mpz_t  cff1, cff2;
-
-  mpz_init(pivot);
-  mpz_init(elem);
-  mpz_init(bez1);
-  mpz_init(bez2);
-  mpz_init(cff1);
-  mpz_init(cff2);
-  mpz_init(gc_div);
-
-  row_limit = (L->rows >= col) ? 
-    col-1 : 
-    L->rows;
-
-  for(ind = 1; ind <= row_limit; ind++)
-    {
-      gmp_matrix_get_elem(elem, ind, col, L);
-
-      /* Eliminate only if nonzero */
-      if(mpz_sgn (elem) != 0)
-	{
-	  gmp_matrix_get_elem(pivot, ind, ind, L);
-
-	  /* Extended Euclid's: 
-	     bez1*pivot+bez2*elem = gc_div */
-	  gmp_blas_rotg(gc_div, bez1, bez2, pivot, elem);
-
-	  /* Make cff1 = -elem/gc_div */
-	  mpz_divexact(cff1, elem,  gc_div);
-	  mpz_neg     (cff1, cff1);
-	  /* Make cff2 = pivot/gc_div */
-	  mpz_divexact(cff2, pivot, gc_div);
-
-	  /* Update the HNF canonical matrix */
-	  gmp_matrix_col_rot(bez1, bez2, ind,
-			     cff1, cff2, col,
-			     L);
-
-	  /* Update the unimodular factor matrix */
-	  if(right_inverted == INVERTED)
-	    {
-	      gmp_matrix_col_rot(bez1, bez2, ind,
-				 cff1, cff2, col,
-				 U);
-	    }
-	  else
-	    {
-
-	      /* [bez1, -elem/gc_div] [pivot/gc_div, elem/gc_div]
-		 [bez2, pivot/gc_div] [-bez2,        bez1       ]  = I_2 */
-	      mpz_neg(cff1, cff1);
-	      mpz_neg(bez2, bez2);
-	      gmp_matrix_row_rot(cff2, cff1, ind,
-				 bez2, bez1, col,
-				 U);
-	    }
-	}
-    }
-  mpz_clear(pivot);
-  mpz_clear(elem);
-  mpz_clear(bez1);
-  mpz_clear(bez2);
-  mpz_clear(cff1);
-  mpz_clear(cff2);
-  mpz_clear(gc_div);
-
-  return EXIT_SUCCESS;
-}
-
-
-
-static int
-gmp_Hermite_reduce_step(gmp_matrix * L,  gmp_matrix * U, 
-			size_t col, inverted_flag right_inverted)
-{
-
-  size_t i, j;
-  mpz_t  pivot, elem;
-  mpz_t  cff;
-
-  mpz_init(pivot);
-  mpz_init(elem);
-  mpz_init(cff);
-
-  if(col > (L->rows))
-    {
-      return EXIT_FAILURE;
-    }
-
-  /*  printf("Col = %i\n", col);
-      printf("L before\n");
-      gmp_matrix_printf(L);*/
-
-  for(j = col-1; j >= 1; j--)
-    {
-      for(i = j+1; i <= col; i++)
-	{
-	  gmp_matrix_get_elem(pivot, i, i, L);
-	  gmp_matrix_get_elem(elem,  i, j, L);
-	  /* printf("   i %i j %i\n",i,j);  */
-
-	  if((mpz_cmpabs(elem, pivot) >= 0) || (mpz_sgn(elem) < 0))
-	    {
-	      /* The objective:
-		  0           <= elem + k*pivot < pivot
-		  -elem       <= k*pivot        < pivot - elem
-		  -elem/pivot <= k              < - elem/pivot + 1
-
-		  Solution:
-		  k = ceil(-elem/pivot)
-	      */
-
-	      /* Make cff = -elem */
-	      mpz_neg    (cff, elem);
-	      mpz_cdiv_q (cff, cff, pivot);
-
-	      /* printf("col %i j %i\n", i, j); 
-		 printf("elem %i k %i pivot %i\n", 
-		 mpz_get_si(elem), 
-		 mpz_get_si(cff), 
-		 mpz_get_si(pivot));*/
-
-
-	      gmp_matrix_add_col(cff, i, j, L);
-
-	      /* Update the unimodular factor matrix */
-	      if(right_inverted == INVERTED)
-		{
-		  gmp_matrix_add_col(cff, i, j, U);
-		}
-
-	      /* [1   0] [ 1   0] = [1 0]
-		 [cff 1] [-cff 1]   [0 1] */
-	      else
-		{
-		  mpz_neg (cff, cff);
-		  gmp_matrix_add_row(cff, j, i, U);
-		}
-
-	      /* printf("\n");
-		 gmp_matrix_printf(L);*/
-
-	    }
-	}
-    }
-
-/*  printf("L after\n"); */
-/*   gmp_matrix_printf(L); */
-
-  mpz_clear(pivot);
-  mpz_clear(elem);
-  mpz_clear(cff);
-  return EXIT_SUCCESS;
-}
-
-
-static int
-gmp_normal_form_make_Hermite(gmp_normal_form * nf)
-{
-  size_t rows, cols;
-  size_t pivot_ind;
-  size_t schur, colind;
-  mpz_t  pivot;
-  gmp_matrix * canonical;
-  gmp_matrix * left;
-  gmp_matrix * right;
-
-  if(nf == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  /* OK, it's safe to get to business */
-  canonical = nf->canonical;
-  left      = nf->left;
-  right     = nf->right;
-  rows      = canonical -> rows;
-  cols      = canonical -> cols;
-
-  mpz_init(pivot);
-
-  /* "schur" denotes where the present Schur complement starts */
-  schur = 1;
-
-  while((schur <= rows) && (schur <= cols))
-    {
-      /* Eliminate a column */
-      if (schur > 1)
-	{
-	  gmp_Hermite_eliminate_step(canonical, right, 
-				     schur, nf->right_inverted);
-	}
-
-      /* Find a pivot */
-      pivot_ind = gmp_matrix_col_inz(schur, rows, schur, canonical);
-
-
-      /* If no nonzeros was found, the column is all zero, hence 
-	 settled with. Permute it to the end and decrement cols. */
-      if(pivot_ind == 0)
-	{
-	  gmp_matrix_swap_cols(schur, cols, canonical);
-
-	  if(nf -> right_inverted == INVERTED)
-	    {
-	      gmp_matrix_swap_cols(schur, cols, right);
-	    }
-	  else
-	    {
-	      gmp_matrix_swap_rows(schur, cols, right);
-	    }
-
-	  cols--;
-
-	  /* When the whole column was zeroed, the diagonal 
-	     elements may have got reduced. Reduce the sub-
-	     diagonals as well*/
-
-	  if(schur > 1)
-	    {
-	      gmp_Hermite_reduce_step (canonical, right, schur-1, 
-				       nf -> right_inverted);
-	    }
-	}
-
-      /* A nonzero pivot was found. Permute it to the diagonal position, 
-	 make it positive, and reduce the off-diagonals. 
-	 The schur complement now starts from the next diagonal. */
-      else
-	{
-	  pivot_ind = schur+pivot_ind-1;
-	  gmp_matrix_swap_rows(schur, pivot_ind, canonical);
-
-	  if(nf->left_inverted == INVERTED)
-	    {
-	      gmp_matrix_swap_rows(schur, pivot_ind, left);
-	    }
-	  else
-	    {
-	      gmp_matrix_swap_cols(schur, pivot_ind, left);
-	    }
-
-	  /* Make the pivot positive */
-	  gmp_matrix_get_elem(pivot, schur, schur, canonical);
-
-	  if(mpz_cmp_si(pivot, 0) < 0)
-	    {
-	      gmp_matrix_negate_col(schur, canonical); 
-
-	      if(nf->right_inverted == INVERTED)
-		{
-		  gmp_matrix_negate_col(schur, right); 
-		}
-	      else
-		{
-		  gmp_matrix_negate_row(schur, right); 
-		}
-	    }
-
-	  /*  Reduce off-diagonals */
-	  gmp_Hermite_reduce_step (canonical, right, schur, nf -> right_inverted);
-
-	  schur++;
-	}
-    }
-
-  /* The Schur complement is now empty. There may still be uneliminated 
-     columns left (in case of a wide matrix) */
-
-  colind = schur;
-  while (colind <= cols)
-    {
-      gmp_Hermite_eliminate_step (canonical, right, colind,  nf->right_inverted);
-      gmp_Hermite_reduce_step    (canonical, right, schur-1, nf->right_inverted);
-      colind++;
-    }
-
-  mpz_clear(pivot);
-
-  return EXIT_SUCCESS;
-}
-
-
-
-gmp_normal_form * 
-create_gmp_Hermite_normal_form(gmp_matrix * A, 
-			       inverted_flag left_inverted,
-			       inverted_flag right_inverted)
-{
-  gmp_normal_form * new_nf;
-
-  if(A == NULL)
-    {
-      return NULL;
-    }
-
-  new_nf = 
-    create_gmp_trivial_normal_form(A, left_inverted, right_inverted);
-
-  if(new_nf == NULL)
-    {
-      /* A has been destroyed already */
-      return NULL;
-    }
-
-  if(gmp_normal_form_make_Hermite(new_nf) != EXIT_SUCCESS)
-    {
-      destroy_gmp_normal_form(new_nf);
-      return NULL;
-    }
-
-  return new_nf;
-}
-
-
-gmp_normal_form *
-create_gmp_Smith_normal_form(gmp_matrix * A,
-			     inverted_flag left_inverted,
-			     inverted_flag right_inverted)
-{
-
-  gmp_normal_form * new_nf;
-  gmp_matrix * canonical;
-  gmp_matrix * elbow;
-  inverted_flag elbow_flag;
-  size_t rows, cols;
-  size_t i, j;
-  size_t subd_ind, row_undivisible;
-  size_t last_ready_row, first_ready_col, ind;
-  mpz_t  pivot;
-  mpz_t  remainder;
-
-  if(A == NULL)
-    {
-      return NULL;
-    }
-
-  new_nf = 
-    create_gmp_trivial_normal_form(A, left_inverted, right_inverted);
-
-  if(new_nf == NULL)
-    {
-      /* A has been destroyed already */
-      return NULL;
-    }
-
-  canonical = new_nf -> canonical;
-  mpz_init(pivot);
-  mpz_init(remainder);
-  rows = canonical->rows;
-  cols = canonical->cols;
-  last_ready_row  = 0;
-  first_ready_col = (cols < rows) ? (cols+1) : (rows+1);
-
-  while(first_ready_col > last_ready_row + 1)
-    {
-      /*******/
-      /* HNF */
-      /*******/
-
-      if(gmp_normal_form_make_Hermite(new_nf) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-
-#ifdef DEBUG
-      printf("HNF\n");
-      gmp_matrix_printf (new_nf -> left);
-      gmp_matrix_printf (new_nf -> canonical);
-      gmp_matrix_printf (new_nf -> right);
-#endif
-
-      /**********************/
-      /* Find ready columns */
-      /**********************/
-
-      /* If a diagonal entry is zero, so is the corresponding 
-	 column. The zero diagonals always reside in the end. 
-	 Seek until zero diagonal encountered, but stay within the matrix! */
-      ind = 1;
-      while ( (ind < first_ready_col) && 
-	      (mpz_cmp_si(canonical -> storage[(ind-1)+(ind-1)*rows], 0) != 0) 
-	      )	     
-	{
-	  ind ++;
-	}
-      first_ready_col = ind;
-
-      /* Note: The number of ready cols is settled after the first HNF, 
-	 but the check is cheap. */
-
-      /**********************************************/
-      /* Permute unit diagonals such that they lead */
-      /**********************************************/
-
-      /* If the recently computed HNF has ones on the diagonal, their 
-	 corresponding rows are all zero (except the diagonal). 
-	 They are then settled, because the next LHNF kills the elements
-	 on their columns. */
-
-      ind = last_ready_row+1;
-  
-      /* Stay within the nonzero cols of the matrix */
-      while (ind < first_ready_col)
-	{
-	  /* Unit diagonal encountered */
-	  if(mpz_cmp_si ( canonical->storage[(ind-1) + (ind-1)*rows], 
-			  1) == 0)
-	    {
-	      /* If not in the beginning, permute to extend the leading minor 
-		 with unit diagonals */
-	      if(ind != last_ready_row+1)
-		{
-		  gmp_matrix_swap_rows(last_ready_row+1,     ind, 
-				       new_nf -> canonical);
-		  
-		  if(left_inverted == INVERTED)
-		    {
-		      gmp_matrix_swap_rows(last_ready_row+1, ind, 
-					   new_nf -> left);
-		    }
-		  else
-		    {
-		      gmp_matrix_swap_cols(last_ready_row+1, ind, 
-					   new_nf -> left);
-		    }
-		  
-		  gmp_matrix_swap_cols(last_ready_row+1,     ind, 
-				       new_nf -> canonical);
-		  
-		  if(right_inverted == INVERTED)
-		    {
-		      gmp_matrix_swap_cols(last_ready_row+1, ind, 
-					   new_nf -> right);
-		    }
-		  else
-		    {
-		      gmp_matrix_swap_rows(last_ready_row+1, ind, 
-					   new_nf -> right);
-		    }
-		}
-	      last_ready_row ++;
-	    }
-	  ind++;
-	}
-      
-#ifdef DEBUG
-      printf("Leading units\n");
-      gmp_matrix_printf (new_nf -> left);
-      gmp_matrix_printf (new_nf -> canonical);
-      gmp_matrix_printf (new_nf -> right);
-#endif
-
-      /********/
-      /* LHNF */
-      /********/
-
-      /* Extravagant strategy: Compute HNF of an explicit tranpose. */
-
-      /* 1. Transpose everything in the normal form */
-      if(gmp_matrix_transp(canonical) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-      if(gmp_matrix_transp(new_nf->left) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-      if(gmp_matrix_transp(new_nf->right) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-
-      elbow          = new_nf ->left;
-      new_nf ->left  = new_nf ->right;
-      new_nf ->right = elbow;
-      elbow_flag              = new_nf ->left_inverted;
-      new_nf ->left_inverted  = new_nf ->right_inverted;
-      new_nf ->right_inverted = elbow_flag;
-
-      /* 2. Compute HNF of the transpose */
-      if(gmp_normal_form_make_Hermite(new_nf) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-
-      /* 3. Transpose everything back */
-      if(gmp_matrix_transp(canonical) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-      if(gmp_matrix_transp(new_nf->left) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-      if(gmp_matrix_transp(new_nf->right) != EXIT_SUCCESS)
-	{
-	  destroy_gmp_normal_form(new_nf);
-	  mpz_clear(pivot);
-	  mpz_clear(remainder);
-	  return NULL;
-	}
-      elbow          = new_nf ->left;
-      new_nf ->left  = new_nf ->right;
-      new_nf ->right = elbow;
-      elbow_flag              = new_nf ->left_inverted;
-      new_nf ->left_inverted  = new_nf ->right_inverted;
-      new_nf ->right_inverted = elbow_flag;
-
-
-#ifdef DEBUG
-      printf("LHNF\n");
-      gmp_matrix_printf (new_nf -> left);
-      gmp_matrix_printf (new_nf -> canonical);
-      gmp_matrix_printf (new_nf -> right);
-#endif
-
-
-      /*****************************************************/
-      /* Check if more of the leading normal form is ready */
-      /*****************************************************/
-
-      /* The matrix is in LHNF, i.e. it is upper triangular. 
-	 If the row trailing the top left diagonal element is 
-	 zero, the diagonal element may be an invariant factor 
-	 on its final position, and the stage may be ready.
-
-	 The stage may not still be ready: The leading diagonal element 
-	 of D may not divide the rest of the Schur complement. */
-
-      subd_ind = 0;
-      row_undivisible = 0;
-
-      /* Explanation of loop conditions:
-	 1.) No relative primes found from Schur complement
-	 2.) Stay within the Schur complement
-	 3.) If a nonzero is found from the trailing row, the stage is 
-	     definitely not ready */
-      while (row_undivisible == 0 &&   
-	     last_ready_row + 1 < first_ready_col && 
-	     subd_ind == 0)        
-	{
-	  subd_ind = 
-	    gmp_matrix_row_inz(last_ready_row+1,
-			       last_ready_row+2, cols, 
-			       canonical);
-
-	  /* printf("subd_ind %i\n", subd_ind);
-	     printf("last_ready_row %i\n", last_ready_row); */
-      
-	  /* No nonzeros found, the stage may be ready */
-	  if (subd_ind == 0)
-	    {
-	      mpz_set (pivot, 
-		       canonical->storage[(last_ready_row)+
-					  (last_ready_row)*rows]);
-
-	      /* Check whether the pivot divides all elements in the Schur 
-		 complement */
-	      row_undivisible = 0;
-	      for(j = last_ready_row+2; j < first_ready_col; j++)
-		{
-		  for(i = last_ready_row+2; i <= j; i++)
-		    {
-		      mpz_tdiv_r (remainder, 
-				  canonical->storage[(i-1)+
-						     (j-1)*rows], 
-				  pivot);
-		  
-		      if(mpz_cmp_si(remainder, 0) !=0)
-			{
-			  row_undivisible = i;
-			  /* col_undivisible = j; */
-			}
-		    }
-		}
-
-	      /* printf("Row undivisible %i\n", row_undivisible); */
-
-	      /* If a relative prime was found from the Schur complement,  
-		 add that row to the first row of the Schur complement */
-	      if(row_undivisible != 0)
-		{
-		  mpz_set_si (remainder, 1);
-		  gmp_matrix_add_row(remainder, 
-				     row_undivisible, last_ready_row+1, 
-				     canonical);
-
-		  /* [ 1 0] [1 0] = [1 0]
-		     [-1 1] [1 1]   [0 1] */
-
-		  if(left_inverted == INVERTED)
-		    {
-		      gmp_matrix_add_row(remainder, 
-					 row_undivisible, last_ready_row+1, 
-					 new_nf->left);
-		    }
-		  else
-		    {
-		      mpz_neg (remainder, remainder);
-		      gmp_matrix_add_col(remainder, 
-					 last_ready_row+1, row_undivisible,
-					 new_nf->left);
-		    }
-		}
-	      /* The Schur complement is smaller by one again */
-	      else
-		{
-		  last_ready_row++;
-		}
-	    }
-	} 
-    }  /* The main loop ends here */
-  
-  mpz_clear(pivot);
-  mpz_clear(remainder);
-  return new_nf;
-}
-
-int destroy_gmp_normal_form(gmp_normal_form * nf)
-{
-  int status;
-
-  if(nf == NULL)
-    {
-      return EXIT_FAILURE;
-    }
-
-  status = EXIT_SUCCESS;
-  if(destroy_gmp_matrix(nf -> left) == EXIT_FAILURE)
-    {
-      status = EXIT_FAILURE;
-    }
-
-  if(destroy_gmp_matrix(nf -> canonical) == EXIT_FAILURE)
-    {
-      status = EXIT_FAILURE;
-    }
-
-  if(destroy_gmp_matrix(nf -> right) == EXIT_FAILURE)
-    {
-      status = EXIT_FAILURE;      
-    }
-  free(nf);
-
-  return status;
-}
-
-