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