source: git/IntegerProgramming/LLL_lattice_to_send.cc @ c2c418

spielwiese
Last change on this file since c2c418 was c2c418, checked in by Hans Schönemann <hannes@…>, 21 years ago
*hannes: make gcc happy git-svn-id: file:///usr/local/Singular/svn/trunk@6517 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*---------------------------------------------------------------------------
2/                         Integral LLL Algorithm                            |
3/                                                                           |
4/                           Implemented by                                  |
5/          Alberto Vigneron-Tenorio and Alfredo Sánchez-Navarro             |
6/            alberto.vigneron@uca.es, alfredo.sanchez@uca.es                |
7/                 E.U.E.Empresariales de Jerez.                             |
8/                   Universidad de Cádiz                                    |
9/                   Porvera 54.                                             |
10/                 Jerez de la Frontera (Cádiz, Spain)                       |
11/                                                                           |
12/                                                                           |
13/ This application computes the LLL-reduced basis of a Z-lattice using      |
14/ the algorithm 2.6.7 appeared in:                                          |
15/ Cohen, H. A course in computational algebraic number theory.              |
16/ GTM 138, Springer 1996.                                                   |
17/                                                                           |
18/ The Input is a file with the structure:                                   |
19/ Number of vectors, Number of coordinates                                  |
20/ b11 b12 b13 ... b1C                                                       |
21/ b21 b22 b23 ... b2C                                                       |
22/       ...                                                                 |
23/ bF1 bF2 bF3 ... bFC                                                       |
24/                                                                           |
25/ All these inputs are integer numbers.                                     |
26/                                                                           |
27/ The Output is a LLL-reduced basis of the Z-lattice generated by           |
28/ (b11,b12,...,b1C),...,(bF1,...,bFC)                                       |
29/                                                                           |
30/ All these outputs are integer numbers.                                    |
31---------------------------------------------------------------------------*/
32
33
34/*---------------------------------------------------------------------------
35| EXAMPLE:                                                                  |
36|                                                                           |
37| Let prf be the file:                                                      |
38| 2,3                                                                       |
39| 1 -2 4                                                                    |
40| 2 1 -7                                                                    |
41| then:                                                                     |
42|                                                                           |
43| ./LLL_lattice <prf                                                        |
44| Output:                                                                   |
45|  1  -2  4                                                                 |
46|  3  -1  -3                                                                |
47|                                                                           |
48| The output is a LLL-reduced basis of the lattice of ZxZxZ generated by    |
49| (1,-2,4),(2,1,-7)                                                         |
50|                                                                           |
51---------------------------------------------------------------------------*/
52
53
54#include <stdio.h>
55#include <stdlib.h>
56#include <ctype.h>
57#include <new>
58#include <cstring>
59#include <gmp.h>
60
61#define LLL_MAX(a,b) (a > b ? a : b)
62
63/* Global variables */
64mpz_t * lll_d;
65mpz_t ** lll_lambda;
66mpz_t ** lll_b;
67
68mpz_t **proc_entrada (int *F, int *C);
69void lll_swapi (int k, int kmax, int C);
70void lll_redi (int k, int l, int C);
71void lll_test (int *k, int kma, int C);
72void lll_product (mpz_t * a, mpz_t * f, int n, mpz_t * prod);
73
74int main (void)
75{
76  int i, j, k, kmax;
77  int F, C;
78  mpz_t prod;
79  mpz_t u;
80  mpz_t auxi1;
81  mpz_t auxi2;
82  mpz_init (prod);
83  mpz_init (u);
84  mpz_init (auxi1);
85  mpz_init (auxi2);
86
87  k = 2;    /* Initialize */
88  kmax = 1; /* Initialize */
89
90  lll_b = proc_entrada (&F, &C);
91
92  lll_d = new mpz_t[F + 1];
93  lll_lambda = new (mpz_t *)[F + 1];
94  mpz_init (lll_d[0]);
95  for (i = 1; i <= F; i++) {
96    mpz_init (lll_d[i]);
97    lll_lambda[i] = new mpz_t[F + 1];
98    for (j = 1; j <= F; j++)
99      mpz_init (lll_lambda[i][j]);
100  }
101  mpz_set_ui (lll_d[0], 1); /* Initialize */
102  lll_product (lll_b[1], lll_b[1], C, &prod);
103  mpz_set (lll_d[1], prod); /* Initialize */
104
105
106/* Incremental Gram-Schmidt */
107  while (k <= F)
108  {
109    if (k > kmax)
110    {
111      kmax = k;
112      for (j = 1; j < k + 1; j++)
113      {
114        lll_product (lll_b[k], lll_b[j], C, &prod);
115        mpz_set (u, prod);
116        for (i = 1; i < j - 1 + 1; i++)
117        {
118          mpz_mul (auxi1, lll_d[i], u);
119          mpz_mul (auxi2, lll_lambda[k][i], lll_lambda[j][i]);
120          mpz_sub (u, auxi1, auxi2);
121          mpz_tdiv_q (u, u, lll_d[i - 1]);
122        }
123        if (j < k)
124        {
125          mpz_set (lll_lambda[k][j], u);
126        }
127        else
128        {
129          mpz_set (lll_d[k], u);
130          if (mpz_cmp_ui (lll_d[k], 0) == 0)
131          { /* The input is not a basis */
132            fprintf (stderr, "\n INPUT NOT BASIS !!!! \n");
133            exit (1);
134          }
135        }
136      }
137    }
138    lll_test (&k, kmax, C);
139    for (i = k - 2; i > 0; i--)
140      lll_redi (k, i, C);
141    k = k + 1;
142  }
143  fprintf (stdout, "list res=");
144  for (i = 1; i < F + 1; i++)
145  {
146    printf ("\nlist(");
147    for (j = 1; j < C + 1; j++)
148    {
149      fprintf (stdout, " ");
150      mpz_out_str (stdout, 0, lll_b[i][j]);
151      if (j!=C) fprintf (stdout, ",");
152    }
153    if (i!=F) printf("),\n");
154    else      printf(");\n");
155  }
156  mpz_clear (auxi1);
157  mpz_clear (auxi2);
158  mpz_clear (u);
159  mpz_clear (prod);
160  mpz_clear (lll_d[0]);
161  for (i = 1; i <= F; i++)
162  {
163    mpz_clear (lll_d[i]);
164    for (j = 1; j <= F; j++)
165      mpz_clear (lll_lambda[i][j]);
166    delete[]lll_lambda[i];
167  }
168  delete[]lll_lambda;
169  delete[]lll_d;
170  for (i = 1; i < F + 1; i++)
171  {
172    for (j = 1; j < C + 1; j++)
173       mpz_clear (lll_b[i][j]);
174    delete[]lll_b[i];
175  }
176  delete[]lll_b;
177  return 0;
178}
179
180/*---------------------------------------------------------------------------
181| proc_entrada {}:                                                          |
182| Read the input file.                                                      |
183|___________________________________________________________________________|*/
184
185mpz_t **proc_entrada (int *F, int *C) /* Inputs */
186{
187  int numF, numC;
188  int i, j, c;
189  mpz_t **base;
190  mpz_t valor;
191  char *aux, caux;
192  int tamano=100;
193
194  aux=new char[tamano];
195  fscanf (stdin, "%i, %i\n", &numF, &numC);
196  base = new (mpz_t *)[numF+1];
197  for (i = 1; i <= numF; i++) {
198    base[i] = new mpz_t[numC+1];
199    for (j = 1; j <= numC; j++)
200    {
201      do { caux=getc (stdin); }
202      while (!feof(stdin) && !(caux=='-' || isdigit(caux)));
203      mpz_init (base[i][j]);
204      c=0;
205      if (!feof(stdin))
206      {
207        do
208        {
209          aux[c++]=caux;
210          if (c==tamano)
211          {
212            char *nuevo=new char[3*tamano/2];
213            memcpy (nuevo, aux, tamano);
214            delete[] aux;
215            aux=nuevo;
216            tamano=3*tamano/2;
217          }
218          caux=getc(stdin);
219        }
220        while (!feof(stdin) && caux!=' ' && caux!='\n' && caux!='\t');
221        aux[c]='\0';
222        mpz_set_str (base[i][j], aux, 0);
223      }
224      else
225      {
226        fprintf(stderr,"Empty file.\n");
227        mpz_set_ui (base[i][j],0);
228      }
229    }
230  }
231  *F = numF;
232  *C = numC;
233  delete[] aux;
234  return (base);
235}
236
237/*---------------------------------------------------------------------------
238| lll_product {}:                                                           |
239| Multiply the integer vectors a and f with n coordinates.                  |
240|___________________________________________________________________________|*/
241
242void  lll_product (mpz_t * a, mpz_t * f, int n, mpz_t * prod)
243{
244  int i;
245  mpz_t auxi;
246
247  mpz_init (auxi);
248  mpz_set_ui (*prod, 0);
249  for (i = 1; i < n + 1; i++)
250  {
251    mpz_mul (auxi, a[i], f[i]);
252    mpz_add (*prod, *prod, auxi);
253  }
254  mpz_clear (auxi);
255}
256
257void lll_test (int *k, int kma, int C) /* Test LLL condition */
258{
259  int i;
260  mpz_t auxi1;
261  mpz_t auxi2;
262  mpz_t auxi3;
263  mpz_t auxi4;
264
265  mpz_init (auxi1);
266  mpz_init (auxi2);
267  mpz_init (auxi3);
268
269  lll_redi (*k, *k - 1, C);
270  mpz_mul (auxi1, lll_d[*k], lll_d[*k - 2]);
271  mpz_mul_ui (auxi1, auxi1, 4);
272  mpz_mul (auxi2, lll_d[*k - 1], lll_d[*k - 1]);
273  mpz_mul_ui (auxi2, auxi2, 3);
274  mpz_mul (auxi3, lll_lambda[*k][*k - 1], lll_lambda[*k][*k - 1]);
275  mpz_mul_ui (auxi3, auxi3, 4);
276  mpz_sub (auxi3, auxi2, auxi3);
277  if (mpz_cmp (auxi1, auxi3) < 0)
278  {
279    lll_swapi (*k, kma, C);
280    *k = LLL_MAX (2, *k - 1);
281    lll_test (&*k, kma, C);
282  }
283
284  mpz_clear (auxi1);
285  mpz_clear (auxi2);
286  mpz_clear (auxi3);
287}
288
289/*---------------------------------------------------------------------------
290| lll_redi {}:                                                              |
291| Make some changes in global variables.                                    |
292|___________________________________________________________________________|*/
293
294
295void lll_redi (int k, int l, int C)
296{
297  int i;
298  mpz_t q;
299  mpz_t auxi1;
300
301  mpz_init (q);
302  mpz_init (auxi1);
303
304  mpz_mul_ui (auxi1, lll_lambda[k][l], 2);
305  mpz_abs (auxi1, auxi1);
306
307    if (mpz_cmp (auxi1, lll_d[l]) > 0)
308    {
309      mpz_mul_ui (auxi1, lll_lambda[k][l], 2);
310      mpz_add (auxi1, auxi1, lll_d[l]);
311      mpz_mul_ui (q, lll_d[l], 2);
312      mpz_fdiv_q (q, auxi1, q);
313      for (i = 1; i < C + 1; i++)
314      {
315        mpz_mul (auxi1, q, lll_b[l][i]);
316        mpz_sub (lll_b[k][i], lll_b[k][i], auxi1);
317      }
318      mpz_mul (auxi1, q, lll_d[l]);
319      mpz_sub (lll_lambda[k][l], lll_lambda[k][l], auxi1);
320      for (i = 1; i <= l - 1; i++)
321      {
322        mpz_mul (auxi1, q, lll_lambda[l][i]);
323        mpz_sub (lll_lambda[k][i], lll_lambda[k][i], auxi1);
324      }
325    }
326    mpz_clear (q);
327    mpz_clear (auxi1);
328}
329
330/*---------------------------------------------------------------------------
331| lll_swapi {}:                                                             |
332| Exchange some global variables                                            |
333|___________________________________________________________________________|*/
334
335void lll_swapi (int k, int kmax, int C)
336{
337  int j;
338  mpz_t lamb;
339  mpz_t B;
340  mpz_t auxi1;
341  mpz_t auxi2;
342  mpz_t t;
343  mpz_t swap;
344
345  mpz_init (lamb);
346  mpz_init (B);
347  mpz_init (auxi1);
348  mpz_init (auxi2);
349  mpz_init (t);
350  mpz_init (swap);
351
352  for (j = 1; j < C + 1; j++)
353  {
354    mpz_set (swap, lll_b[k][j]);
355    mpz_set (lll_b[k][j], lll_b[k - 1][j]);
356    mpz_set (lll_b[k - 1][j], swap);
357  }
358  if (k > 2)
359  {
360    for (j = 1; j <= k - 2; j++)
361    {
362      mpz_set (swap, lll_lambda[k][j]);
363      mpz_set (lll_lambda[k][j], lll_lambda[k - 1][j]);
364      mpz_set (lll_lambda[k - 1][j], swap);
365    }
366  }
367
368  mpz_set (lamb, lll_lambda[k][k - 1]);
369  mpz_mul (auxi1, lll_d[k - 2], lll_d[k]);
370  mpz_mul (auxi2, lamb, lamb);
371  mpz_add (B, auxi1, auxi2);
372  mpz_tdiv_q (B, B, lll_d[k - 1]);
373  for (j = k + 1; j <= kmax; j++)
374  {
375    mpz_set (t, lll_lambda[j][k]);
376    mpz_mul (auxi1, lll_d[k], lll_lambda[j][k - 1]);
377    mpz_mul (auxi2, lamb, t);
378    mpz_sub (auxi1, auxi1, auxi2);
379    mpz_tdiv_q (lll_lambda[j][k], auxi1, lll_d[k - 1]);
380    mpz_mul (auxi2, lamb, lll_lambda[j][k]);
381    mpz_mul (auxi1, B, t);
382    mpz_add (auxi1, auxi1, auxi2);
383    mpz_tdiv_q (lll_lambda[j][k - 1], auxi1, lll_d[k]);
384  }
385  mpz_set (lll_d[k - 1], B);
386
387  mpz_clear (auxi1);
388  mpz_clear (auxi2);
389  mpz_clear (lamb);
390  mpz_clear (B);
391  mpz_clear (t);
392  mpz_clear (swap);
393}
Note: See TracBrowser for help on using the repository browser.