1 //==============================================================================================
2 //
3 // This file is part of LiDIA --- a library for computational number theory
4 //
5 // Copyright (c) 1994--2001 the LiDIA Group. All rights reserved.
6 //
7 // See http://www.informatik.tu-darmstadt.de/TI/LiDIA/
8 //
9 //----------------------------------------------------------------------------------------------
10 //
11 // $Id$
12 //
13 // Author : Werner Backes (WB), Thorsten Lauer (TL)
14 // Changes : See CVS log
15 //
16 //==============================================================================================
17
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 #include "LiDIA/bigint_lattice.h"
23
24
25
26 #ifdef LIDIA_NAMESPACE
27 namespace LiDIA {
28 #endif
29
30
31
32 //
33 // Set special lattice characteristics
34 //
set_red_orientation_columns()35 void bigint_lattice::set_red_orientation_columns()
36 {
37 debug_handler("bigint_lattice", "set_red_orentation_columns()");
38 bitfield.lattice_mode &= !REDUCE_ROWS;
39 }
40
41
42
set_red_orientation_rows()43 void bigint_lattice::set_red_orientation_rows()
44 {
45 debug_handler("bigint_lattice", "set_red_orentation_rows()");
46 bitfield.lattice_mode |= REDUCE_ROWS;
47 }
48
49
50
set_gram_flag()51 void bigint_lattice::set_gram_flag()
52 {
53 debug_handler("bigint_lattice", "set_gram_flag()");
54 bitfield.info_mode |= GRAM_MATRIX;
55 }
56
57
58
set_basis_flag()59 void bigint_lattice::set_basis_flag()
60 {
61 debug_handler("bigint_lattice", "set_basis_flag()");
62 if (bitfield.lattice_mode & REDUCE_ROWS)
63 bitfield.structure_mode |= ROWS_LININD;
64 else
65 bitfield.structure_mode |= COLUMNS_LININD;
66 }
67
68
69
delete_gram_flag()70 void bigint_lattice::delete_gram_flag()
71 {
72 debug_handler("bigint_lattice", "delete_gram_flag()");
73 bitfield.info_mode &= !GRAM_MATRIX;
74 }
75
76
77
delete_basis_flag()78 void bigint_lattice::delete_basis_flag()
79 {
80 debug_handler("bigint_lattice", "delete_basis_flag()");
81 if (bitfield.lattice_mode & REDUCE_ROWS)
82 bitfield.structure_mode &= !ROWS_LININD;
83 else
84 bitfield.structure_mode &= !COLUMNS_LININD;
85 }
86
87
88
89 //
90 // get the special lattice characteristics
91 //
get_red_orientation()92 bool bigint_lattice::get_red_orientation()
93 {
94 debug_handler("bigint_lattice", "get_red_orentation()");
95 return ((bitfield.lattice_mode & REDUCE_ROWS) ? false : true);
96 // return (!((bool )(bitfield.lattice_mode & REDUCE_ROWS)));
97 }
98
99
100
get_basis_flag()101 bool bigint_lattice::get_basis_flag()
102 {
103 debug_handler("bigint_lattice", "get_basis_flag()");
104 if (bitfield.lattice_mode & REDUCE_ROWS)
105 return ((bitfield.structure_mode & ROWS_LININD) ? true : false);
106 else
107 return ((bitfield.structure_mode & COLUMNS_LININD) ? true : false);
108 }
109
110
111
get_gram_flag()112 bool bigint_lattice::get_gram_flag()
113 {
114 debug_handler("bigint_lattice", "get_gram_flag()");
115 return ((bitfield.structure_mode & GRAM_MATRIX) ? true : false);
116 }
117
118
119
chk_basis()120 bool bigint_lattice::chk_basis()
121 {
122 debug_handler("bigint_lattice", "chk_basis()");
123 if (bitfield.lattice_mode & REDUCE_ROWS)
124 return ((bitfield.structure_mode & ROWS_LININD) ? true : false);
125 else
126 return ((bitfield.structure_mode & COLUMNS_LININD) ? true : false);
127 }
128
129
130
chk_gram()131 bool bigint_lattice::chk_gram()
132 {
133 debug_handler("bigint_lattice", "chk_gram()");
134 return ((bitfield.info_mode & GRAM_MATRIX) ? true : false);
135 // return ((bool )(bitfield.info_mode & GRAM_MATRIX));
136 }
137
138
139
chk_trans()140 bool bigint_lattice::chk_trans()
141 {
142 debug_handler("bigint_lattice", "chk_trans()");
143 if (chk_gram())
144 return (false);
145 else {
146 if (((bitfield.lattice_mode & REDUCE_ROWS) && (bitfield.structure_mode & COLUMN_ORIENTED)) ||
147 (!(bitfield.lattice_mode & REDUCE_ROWS) && !(bitfield.structure_mode & COLUMN_ORIENTED)))
148 return (true);
149 else
150 return (false);
151 }
152 // return (((bool )(bitfield.lattice_mode & REDUCE_ROWS)) ==
153 // ((bool )(bitfield.structure_mode & COLUMN_ORIENTED)));
154
155 }
156
157
158
chk_reduce_columns()159 bool bigint_lattice::chk_reduce_columns()
160 {
161 debug_handler("bigint_lattice", "chk_reduce_columns()");
162 return ((bitfield.lattice_mode & REDUCE_ROWS) ? false : true);
163 // return(!((bool )(bitfield.lattice_mode & REDUCE_ROWS)));
164 }
165
166
167
168 //
169 // Dimension checking
170 //
chk_mlll_dim()171 bool bigint_lattice::chk_mlll_dim()
172 {
173 debug_handler("bigint_lattice", "chk_mlll_dim()");
174 return (rows+static_cast<lidia_size_t>(chk_reduce_columns()) ==
175 columns+static_cast<lidia_size_t>(!chk_reduce_columns()));
176 }
177
178
179
chk_lll_dim()180 bool bigint_lattice::chk_lll_dim()
181 {
182 debug_handler("bigint_lattice", "chk_lll_dim()");
183 bool chk = false;
184 if (chk_gram())
185 chk = (rows == columns);
186 else {
187 if (chk_reduce_columns())
188 chk = (rows >= columns);
189 else
190 chk = (columns >= rows);
191 if (!chk_basis())
192 chk = true;
193 }
194 return (chk);
195 }
196
197
198
199 //
200 // Other checkings
201 //
chk_corr_param(double & y)202 void bigint_lattice::chk_corr_param(double& y)
203 {
204 debug_handler("bigint_lattice", "chk_corr_param(y)");
205 if ((y > 1.0) || (y <= 0.5))
206 y = 0.99;
207 }
208
209
210
chk_corr_param(sdigit & nom,sdigit & denom)211 void bigint_lattice::chk_corr_param(sdigit& nom, sdigit& denom)
212 {
213 debug_handler("bigint_lattice", "chk_corr_param(nom, denom)");
214 double y;
215 y = static_cast<double>(nom)/static_cast<double>(denom);
216 if ((y > 1.0) || (y <= 0.5)) {
217 nom = 99;
218 denom = 100;
219 }
220 }
221
222
223
224 //
225 // Schnorr - Euchner
226 //
lll_schnorr_euchner_orig(double y,lattice_info & li,sdigit x_factor)227 void bigint_lattice::lll_schnorr_euchner_orig(double y, lattice_info& li,
228 sdigit x_factor)
229 {
230 debug_handler("bigint_lattice", "lll_schnorr_euchner_orig(y, li, factor)");
231 ALG_DEF_BASIS(bigint, vector_op, Normal) alg_basis;
232 ALG_DEF_GENSYS(bigint, vector_op, Normal) alg_gensys;
233
234 if (!(chk_lll_dim()))
235 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_orig(y, li, factor) ::"
236 "wrong dimension (no basis)");
237 dense_alg< bigint > da;
238 da.b.y = y;
239 chk_corr_param(da.b.y);
240 da.b.alg_trans = false;
241 x_factor = ((x_factor < 1) ? 1 : x_factor);
242 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
243 Tr_dense_create(da);
244 if (chk_basis()) {
245 if (chk_gram())
246 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
247 else
248 ALG_CALL(alg_basis, lll, da, li, x_factor)
249 }
250 else {
251 if (chk_gram())
252 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
253 else
254 ALG_CALL(alg_gensys, lll, da, li, x_factor)
255 }
256 Tr_dense_extract(da);
257 }
258
259
260
lll_schnorr_euchner_orig(ring_matrix<bigint> & T,double y,lattice_info & li,sdigit x_factor)261 void bigint_lattice::lll_schnorr_euchner_orig(ring_matrix< bigint > & T, double y,
262 lattice_info& li, sdigit x_factor)
263 {
264 debug_handler("bigint_lattice", "lll_schnorr_euchner_orig(T, y, li, factor)");
265 ALG_DEF_BASIS(bigint, vector_op, Normal) alg_basis;
266 ALG_DEF_GENSYS(bigint, vector_op, Normal) alg_gensys;
267
268 if (!(chk_lll_dim()))
269 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_orig(T, y, li, "
270 " factor) :: wrong dimension (no basis)");
271 dense_alg< bigint > da;
272 da.b.y = y;
273 chk_corr_param(da.b.y);
274 da.b.alg_trans = true;
275 da.s.TMatrix = &T;
276 x_factor = ((x_factor < 1) ? 1 : x_factor);
277 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
278 Tr_dense_create(da);
279 if (chk_basis()) {
280 if (chk_gram())
281 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
282 else
283 ALG_CALL(alg_basis, lll, da, li, x_factor)
284 }
285 else {
286 if (chk_gram())
287 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
288 else
289 ALG_CALL(alg_gensys, lll, da, li, x_factor)
290 }
291 Tr_dense_extract(da);
292 }
293
294
295
lll_schnorr_euchner_fact(double y,lattice_info & li,sdigit x_factor)296 void bigint_lattice::lll_schnorr_euchner_fact(double y, lattice_info& li,
297 sdigit x_factor)
298 {
299 debug_handler("bigint_lattice", "lll_schnorr_euchner_fact(y, li, factor)");
300 ALG_DEF_BASIS(bigint, vector_op, VariationI) alg_basis;
301 ALG_DEF_GENSYS(bigint, vector_op, VariationI) alg_gensys;
302
303 if (!(chk_lll_dim()))
304 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_fact(y, li, factor) ::"
305 "wrong dimension (no basis)");
306 dense_alg< bigint > da;
307 da.b.y = y;
308 chk_corr_param(da.b.y);
309 da.b.alg_trans = false;
310 x_factor = ((x_factor < 1) ? 1 : x_factor);
311 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
312 Tr_dense_create(da);
313 da.d.bit_factor = TrD_search_factor(da);
314 if (chk_basis()) {
315 if (chk_gram())
316 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
317 else
318 ALG_CALL(alg_basis, lll, da, li, x_factor)
319 }
320 else {
321 if (chk_gram())
322 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
323 else
324 ALG_CALL(alg_gensys, lll, da, li, x_factor)
325 }
326 Tr_dense_extract(da);
327 }
328
329
330
lll_schnorr_euchner_fact(ring_matrix<bigint> & T,double y,lattice_info & li,sdigit x_factor)331 void bigint_lattice::lll_schnorr_euchner_fact(ring_matrix< bigint > & T, double y,
332 lattice_info& li, sdigit x_factor)
333 {
334 debug_handler("bigint_lattice", "lll_schnorr_euchner_fact(T, y, li, factor)");
335 ALG_DEF_BASIS(bigint, vector_op, VariationI) alg_basis;
336 ALG_DEF_GENSYS(bigint, vector_op, VariationI) alg_gensys;
337
338 if (!(chk_lll_dim()))
339 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_fact(T, y, li, "
340 " factor) :: wrong dimension (no basis)");
341 dense_alg< bigint > da;
342 da.b.y = y;
343 chk_corr_param(da.b.y);
344 da.b.alg_trans = true;
345 da.s.TMatrix = &T;
346 x_factor = ((x_factor < 1) ? 1 : x_factor);
347 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
348 Tr_dense_create(da);
349 da.d.bit_factor = TrD_search_factor(da);
350 if (chk_basis()) {
351 if (chk_gram())
352 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
353 else
354 ALG_CALL(alg_basis, lll, da, li, x_factor)
355 }
356 else {
357 if (chk_gram())
358 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
359 else
360 ALG_CALL(alg_gensys, lll, da, li, x_factor)
361 }
362 Tr_dense_extract(da);
363 }
364
365
366
367 //
368 // Schnorr - Euchner for user defined Scalar Product
369 //
lll_schnorr_euchner_orig(double y,lattice_info & li,user_SP SP,sdigit x_factor)370 void bigint_lattice::lll_schnorr_euchner_orig(double y, lattice_info& li,
371 user_SP SP, sdigit x_factor)
372 {
373 debug_handler("bigint_lattice", "lll_schnorr_euchner_orig(y, li, SP, factor)");
374 ALG_DEF_BASIS(bigint, vector_op_SP, Normal) alg_basis;
375 ALG_DEF_GENSYS(bigint, vector_op_SP, Normal) alg_gensys;
376
377 ALG_POINTER(alg_basis, SP, bin);
378 ALG_POINTER(alg_gensys, SP, bin);
379
380 if (!(chk_lll_dim()))
381 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_orig(y, li, SP, "
382 " factor) :: wrong dimension (no basis)");
383 dense_alg< bigint > da;
384 da.b.y = y;
385 chk_corr_param(da.b.y);
386 da.b.alg_trans = false;
387 x_factor = ((x_factor < 1) ? 1 : x_factor);
388 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
389 Tr_dense_create(da);
390 if (chk_basis()) {
391 if (chk_gram())
392 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
393 else
394 ALG_CALL(alg_basis, lll, da, li, x_factor)
395 }
396 else {
397 if (chk_gram())
398 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
399 else
400 ALG_CALL(alg_gensys, lll, da, li, x_factor)
401 }
402 Tr_dense_extract(da);
403 }
404
405
406
lll_schnorr_euchner_orig(ring_matrix<bigint> & T,double y,lattice_info & li,user_SP SP,sdigit x_factor)407 void bigint_lattice::lll_schnorr_euchner_orig(ring_matrix< bigint > & T, double y,
408 lattice_info& li, user_SP SP,
409 sdigit x_factor)
410 {
411 debug_handler("bigint_lattice", "lll_schnorr_euchner_orig(T, y, li, SP, factor)");
412 ALG_DEF_BASIS(bigint, vector_op_SP, Normal) alg_basis;
413 ALG_DEF_GENSYS(bigint, vector_op_SP, Normal) alg_gensys;
414
415 ALG_POINTER(alg_basis, SP, bin);
416 ALG_POINTER(alg_gensys, SP, bin);
417
418 if (!(chk_lll_dim()))
419 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_orig(T, y, li, SP, "
420 " factor) :: wrong dimension (no basis)");
421 dense_alg< bigint > da;
422 da.b.y = y;
423 chk_corr_param(da.b.y);
424 da.b.alg_trans = true;
425 da.s.TMatrix = &T;
426 x_factor = ((x_factor < 1) ? 1 : x_factor);
427 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
428 Tr_dense_create(da);
429 if (chk_basis()) {
430 if (chk_gram())
431 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
432 else
433 ALG_CALL(alg_basis, lll, da, li, x_factor)
434 }
435 else {
436 if (chk_gram())
437 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
438 else
439 ALG_CALL(alg_gensys, lll, da, li, x_factor)
440 }
441 Tr_dense_extract(da);
442 }
443
444
445
lll_schnorr_euchner_fact(double y,lattice_info & li,user_SP SP,sdigit x_factor)446 void bigint_lattice::lll_schnorr_euchner_fact(double y, lattice_info& li,
447 user_SP SP, sdigit x_factor)
448 {
449 debug_handler("bigint_lattice", "lll_schnorr_euchner_fact(y, li, SP, factor)");
450 ALG_DEF_BASIS(bigint, vector_op_SP, VariationI) alg_basis;
451 ALG_DEF_GENSYS(bigint, vector_op_SP, VariationI) alg_gensys;
452
453 ALG_POINTER(alg_basis, SP, bin);
454 ALG_POINTER(alg_gensys, SP, bin);
455
456 if (!(chk_lll_dim()))
457 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_fact(y, li, SP, "
458 "factor) :: wrong dimension (no basis)");
459 dense_alg< bigint > da;
460 da.b.y = y;
461 chk_corr_param(da.b.y);
462 da.b.alg_trans = false;
463 x_factor = ((x_factor < 1) ? 1 : x_factor);
464 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
465 Tr_dense_create(da);
466 da.d.bit_factor = TrD_search_factor(da);
467 if (chk_basis()) {
468 if (chk_gram())
469 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
470 else
471 ALG_CALL(alg_basis, lll, da, li, x_factor)
472 }
473 else {
474 if (chk_gram())
475 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
476 else
477 ALG_CALL(alg_gensys, lll, da, li, x_factor)
478 }
479 Tr_dense_extract(da);
480 }
481
482
483
lll_schnorr_euchner_fact(ring_matrix<bigint> & T,double y,lattice_info & li,user_SP SP,sdigit x_factor)484 void bigint_lattice::lll_schnorr_euchner_fact(ring_matrix< bigint > & T, double y,
485 lattice_info& li, user_SP SP,
486 sdigit x_factor)
487 {
488 debug_handler("bigint_lattice", "lll_schnorr_euchner_fact(T, y, li, SP, factor)");
489 ALG_DEF_BASIS(bigint, vector_op_SP, VariationI) alg_basis;
490 ALG_DEF_GENSYS(bigint, vector_op_SP, VariationI) alg_gensys;
491
492 ALG_POINTER(alg_basis, SP, bin);
493 ALG_POINTER(alg_gensys, SP, bin);
494
495 if (!(chk_lll_dim()))
496 lidia_error_handler("bigint_lattice", "lll_schnorr_euchner_fact(T, y, li, SP, "
497 "factor) :: wrong dimension (no basis)");
498 dense_alg< bigint > da;
499 da.b.y = y;
500 chk_corr_param(da.b.y);
501 da.b.alg_trans = true;
502 da.s.TMatrix = &T;
503 x_factor = ((x_factor < 1) ? 1 : x_factor);
504 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
505 Tr_dense_create(da);
506 da.d.bit_factor = TrD_search_factor(da);
507 if (chk_basis()) {
508 if (chk_gram())
509 ALG_CALL(alg_basis, lll_gram, da, li, x_factor)
510 else
511 ALG_CALL(alg_basis, lll, da, li, x_factor)
512 }
513 else {
514 if (chk_gram())
515 ALG_CALL(alg_gensys, lll_gram, da, li, x_factor)
516 else
517 ALG_CALL(alg_gensys, lll, da, li, x_factor)
518 }
519 Tr_dense_extract(da);
520 }
521
522
523
524 //
525 // Benne de Weger
526 //
lll_benne_de_weger(sdigit y_nom,sdigit y_denom,lattice_info & li)527 void bigint_lattice::lll_benne_de_weger(sdigit y_nom, sdigit y_denom,
528 lattice_info& li)
529 {
530 debug_handler("bigint_lattice", "lll_benne_de_weger(y_nom, y_denom, li)");
531
532 if (!chk_basis() || !chk_lll_dim() || chk_gram())
533 lidia_error_handler("bigint_lattice", "lll_benne_de_weger(y_nom, y_denom, "
534 "li) :: not implemented for gensys or gram");
535
536 dense_alg< bigint > da;
537 da.b.y_nom = y_nom;
538 da.b.y_denom = y_denom;
539 chk_corr_param(da.b.y_nom, da.b.y_denom);
540 da.b.alg_trans = false;
541 Tr_dense_create(da);
542 TrD_lll(da, li);
543 Tr_dense_extract(da);
544 }
545
546
547
lll_benne_de_weger(ring_matrix<bigint> & T,sdigit y_nom,sdigit y_denom,lattice_info & li)548 void bigint_lattice::lll_benne_de_weger(ring_matrix< bigint > & T,
549 sdigit y_nom, sdigit y_denom,
550 lattice_info& li)
551 {
552 debug_handler("bigint_lattice", "lll_benne_de_weger(T, y_nom, y_denom, li)");
553 if (!chk_basis() || !chk_lll_dim() || chk_gram())
554 lidia_error_handler("bigint_lattice", "lll_benne_de_weger(T, y_nom, y_denom, "
555 " li) :: not implemented for gensys or gram");
556
557 dense_alg< bigint > da;
558 da.b.y_nom = y_nom;
559 da.b.y_denom = y_denom;
560 chk_corr_param(da.b.y_nom, da.b.y_denom);
561 da.b.alg_trans = false;
562 da.s.TMatrix = &T;
563 Tr_dense_create(da);
564 TrD_lll_trans(da, li);
565 Tr_dense_extract(da);
566 if (da.b.transpose)
567 LiDIA::multiply(*this, *this, T);
568 else
569 LiDIA::multiply(*this, T, *this);
570 }
571
572
573
574 //
575 // Buchmann - Kessler
576 //
buchmann_kessler(ring_matrix<bigint> & T,double y,lattice_info & li)577 void bigint_lattice::buchmann_kessler(ring_matrix< bigint > & T, double y,
578 lattice_info& li)
579 {
580 debug_handler("bigint_lattice", "buchmann_kessler(T, y, li)");
581 if (chk_gram())
582 lidia_error_handler("bigint_lattice", "buchmann_kessler(T, y, "
583 " li) :: not avaidable for gram");
584
585 dense_alg< bigint > da;
586 da.b.y = y;
587 chk_corr_param(da.b.y);
588 da.b.alg_trans = true;
589 da.s.TMatrix = &T;
590 Tr_dense_create(da);
591 TrD_buchmann_kessler(da, li);
592 Tr_dense_extract(da);
593 if (da.b.transpose)
594 LiDIA::multiply(*this, *this, T);
595 else
596 LiDIA::multiply(*this, T, *this);
597 }
598
599
600
601 //
602 // Modified lll
603 //
mlll(double y,bigint * & v,lattice_info & li)604 void bigint_lattice::mlll(double y, bigint*& v, lattice_info& li)
605 {
606 debug_handler("bigint_lattice", "mlll(y, v, li)");
607
608 if (!chk_mlll_dim())
609 lidia_error_handler("bigint_lattice", "mlll(y, v, li) ::"
610 " wrong dimension");
611
612 dense_alg< bigint > da;
613 da.b.y = y;
614 chk_corr_param(da.b.y);
615 da.b.alg_trans = false;
616 Tr_dense_create(da);
617 v = TrD_mlll_bfl(da, li);
618 Tr_dense_extract(da);
619 }
620
621
622
mlll(double y,base_vector<bigint> & bv,lattice_info & li)623 void bigint_lattice::mlll(double y, base_vector< bigint > & bv, lattice_info& li)
624 {
625 debug_handler("bigint_lattice", "mlll(y, bv, li)");
626 if (!chk_mlll_dim())
627 lidia_error_handler("bigint_lattice", "mlll(y, bv, li) ::"
628 " wrong dimension");
629
630 dense_alg< bigint > da;
631 bigint *v;
632 da.b.y = y;
633 chk_corr_param(da.b.y);
634 da.b.alg_trans = false;
635 Tr_dense_create(da);
636 v = TrD_mlll_bfl(da, li);
637 base_vector< bigint > temp(v, da.b.rows);
638 bv = temp;
639 Tr_dense_extract(da);
640 }
641
642
643
close_vector(const base_vector<bigint> & v,base_vector<bigint> & cv,sdigit x_factor)644 void bigint_lattice::close_vector(const base_vector< bigint > & v,
645 base_vector< bigint > & cv,
646 sdigit x_factor)
647 {
648 debug_handler("bigint_lattice", "close_vector(v, cv)");
649 ALG_DEF_BASIS(bigint, vector_op, Normal) alg_basis;
650 bigint_lattice cA(*this);
651 dense_alg< bigint > da;
652 lattice_info li;
653 p_vector< bigint > vector;
654 bigfloat sqrtBmax;
655 bigint C, B, Bmax;
656
657 if ((!chk_basis()) || (chk_gram()))
658 lidia_error_handler("bigint_lattice", "close_vector(c, cv) :: "
659 "not implemented for gram or gensys !");
660 cA.set_no_of_rows(get_no_of_rows()+1);
661 cA.set_no_of_columns(get_no_of_columns()+1);
662 da.b.alg_trans = false;
663 x_factor = ((x_factor < 1) ? 1 : x_factor);
664 da.d.bit_prec = x_factor*DOUBLE_MANTISSA_BITS;
665 da.b.y = 0.99;
666 cA.Tr_dense_create(da);
667 vector.vectsize = da.b.columns;
668 //
669 // Berechne C
670 //
671 Bmax.assign_zero();
672 for (lidia_size_t i = 0; i < da.b.rows; i++) {
673 vector.scalprod(B, da.s.value[i], da.s.value[i]);
674 if (B > Bmax)
675 Bmax.assign(B);
676 }
677 sqrtBmax.assign(Bmax);
678 sqrt(sqrtBmax, sqrtBmax);
679 sqrtBmax.divide_by_2();
680 LiDIA::multiply(sqrtBmax, sqrtBmax, sqrt(bigfloat(3.0)));
681 ceil(C, sqrtBmax);
682 //
683 // Insert vector
684 //
685 if (v.size() != da.b.columns-1)
686 lidia_error_handler("bigint_lattice", "close_vector(c, cv) :: "
687 "illegal size of vector !");
688 for (lidia_size_t i = 0; i < da.b.columns-1; i++)
689 da.s.value[da.b.rows-1][i].assign(v[i]);
690 da.s.value[da.b.rows-1][da.b.columns-1].assign(C);
691 ALG_CALL(alg_basis, lll, da, li, x_factor)
692 for (lidia_size_t i = 0; i < da.b.columns-1; i++)
693 LiDIA::subtract(da.s.value[da.b.rows-1][i], v[i], da.s.value[da.b.rows-1][i]);
694 cv.set_size(da.b.columns-1);
695 cv.set_data(da.s.value[da.b.rows-1], da.b.columns-1);
696 }
697
698
699
700 //
701 // Interface to Algorithms
702 //
703 // friend functions
704 //
lll_schnorr_euchner_orig(const bigint_lattice & A,double y,lattice_info & li,sdigit factor)705 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A, double y,
706 lattice_info& li, sdigit factor)
707 {
708 bigint_lattice tA(A);
709 tA.lll_schnorr_euchner_orig(y, li, factor);
710 return(tA);
711 }
712
713
714
lll_schnorr_euchner_orig(const bigint_lattice & A,ring_matrix<bigint> & T,double y,lattice_info & li,sdigit factor)715 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A,
716 ring_matrix< bigint > & T, double y,
717 lattice_info& li, sdigit factor)
718 {
719 bigint_lattice tA(A);
720 tA.lll_schnorr_euchner_orig(T, y, li, factor);
721 return(tA);
722 }
723
724
725
lll_schnorr_euchner_orig(const bigint_lattice & A,double y,sdigit factor)726 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A, double y,
727 sdigit factor)
728 {
729 bigint_lattice tA(A);
730 tA.lll_schnorr_euchner_orig(y, factor);
731 return(tA);
732 }
733
734
735
lll_schnorr_euchner_orig(const bigint_lattice & A,ring_matrix<bigint> & T,double y,sdigit factor)736 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A,
737 ring_matrix< bigint > & T, double y,
738 sdigit factor)
739 {
740 bigint_lattice tA(A);
741 tA.lll_schnorr_euchner_orig(T, y, factor);
742 return(tA);
743 }
744
745
746
747 //
748 // user defined Scalar Product
749 //
lll_schnorr_euchner_orig(const bigint_lattice & A,double y,lattice_info & li,user_SP SP,sdigit factor)750 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A, double y,
751 lattice_info& li, user_SP SP,
752 sdigit factor)
753 {
754 bigint_lattice tA(A);
755 tA.lll_schnorr_euchner_orig(y, li, SP, factor);
756 return(tA);
757 }
758
759
760
lll_schnorr_euchner_orig(const bigint_lattice & A,ring_matrix<bigint> & T,double y,lattice_info & li,user_SP SP,sdigit factor)761 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A,
762 ring_matrix< bigint > & T, double y,
763 lattice_info& li, user_SP SP, sdigit factor)
764 {
765 bigint_lattice tA(A);
766 tA.lll_schnorr_euchner_orig(T, y, li, SP, factor);
767 return(tA);
768 }
769
770
771
lll_schnorr_euchner_orig(const bigint_lattice & A,double y,user_SP SP,sdigit factor)772 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A, double y,
773 user_SP SP, sdigit factor)
774 {
775 bigint_lattice tA(A);
776 tA.lll_schnorr_euchner_orig(y, SP, factor);
777 return(tA);
778 }
779
780
781
lll_schnorr_euchner_orig(const bigint_lattice & A,ring_matrix<bigint> & T,double y,user_SP SP,sdigit factor)782 bigint_lattice lll_schnorr_euchner_orig(const bigint_lattice& A,
783 ring_matrix< bigint > & T, double y,
784 user_SP SP, sdigit factor)
785 {
786 bigint_lattice tA(A);
787 tA.lll_schnorr_euchner_orig(T, y, SP, factor);
788 return(tA);
789 }
790
791
792
793 //
794 // Variation of Schnorr - Euchner
795 //
796 // friend functions
797 //
lll_schnorr_euchner_fact(const bigint_lattice & A,double y,lattice_info & li,sdigit factor)798 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A, double y,
799 lattice_info& li, sdigit factor)
800 {
801 bigint_lattice tA(A);
802 tA.lll_schnorr_euchner_fact(y, li, factor);
803 return(tA);
804 }
805
806
807
lll_schnorr_euchner_fact(const bigint_lattice & A,ring_matrix<bigint> & T,double y,lattice_info & li,sdigit factor)808 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A,
809 ring_matrix< bigint > & T, double y,
810 lattice_info& li, sdigit factor)
811 {
812 bigint_lattice tA(A);
813 tA.lll_schnorr_euchner_fact(T, y, li, factor);
814 return(tA);
815 }
816
817
818
lll_schnorr_euchner_fact(const bigint_lattice & A,double y,sdigit factor)819 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A, double y,
820 sdigit factor)
821 {
822 bigint_lattice tA(A);
823 tA.lll_schnorr_euchner_fact(y, factor);
824 return(tA);
825 }
826
827
828
lll_schnorr_euchner_fact(const bigint_lattice & A,ring_matrix<bigint> & T,double y,sdigit factor)829 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A,
830 ring_matrix< bigint > & T, double y,
831 sdigit factor)
832 {
833 bigint_lattice tA(A);
834 tA.lll_schnorr_euchner_fact(T, y, factor);
835 return(tA);
836 }
837
838
839
840 //
841 // user defined Scalar Product
842 //
lll_schnorr_euchner_fact(const bigint_lattice & A,double y,lattice_info & li,user_SP SP,sdigit factor)843 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A, double y,
844 lattice_info& li, user_SP SP,
845 sdigit factor)
846 {
847 bigint_lattice tA(A);
848 tA.lll_schnorr_euchner_fact(y, li, SP, factor);
849 return(tA);
850 }
851
852
853
lll_schnorr_euchner_fact(const bigint_lattice & A,ring_matrix<bigint> & T,double y,lattice_info & li,user_SP SP,sdigit factor)854 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A,
855 ring_matrix< bigint > & T, double y,
856 lattice_info& li, user_SP SP, sdigit factor)
857 {
858 bigint_lattice tA(A);
859 tA.lll_schnorr_euchner_fact(T, y, li, SP, factor);
860 return(tA);
861 }
862
863
864
lll_schnorr_euchner_fact(const bigint_lattice & A,double y,user_SP SP,sdigit factor)865 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A, double y,
866 user_SP SP, sdigit factor)
867 {
868 bigint_lattice tA(A);
869 tA.lll_schnorr_euchner_fact(y, SP, factor);
870 return(tA);
871 }
872
873
874
lll_schnorr_euchner_fact(const bigint_lattice & A,ring_matrix<bigint> & T,double y,user_SP SP,sdigit factor)875 bigint_lattice lll_schnorr_euchner_fact(const bigint_lattice& A,
876 ring_matrix< bigint > & T, double y,
877 user_SP SP, sdigit factor)
878 {
879 bigint_lattice tA(A);
880 tA.lll_schnorr_euchner_fact(T, y, SP, factor);
881 return(tA);
882 }
883
884
885
886 //
887 // Benne de Weger
888 //
889 // friend functions
890 //
lll_benne_de_weger(const bigint_lattice & A,sdigit y_nom,sdigit y_denom,lattice_info & li)891 bigint_lattice lll_benne_de_weger(const bigint_lattice& A,
892 sdigit y_nom, sdigit y_denom,
893 lattice_info& li)
894 {
895 bigint_lattice tA(A);
896 tA.lll_benne_de_weger(y_nom, y_denom, li);
897 return(tA);
898 }
899
900
901
lll_benne_de_weger(const bigint_lattice & A,ring_matrix<bigint> & T,sdigit y_nom,sdigit y_denom,lattice_info & li)902 bigint_lattice lll_benne_de_weger(const bigint_lattice& A,
903 ring_matrix< bigint > & T,
904 sdigit y_nom, sdigit y_denom,
905 lattice_info& li)
906 {
907 bigint_lattice tA(A);
908 tA.lll_benne_de_weger(T, y_nom, y_denom, li);
909 return(tA);
910 }
911
912
913
lll_benne_de_weger(const bigint_lattice & A,sdigit y_nom,sdigit y_denom)914 bigint_lattice lll_benne_de_weger(const bigint_lattice& A,
915 sdigit y_nom, sdigit y_denom)
916 {
917 bigint_lattice tA(A);
918 tA.lll_benne_de_weger(y_nom, y_denom);
919 return(tA);
920 }
921
922
923
lll_benne_de_weger(const bigint_lattice & A,ring_matrix<bigint> & T,sdigit y_nom,sdigit y_denom)924 bigint_lattice lll_benne_de_weger(const bigint_lattice& A,
925 ring_matrix< bigint > & T,
926 sdigit y_nom, sdigit y_denom)
927 {
928 bigint_lattice tA(A);
929 tA.lll_benne_de_weger(T, y_nom, y_denom);
930 return(tA);
931 }
932
933
934
935 //
936 // Buchmann - Kessler
937 //
buchmann_kessler(const bigint_lattice & A,ring_matrix<bigint> & T,double y,lattice_info & li)938 bigint_lattice buchmann_kessler(const bigint_lattice& A,
939 ring_matrix< bigint > & T,
940 double y, lattice_info& li)
941 {
942 bigint_lattice tA(A);
943 tA.buchmann_kessler(T, y, li);
944 return(tA);
945 }
946
947
948
buchmann_kessler(const bigint_lattice & A,ring_matrix<bigint> & T,double y)949 bigint_lattice buchmann_kessler(const bigint_lattice& A,
950 ring_matrix< bigint > & T, double y)
951 {
952 bigint_lattice tA(A);
953 tA.buchmann_kessler(T, y);
954 return(tA);
955 }
956
957
958
959 //
960 // Modified lll
961 //
962 // friend functions
963 //
mlll(const bigint_lattice & A,double y,bigint * & v,lattice_info & li)964 bigint_lattice mlll(const bigint_lattice& A, double y,
965 bigint*& v, lattice_info& li)
966 {
967 bigint_lattice tA(A);
968 tA.mlll(y, v, li);
969 return(tA);
970 }
971
972
973
mlll(const bigint_lattice & A,double y,base_vector<bigint> & v,lattice_info & li)974 bigint_lattice mlll(const bigint_lattice& A, double y,
975 base_vector< bigint > & v, lattice_info& li)
976 {
977 bigint_lattice tA(A);
978 tA.mlll(y, v, li);
979 return(tA);
980 }
981
982
983
mlll(const bigint_lattice & A,double y,bigint * & v)984 bigint_lattice mlll(const bigint_lattice& A, double y, bigint*& v)
985 {
986 bigint_lattice tA(A);
987 tA.mlll(y, v);
988 return(tA);
989 }
990
991
992
mlll(const bigint_lattice & A,double y,base_vector<bigint> & v)993 bigint_lattice mlll(const bigint_lattice& A, double y, base_vector< bigint > & v)
994 {
995 bigint_lattice tA(A);
996 tA.mlll(y, v);
997 return(tA);
998 }
999
1000
1001
1002 //
1003 // Other Things
1004 //
1005 // flag - checkings
1006 //
check_basis()1007 bool bigint_lattice::check_basis()
1008 {
1009 debug_handler("bigint_lattice", "check_basis()");
1010 dense_alg< bigint > da;
1011 bool flag;
1012
1013 da.b.alg_trans = false;
1014 Tr_dense_create(da);
1015 flag = TrD_check_basis(da);
1016 Tr_dense_extract(da);
1017 if (flag)
1018 set_basis_flag();
1019 return(flag);
1020 }
1021
1022
1023
check_gram()1024 bool bigint_lattice::check_gram()
1025 {
1026 debug_handler("bigint_lattice", "check_gram()");
1027 dense_alg< bigint > da;
1028 bool flag;
1029
1030 da.b.alg_trans = false;
1031 Tr_dense_create(da);
1032 flag = TrD_check_gram(da);
1033 Tr_dense_extract(da);
1034 if (flag)
1035 set_gram_flag();
1036 return(flag);
1037 }
1038
1039
1040
1041 //
1042 // lll - checkings
1043 //
lll_check(sdigit nom,sdigit denom)1044 bool bigint_lattice::lll_check(sdigit nom, sdigit denom)
1045 {
1046 debug_handler("bigint_lattice", "lll_check(nom, denom)");
1047 dense_alg< bigint > da;
1048 bool red_flag;
1049
1050 if (chk_gram())
1051 lidia_error_handler("bigint_lattice", "lll_check(nom, denom) "
1052 ":: not avaidable for gram");
1053
1054 da.b.y = static_cast<double>(nom)/static_cast<double>(denom);
1055 da.b.alg_trans = false;
1056 if ((da.b.y > 1.0) || (da.b.y < 0.5)) {
1057 lidia_warning_handler("bigint_lattice", "lll_check(nom, denom) :: "
1058 "no allowed y for schnorr - euchner - lll");
1059 return(false);
1060 }
1061 Tr_dense_create(da);
1062 red_flag = TrD_lll_check(da, nom, denom);
1063 Tr_dense_extract(da);
1064 return(red_flag);
1065 }
1066
1067
1068
lll_check_search(sdigit & nom,sdigit & denom)1069 void bigint_lattice::lll_check_search(sdigit& nom, sdigit& denom)
1070 {
1071 debug_handler("bigint_lattice", "lll_check_search(nom, denom)");
1072 dense_alg< bigint > da;
1073
1074 if (chk_gram())
1075 lidia_error_handler("bigint_lattice", "lll_check_search(nom, denom) "
1076 ":: not avaidable for gram");
1077
1078 da.b.alg_trans = false;
1079 Tr_dense_create(da);
1080 TrD_lll_check_search(da, nom, denom);
1081 Tr_dense_extract(da);
1082 }
1083
1084
1085
1086 //
1087 // Creating needed structure for dense lattice algorithms
1088 //
1089 // Reducing 2 matrix assignments in performing transposition
1090 // 2*rows*columns real bigint (> 4 Bytes) assignments to
1091 // 2*rows*columns*3 pointer assignments (4 Bytes)
1092 //
Tr_dense_create(dense_alg<bigint> & da)1093 void bigint_lattice::Tr_dense_create(dense_alg< bigint > & da)
1094 {
1095 debug_handler("bigint_lattice", "Tr_dense_create(da)");
1096
1097 // Hier soll spaeter die Abfrage nach dem entspr. Bit hin !!
1098 if (!(da.b.transpose = chk_trans())) {
1099 //
1100 // Copy pointer only, no trans needed
1101 //
1102 da.b.rows = rows;
1103 da.b.columns = columns;
1104 if (da.b.alg_trans)
1105 da.b.real_columns = da.b.rows+da.b.columns;
1106 else
1107 da.b.real_columns = da.b.columns;
1108 da.b.rank = da.b.rows;
1109 resize(da.b.rows, da.b.real_columns);
1110 da.s.value = value;
1111 //
1112 // If trans - version, concate identic matrix
1113 //
1114 for (lidia_size_t i = da.b.columns; i < da.b.real_columns; i++)
1115 da.s.value[i-da.b.columns][i].assign_one();
1116 }
1117 else {
1118 //
1119 // Transpose and swap matrix, structure of bigint_lattice will be
1120 // destroyed
1121 //
1122 da.b.rows = columns;
1123 da.b.columns = rows;
1124 if (da.b.alg_trans)
1125 da.b.real_columns = da.b.rows+da.b.columns;
1126 else
1127 da.b.real_columns = da.b.columns;
1128 da.b.rank = da.b.rows;
1129
1130 //
1131 // Allocate space for transposed structure
1132 //
1133 da.s.value = new bigint*[da.b.rows];
1134 memory_handler(da.s.value, "bigint_lattice", "Tr_dense_create(da) :: "
1135 "not enough memory !");
1136 da.s.delvalue = new bigint[da.b.rows*da.b.real_columns];
1137 memory_handler(da.s.delvalue, "bigint_lattice", "Tr_dense_create(da) ::"
1138 "not enough memory !");
1139
1140 for (lidia_size_t i = 0; i < da.b.rows; i++)
1141 da.s.value[i] = &da.s.delvalue[i*da.b.real_columns];
1142 for (lidia_size_t i = 0; i < da.b.rows; i++)
1143 for (lidia_size_t j = 0; j < da.b.columns; j++)
1144 LiDIA::swap(value[j][i], da.s.value[i][j]);
1145 //
1146 // If trans - version, concate identic matrix
1147 //
1148 for (lidia_size_t i = da.b.columns; i < da.b.real_columns; i++)
1149 da.s.value[i-da.b.columns][i].assign_one();
1150 }
1151 }
1152
1153
1154
1155 //
1156 // Extracting lattice after performing a dense lattice algorithm
1157 // (See Tr_dense_create() above)
1158 //
Tr_dense_extract(const dense_alg<bigint> & da)1159 void bigint_lattice::Tr_dense_extract(const dense_alg< bigint > & da)
1160 {
1161 debug_handler("bigint_lattice", "Tr_dense_create(da)");
1162 bigint **Taddr;
1163
1164 // Hier soll spaeter die Abfrage nach dem entspr. Bit hin !!
1165 if (!da.b.transpose) {
1166 value = da.s.value;
1167 //
1168 // Trans matrix computed ->
1169 // extract and store into da.TMatrix
1170 //
1171 if (da.b.alg_trans) {
1172 (da.s.TMatrix)->resize(da.b.rows, da.b.rows);
1173 Taddr = (da.s.TMatrix)->get_data_address();
1174 for (lidia_size_t i = 0; i < da.b.rows; i++)
1175 for (lidia_size_t j = 0; j < da.b.rows; j++)
1176 LiDIA::swap(Taddr[i][j], da.s.value[i][j+da.b.columns]);
1177 }
1178 resize(da.b.rows, da.b.columns);
1179 }
1180 else {
1181 resize(da.b.columns, da.b.rows);
1182 for (lidia_size_t i = 0; i < da.b.rows; i++)
1183 for (lidia_size_t j = 0; j < da.b.columns; j++)
1184 LiDIA::swap(da.s.value[i][j], value[j][i]);
1185 //
1186 // Trans matrix computed ->
1187 // extract and store transposed into da.TMatrix
1188 //
1189 if (da.b.alg_trans) {
1190 (da.s.TMatrix)->resize(da.b.rows, da.b.rows);
1191 Taddr = (da.s.TMatrix)->get_data_address();
1192 for (lidia_size_t i = 0; i < da.b.rows; i++)
1193 for (lidia_size_t j = 0; j < da.b.rows; j++)
1194 LiDIA::swap(Taddr[j][i], da.s.value[i][j+da.b.columns]);
1195 }
1196 //
1197 // Free storage allocated by Tr_dense_create !!
1198 // Every Tr_dense_create is followed by a Tr_dense_extract
1199 //
1200 delete[] da.s.delvalue;
1201 delete[] da.s.value;
1202 }
1203 }
1204
1205
1206
randomize_vectors()1207 void bigint_lattice::randomize_vectors()
1208 {
1209 debug_handler("bigint_lattice", "randomize_vectors()");
1210 //
1211 // First step is to transpose the lattice
1212 // Second is to generate a permutation of the rows (using random - functions)
1213 // Third to transpose again
1214 //
1215 dense_alg< bigint > da;
1216 da.b.alg_trans = false;
1217 Tr_dense_create(da);
1218 TrD_randomize_vectors(da);
1219 Tr_dense_extract(da);
1220 }
1221
1222
1223
sort_big_vectors()1224 void bigint_lattice::sort_big_vectors()
1225 {
1226 debug_handler("bigint_lattice", "sort_big_vectors()");
1227 //
1228 // First step is to transpose the lattice
1229 // Second is to sort the rows by length (biggest first)
1230 // Third to transpose again
1231 //
1232 dense_alg< bigint > da;
1233 da.b.alg_trans = false;
1234 Tr_dense_create(da);
1235 TrD_sort_vectors(da, 1);
1236 Tr_dense_extract(da);
1237 }
1238
1239
1240
sort_small_vectors()1241 void bigint_lattice::sort_small_vectors()
1242 {
1243 debug_handler("bigint_lattice", "sort_small_vectors()");
1244 //
1245 // First step is to transpose the lattice
1246 // Second is to sort the rows by length (smallest first)
1247 // Third to transpose again
1248 //
1249 dense_alg< bigint > da;
1250 da.b.alg_trans = false;
1251 Tr_dense_create(da);
1252 TrD_sort_vectors(da, -1);
1253 Tr_dense_extract(da);
1254 }
1255
1256
1257
sort_vectors(bin_cmp_func cpf)1258 void bigint_lattice::sort_vectors(bin_cmp_func cpf)
1259 {
1260 debug_handler("bigint_lattice", "sort_vectors(cpf)");
1261 //
1262 // First step is to transpose the lattice
1263 // Second is to sort the rows by the given compare functions cpf
1264 // (See header file for more information)
1265 // Third to transpose again
1266 //
1267 dense_alg< bigint > da;
1268 da.b.alg_trans = false;
1269 Tr_dense_create(da);
1270 TrD_sort_vectors(da, cpf);
1271 Tr_dense_extract(da);
1272 }
1273
1274
1275
1276 //
1277 // Routine needed by another variation of the schnorr - euchner - lll
1278 // try to reduced lattices with bigger entries with less precision
1279 // for the approximation (try to use doubles)
1280 //
TrD_search_factor(const dense_alg<bigint> & da)1281 sdigit bigint_lattice::TrD_search_factor(const dense_alg< bigint > & da)
1282 {
1283 debug_handler("bigint_lattice", "TrD_search_factor(da)");
1284 sdigit min_bits = da.s.value[0][0].bit_length();
1285 sdigit max_bits = 0;
1286 sdigit bi_bit_len;
1287
1288 for (lidia_size_t i = 0; i < da.b.rows; i++)
1289 for (lidia_size_t j = 0; j < da.b.columns; j++) {
1290 if ((bi_bit_len = da.s.value[i][j].bit_length()) < min_bits)
1291 min_bits = bi_bit_len;
1292 if (bi_bit_len > max_bits)
1293 max_bits = bi_bit_len;
1294 }
1295 return ((max_bits+min_bits) << 1);
1296 }
1297
1298
1299
1300 //
1301 // Algorithm`s
1302 //
1303 //
1304 // Real implementation of the algorithms
1305 // They are working on the transposed lattice
1306 //
TrD_randomize_vectors(dense_alg<bigint> & da)1307 void bigint_lattice::TrD_randomize_vectors(dense_alg< bigint > & da)
1308 {
1309 debug_handler("bigint_lattice", "TrD_randomize_vectors(da)");
1310 random_generator rg;
1311 char *bitvect;
1312 sdigit *perm;
1313 sdigit ran;
1314 bigint **temp;
1315
1316
1317 //
1318 // Allocate memory
1319 //
1320 bitvect = new char[da.b.rows];
1321 memory_handler(bitvect, "bigint_lattice", "TrD_randomize_vectors(da) :: "
1322 "not enough memory !");
1323 perm = new sdigit[da.b.rows];
1324 memory_handler(perm, "bigint_lattice", "TrD_randomize_vectors(da) :: "
1325 "not enough memory !");
1326 temp = new bigint*[da.b.rows];
1327 memory_handler(temp, "bigint_lattice", "TrD_randomize_vectors(da) :: "
1328 "not enough memory !");
1329
1330 //
1331 // Clear bitvector
1332 //
1333 for (lidia_size_t i = 0; i < da.b.rows; bitvect[i++] = 0);
1334 //
1335 // Generate a permutation
1336 // Try rows times to find valid value
1337 //
1338 for (lidia_size_t i = 0; i < da.b.rows; i++) {
1339 for (lidia_size_t j = 0; j < da.b.rows; j++) {
1340 rg >> ran;
1341 ran = ran%da.b.rows;
1342 if (bitvect[ran] == 0) {
1343 bitvect[ran] = 1;
1344 perm[i] = ran;
1345 break;
1346 }
1347 else
1348 if (j == rows-1) {
1349 for (lidia_size_t l = 0; l < da.b.rows; l++)
1350 if (bitvect[l] == 0) {
1351 perm[i] = l;
1352 bitvect[l] = 1;
1353 break;
1354 }
1355 break;
1356 }
1357 }
1358 }
1359
1360 //
1361 // Perform permutation on lattice
1362 //
1363 for (lidia_size_t i = 0; i < da.b.rows; i++)
1364 temp[perm[i]] = da.s.value[i];
1365 for (lidia_size_t i = 0; i < da.b.rows; i++)
1366 da.s.value[i] = temp[i];
1367
1368 //
1369 // Free allocated storage
1370 //
1371 delete[] perm;
1372 delete[] bitvect;
1373 delete[] temp;
1374 }
1375
1376
1377
TrD_sort_vectors(dense_alg<bigint> & da,sdigit vgl)1378 void bigint_lattice::TrD_sort_vectors(dense_alg< bigint > & da, sdigit vgl)
1379 {
1380 debug_handler("bigint_lattice", "TrD_sort_vectors(da, vgl)");
1381 p_vector< bigint > vector;
1382 bigint *quads;
1383
1384 //
1385 // Allocate memory for scalar product of the vectors
1386 //
1387 quads = new bigint[da.b.rows];
1388 memory_handler(quads, "bigint_lattice", "TrD_sort_vectors(da, vgl) :: "
1389 "not enough memory !");
1390
1391 //
1392 // Compute scalar products
1393 //
1394 vector.vectsize = da.b.columns;
1395 for (lidia_size_t i = 0; i < da.b.rows; i++)
1396 vector.scalprod(quads[i], da.s.value[i], da.s.value[i]);
1397 //
1398 // sort by scalar products ("length^2")
1399 // vgl = -1 -> smallest vector first
1400 // vgl = 1 -> biggest vector first
1401 //
1402 for (lidia_size_t i = 0; i < da.b.rows-1; i++)
1403 for (lidia_size_t j = i+1; j < da.b.rows; j++) {
1404 if (quads[i].compare(quads[j]) == vgl) {
1405 vector.swap(da.s.value[i], da.s.value[j]);
1406 LiDIA::swap(quads[i], quads[j]);
1407 }
1408 }
1409 //
1410 // Free allocated storage
1411 //
1412 delete[] quads;
1413 }
1414
1415
1416
TrD_sort_vectors(dense_alg<bigint> & da,bin_cmp_func cpf)1417 void bigint_lattice::TrD_sort_vectors(dense_alg< bigint > & da, bin_cmp_func cpf)
1418 {
1419 debug_handler("bigint_lattice", "TrD_sort_vectors(da, cpf)");
1420 p_vector< bigint > vector;
1421 //
1422 // Sort vectors by specified compare function cpf
1423 // Perform bubble sort (for typical sizes of the
1424 // lattice quicksort not nessesary)
1425 //
1426 vector.vectsize = da.b.columns;
1427 for (lidia_size_t i = 0; i < da.b.rows-1; i++)
1428 for (lidia_size_t j = i+1; j < da.b.rows; j++)
1429 if (cpf(da.s.value[i], da.s.value[j], da.b.columns) > 0)
1430 vector.swap(da.s.value[i], da.s.value[j]);
1431 }
1432
1433
1434
TrD_gram_schmidt_orth_bdw(const dense_alg<bigint> & da,bigint ** my,bigint ** gso,bigint * v)1435 bool bigint_lattice::TrD_gram_schmidt_orth_bdw(const dense_alg< bigint > & da,
1436 bigint** my, bigint** gso,
1437 bigint* v)
1438 {
1439 debug_handler("bigint_lattice", "TrD_gram_schmidt_orth_bdw(da, my, gso, v)");
1440
1441 bigint* tempPbin0;
1442 bigint* tempPbin1;
1443 p_vector< bigint > vector;
1444
1445 if (da.b.rows > da.b.columns)
1446 return(false);
1447
1448 tempPbin0 = new bigint[da.b.rows+da.b.columns+1];
1449 memory_handler(tempvect0, "bigint_lattice", "TrD_gram_schmidt_orth_bdw(da, my, "
1450 " gso, v) :: not enough memory !");
1451 tempPbin1 = &tempPbin0[da.b.rows+1];
1452
1453 vector.vectsize = da.b.rows+1;
1454 vector.assign_zero(tempPbin0);
1455 tempPbin0[0].assign_one();
1456 vector.vectsize = da.b.columns;
1457
1458 for (lidia_size_t i = 0; i < da.b.rows; i++) {
1459 vector.assign(gso[i], da.s.value[i]);
1460 for (lidia_size_t j = 0; j < i; j++) {
1461 vector.scalprod(my[j][i], da.s.value[i], gso[j]);
1462 for (lidia_size_t cx = 0; cx < da.b.columns; cx++) {
1463 LiDIA::multiply(gso[i][cx], tempPbin0[j+1], gso[i][cx]);
1464 LiDIA::multiply(tempPbin1[cx], my[j][i], gso[j][cx]);
1465 LiDIA::subtract(gso[i][cx], gso[i][cx], tempPbin1[cx]);
1466 }
1467 if (tempPbin0[j].is_zero()) {
1468 delete[] tempPbin0;
1469 return(false);
1470 }
1471 for (lidia_size_t m = 0; m < da.b.columns; m++)
1472 LiDIA::divide(gso[i][m], gso[i][m], tempPbin0[j]);
1473 }
1474 vector.scalprod(tempPbin0[i+1], gso[i], gso[i]);
1475 if (tempPbin0[i].is_zero()) {
1476 delete[] tempPbin0;
1477 return(false);
1478 }
1479 else
1480 LiDIA::divide(tempPbin0[i+1], tempPbin0[i+1], tempPbin0[i]);
1481 }
1482 vector.vectsize = da.b.rows+1;
1483 vector.assign(v, tempPbin0);
1484 delete[] tempPbin0;
1485 return(true);
1486 }
1487
1488
1489
TrD_lll_check(const dense_alg<bigint> & da,sdigit y_nom,sdigit y_denom)1490 bool bigint_lattice::TrD_lll_check(const dense_alg< bigint > & da,
1491 sdigit y_nom, sdigit y_denom)
1492 {
1493 debug_handler("bigint_lattice", "Tr_lll_check(da, y_nom, y_denom)");
1494 bigint tempbin0;
1495 bigint tempbin1;
1496 bigint tempbin2;
1497 bigint* tempPbin0;
1498 bigint** my;
1499 bigint* mydel;
1500 bigint** gso;
1501 p_vector< bigint > vector;
1502
1503 my = new bigint*[da.b.rows*2];
1504 memory_handler(my, "bigint_lattice", "Tr_lll_check(da, y_nom, y_denom) :: "
1505 "not enough memory !");
1506 mydel = new bigint[da.b.rows*(da.b.rows+da.b.columns)];
1507 memory_handler(mydel, "bigint_lattice", "Tr_lll_check(da, y_nom, y_denom) :: "
1508 "not enough memory !");
1509 gso = &my[da.b.rows];
1510 for (lidia_size_t i = 0; i < da.b.rows; i++) {
1511 my[i] = &mydel[i*da.b.rows];
1512 gso[i] = &mydel[da.b.rows*da.b.rows+i*da.b.columns];
1513 }
1514
1515 tempPbin0 = new bigint[da.b.rows+1];
1516 memory_handler(tempvect0, "bigint_lattice", "Tr_lll_check(da, y_nom, "
1517 "y_denom) :: not enough memory !");
1518
1519 if (!TrD_gram_schmidt_orth_bdw(da, my, gso, tempPbin0)) {
1520 delete[] mydel;
1521 delete[] my;
1522 delete[] tempPbin0;
1523 lidia_error_handler("bigint_lattice", "Tr_lll_check(da, y_nom, "
1524 "y_denom) :: lattice is no basis !");
1525 return (false);
1526 }
1527
1528 for (lidia_size_t i = 0; i < da.b.rows; i++)
1529 for (lidia_size_t j = 0; j < i; j++) {
1530 tempbin0.assign(abs(my[j][i]));
1531 tempbin0.multiply_by_2();
1532 if (tempbin0 > tempPbin0[j+1]) {
1533 delete[] mydel;
1534 delete[] my;
1535 delete[] tempPbin0;
1536 return (false);
1537 }
1538 }
1539 vector.vectsize = da.b.columns;
1540 for (lidia_size_t i = 1; i < da.b.rows; i++) {
1541 LiDIA::square(tempbin0, tempPbin0[i]);
1542 LiDIA::multiply(tempbin1, tempbin0, y_nom);
1543
1544 LiDIA::square(tempbin0, my[i-1][i]);
1545 LiDIA::multiply(tempbin2, tempbin0, y_denom);
1546 LiDIA::subtract(tempbin0, tempbin1, tempbin2);
1547 LiDIA::multiply(tempbin1, tempPbin0[i-1], tempPbin0[i+1]);
1548 LiDIA::multiply(tempbin2, tempbin1, y_denom);
1549
1550 if (tempbin2 < tempbin0) {
1551 delete[] mydel;
1552 delete[] my;
1553 delete[] tempPbin0;
1554 return(false);
1555 }
1556
1557 }
1558 delete[] mydel;
1559 delete[] my;
1560 delete[] tempPbin0;
1561 return (true);
1562 }
1563
1564
1565
TrD_lll_check_search(const dense_alg<bigint> & da,sdigit & a,sdigit & b)1566 void bigint_lattice::TrD_lll_check_search(const dense_alg< bigint > & da,
1567 sdigit& a, sdigit& b)
1568 {
1569 debug_handler("bigint_lattice", "Tr_lll_check_search(da, a, b)");
1570 bool success;
1571 sdigit param_nom = 3;
1572 sdigit param_den = 4;
1573 sdigit upper_nom = 4;
1574 sdigit upper_den = 4;
1575 sdigit downer_nom = 2;
1576 sdigit downer_den = 4;
1577 bigint tempbin0;
1578 bigint tempbin1;
1579 bigint tempbin2;
1580 bigint tempbin3;
1581 bigint* tempPbin0;
1582 bigint** my;
1583 bigint* mydel;
1584 bigint** gso;
1585 p_vector< bigint > vector;
1586
1587
1588 my = new bigint*[da.b.rows*2];
1589 memory_handler(my, "bigint_lattice", "Tr_lll_check_search(da, a, b) :: "
1590 "not enough memory !");
1591 mydel = new bigint[da.b.rows*(da.b.rows+da.b.columns)];
1592 memory_handler(mydel, "bigint_lattice", "Tr_lll_check_search(da, a, b) :: "
1593 "not enough memory !");
1594 gso = &my[da.b.rows];
1595 for (lidia_size_t i = 0; i < da.b.rows; i++) {
1596 my[i] = &mydel[i*da.b.rows];
1597 gso[i] = &mydel[da.b.rows*da.b.rows+i*da.b.columns];
1598 }
1599
1600 tempPbin0 = new bigint[da.b.rows+1];
1601 memory_handler(tempPbin0, "bigint_lattice", "Tr_lll_check_search(da, "
1602 "a, b) :: not enough memory !");
1603
1604 if (!TrD_gram_schmidt_orth_bdw(da, my, gso, tempPbin0)) {
1605 delete[] mydel;
1606 delete[] my;
1607 delete[] tempPbin0;
1608 lidia_error_handler("bigint_lattice", "Tr_lll_check_search(da, a, b) :: "
1609 "lattice is no basis !");
1610 return;
1611 }
1612
1613 a = 0;
1614 b = 1;
1615 for (lidia_size_t i = 0; i < da.b.rows; i++)
1616 for (lidia_size_t j = 0; j < i; j++) {
1617 tempbin1.assign(abs(my[j][i]));
1618 tempbin1.multiply_by_2();
1619 if (tempbin1 > tempPbin0[j+1]) {
1620 delete[] mydel;
1621 delete[] my;
1622 delete[] tempPbin0;
1623 return;
1624 }
1625 }
1626 vector.vectsize = da.b.columns;
1627 for (lidia_size_t j = 0; j < 20; j++) // 2^-20
1628 {
1629 success = true;
1630 for (lidia_size_t i = 1; i < da.b.rows; i++) {
1631 LiDIA::square(tempbin0, tempPbin0[i]);
1632 LiDIA::multiply(tempbin1, tempbin0, param_nom);
1633
1634 LiDIA::square(tempbin0, my[i-1][i]);
1635 LiDIA::multiply(tempbin2, tempbin0, param_den);
1636 LiDIA::subtract(tempbin0, tempbin1, tempbin2);
1637 LiDIA::multiply(tempbin1, tempPbin0[i-1], tempPbin0[i+1]);
1638 LiDIA::multiply(tempbin2, tempbin1, param_den);
1639
1640 if (tempbin2 < tempbin0) {
1641 success = false;
1642 break;
1643 }
1644
1645 }
1646 if (success) {
1647 a = param_nom;
1648 b = param_den;
1649
1650 downer_nom = param_nom;
1651 downer_den = param_den << 1;
1652 upper_den <<= 1;
1653 param_nom = (downer_nom+upper_nom);
1654 param_den <<= 1;
1655 upper_nom <<= 1;
1656 downer_nom <<= 1;
1657 }
1658 else {
1659 upper_nom = param_nom;
1660 upper_den = param_den << 1;
1661 downer_den <<= 1;
1662 param_nom = (upper_nom+downer_nom);
1663 param_den <<= 1;
1664 upper_nom <<= 1;
1665 downer_nom <<= 1;
1666 }
1667 }
1668 delete[] mydel;
1669 delete[] my;
1670 delete[] tempPbin0;
1671 }
1672
1673
1674
TrD_check_basis(const dense_alg<bigint> & da)1675 bool bigint_lattice::TrD_check_basis(const dense_alg< bigint > & da)
1676 {
1677 debug_handler("bigint_lattice", "TrD_check_basis(da)");
1678 bigint tempbin0;
1679 matrix< bigint > Tbin0(da.b.rows, da.b.columns, const_cast<const bigint **>(da.s.value));
1680 matrix< bigint > Tbin1;
1681
1682 if (da.b.rows > da.b.columns)
1683 return (false);
1684 if (da.b.rows == da.b.columns) {
1685 tempbin0.assign(Tbin0.det());
1686 if (tempbin0.is_zero())
1687 return(false);
1688 else
1689 return(true);
1690 }
1691 // Tbin1.assign(Tbin0*Tbin0.trans());
1692 Tbin1.assign(Tbin0.trans());
1693 LiDIA::multiply(Tbin1, Tbin0, Tbin1);
1694 // A * A^T
1695
1696
1697 tempbin0.assign(Tbin1.det());
1698 if (tempbin0.is_zero())
1699 return(false);
1700 else
1701 return(true);
1702
1703 return(false);
1704 }
1705
1706
1707
TrD_check_gram(const dense_alg<bigint> & da)1708 bool bigint_lattice::TrD_check_gram(const dense_alg< bigint > & da)
1709 {
1710 debug_handler("bigint_lattice", "TrD_check_gram(da)");
1711 bigint tempbin0;
1712 matrix< bigint > Tbin0(da.b.rows, da.b.columns, const_cast<const bigint **>(da.s.value));
1713
1714
1715 //
1716 // quadratic
1717 //
1718 if (da.b.rows != da.b.columns)
1719 return(false);
1720
1721 //
1722 // symmetric
1723 //
1724 for (lidia_size_t i = 0; i < da.b.rows; i++)
1725 for (lidia_size_t j = i; j < da.b.columns; j++)
1726 if (da.s.value[i][j] != da.s.value[j][i])
1727 return(false);
1728 //
1729 // positiv definit, funktioniert nicht bei gensys
1730 //
1731 for (lidia_size_t i = da.b.rows; i > 0; i--) {
1732 Tbin0.set_no_of_rows(i);
1733 Tbin0.set_no_of_columns(i);
1734 tempbin0.assign(Tbin0.det());
1735 // if (tempbin0.is_le_zero())
1736 if (tempbin0.is_lt_zero())
1737 return(false);
1738 }
1739 return(true);
1740 }
1741
1742
1743
compute_read_precision(const dense_alg<bigint> & da)1744 sdigit bigint_lattice::compute_read_precision(const dense_alg< bigint > & da)
1745 {
1746 debug_handler("bigint_lattice", "compute_read_precision(da)");
1747 //
1748 // Give the digit size of longest value
1749 //
1750 sdigit new_prec;
1751 sdigit read_prec = 0;
1752 for (lidia_size_t x = 0; x < da.b.rows; ++x)
1753 for (lidia_size_t y = 0; y < da.b.columns; ++y)
1754 if (read_prec < (new_prec = static_cast<sdigit>(da.s.value[x][y].bit_length()/
1755 std::log(10.0)+1)))
1756 read_prec = new_prec;
1757 return (read_prec);
1758 }
1759
1760
1761
compute_precision(const dense_alg<bigint> & da)1762 sdigit bigint_lattice::compute_precision(const dense_alg< bigint > & da)
1763 {
1764 debug_handler("bigint_lattice", "compute_precision(da)");
1765 bigfloat alpha, zweipotq;
1766 sdigit read_prec = compute_read_precision(da);
1767 sdigit n2 = da.b.rows;
1768 sdigit prec;
1769 alpha_compute(da, alpha);
1770 zwei_pot_q_compute(da, zweipotq, n2, alpha);
1771 read_prec = 2*read_prec+da.b.rows-1;
1772 prec = static_cast<sdigit>(2*(((zweipotq.bit_length()+1)*
1773 std::log(2.0)/std::log(10.0)+1)+read_prec)+(da.b.columns+da.b.rows)-1);
1774 return (prec);
1775 }
1776
1777
1778
gamma_compute(bigfloat & g,sdigit l)1779 void bigint_lattice::gamma_compute(bigfloat& g, sdigit l)
1780 {
1781 debug_handler("bigint_lattice", "gamma_compute(g, l)");
1782 bigfloat ha[] = {1, 4.0/3.0, 2, 4, 8, 64.0/3.0, 64, 256};
1783 //
1784 // Computation of the l-th Hermite - Constant gamma,
1785 //
1786 bigfloat lg;
1787 if ((l > 0) && (l < 9))
1788 g.assign(ha[l-1]);
1789 else {
1790 lg.assign(0.75);
1791 LiDIA::log(lg, lg);
1792 g.assign(static_cast<sdigit>(l * (l-1)));
1793 g.divide_by_2();
1794 LiDIA::multiply(lg, lg, g);
1795 LiDIA::exp(g, lg);
1796 }
1797 }
1798
1799
1800
alpha_compute(const dense_alg<bigint> & da,bigfloat & alpha)1801 void bigint_lattice::alpha_compute(const dense_alg< bigint > & da, bigfloat& alpha)
1802 {
1803 //
1804 // alpha = max{vect[1].l2_norm(),...,vect[columns].l2_norm()}
1805 // norm = vect[i].l2_norm(), 0 <= i < columns
1806 //
1807 debug_handler("bigint_lattice", "alpha_compute(da, alpha)");
1808 bigint tempbin0;
1809 bigint bi_alpha;
1810 p_vector< bigint > vector;
1811 vector.vectsize = da.b.columns;
1812 vector.scalprod(bi_alpha, da.s.value[0], da.s.value[0]);
1813 for (lidia_size_t i = 1; i < da.b.rows; ++i) {
1814 vector.scalprod(tempbin0, da.s.value[i], da.s.value[i]);
1815 if (bi_alpha.compare(tempbin0) < 0)
1816 bi_alpha.assign(tempbin0);
1817 }
1818 //
1819 // calculating sqrt of l2_norm
1820 //
1821 alpha.assign(bi_alpha);
1822 LiDIA::sqrt(alpha, alpha);
1823 }
1824
1825
1826
zwei_pot_q_compute(const dense_alg<bigint> & da,bigfloat & zweipotq,sdigit & n2,bigfloat & alpha)1827 void bigint_lattice::zwei_pot_q_compute(const dense_alg< bigint > & da,
1828 bigfloat& zweipotq,
1829 sdigit& n2, bigfloat& alpha)
1830 {
1831 debug_handler("bigint_lattice", "zwei_pot_q_compute(da, zwpq, n2, alpha)");
1832 sdigit beta = da.b.rows;
1833 bigint tempbin0;
1834 bigfloat tempbfl0;
1835 bigfloat tempbfl1;
1836 bigfloat tempbfl2;
1837
1838 // Computation of beta = min (A.columns, A.rows)
1839 if (da.b.columns < da.b.rows)
1840 beta = da.b.columns;
1841
1842 tempbfl0.assign(n2);
1843 LiDIA::sqrt(tempbfl0, tempbfl0);
1844 tempbfl0.divide_by_2();
1845 LiDIA::multiply(tempbfl0, rows, tempbfl0);
1846 tempbfl1.assign(rows);
1847 LiDIA::sqrt(tempbfl1, tempbfl1);
1848 LiDIA::add(tempbfl0, tempbfl0, tempbfl1);
1849
1850 LiDIA::log(tempbfl1, alpha);
1851 LiDIA::multiply(tempbfl1, tempbfl1, beta);
1852 LiDIA::exp(tempbfl1, tempbfl1);
1853 gamma_compute(tempbfl2 , beta);
1854
1855 LiDIA::sqrt(tempbfl2, tempbfl2);
1856 LiDIA::multiply(tempbfl2, tempbfl2, tempbfl1);
1857 LiDIA::multiply(tempbfl2, tempbfl2, tempbfl0);
1858 tempbin0.assign(n2);
1859 LiDIA::multiply(tempbfl0, tempbfl0, rows);
1860 LiDIA::sqrt(tempbfl0, tempbin0);
1861 LiDIA::add(tempbfl0, tempbfl0, 2);
1862 LiDIA::multiply(zweipotq, tempbfl0, tempbfl2);
1863
1864 tempbfl0.assign(beta + rows);
1865 tempbfl0.divide_by_2();
1866 LiDIA::subtract(tempbfl0, tempbfl0, 1);
1867 tempbfl0.multiply_by_2();
1868 LiDIA::exp(tempbfl0, tempbfl0);
1869 LiDIA::multiply(tempbfl0, zweipotq, tempbfl0);
1870
1871 tempbfl2.assign(beta + 1);
1872 tempbfl2.divide_by_2();
1873 tempbfl1.assign(columns);
1874 LiDIA::log(tempbfl1, tempbfl1);
1875 LiDIA::multiply(tempbfl2, tempbfl2, tempbfl1);
1876 LiDIA::exp(tempbfl2, tempbfl2);
1877 LiDIA::divide(tempbfl0, tempbfl0, tempbfl2);
1878 LiDIA::ceil(zweipotq, tempbfl0);
1879 }
1880
1881
1882
1883 #ifdef LIDIA_NAMESPACE
1884 } // end of namespace LiDIA
1885 #endif
1886