eg_dmatrix.ex.c

00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 /** @file 
00021  * @ingroup EGdMatrix
00022  * @brief This file shows some examples of the use of #EGdMatrix_t structure 
00023  * and functions. as a test-set we use the Hilber Matrix wich is a matrix
00024  * with coefficients \f$H^n_{i,j} = \frac1{i+j-1}\f$. It is well known that the
00025  * Hilbert matrix is extremmaly ill conditioned, and is very hard to invert,
00026  * here are some values for it's determinant for different dimmensions \f$n\f$.
00027  * - \f$\mathrm{det}(H_1) = 1 \f$. 
00028  * - \f$\mathrm{det}(H_2) = \frac1{12} \f$. 
00029  * - \f$\mathrm{det}(H_3) = \frac1{2160} \f$. 
00030  * - \f$\mathrm{det}(H_4) = \frac1{604800} \f$. 
00031  * - \f$\mathrm{det}(H_5) = \frac1{266716800000} \f$. 
00032  * Since a lot is known about the Hilber Matrix, some accuracy tests are
00033  * possible. For more details see <A HREF=http://mathworld.wolfram.com/HilbertMatrix.html TARGET=_top>MathWorld</A>
00034  * This test program takes as input the number of columns and rows for the
00035  * hilbert matrix, and so some operations on it and display it to the standard
00036  * output.
00037  * */
00038 /** @addtogroup EGdMatrix */
00039 /** @{ */
00040 /* ========================================================================= */
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <inttypes.h>
00044 #include "eg_dmatrix.h"
00045 #include "eg_dbasis_red.h"
00046 
00047 /* ========================================================================= */
00048 /** @brief size of the table of eigenvalues of the hilbert matrix */
00049 #define HILBERT_TABLE_SIZE 9U
00050 
00051 /* ========================================================================= */
00052 /** @brief table containing 1/eigenvalues of the hilbert matrix. */
00053 static unsigned dmatrix_hilbert_eigenvalues[HILBERT_TABLE_SIZE] = {
00054   1,
00055   12,
00056   180,
00057   2800,
00058   44100,
00059   698544,
00060   11099088,
00061   176679360,
00062   2815827300
00063 };
00064 
00065 /* ========================================================================= */
00066 /** @brief display the usage message for this program */
00067 void dmatrix_usage (char *program)
00068 {
00069   fprintf (stdout, "Usage: %s [options]\n", program);
00070   fprintf (stdout, "Options:\n");
00071   fprintf (stdout, "     -n n   number of rows in the hilbert matrix.\n");
00072   fprintf (stdout, "     -m n   number of columns in the hilbert matrixt.\n");
00073 
00074 }
00075 
00076 /* ========================================================================= */
00077 /** @brief parse the input argumenbts for the program */
00078 int dmatrix_parseargs (int argc,
00079                        char **argv,
00080                        size_t * n,
00081                        size_t * m)
00082 {
00083   int c;
00084   while ((c = getopt (argc, argv, "n:m:")) != EOF)
00085   {
00086     switch (c)
00087     {
00088     case 'n':
00089       *n = atoi (optarg);
00090       break;
00091     case 'm':
00092       *m = atoi (optarg);
00093       break;
00094     default:
00095       dmatrix_usage (argv[0]);
00096       return 1;
00097     }
00098   }
00099   /* reporting the options */
00100   if (!(*m) || !(*n))
00101   {
00102     dmatrix_usage (argv[0]);
00103     return 1;
00104   }
00105   fprintf (stdout, "Parsed Options:\n");
00106   fprintf (stdout, "n : %u\n", *n);
00107   fprintf (stdout, "m : %u\n", *m);
00108   return 0;
00109 }
00110 
00111 /* ========================================================================= */
00112 /** @brief main function */
00113 int main (int argc,
00114           char **argv)
00115 {
00116 
00117   int rval = 0,
00118     status;
00119   size_t n = 1,
00120     m = 1;
00121   register unsigned i = 0,
00122     j = 0;
00123   unsigned rank;
00124   EGdMatrix_t dmatrix;
00125   EGdBsRed_t bsred;
00126   EGlpNum_t error;
00127   /* start */
00128   EGlpNumStart ();
00129   EGlpNumInitVar (error);
00130   EGdMatrixInit (&dmatrix);
00131   EGdBsRedInit (&bsred);
00132   /* parse args */
00133   rval = dmatrix_parseargs (argc, argv, &n, &m);
00134   CHECKRVALG (rval, CLEANUP);
00135   /* set the matrix size */
00136   EGdMatrixSetDimension (&dmatrix, n, m);
00137   /* set the coefficients of the hilbert matrix */
00138   for (i = n; i--;)
00139     for (j = m; j--;)
00140     {
00141       EGlpNumOne (dmatrix.matrow[i][j]);
00142       EGlpNumDivUiTo (dmatrix.matrow[i][j], i + j + 1);
00143     }
00144   /* Display the hilbert matrix */
00145   fprintf (stdout, "Hilber ");
00146   EGdMatrixDisplay (&dmatrix, 1, stdout);
00147   fflush (stdout);
00148   /* now we call gaussian elimination */
00149   rval =
00150     EGdMatrixGaussianElimination (&dmatrix, 0, 0, &rank, epsLpNum, &status);
00151   CHECKRVALG (rval, CLEANUP);
00152   fprintf (stdout, "Gaussian Elimination ended with status %d, rank %u and ",
00153            status, rank);
00154   EGdMatrixDisplay (&dmatrix, 0, stdout);
00155   fflush (stdout);
00156   /* now we compute the worst error in the diagonal up to
00157    * EGmin(HILBERT_TABLE_SIZE,rank) */
00158   fprintf (stdout, "Relative errors in eigenvalues:\n");
00159   for (i = EGmin (HILBERT_TABLE_SIZE, rank); i--;)
00160   {
00161     EGlpNumCopy (error, dmatrix.matrow[dmatrix.row_ord[i]][dmatrix.col_ord[i]]);
00162     fprintf (stdout, "Lambda_%u = %lg", i + 1, EGlpNumToLf (error));
00163     EGlpNumMultUiTo (error, dmatrix_hilbert_eigenvalues[i]);
00164     EGlpNumSubTo (error, oneLpNum);
00165     fprintf (stdout, " error = %lg\n", EGlpNumToLf (error));
00166   }
00167   /* set the coefficients of the hilbert matrix */
00168   for (i = n; i--;)
00169     for (j = m; j--;)
00170     {
00171       EGlpNumOne (dmatrix.matrow[i][j]);
00172       EGlpNumDivUiTo (dmatrix.matrow[i][j], i + j + 1);
00173     }
00174   fprintf (stdout, "Using Basis Reduction on ");
00175   EGdMatrixDisplay (&dmatrix, 1, stdout);
00176   /* now we do basis reduction over the rows of the matrix */
00177   /* ending */
00178   EGdBsRedSetLength (&bsred, m);
00179   for (i = 0; i < rank; i++)
00180     EGdBsRedAddElement (&bsred, dmatrix.matrow[dmatrix.row_ord[i]]);
00181   /* now call the Basis Reduction Algorithm and print the reduced basis */
00182   rval = EGdBsRed (&bsred, &rank, epsLpNum, &status);
00183   CHECKRVALG (rval, CLEANUP);
00184   fprintf (stdout, "Basis Reduction ended with status %d, rank %u and ",
00185            status, rank);
00186   EGdMatrixDisplay (&dmatrix, 1, stdout);
00187   fflush (stdout);
00188 CLEANUP:
00189   EGdBsRedProfile (stderr);
00190   EGlpNumClearVar (error);
00191   EGdBsRedClear (&bsred);
00192   EGdMatrixClear (&dmatrix);
00193   EGlpNumExit ();
00194   return rval;
00195 }
00196 
00197 /* ========================================================================= */
00198 /** @} */

Generated on Mon Jan 30 08:48:51 2006 for EGlib by  doxygen 1.4.5