int test_heuristic_scalar_product() { int result = 1; ulong count1, count2, i; double ** mat; F_mpz_mat_t B; int expo[50]; for (count1 = 0; count1 < 1000; count1++) { ulong rows = z_randint(50) + 1; ulong cols = z_randint(50) + 2; F_mpz_mat_init(B, rows, cols); F_mpz_randmat(B, rows, cols, 900); mat = d_mat_init(rows, cols); for (i = 0; i < rows; i++) expo[i] = _F_mpz_vec_to_d_vec_2exp(mat[i], B->rows[i], cols); for (count2 = 0; (count2 < 100); count2++) { ulong r1 = z_randint(rows); ulong r2 = z_randint(rows); double d1 = heuristic_scalar_product(mat[r1], mat[r2], cols, B, r1, r2, expo[r1] + expo[r2]); double d2 = heuristic_scalar_product(mat[r1], mat[r1], cols, B, r1, r1, expo[r1] + expo[r1]); double d3 = heuristic_scalar_product(mat[r2], mat[r2], cols, B, r2, r2, expo[r2] + expo[r2]); _d_vec_add(mat[r2], mat[r1], mat[r2], cols); _F_mpz_vec_add(B->rows[r2], B->rows[r1], B->rows[r2], cols); double d4 = heuristic_scalar_product(mat[r2], mat[r2], cols, B, r2, r2, expo[r2] + expo[r2]); result = (fabs(d4 - d3 - d2 - 2*d1) < 1.0E-12); if (!result) { printf("count2 = %ld Failed expo[r1] = %d expo[r2] = %d, d1 = %lf, d2 = %lf, d3 = %lf, d4 = %f\n", count2, expo[r1], expo[r2], d1, d2, d3, d4); } expo[r2] = _F_mpz_vec_to_d_vec_2exp(mat[r2], B->rows[r2], cols); } F_mpz_mat_clear(B); d_mat_clear(mat); } return result; }
void LLL(F_mpz_mat_t B) { int kappa, kappa2, d, n, i, j, zeros, kappamax; double ** mu, ** r, ** appB, ** appSP; double * s, * mutmp, * appBtmp, * appSPtmp; double tmp = 0.0; int * expo, * alpha; mp_limb_t * Btmp; n = B->c; d = B->r; ulong shift = getShift(B); alpha = (int *) malloc(d * sizeof(int)); expo = (int *) malloc(d * sizeof(int)); mu = d_mat_init(d, d); r = d_mat_init(d, d); appB = d_mat_init(d, n); appSP = d_mat_init(d, d); s = (double *) malloc (d * sizeof(double)); appSPtmp = (double *) malloc (d * sizeof(double)); for (i = 0; i < d; i++) for (j = 0; j < d; j++) appSP[i][j] = NAN;//0.0/0.0; /* ************************** */ /* Step1: Initialization Step */ /* ************************** */ for (i = 0; i < d; i++) expo[i] = F_mpz_mat_set_line_d(appB[i], B, i, n); /* ********************************* */ /* Step2: Initializing the main loop */ /* ********************************* */ kappamax = 0; i = 0; do appSP[i][i] = d_vec_norm(appB[i], n); while ((appSP[i][i] <= 0.0) && (++i < d)); // Fixme : should this be EPS not 0.0 zeros = i - 1; /* all vectors B[i] with i <= zeros are zero vectors */ kappa = i + 1; if (zeros < d - 1) r[i][i] = appSP[i][i]; for (i = zeros + 1; i < d; i++) alpha[i] = 0; while (kappa < d) { if (kappa > kappamax) kappamax++; // Fixme : should this be kappamax = kappa instead of kappamax++ /* ********************************** */ /* Step3: Call to the Babai algorithm */ /* ********************************** */ Babai(kappa, B, mu, r, s, appB, expo, appSP, alpha[kappa], zeros, kappamax, FLINT_MIN(kappamax + 1 + shift, n)); /* ************************************ */ /* Step4: Success of Lovasz's condition */ /* ************************************ */ /* ctt * r.coeff[kappa-1][kappa-1] <= s[kappa-2] ?? */ tmp = r[kappa-1][kappa-1] * ctt; tmp = ldexp (tmp, 2*(expo[kappa-1] - expo[kappa])); if (tmp <= s[kappa-1]) { alpha[kappa] = kappa; tmp = mu[kappa][kappa-1] * r[kappa][kappa-1]; r[kappa][kappa] = s[kappa-1] - tmp; kappa++; } else { /* ******************************************* */ /* Step5: Find the right insertion index kappa */ /* kappa2 remains the initial kappa */ /* ******************************************* */ kappa2 = kappa; do { kappa--; if (kappa > zeros + 1) { tmp = r[kappa-1][kappa-1] * ctt; tmp = ldexp(tmp, 2*(expo[kappa-1] - expo[kappa2])); } } while ((kappa >= zeros + 2) && (s[kappa-1] <= tmp)); for (i = kappa; i < kappa2; i++) if (kappa <= alpha[i]) alpha[i] = kappa; for (i = kappa2; i > kappa; i--) alpha[i] = alpha[i-1]; for (i = kappa2 + 1; i <= kappamax; i++) if (kappa < alpha[i]) alpha[i] = kappa; alpha[kappa] = kappa; /* ****************************** */ /* Step6: Update the mu's and r's */ /* ****************************** */ mutmp = mu[kappa2]; for (i = kappa2; i > kappa; i--) mu[i] = mu[i-1]; mu[kappa] = mutmp; mutmp = r[kappa2]; for (i = kappa2; i > kappa; i--) r[i] = r[i-1]; r[kappa] = mutmp; r[kappa][kappa] = s[kappa]; /* ************************ */ /* Step7: Update B and appB */ /* ************************ */ Btmp = B->rows[kappa2]; for (i = kappa2; i > kappa; i--) B->rows[i] = B->rows[i-1]; B->rows[kappa] = Btmp; appBtmp = appB[kappa2]; for (i = kappa2; i > kappa; i--) appB[i] = appB[i-1]; appB[kappa] = appBtmp; j = expo[kappa2]; for (i = kappa2; i > kappa; i--) expo[i] = expo[i-1]; expo[kappa] = j; /* *************************** */ /* Step8: Update appSP: tricky */ /* *************************** */ for (i = 0; i <= kappa2; i++) appSPtmp[i] = appSP[kappa2][i]; for (i = kappa2 + 1; i <= kappamax; i++) appSPtmp[i] = appSP[i][kappa2]; for (i = kappa2; i > kappa; i--) { for (j = 0; j < kappa; j++) appSP[i][j] = appSP[i-1][j]; appSP[i][kappa] = appSPtmp[i-1]; for (j = kappa + 1; j <= i; j++) appSP[i][j] = appSP[i-1][j-1]; for (j = kappa2 + 1; j <= kappamax; j++) appSP[j][i] = appSP[j][i-1]; } for (i = 0; i < kappa; i++) appSP[kappa][i] = appSPtmp[i]; appSP[kappa][kappa] = appSPtmp[kappa2]; for (i = kappa2 + 1; i <= kappamax; i++) appSP[i][kappa] = appSPtmp[i]; if (r[kappa][kappa] <= 0.0) { zeros++; kappa++; appSP[kappa][kappa] = d_vec_norm(appB[kappa], n); r[kappa][kappa] = appSP[kappa][kappa]; } kappa++; } } free(alpha); free(expo); d_mat_clear(mu); d_mat_clear(r); d_mat_clear(appB); d_mat_clear(appSP); free(s); free(appSPtmp); }