eg_dbasis_red.h

Go to the documentation of this file.
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 #ifndef __EG_DBASIS_REDUCTION__
00021 #define __EG_DBASIS_REDUCTION__
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <limits.h>
00026 #include <math.h>
00027 #include <float.h>
00028 #include "eg_macros.h"
00029 #include "eg_mem.h"
00030 #include "eg_lpnum.h"
00031 #include "eg_dmatrix.h"
00032 #include "eg_numutil.h"
00033 /* ========================================================================= */
00034 /** @defgroup EGdBasisRed LLL Basis Reduction
00035  * Here we define a common interface for dense matrices (i.e. a structure), and
00036  * some common operations over dense matrices. The definition uses EGlpNum as
00037  * reference number type, this allow for template initializations.
00038  * 
00039  * @par History:
00040  * Revision 0.0.2
00041  *  - 2005-10-28
00042  *            - First implementation.
00043  * */
00044 /** @{*/
00045 /** @file
00046  * @brief This file provide the user interface and function definitions for
00047  * the so-called LLL Basis Reduction Algorithm. This algorithm was first
00048  * presented in the paper "Factoring polynomials with rational coefficients",
00049  * Mathematische Annalen 261 (1981), p515-534. and has been extensivelly
00050  * studied elsewere. for more details just Google-it.
00051  * */
00052 /** @example eg_dmatrix.ex.c */
00053 /* ========================================================================= */
00054 /** @brief verbosity level */
00055 #define EG_DBSRED_VERBOSE 0
00056 
00057 /* ========================================================================= */
00058 /** @name Profiling structures and functions for the basis reduction algorithm.
00059  * */
00060 /*@{*/
00061 /* ========================================================================= */
00062 /** @brief where to hold the profile information */
00063 extern uintmax_t EGdBsRedStats[10];
00064 
00065 /* ========================================================================= */
00066 /** @brief where we store the number of calls to #EGdBsRed */
00067 #define EG_BSRED_CALLS 0
00068 
00069 /* ========================================================================= */
00070 /** @brief where we store the total number of size reductions performed in 
00071  * #EGdBsRed */
00072 #define EG_BSRED_SZRED 1
00073 
00074 /* ========================================================================= */
00075 /** @brief where we store the total number of interchanges performed in 
00076  * #EGdBsRed */
00077 #define EG_BSRED_INTR 2
00078 
00079 /* ========================================================================= */
00080 /** @brief where we store the total number of innermost loops performed in 
00081  * #EGdBsRed */
00082 #define EG_BSRED_ITT 3
00083 
00084 /* ========================================================================= */
00085 /** @brief Print into the given file stream, the current statistics related
00086  * to the #EGdBsRed algorithm. And reset all counters to zero.
00087  * @param ofile where we want to print the profile information. */
00088 #define EGdBsRedProfile(ofile) do{\
00089   fprintf(ofile,"LLL Basis Reduction Statistics:\n");\
00090   fprintf(ofile,"\tNumber Calls    : %ju\n", EGdBsRedStats[EG_BSRED_CALLS]);\
00091   fprintf(ofile,"\tLoops           : %ju\n", EGdBsRedStats[EG_BSRED_ITT]);\
00092   fprintf(ofile,"\tSize Reductions : %ju\n", EGdBsRedStats[EG_BSRED_SZRED]);\
00093   fprintf(ofile,"\tInterchanges    : %ju\n", EGdBsRedStats[EG_BSRED_INTR]);\
00094   memset(EGdBsRedStats,0,sizeof(EGdBsRedStats));} while(0)
00095 
00096 /*@}*/
00097 
00098 /* ========================================================================= */
00099 /** @brief Value used in condition two of the LLL algorithm, remember that this
00100  * number should be between \f$(1/4,1)\f$. By default we choose \f$\lambda =
00101  * \frac{2^{20}-1}{2^{20}} \approx .99999904632568359375 \f$. */
00102 #define EG_DBSRED_ALPHA 0x3ffp-10
00103 
00104 /* ========================================================================= */
00105 /** @brief structure to hold all necesary data to perform the LLL's basis
00106  * reduction algorithm. */
00107 typedef struct EGdBsRed_t
00108 {
00109   size_t dim;       /**< @brief Number of elements in the basis */
00110   size_t length;    /**< @brief Length of the vectors in the basis, note that
00111                          it should be that length >= dim */
00112   size_t basis_sz;  /**< @brief Actual length of the #EGdBsRed_t::basis 
00113                          array */
00114   EGlpNum_t **basis;/**< @brief array of pointers to arrays containing the 
00115                          vector basis in extended (including zero coef) form. 
00116                          The vectors themselves are considered as allocated 
00117                          outside. everything else is considered as internally
00118                          allocated. */
00119   EGdMatrix_t GM;   /**< @brief Here we store and compute the Gram-Schmidt 
00120                          needed for the LLL basis reduction algorithm */
00121 }
00122 EGdBsRed_t;
00123 
00124 /* ========================================================================= */
00125 /** @brief Initialize an #EGdBsRed_t structure, as a basis with zero elements
00126  * of dimension zero.
00127  * @param bsred pointer to an #EGdBsRed_t structure.
00128  * */
00129 #define EGdBsRedInit(bsred) do{\
00130   EGdBsRed_t*const __EGdbs = (bsred);\
00131   memset(__EGdbs,0,sizeof(EGdBsRed_t));\
00132   EGdMatrixInit(&(__EGdbs->GM));} while(0)
00133 
00134 /* ========================================================================= */
00135 /** @brief Free any internally allocated memory in a #EGdBsRed_t structure.
00136  * @param bsred pointer to an #EGdBsRed_t structure.
00137  * */
00138 #define EGdBsRedClear(bsred) do{\
00139   EGdBsRed_t*const __EGdbs = (bsred);\
00140   if(__EGdbs->basis) EGfree(__EGdbs->basis);\
00141   EGdMatrixClear(&(__EGdbs->GM));} while(0)
00142 
00143 /* ========================================================================= */
00144 /** @brief reset an #EGdBsRed_t structure as a basis without elements (note
00145  * that we do not reset the length of the vectors, just the number of vectors 
00146  * in the basis).
00147  * @param bsred pointer to an #EGdBsRed_t structure.
00148  * */
00149 #define EGdBsRedReset(bsred) ((bsred)->dim = 0)
00150 
00151 /* ========================================================================= */
00152 /** @brief set the length of the vectors used in the basis for an #EGdBsRed_t
00153  * structure.
00154  * @param bsred pointer to an #EGdBsRed_t structure.
00155  * @param new_length length of the vectors in the basis.
00156  * */
00157 #define EGdBsRedSetLength(bsred,new_length) ((bsred)->length = (new_length))
00158 
00159 /* ========================================================================= */
00160 /** @brief add a new vector to the basis.
00161  * @param bsred pointer to an #EGdBsRed_t structure.
00162  * @param new_elem new vector to add to the basis.
00163  * */
00164 #define EGdBsRedAddElement(bsred,new_elem) do{\
00165   EGdBsRed_t*const __EGdbs = (bsred);\
00166   if(__EGdbs->basis_sz <= __EGdbs->dim){\
00167     __EGdbs->basis_sz += 10U;\
00168     EGrealloc(__EGdbs->basis,sizeof(EGlpNum_t*)*__EGdbs->basis_sz);}\
00169   __EGdbs->basis[__EGdbs->dim++] = (new_elem);} while(0)
00170 
00171 /* ========================================================================= */
00172 /** @brief This function performs the so-called LLL basis reduction algorithm.
00173  * @param bsred pointer to an #EGdBsRed_t structure.
00174  * @param status where we return the status of the algorithm, if the algorithm
00175  * finish with non-zero reduced elements, the status is #EG_ALGSTAT_SUCCESS. if
00176  * the algorithm finish with some zero reduced vector, the status is
00177  * #EG_ALGSTAT_PARTIAL. if the algorithm stop because of numerical problems,
00178  * the status is #EG_ALGSTAT_NUMERROR.
00179  * @param zero_tol threshold for a number to be considered as zero.
00180  * @param dim pointer to a number where we return the dimension of the basis
00181  * that the algorithm could prove before running in any numerical problem. If
00182  * the algorithm stop with status #EG_ALGSTAT_SUCCESS, then this number should
00183  * be equal to #EGdBsRed_t::dim. The vectors that we finish reducing are stored
00184  * in #EGdMatrix_t::row_ord[0], ... , #EGdMatrix_t::row_ord[dim], in the
00185  * #EGdBsRed_t::GM matrix.
00186  * @return zero if the algorithm finish, non-zero if an unforeseen error occure
00187  * during execution. 
00188  * @par Details:
00189  * The implementation that we use introduce (as an heuristic step) the sorting
00190  * of the original basis vectors in increasing order according to their norms,
00191  * this simple step reduced the total running time of the algorithm, but does
00192  * not improve the theoretical running time. A second detail is that we only
00193  * compute the Gram-Schmidth coefficients only once (at the beggining of the
00194  * program), and then, we only update the changed entries for both operations
00195  * \a size \a reduction and \a interchange. The advantage of the approach is
00196  * that we save most Gram-Schmidth computations and also all the recomputations
00197  * of the inner products of the elements currently in the basis. Again, this
00198  * are improvements form the practical point of view, but not in practice. The
00199  * dissadvantage of this approach is that we do accumulate rounding errors in
00200  * the Gram-Schmidth coefficients allong the way, but if all original vectors
00201  * coefficients where integer (and not too big), then the error should not grow
00202  * too much. Still this may happen if the input basis is ill conditioned.
00203  * */
00204 int EGdBsRed (EGdBsRed_t * const bsred,
00205               unsigned *const dim,
00206               EGlpNum_t zero_tol,
00207               int *const status);
00208 
00209 /* ========================================================================= */
00210 /** @}*/
00211 #endif

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