00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "eg_dbasis_red.h"
00021
00022
00023
00024
00025
00026 uintmax_t EGdBsRedStats[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00027
00028
00029
00030 static void EGdBsRedBuildGM (EGdMatrix_t * const GM,
00031 const unsigned full_dim,
00032 const unsigned length,
00033 EGlpNum_t ** const basis,
00034 EGlpNum_t orilen,
00035 EGlpNum_t tmpval)
00036 {
00037 register unsigned i,
00038 j;
00039
00040 EGlpNumOne (orilen);
00041 for (i = full_dim; i--;)
00042 {
00043 EGlpNumInnProd (tmpval, basis[i], basis[i], length);
00044 EGlpNumCopy (GM->matrow[0][i], tmpval);
00045 EGlpNumCopy (GM->matrow[i][i], tmpval);
00046 EGlpNumMultTo (orilen, tmpval);
00047 }
00048
00049
00050
00051 EGutilPermSort (full_dim, GM->col_ord, GM->matrow[0]);
00052 memcpy (GM->row_ord, GM->col_ord, sizeof (int) * full_dim);
00053
00054 for (i = full_dim; i--;)
00055 {
00056 for (j = i + 1; j < full_dim; j++)
00057 {
00058 EGlpNumInnProd (tmpval, basis[i], basis[j], length);
00059 EGlpNumCopy (GM->matrow[i][j], tmpval);
00060 EGlpNumCopy (GM->matrow[j][i], tmpval);
00061 }
00062 }
00063 }
00064
00065
00066 int EGdBsRed (EGdBsRed_t * const bsred,
00067 unsigned *const ext_dim,
00068 EGlpNum_t zero_tol,
00069 int *const ext_status)
00070 {
00071 EGdMatrix_t *const GM = &(bsred->GM);
00072 const unsigned full_dim = bsred->dim;
00073 const unsigned length = bsred->length;
00074 EGlpNum_t **const basis = bsred->basis;
00075 int rval = 0;
00076 EGlpNum_t tmpval,
00077 tmpval2,
00078 orilen,
00079 endlen;
00080 unsigned dim = 1;
00081 unsigned rank = 0;
00082 int status = EG_ALGSTAT_SUCCESS;
00083 int ge_status = 0;
00084 int tmpint;
00085 register unsigned i,
00086 j,
00087 k;
00088 MESSAGE (EG_DBSRED_VERBOSE, "Entering with dimension %u length %u", full_dim,
00089 length);
00090 EGdBsRedStats[EG_BSRED_CALLS]++;
00091 EGlpNumInitVar (tmpval);
00092 EGlpNumInitVar (tmpval2);
00093 EGlpNumInitVar (orilen);
00094 EGlpNumInitVar (endlen);
00095 TESTG ((rval = (full_dim > length)), CLEANUP, "the length of the vectors "
00096 "(%u) is smaller than the number of vectors (%u) being considered!",
00097 length, full_dim);
00098
00099
00100 if (full_dim < 2)
00101 {
00102 dim = full_dim;
00103 goto CLEANUP;
00104 }
00105
00106
00107 EGdMatrixSetDimension (GM, full_dim, full_dim);
00108 EGlpNumOne (orilen);
00109
00110
00111 EGdBsRedBuildGM (GM, full_dim, length, basis, orilen, tmpval);
00112 #if EG_DBSRED_VERBOSE +100<= DEBUG
00113 fprintf (stderr, "Order ");
00114 for (i = 0; i < full_dim; i++)
00115 fprintf (stderr, "%d ", GM->row_ord[i]);
00116 fprintf (stderr, "\nGM ");
00117 EGdMatrixDisplay (GM, 0, stderr);
00118 #endif
00119
00120 while (dim < full_dim)
00121 {
00122 EGdBsRedStats[EG_BSRED_ITT]++;
00123
00124 rval = EGdMatrixGaussianElimination (GM, 0, 0, &rank, zero_tol, &ge_status);
00125 CHECKRVALG (rval, CLEANUP);
00126 #if EG_DBSRED_VERBOSE+100 <= DEBUG
00127 fprintf (stderr, "Order ");
00128 for (i = 0; i < full_dim; i++)
00129 fprintf (stderr, "%d ", GM->row_ord[i]);
00130 fprintf (stderr, "\nafter Gausian Elimination GM ");
00131 EGdMatrixDisplay (GM, 0, stderr);
00132 #endif
00133
00134
00135 if (ge_status != EG_ALGSTAT_SUCCESS)
00136 {
00137 status = ge_status;
00138 break;
00139 }
00140
00141
00142 j = dim;
00143 for (; j < full_dim; j++)
00144 {
00145 for (i = j; i--;)
00146 {
00147 EGlpNumCopy (tmpval, GM->matrow[GM->col_ord[i]][GM->col_ord[j]]);
00148 EGlpNumDivTo (tmpval, GM->matrow[GM->col_ord[i]][GM->col_ord[i]]);
00149 EGlpNumCopyAbs (tmpval2, tmpval);
00150
00151 if (EGlpNumIsGreaDbl (tmpval2, 0x1p-1))
00152 {
00153 EGdBsRedStats[EG_BSRED_SZRED]++;
00154
00155 EGlpNumFloor (tmpval2, tmpval);
00156 EGlpNumSubTo (tmpval, tmpval2);
00157 if (EGlpNumIsGreaDbl (tmpval, 0x1p-1))
00158 EGlpNumAddTo (tmpval2, oneLpNum);
00159 MESSAGE (EG_DBSRED_VERBOSE + 100, "Doing reduction for mu(%u,%u)=%lf,"
00160 " multiple %lf", j, i, EGlpNumToLf (tmpval),
00161 EGlpNumToLf (tmpval2));
00162
00163 EGdMatrixSubColMultiple (GM, GM->col_ord[j], GM->col_ord[i], tmpval2);
00164 for (k = length; k--;)
00165 EGlpNumSubInnProdTo (basis[GM->col_ord[j]][k],
00166 basis[GM->col_ord[i]][k], tmpval2);
00167 }
00168 }
00169 }
00170 #if EG_DBSRED_VERBOSE+100 <= DEBUG
00171 fprintf (stderr, "Order ");
00172 for (i = 0; i < full_dim; i++)
00173 fprintf (stderr, "%d ", GM->row_ord[i]);
00174 fprintf (stderr, "\nafter Step I GM ");
00175 EGdMatrixDisplay (GM, 0, stderr);
00176 #endif
00177
00178
00179
00180
00181 for (i = 1; i < full_dim; i++)
00182 {
00183 EGlpNumCopy (tmpval, GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i]]);
00184 EGlpNumMultTo (tmpval, tmpval);
00185 EGlpNumDivTo (tmpval, GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i - 1]]);
00186 EGlpNumAddTo (tmpval, GM->matrow[GM->col_ord[i]][GM->col_ord[i]]);
00187 EGlpNumDivTo (tmpval, GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i - 1]]);
00188
00189
00190 if (EGlpNumIsLessDbl (tmpval, EG_DBSRED_ALPHA))
00191 {
00192 EGdBsRedStats[EG_BSRED_INTR]++;
00193 MESSAGE (EG_DBSRED_VERBOSE + 100, "Doing swap between columns %u,%u",
00194 i - 1, i);
00195 EGlpNumCopy (tmpval2, GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i]]);
00196 EGlpNumCopy (tmpval, tmpval2);
00197 EGlpNumMultTo (tmpval, tmpval);
00198 EGlpNumDivTo (tmpval2,
00199 GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i - 1]]);
00200 EGlpNumDivTo (tmpval,
00201 GM->matrow[GM->col_ord[i - 1]][GM->col_ord[i - 1]]);
00202 EGlpNumAddTo (tmpval, GM->matrow[GM->col_ord[i]][GM->col_ord[i]]);
00203 EGdMatrixAddRowMultiple (GM, GM->col_ord[i], GM->col_ord[i - 1],
00204 tmpval2);
00205 EGlpNumCopy (GM->matrow[GM->col_ord[i]][GM->col_ord[i]], tmpval);
00206 EGswap (GM->col_ord[i], GM->col_ord[i - 1], tmpint);
00207 EGswap (GM->row_ord[i], GM->row_ord[i - 1], tmpint);
00208 break;
00209 }
00210 }
00211 dim = i;
00212 #if EG_DBSRED_VERBOSE+100 <= DEBUG
00213 fprintf (stderr, "Order ");
00214 for (i = 0; i < full_dim; i++)
00215 fprintf (stderr, "%d ", GM->row_ord[i]);
00216 fprintf (stderr, "\nafter Step II GM ");
00217 EGdMatrixDisplay (GM, 0, stderr);
00218 #endif
00219 MESSAGE (EG_DBSRED_VERBOSE + 100, "Current Dimension %u", dim);
00220 }
00221
00222 EGlpNumOne (endlen);
00223 for (i = full_dim; i--;)
00224 EGlpNumMultTo (endlen, GM->matrow[i][i]);
00225
00226 CLEANUP:
00227 *ext_dim = dim;
00228 *ext_status = status;
00229 MESSAGE (EG_DBSRED_VERBOSE, "Ending with dimmension %u, status %d\nOriginal "
00230 "Basis Length %lg, Final Length %lg, gain %lg", dim, status,
00231 EGlpNumToLf (orilen), EGlpNumToLf (endlen),
00232 EGlpNumToLf (orilen) / EGlpNumToLf (endlen));
00233 EGlpNumClearVar (endlen);
00234 EGlpNumClearVar (orilen);
00235 EGlpNumClearVar (tmpval2);
00236 EGlpNumClearVar (tmpval);
00237 return rval;
00238 }
00239
00240
00241