source: git/IntegerProgramming/LLL_lattice_to_send.cc @ 764f5d

spielwiese
Last change on this file since 764f5d was 764f5d, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: Ikernel git-svn-id: file:///usr/local/Singular/svn/trunk@5352 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.2 KB
RevLine 
[9ec090]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
74void 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}
178
179/*---------------------------------------------------------------------------
180| proc_entrada {}:                                                          |
181| Read the input file.                                                      |
182|___________________________________________________________________________|*/
183
184mpz_t **proc_entrada (int *F, int *C) /* Inputs */
185{
186  int numF, numC;
187  int i, j, c;
188  mpz_t **base;
189  mpz_t valor;
190  char *aux, caux;
191  int tamano=100;
192
193  aux=new char[tamano];
194  fscanf (stdin, "%i, %i\n", &numF, &numC);
195  base = new (mpz_t *)[numF+1];
196  for (i = 1; i <= numF; i++) {
197    base[i] = new mpz_t[numC+1];
198    for (j = 1; j <= numC; j++)
199    {
200      do { caux=getc (stdin); }
201      while (!feof(stdin) && !(caux=='-' || isdigit(caux)));
202      mpz_init (base[i][j]);
203      c=0;
204      if (!feof(stdin))
205      {
206        do
207        {
208          aux[c++]=caux;
209          if (c==tamano)
210          {
211            char *nuevo=new char[3*tamano/2];
212            memcpy (nuevo, aux, tamano);
213            delete[] aux;
214            aux=nuevo;
215            tamano=3*tamano/2;
216          }
217          caux=getc(stdin);
218        }
219        while (!feof(stdin) && caux!=' ' && caux!='\n' && caux!='\t');
220        aux[c]='\0';
221        mpz_set_str (base[i][j], aux, 0);
222      }
223      else
224      {
225        fprintf(stderr,"Empty file.\n");
226        mpz_set_ui (base[i][j],0);
227      }
228    }
229  }
230  *F = numF;
231  *C = numC;
232  delete[] aux;
233  return (base);
234}
235
236/*---------------------------------------------------------------------------
237| lll_product {}:                                                           |
238| Multiply the integer vectors a and f with n coordinates.                  |
239|___________________________________________________________________________|*/
240
241void  lll_product (mpz_t * a, mpz_t * f, int n, mpz_t * prod)
242{
243  int i;
244  mpz_t auxi;
245
246  mpz_init (auxi);
247  mpz_set_ui (*prod, 0);
248  for (i = 1; i < n + 1; i++)
249  {
250    mpz_mul (auxi, a[i], f[i]);
251    mpz_add (*prod, *prod, auxi);
252  }
253  mpz_clear (auxi);
254}
255
256void lll_test (int *k, int kma, int C) /* Test LLL condition */
257{
258  int i;
259  mpz_t auxi1;
260  mpz_t auxi2;
261  mpz_t auxi3;
262  mpz_t auxi4;
263
264  mpz_init (auxi1);
265  mpz_init (auxi2);
266  mpz_init (auxi3);
267
268  lll_redi (*k, *k - 1, C);
269  mpz_mul (auxi1, lll_d[*k], lll_d[*k - 2]);
270  mpz_mul_ui (auxi1, auxi1, 4);
271  mpz_mul (auxi2, lll_d[*k - 1], lll_d[*k - 1]);
272  mpz_mul_ui (auxi2, auxi2, 3);
273  mpz_mul (auxi3, lll_lambda[*k][*k - 1], lll_lambda[*k][*k - 1]);
274  mpz_mul_ui (auxi3, auxi3, 4);
275  mpz_sub (auxi3, auxi2, auxi3);
276  if (mpz_cmp (auxi1, auxi3) < 0)
277  {
278    lll_swapi (*k, kma, C);
279    *k = LLL_MAX (2, *k - 1);
280    lll_test (&*k, kma, C);
281  }
282
283  mpz_clear (auxi1);
284  mpz_clear (auxi2);
285  mpz_clear (auxi3);
286}
287
288/*---------------------------------------------------------------------------
289| lll_redi {}:                                                              |
290| Make some changes in global variables.                                    |
291|___________________________________________________________________________|*/
292
293
294void lll_redi (int k, int l, int C)
295{
296  int i;
297  mpz_t q;
298  mpz_t auxi1;
299
300  mpz_init (q);
301  mpz_init (auxi1);
302
303  mpz_mul_ui (auxi1, lll_lambda[k][l], 2);
304  mpz_abs (auxi1, auxi1);
305
306    if (mpz_cmp (auxi1, lll_d[l]) > 0)
307    {
308      mpz_mul_ui (auxi1, lll_lambda[k][l], 2);
309      mpz_add (auxi1, auxi1, lll_d[l]);
310      mpz_mul_ui (q, lll_d[l], 2);
311      mpz_fdiv_q (q, auxi1, q);
312      for (i = 1; i < C + 1; i++)
313      {
314        mpz_mul (auxi1, q, lll_b[l][i]);
315        mpz_sub (lll_b[k][i], lll_b[k][i], auxi1);
316      }
317      mpz_mul (auxi1, q, lll_d[l]);
318      mpz_sub (lll_lambda[k][l], lll_lambda[k][l], auxi1);
319      for (i = 1; i <= l - 1; i++)
320      {
321        mpz_mul (auxi1, q, lll_lambda[l][i]);
322        mpz_sub (lll_lambda[k][i], lll_lambda[k][i], auxi1);
323      }
324    }
325    mpz_clear (q);
326    mpz_clear (auxi1);
327}
328
329/*---------------------------------------------------------------------------
330| lll_swapi {}:                                                             |
331| Exchange some global variables                                            |
332|___________________________________________________________________________|*/
333
334void lll_swapi (int k, int kmax, int C)
335{
336  int j;
337  mpz_t lamb;
338  mpz_t B;
339  mpz_t auxi1;
340  mpz_t auxi2;
341  mpz_t t;
342  mpz_t swap;
343
344  mpz_init (lamb);
345  mpz_init (B);
346  mpz_init (auxi1);
347  mpz_init (auxi2);
348  mpz_init (t);
349  mpz_init (swap);
350
351  for (j = 1; j < C + 1; j++)
352  {
353    mpz_set (swap, lll_b[k][j]);
354    mpz_set (lll_b[k][j], lll_b[k - 1][j]);
355    mpz_set (lll_b[k - 1][j], swap);
356  }
357  if (k > 2)
358  {
359    for (j = 1; j <= k - 2; j++)
360    {
361      mpz_set (swap, lll_lambda[k][j]);
362      mpz_set (lll_lambda[k][j], lll_lambda[k - 1][j]);
363      mpz_set (lll_lambda[k - 1][j], swap);
364    }
365  }
366
367  mpz_set (lamb, lll_lambda[k][k - 1]);
368  mpz_mul (auxi1, lll_d[k - 2], lll_d[k]);
369  mpz_mul (auxi2, lamb, lamb);
370  mpz_add (B, auxi1, auxi2);
371  mpz_tdiv_q (B, B, lll_d[k - 1]);
372  for (j = k + 1; j <= kmax; j++)
373  {
374    mpz_set (t, lll_lambda[j][k]);
375    mpz_mul (auxi1, lll_d[k], lll_lambda[j][k - 1]);
376    mpz_mul (auxi2, lamb, t);
377    mpz_sub (auxi1, auxi1, auxi2);
378    mpz_tdiv_q (lll_lambda[j][k], auxi1, lll_d[k - 1]);
379    mpz_mul (auxi2, lamb, lll_lambda[j][k]);
380    mpz_mul (auxi1, B, t);
381    mpz_add (auxi1, auxi1, auxi2);
382    mpz_tdiv_q (lll_lambda[j][k - 1], auxi1, lll_d[k]);
383  }
384  mpz_set (lll_d[k - 1], B);
385
386  mpz_clear (auxi1);
387  mpz_clear (auxi2);
388  mpz_clear (lamb);
389  mpz_clear (B);
390  mpz_clear (t);
391  mpz_clear (swap);
392}
Note: See TracBrowser for help on using the repository browser.