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/lattice_gensys.h"
23 
24 
25 
26 #ifdef LIDIA_NAMESPACE
27 namespace LiDIA {
28 #endif
29 
30 
31 
32 //
33 // Constructors
34 //
lattice_gensys(lidia_size_t n,lidia_size_t m)35 lattice_gensys::lattice_gensys(lidia_size_t n, lidia_size_t m)
36 {
37 	debug_handler("lattice_gensys", "lattice_gensys(n, m)");
38 	if ((n > 0) && (m > 0)) {
39 		comp_mode = bigfloat_mode;
40 		io_mode = own_io_mode;
41 		lbf = new bigfloat_lattice_basis(n, m);
42 		memory_handler(lbf, "lattice_gensys", "lattice_gensys(n, m) :: "
43 			       "not enough memory");
44 		return;
45 	}
46 	lidia_error_handler("lattice_gensys", "lattice_gensys(n, m) :: "
47 			    "illegal lattice size !");
48 }
49 
50 //
51 // Initialising constructors
52 //
lattice_gensys(lidia_size_t n,lidia_size_t m,const double ** ado)53 lattice_gensys::lattice_gensys(lidia_size_t n, lidia_size_t m, const double** ado)
54 {
55 	debug_handler("lattice_gensys", "lattice_gensys(n, m, ado)");
56 	if ((n > 0) && (m > 0)) {
57 		comp_mode = bigfloat_mode;
58 		io_mode = own_io_mode;
59 		lbf = new bigfloat_lattice_basis(n, m);
60 		memory_handler(lbf, "lattice_gensys", "lattice_gensys(n, m, ado) :: "
61 			       "not enough memory");
62 		sto(n, m, ado);
63 		return;
64 	}
65 	lidia_error_handler("lattice_gensys", "lattice_gensys(n, m, ado) :: "
66 			    "illegal lattice size !");
67 }
68 
lattice_gensys(lidia_size_t n,lidia_size_t m,const bigint ** abi)69 lattice_gensys::lattice_gensys(lidia_size_t n, lidia_size_t m, const bigint** abi)
70 {
71 	debug_handler("lattice_gensys", "lattice_gensys(n, m, abi)");
72 	if ((n > 0) && (m > 0)) {
73 		comp_mode = bigint_mode;
74 		io_mode = own_io_mode;
75 		lbi = new bigint_lattice_basis(n, m);
76 		memory_handler(lbi, "lattice_gensys", "lattice_gensys(n, m, abi) :: "
77 			       "not enough memory");
78 		sto(n, m, abi);
79 		return;
80 	}
81 	lidia_error_handler("lattice_gensys", "lattice_gensys(n, m, abi) :: "
82 			    "illegal lattice size !");
83 }
84 
lattice_gensys(lidia_size_t n,lidia_size_t m,const bigfloat ** abf)85 lattice_gensys::lattice_gensys(lidia_size_t n, lidia_size_t m, const bigfloat** abf)
86 {
87 	debug_handler("lattice_gensys", "lattice_gensys(n, m, abf)");
88 	if ((n > 0) && (m > 0)) {
89 		comp_mode = bigfloat_mode;
90 		io_mode = own_io_mode;
91 		lbf = new bigfloat_lattice_basis(n, m);
92 		memory_handler(lbf, "lattice_gensys", "lattice_gensys(n, m, abf) :: "
93 			       "not enough memory");
94 		sto(n, m, abf);
95 		return;
96 	}
97 	lidia_error_handler("lattice_gensys", "lattice_gensys(n, m, abf) :: "
98 			    "illegal lattice size !");
99 }
100 
101 //
102 // Copy - constructor
103 //
lattice_gensys(const lattice_gensys & L)104 lattice_gensys::lattice_gensys(const lattice_gensys& L)
105 {
106 	debug_handler("lattice_gensys", "lattice_gensys(L)");
107 	comp_mode = L.comp_mode;
108 	io_mode = L.io_mode;
109 	if (comp_mode == bigint_mode) {
110 		lbi = new bigint_lattice_basis(*L.lbi);
111 		memory_handler(lbi, "lattice_gensys", "lattice_gensys(L) :: "
112 			       "not enough memory");
113 	}
114 	else {
115 		lbf = new bigfloat_lattice_basis(*L.lbf);
116 		memory_handler(lbf, "lattice_gensys", "lattice_gensys(L) :: "
117 			       "not enough memory");
118 	}
119 }
120 
121 //
122 // Special copy - constructors
123 //
lattice_gensys(const math_matrix<bigint> & A)124 lattice_gensys::lattice_gensys(const math_matrix< bigint > & A)
125 {
126 	debug_handler("lattice_gensys", "lattice_gensys(A)");
127 	lbi = new bigint_lattice_basis(A);
128 	memory_handler(lbi, "lattice_gensys", "lattice_gensys(A) :: "
129 		       "not enough memory");
130 	comp_mode = bigint_mode;
131 	io_mode = own_io_mode;
132 }
133 
lattice_gensys(const math_matrix<bigfloat> & A)134 lattice_gensys::lattice_gensys(const math_matrix< bigfloat > & A)
135 {
136 	debug_handler("lattice_gensys", "lattice_gensys(A)");
137 	lbf = new bigfloat_lattice_basis(A);
138 	memory_handler(lbf, "lattice_gensys", "lattice_gensys(A) :: "
139 		       "not enough memory");
140 	comp_mode = bigfloat_mode;
141 	io_mode = own_io_mode;
142 }
143 
144 //
145 // Destructor
146 //
~lattice_gensys()147 lattice_gensys::~lattice_gensys()
148 {
149 	debug_handler("lattice_gensys", "~lattice_gensys()");
150 	if (comp_mode == bigint_mode)
151 		delete lbi;
152 	else
153 		delete lbf;
154 }
155 
156 //
157 // Assignments
158 //
assign(const lattice_gensys & L)159 void lattice_gensys::assign(const lattice_gensys& L)
160 {
161 	debug_handler("lattice_gensys", "assign(L)");
162 	set_computing_mode(L.comp_mode);
163 	io_mode = L.io_mode;
164 	comp_mode = L.comp_mode;
165 	if (comp_mode == bigint_mode)
166 		lbi->assign(*L.lbi);
167 	else
168 		lbf->assign(*L.lbf);
169 }
170 
assign(const math_matrix<bigint> & M)171 void lattice_gensys::assign(const math_matrix< bigint > & M)
172 {
173 	debug_handler("lattice_gensys", "assign(M)");
174 	if (comp_mode == bigfloat_mode) {
175 		delete lbf;
176 		lbi = new bigint_lattice_basis(M);
177 		memory_handler(lbi, "lattice_gensys", "assign(M) :: "
178 			       "not enough memory !");
179 	}
180 	else
181 		lbi->assign(M);
182 	comp_mode = bigint_mode;
183 	io_mode = own_io_mode;
184 }
185 
assign(const math_matrix<bigfloat> & M)186 void lattice_gensys::assign(const math_matrix< bigfloat > & M)
187 {
188 	debug_handler("lattice_gensys", "assign(M)");
189 	if (comp_mode == bigint_mode) {
190 		delete lbi;
191 		lbf = new bigfloat_lattice_basis(M);
192 		memory_handler(lbf, "lattice_gensys", "assign(M) :: "
193 			       "not enough memory !");
194 	}
195 	else
196 		lbf->assign(M);
197 	comp_mode = bigfloat_mode;
198 	io_mode = own_io_mode;
199 }
200 
operator =(const lattice_gensys & L)201 lattice_gensys& lattice_gensys::operator = (const lattice_gensys& L)
202 {
203 	debug_handler("lattice_gensys", "operator = (L)");
204 	assign(L);
205 	return(*this);
206 }
207 
operator =(const math_matrix<bigint> & M)208 lattice_gensys& lattice_gensys::operator = (const math_matrix< bigint > &M)
209 {
210 	debug_handler("lattice_gensys", "operator = (M)");
211 	assign(M);
212 	return(*this);
213 }
214 
operator =(const math_matrix<bigfloat> & M)215 lattice_gensys& lattice_gensys::operator = (const math_matrix< bigfloat > &M)
216 {
217 	debug_handler("lattice_gensys", "operator = (M)");
218 	assign(M);
219 	return(*this);
220 }
221 
assign(lattice_gensys & A,const lattice_gensys & B)222 void assign(lattice_gensys& A, const lattice_gensys& B)
223 {
224 	debug_handler("lattice_gensys", "assign(A, B)");
225 	A.assign(B);
226 }
227 
assign(lattice_gensys & A,const math_matrix<bigint> & Bbi)228 void assign(lattice_gensys& A, const math_matrix< bigint > & Bbi)
229 {
230 	debug_handler("lattice_gensys", "assign(A, Bbi)");
231 	A.assign(Bbi);
232 }
233 
assign(lattice_gensys & A,const math_matrix<bigfloat> & Bbf)234 void assign(lattice_gensys& A, const math_matrix< bigfloat > &Bbf)
235 {
236 	debug_handler("lattice_gensys", "assign(A, Bbf)");
237 	A.assign(Bbf);
238 }
239 
240 //
241 // Input / Output
242 //
operator >>(std::istream & in,lattice_gensys & L)243 std::istream& operator >> (std::istream& in, lattice_gensys& L)
244 {
245 	debug_handler("lattice_gensys", "operator >> (in, L)");
246 	if (L.comp_mode == bigint_mode)
247 		in >> *(L.lbi);
248 	else
249 		in >> *(L.lbf);
250 	L.io_mode = own_io_mode;
251 	return (in);
252 }
253 
operator <<(std::ostream & out,const lattice_gensys & L)254 std::ostream& operator << (std::ostream& out, const lattice_gensys& L)
255 {
256 	debug_handler("lattice_gensys", "operator << (out, L)");
257 	int mode = 0;
258 	switch (L.io_mode) {
259 	case pari_io_mode : {
260 		mode = GP_MODE;
261 	} break;
262 	case maple_io_mode : {
263 		mode = MAPLE_MODE;
264 	} break;
265 	case mathematica_io_mode : {
266 		mode = MATHEMATICA_MODE;
267 	} break;
268 	case own_io_mode : {
269 		mode = BEAUTY_MODE;
270 	} break;
271 	default : {
272 		lidia_error_handler("lattice_gensys", "operator << (out, L) :: "
273 				    "illegal IO Mode !");
274 	} break;
275 	}
276 	if (L.comp_mode == bigint_mode) {
277 		L.lbi->set_print_mode(mode);
278 		out << *(L.lbi);
279 	}
280 	else {
281 		L.lbf->set_print_mode(mode);
282 		out << *(L.lbf);
283 	}
284 	return (out);
285 }
286 
287 //
288 // Element Operations
289 //
member(lidia_size_t x,lidia_size_t y,double & d)290 void lattice_gensys::member(lidia_size_t x, lidia_size_t y, double& d)
291 {
292 	debug_handler("lattice_gensys", "member(x, y, d)");
293 	bigfloat temp;
294 	if (comp_mode == bigint_mode)
295 		temp.assign(lbi->member(x, y));
296 	else
297 		temp.assign(lbf->member(x, y));
298 	temp.doublify(d);
299 }
300 
member(lidia_size_t x,lidia_size_t y,bigint & bi)301 void lattice_gensys::member(lidia_size_t x, lidia_size_t y, bigint& bi)
302 {
303 	debug_handler("lattice_gensys", "member(x, y, bi)");
304 	if (comp_mode == bigint_mode)
305 		bi.assign(lbi->member(x, y));
306 	else
307 		lbf->member(x, y).bigintify(bi);
308 }
309 
member(lidia_size_t x,lidia_size_t y,bigfloat & bf)310 void lattice_gensys::member(lidia_size_t x, lidia_size_t y, bigfloat& bf)
311 {
312 	debug_handler("lattice_gensys", "member(x, y, bf)");
313 	if (comp_mode == bigint_mode)
314 		bf.assign(lbi->member(x, y));
315 	else
316 		bf.assign(lbf->member(x, y));
317 }
318 
sto(lidia_size_t x,lidia_size_t y,const double & d)319 void lattice_gensys::sto(lidia_size_t x, lidia_size_t y, const double& d)
320 {
321 	debug_handler("lattice_gensys", "sto(x, y, d)");
322 	if (comp_mode == bigint_mode) {
323 		bigint temp;
324 		temp.assign(d);
325 		lbi->sto(x, y, temp);
326 	}
327 	else {
328 		bigfloat temp(d);
329 		lbf->sto(x, y, temp);
330 	}
331 }
332 
sto(lidia_size_t x,lidia_size_t y,const bigint & bi)333 void lattice_gensys::sto(lidia_size_t x, lidia_size_t y, const bigint& bi)
334 {
335 	debug_handler("lattice_gensys", "sto(x, y, bi)");
336 	if (comp_mode == bigint_mode)
337 		lbi->sto(x, y, bi);
338 	else {
339 		bigfloat temp(bi);
340 		lbf->sto(x, y, temp);
341 	}
342 }
343 
sto(lidia_size_t x,lidia_size_t y,const bigfloat & bf)344 void lattice_gensys::sto(lidia_size_t x, lidia_size_t y, const bigfloat& bf)
345 {
346 	debug_handler("lattice_gensys", "sto(x, y, bf)");
347 	if (comp_mode == bigint_mode) {
348 		bigint temp;
349 		bf.bigintify(temp);
350 		lbi->sto(x, y, temp);
351 	}
352 	else
353 		lbf->sto(x, y, bf);
354 }
355 
member(lidia_size_t & n,lidia_size_t & m,double ** & ado)356 void lattice_gensys::member(lidia_size_t& n, lidia_size_t& m, double**& ado)
357 {
358 	debug_handler("lattice_gensys", "member(n, m, ado)");
359 	lidia_size_t rows = get_no_of_rows();
360 	lidia_size_t columns = get_no_of_columns();
361 	bigfloat temp;
362 
363 	n = rows;
364 	m = columns;
365 	ado = new double*[rows];
366 	memory_handler(ado, "lattice_gensys", "member(n, m, ado) :: "
367 		       "not enough memory !");
368 	ado[0] = new double[rows*columns];
369 	memory_handler(ado[0], "lattice_gensys", "member(n, m, ado) :: "
370 		       "not enough memory !");
371 //
372 // Set pointers (tricky)
373 //
374 	for (lidia_size_t x = 0; x < rows; ado[x] = &ado[0][x++*columns]);
375 
376 	if (comp_mode == bigint_mode) {
377 		for (lidia_size_t x = 0; x < rows; ++x)
378 			for (lidia_size_t y = 0; y < columns; ++y) {
379 				temp.assign(lbi->member(x, y));
380 				temp.doublify(ado[x][y]);
381 			}
382 	}
383 	else {
384 		for (lidia_size_t x = 0; x < rows; ++x)
385 			for (lidia_size_t y = 0; y < columns; ++y)
386 				lbf->member(x, y).doublify(ado[x][y]);
387 	}
388 }
389 
member(lidia_size_t & n,lidia_size_t & m,bigint ** & abi)390 void lattice_gensys::member(lidia_size_t& n, lidia_size_t& m, bigint**& abi)
391 {
392 	debug_handler("lattice_gensys", "member(n, m, abi)");
393 	lidia_size_t rows = get_no_of_rows();
394 	lidia_size_t columns = get_no_of_columns();
395 	bigfloat temp;
396 
397 	n = rows;
398 	m = columns;
399 	abi = new bigint*[rows];
400 	memory_handler(abi, "lattice_gensys", "member(n, m, abi) :: "
401 		       "not enough memory !");
402 	abi[0] = new bigint[rows*columns];
403 	memory_handler(abi[0], "lattice_gensys", "member(n, m, abi) :: "
404 		       "not enough memory !");
405 
406 	for (lidia_size_t x = 0; x < rows; abi[x] = &abi[0][x++*columns]);
407 
408 	if (comp_mode == bigint_mode) {
409 		for (lidia_size_t x = 0; x < rows; ++x)
410 			for (lidia_size_t y = 0; y < columns; ++y)
411 				abi[x][y].assign(lbi->member(x, y));
412 	}
413 	else {
414 		for (lidia_size_t x = 0; x < rows; ++x)
415 			for (lidia_size_t y = 0; y < columns; ++y)
416 				lbf->member(x, y).bigintify(abi[x][y]);
417 	}
418 }
419 
member(lidia_size_t & n,lidia_size_t & m,bigfloat ** & abf)420 void lattice_gensys::member(lidia_size_t& n, lidia_size_t& m, bigfloat**& abf)
421 {
422 	debug_handler("lattice_gensys", "member(n, m, abf)");
423 	lidia_size_t rows = get_no_of_rows();
424 	lidia_size_t columns = get_no_of_columns();
425 
426 	n = rows;
427 	m = columns;
428 	abf = new bigfloat*[rows];
429 	memory_handler(abf, "lattice_gensys", "member(n, m, abf) :: "
430 		       "not enough memory !");
431 	abf[0] = new bigfloat[rows*columns];
432 	memory_handler(abf[0], "lattice_gensys", "member(n, m, abf) :: "
433 		       "not enough memory !");
434 	for (lidia_size_t x = 0; x < rows; abf[x] = &abf[0][x++*columns]);
435 
436 	if (comp_mode == bigint_mode) {
437 		for (lidia_size_t x = 0; x < rows; ++x)
438 			for (lidia_size_t y = 0; y < columns; ++y)
439 				abf[x][y].assign(lbi->member(x, y));
440 	}
441 	else {
442 		for (lidia_size_t x = 0; x < rows; ++x)
443 			for (lidia_size_t y = 0; y < columns; ++y)
444 				abf[x][y].assign(lbf->member(x, y));
445 	}
446 }
447 
member(math_matrix<bigint> & Mbi)448 void lattice_gensys::member(math_matrix< bigint > & Mbi)
449 {
450 	debug_handler("lattice_gensys", "member(Mbi)");
451 	lidia_size_t rows = get_no_of_rows();
452 	lidia_size_t columns = get_no_of_columns();
453 	bigfloat temp;
454 	bigint temp_bi;
455 
456 	Mbi.set_no_of_columns(columns);
457 	Mbi.set_no_of_rows(rows);
458 
459 	if (comp_mode == bigint_mode) {
460 		for (lidia_size_t x = 0; x < rows; ++x)
461 			for (lidia_size_t y = 0; y < columns; ++y)
462 				Mbi.sto(x, y, lbi->member(x, y));
463 	}
464 	else {
465 		for (lidia_size_t x = 0; x < rows; ++x)
466 			for (lidia_size_t y = 0; y < columns; ++y) {
467 				lbf->member(x, y).bigintify(temp_bi);
468 				Mbi.sto(x, y, temp_bi);
469 			}
470 	}
471 }
472 
member(math_matrix<bigfloat> & Mbf)473 void lattice_gensys::member(math_matrix< bigfloat > & Mbf)
474 {
475 	debug_handler("lattice_gensys", "member(Mbf)");
476 	lidia_size_t rows = get_no_of_rows();
477 	lidia_size_t columns = get_no_of_columns();
478 	bigfloat temp;
479 
480 	Mbf.set_no_of_rows(rows);
481 	Mbf.set_no_of_columns(columns);
482 
483 	if (comp_mode == bigint_mode) {
484 		for (lidia_size_t x = 0; x < rows; ++x)
485 			for (lidia_size_t y = 0; y < columns; ++y) {
486 				temp.assign(lbf->member(x, y));
487 				Mbf.sto(x, y, temp);
488 			}
489 	}
490 	else {
491 		for (lidia_size_t x = 0; x < rows; ++x)
492 			for (lidia_size_t y = 0; y < columns; ++y)
493 				Mbf.sto(x, y, lbf->member(x, y));
494 	}
495 }
496 
sto(lidia_size_t n,lidia_size_t m,const double ** ado)497 void lattice_gensys::sto(lidia_size_t n, lidia_size_t m, const double** ado)
498 {
499 	debug_handler("lattice_gensys", "sto(n, m, ado)");
500 	lidia_size_t rows = get_no_of_rows();
501 	lidia_size_t columns = get_no_of_columns();
502 	bigfloat temp;
503 	bigint temp_bi;
504 
505 	if ((n == rows) && (m == columns)) {
506 		if (comp_mode == bigint_mode) {
507 			for (lidia_size_t x = 0; x < rows; ++x)
508 				for (lidia_size_t y = 0; y < columns; ++y) {
509 					temp.assign(ado[x][y]);
510 					temp.bigintify(temp_bi);
511 					lbi->sto(x, y, temp_bi);
512 				}
513 		}
514 		else {
515 			for (lidia_size_t x = 0; x < rows; ++x)
516 				for (lidia_size_t y = 0; y < columns; ++y) {
517 					temp.assign(ado[x][y]);
518 					lbf->sto(x, y, temp);
519 				}
520 		}
521 		return;
522 	}
523 	lidia_error_handler("lattice_gensys", "sto(n, m, ado) :: "
524 			    "illegal array size !");
525 }
526 
sto(lidia_size_t n,lidia_size_t m,const bigint ** abi)527 void lattice_gensys::sto(lidia_size_t n, lidia_size_t m, const bigint** abi)
528 {
529 	debug_handler("lattice_gensys", "sto(n, m, abi)");
530 	lidia_size_t rows = get_no_of_rows();
531 	lidia_size_t columns = get_no_of_columns();
532 	bigfloat temp;
533 	if ((n == rows) && (m == columns)) {
534 		if (comp_mode == bigint_mode) {
535 			for (lidia_size_t x = 0; x < rows; ++x)
536 				for (lidia_size_t y = 0; y < columns; ++y)
537 					lbi->sto(x, y, abi[x][y]);
538 		}
539 		else {
540 			for (lidia_size_t x = 0; x < rows; ++x)
541 				for (lidia_size_t y = 0; y < columns; ++y) {
542 					temp.assign(abi[x][y]);
543 					lbf->sto(x, y, temp);
544 				}
545 		}
546 		return;
547 	}
548 	lidia_error_handler("lattice_gensys", "sto(n, m, abi) :: "
549 			    "illegal array size !");
550 }
551 
sto(lidia_size_t n,lidia_size_t m,const bigfloat ** abf)552 void lattice_gensys::sto(lidia_size_t n, lidia_size_t m, const bigfloat** abf)
553 {
554 	debug_handler("lattice_gensys", "sto(n, m, abf)");
555 	lidia_size_t rows = get_no_of_rows();
556 	lidia_size_t columns = get_no_of_columns();
557 	bigint temp;
558 	if ((n == rows) && (m == columns)) {
559 		if (comp_mode == bigint_mode) {
560 			for (lidia_size_t x = 0; x < rows; ++x)
561 				for (lidia_size_t y = 0; y < columns; ++y) {
562 					abf[x][y].bigintify(temp);
563 					lbi->sto(x, y, temp);
564 				}
565 		}
566 		else {
567 			for (lidia_size_t x = 0; x < rows; ++x)
568 				for (lidia_size_t y = 0; y < columns; ++y)
569 					lbf->sto(x, y, abf[x][y]);
570 		}
571 		return;
572 	}
573 	lidia_error_handler("lattice_gensys", "sto(n, m, abf) :: "
574 			    "illegal array size !");
575 }
576 
get_no_of_rows()577 lidia_size_t lattice_gensys::get_no_of_rows()
578 {
579 	debug_handler("lattice_gensys", "get_no_of_rows()");
580 	if (comp_mode == bigint_mode)
581 		return (lbi->get_no_of_rows());
582 	else
583 		return (lbf->get_no_of_rows());
584 }
585 
get_no_of_columns()586 lidia_size_t lattice_gensys::get_no_of_columns()
587 {
588 	debug_handler("lattice_gensys", "get_no_of_columns()");
589 	if (comp_mode == bigint_mode)
590 		return (lbi->get_no_of_columns());
591 	else
592 		return (lbf->get_no_of_columns());
593 }
594 
595 //
596 // Type Checking
597 //
598 
599 // Checks if you can convert to double without losing significant digits
check_double()600 bool lattice_gensys::check_double()
601 {
602 	debug_handler("lattice_gensys", "check_double()");
603 	lidia_size_t rows = get_no_of_rows();
604 	lidia_size_t columns = get_no_of_columns();
605 	if (comp_mode == bigfloat_mode) {
606 		for (lidia_size_t x = 0; x < rows; ++x) {
607 			for (lidia_size_t y = 0; y < columns; ++y)
608 				if (is_double(lbf->member(x, y)) == 0)
609 					return (false);
610 		}
611 	}
612 	else
613 		return (false);
614 
615 	return (true);
616 }
617 
618 // Checks if you can covert to bigint (no floating point)
check_bigint()619 bool lattice_gensys::check_bigint()
620 {
621 	debug_handler("lattice_gensys", "check_bigint()");
622 	lidia_size_t rows = get_no_of_rows();
623 	lidia_size_t columns = get_no_of_columns();
624 	bigfloat x_factor;
625 	bigfloat zero;
626 	if (comp_mode == bigfloat_mode) {
627 		for (lidia_size_t x = 0; x < rows; ++x) {
628 			for (lidia_size_t y = 0; y < columns; ++y) {
629 				x_factor = lbf->member(x, y);
630 				round(x_factor, zero);
631 				subtract(zero, zero, x_factor);
632 				if (zero.is_approx_zero() == 0)
633 					return(false);
634 			}
635 		}
636 	}
637 	return (true);
638 }
639 
set_computing_mode(sdigit m)640 void lattice_gensys::set_computing_mode(sdigit m)
641 {
642 	debug_handler("lattice_gensys", "set_computing_mode(m)");
643 	lidia_size_t rows = get_no_of_rows();
644 	lidia_size_t columns = get_no_of_columns();
645 
646 	if (m == double_mode)
647 		m = bigfloat_mode;
648 	if ((m != bigint_mode) && (m != bigfloat_mode))
649 		lidia_error_handler("lattice_gensys", "set_computing_mode(m) :: "
650 				    "illegal computing mode !");
651 
652 	if (comp_mode == bigfloat_mode) {
653 		if (m == bigint_mode) {
654 			bigint temp;
655 			lbi = new bigint_lattice_basis(rows, columns);
656 			memory_handler(lbi, "lattice_gensys", "set_computing_mode(m) :: "
657 				       "not enough memory !");
658 			for (lidia_size_t x = 0; x < rows; ++x)
659 				for (lidia_size_t y = 0; y < columns; ++y) {
660 					lbf->member(x, y).bigintify(temp);
661 					lbi->sto(x, y, temp);
662 				}
663 			comp_mode = bigint_mode;
664 			lbi->set_reduction_parameter(lbf->get_reduction_parameter());
665 			delete lbf;
666 		}
667 	}
668 	else {
669 		if (m == bigfloat_mode) {
670 			bigfloat temp;
671 			lbf = new bigfloat_lattice_basis(rows, columns);
672 			memory_handler(lbf, "lattice_gensys", "set_computing_mode(m) :: "
673 				       "not enough memory !");
674 			for (lidia_size_t x = 0; x < rows; ++x)
675 				for (lidia_size_t y = 0; y < columns; ++y) {
676 					temp.assign(lbi->member(x, y));
677 					lbf->sto(x, y, temp);
678 				}
679 			comp_mode = bigfloat_mode;
680 			lbf->set_reduction_parameter(lbi->get_reduction_parameter());
681 			delete lbi;
682 		}
683 	}
684 }
685 
get_computing_mode()686 sdigit lattice_gensys::get_computing_mode()
687 {
688 	debug_handler("lattice_gensys", "get_computing_mode()");
689 	return (comp_mode);
690 }
691 
set_io_mode(sdigit m)692 void lattice_gensys::set_io_mode(sdigit m)
693 {
694 	debug_handler("lattice_gensys", "set_io_mode(m)");
695 	if ((m == own_io_mode) ||
696 	    (m == pari_io_mode) ||
697 	    (m == maple_io_mode) ||
698 	    (m == mathematica_io_mode)) {
699 		io_mode = m;
700 		return;
701 	}
702 	lidia_error_handler("lattice_gensys", "set_io_mode(m) :: "
703 			    "illegal IO mode");
704 }
705 
get_io_mode()706 sdigit lattice_gensys::get_io_mode()
707 {
708 	debug_handler("lattice_gensys", "get_io_mode()");
709 	return (io_mode);
710 }
711 
712 
713 //
714 // Other Member Functions
715 //
set_reduction_parameter(double y)716 void lattice_gensys::set_reduction_parameter(double y)
717 {
718 	debug_handler("lattice_gensys", "set_reduction_parameter(y)");
719 	if (comp_mode == bigfloat_mode)
720 		lbf->set_reduction_parameter(y);
721 	else
722 		lbi->set_reduction_parameter(y);
723 }
724 
set_reduction_parameter(sdigit a,sdigit b)725 void lattice_gensys::set_reduction_parameter(sdigit a, sdigit b)
726 {
727 	debug_handler("lattice_gensys", "set_reduction_parameter(a, b)");
728 	if (comp_mode == bigfloat_mode)
729 		lbf->set_reduction_parameter(a, b);
730 	else
731 		lbi->set_reduction_parameter(a, b);
732 }
733 
get_reduction_parameter()734 double lattice_gensys::get_reduction_parameter()
735 {
736 	debug_handler("lattice_gensys", "get_reduction_parameter()");
737 	if (comp_mode == bigfloat_mode)
738 		return(lbf->get_reduction_parameter());
739 	else
740 		return(lbi->get_reduction_parameter());
741 }
742 
get_reduction_parameter(sdigit & a,sdigit & b)743 void lattice_gensys::get_reduction_parameter(sdigit& a, sdigit& b)
744 {
745 	debug_handler("lattice_gensys", "get_reduction_parameter(a, b)");
746 	if (comp_mode == bigfloat_mode)
747 		lbf->get_reduction_parameter(a, b);
748 	else
749 		lbi->get_reduction_parameter(a, b);
750 }
751 
get_no_of_reduction_steps()752 sdigit lattice_gensys::get_no_of_reduction_steps()
753 {
754 	debug_handler("lattice_gensys", "get_no_of_reduction_steps()");
755 	if (comp_mode == bigfloat_mode)
756 		return(lbf->get_no_of_reduction_steps());
757 	else
758 		return(lbi->get_no_of_reduction_steps());
759 }
760 
get_no_of_swaps()761 sdigit lattice_gensys::get_no_of_swaps()
762 {
763 	debug_handler("lattice_gensys", "get_no_of_swaps()");
764 	if (comp_mode == bigfloat_mode)
765 		return(lbf->get_no_of_swaps());
766 	else
767 		return(lbi->get_no_of_swaps());
768 }
769 
get_no_of_corrections()770 sdigit lattice_gensys::get_no_of_corrections()
771 {
772 	debug_handler("lattice_gensys", "get_no_of_corrections()");
773 	if (comp_mode == bigfloat_mode)
774 		return(lbf->get_no_of_corrections());
775 	else
776 		return(lbi->get_no_of_corrections());
777 }
778 
779 //
780 // Time needed
781 //
get_computing_time()782 timer& lattice_gensys::get_computing_time()
783 {
784 	debug_handler("lattice_gensys", "get_computing_time()");
785 	return(CT);
786 }
787 
788 //
789 // Algorithms
790 //
mlll(base_vector<bigint> & v)791 void lattice_gensys::mlll(base_vector< bigint > & v)
792 {
793 	debug_handler("lattice_gensys", "mlll(v)");
794 	CT.start_timer();
795 	if (comp_mode == bigfloat_mode)
796 		lbf->mlll(v);
797 	else
798 		lbi->mlll(v);
799 	CT.stop_timer();
800 }
801 
mlll(const lattice_gensys & B,base_vector<bigint> & v)802 void lattice_gensys::mlll(const lattice_gensys& B, base_vector< bigint > & v)
803 {
804 	debug_handler("lattice_gensys", "lll_gensys(B, rank)");
805 	assign(B);
806 	CT.start_timer();
807 	if (comp_mode == bigfloat_mode)
808 		lbf->mlll(v);
809 	else
810 		lbi->mlll(v);
811 	CT.stop_timer();
812 }
813 
mlll(bigint * & v)814 void lattice_gensys::mlll(bigint*& v)
815 {
816 	debug_handler("lattice_gensys", "mlll(v)");
817 	CT.start_timer();
818 	if (comp_mode == bigfloat_mode)
819 		lbf->mlll(v);
820 	else
821 		lbi->mlll(v);
822 	CT.stop_timer();
823 }
824 
mlll(const lattice_gensys & B,bigint * & v)825 void lattice_gensys::mlll(const lattice_gensys& B, bigint*& v)
826 {
827 	debug_handler("lattice_gensys", "lll_gensys(B, rank)");
828 	assign(B);
829 	CT.start_timer();
830 	if (comp_mode == bigfloat_mode)
831 		lbf->mlll(v);
832 	else
833 		lbi->mlll(v);
834 	CT.stop_timer();
835 }
836 
lll_gensys(lidia_size_t & rank)837 void lattice_gensys::lll_gensys(lidia_size_t& rank)
838 {
839 	debug_handler("lattice_gensys", "lll_gensys(rank)");
840 	CT.start_timer();
841 	if (comp_mode == bigfloat_mode)
842 		lbf->lll_var_gensys(rank);
843 	else
844 		lbi->lll_gensys(rank);
845 	CT.stop_timer();
846 }
847 
lll_gensys(const lattice_gensys & B,lidia_size_t & rank)848 void lattice_gensys::lll_gensys(const lattice_gensys& B, lidia_size_t& rank)
849 {
850 	debug_handler("lattice_gensys", "lll_gensys(B, rank)");
851 	assign(B);
852 	CT.start_timer();
853 	if (comp_mode == bigfloat_mode)
854 		lbf->lll_var_gensys(rank);
855 	else
856 		lbi->lll_gensys(rank);
857 	CT.stop_timer();
858 }
859 
lll_trans_gensys(lattice_gensys & Tr,lidia_size_t & rank)860 void lattice_gensys::lll_trans_gensys(lattice_gensys& Tr, lidia_size_t& rank)
861 {
862 	debug_handler("lattice_gensys", "lll_trans_gensys(Tr, rank)");
863 	Tr.set_computing_mode(comp_mode);
864 	CT.start_timer();
865 	if (comp_mode == bigfloat_mode)
866 		lbf->lll_trans_var_gensys(*Tr.lbf, rank);
867 	else
868 		lbi->lll_trans_gensys(*Tr.lbi, rank);
869 	CT.stop_timer();
870 }
871 
872 
873 // The Buchmann - Kessler algoritm on the identic matrix, result : transformation matrix
lin_gen_system(lattice_gensys & Tr,lidia_size_t & rank)874 void lattice_gensys::lin_gen_system(lattice_gensys& Tr, lidia_size_t& rank)
875 {
876 	debug_handler("lattice_gensys", "lin_gen_system(Tr, rank)");
877 	Tr.set_computing_mode(comp_mode);
878 	CT.start_timer();
879 	if (comp_mode == bigfloat_mode)
880 		lbf->lin_gen_system(*Tr.lbf, rank);
881 	else
882 		lbi->lin_gen_system(*Tr.lbi, rank);
883 	CT.stop_timer();
884 }
885 
886 // Multiplies the matrix with the transformation matrix, result : reduced matrix
compute_basis(const lattice_gensys & A,const lattice_gensys & B)887 void lattice_gensys::compute_basis(const lattice_gensys& A, const lattice_gensys& B)
888 {
889 	debug_handler("lattice_gensys", "compute_basis(A, B)");
890 	if (A.comp_mode == B.comp_mode) {
891 		set_computing_mode(A.comp_mode);
892 		if (comp_mode == bigfloat_mode)
893 			lbf->compute_basis(*A.lbf, *B.lbf);
894 		else
895 			lbi->compute_basis(*A.lbi, *B.lbi);
896 		return;
897 	}
898 	lidia_error_handler("lattice_gensys", "compute_basis(A, B) :: "
899 			    "different computing modes !");
900 }
901 
902 //
903 // Friend functions
904 //
905 
lll_gensys(math_matrix<bigint> & A,const math_matrix<bigint> & B,lidia_size_t & rank)906 void lll_gensys(math_matrix< bigint > & A,
907                 const math_matrix< bigint > & B,
908                 lidia_size_t& rank)
909 {
910 	debug_handler("lattice_gensys", "friend lll_gensys(A, B, rank)");
911 	bigint_lattice_basis temp(B);
912 	temp.lll_gensys(rank);
913 	A.assign(temp);
914 }
915 
lll_trans_gensys(math_matrix<bigint> & T,math_matrix<bigint> & A,lidia_size_t & rank)916 void lll_trans_gensys(math_matrix< bigint > & T,
917                       math_matrix< bigint > & A,
918                       lidia_size_t& rank)
919 {
920 	debug_handler("lattice_gensys", "friend lll_trans_gensys(T, A, rank)");
921 	bigint_lattice_basis temp(A);
922 	temp.lll_trans_gensys(T, rank);
923 	A.assign(temp);
924 }
925 
lll_gensys(math_matrix<bigfloat> & A,const math_matrix<bigfloat> & B,lidia_size_t & rank)926 void lll_gensys(math_matrix< bigfloat > & A,
927                 const math_matrix< bigfloat > & B,
928                 lidia_size_t& rank)
929 {
930 	debug_handler("lattice_gensys", "friend lll_gensys(A, B, rank)");
931 	bigfloat_lattice_basis temp(B);
932 	temp.lll_var_gensys(rank);
933 	A.assign(temp);
934 }
935 
lll_trans_gensys(math_matrix<bigint> & T,math_matrix<bigfloat> & A,lidia_size_t & rank)936 void lll_trans_gensys(math_matrix< bigint > & T,
937                       math_matrix< bigfloat > & A,
938                       lidia_size_t& rank)
939 {
940 	debug_handler("lattice_gensys", "friend lll_trans_gensys(T, A, rank)");
941 	bigfloat_lattice_basis temp(A);
942 	temp.lll_trans_var_gensys(T, rank);
943 	A.assign(temp);
944 }
945 
lll_trans_gensys(math_matrix<bigfloat> & T,math_matrix<bigfloat> & A,lidia_size_t & rank)946 void lll_trans_gensys(math_matrix< bigfloat > & T,
947                       math_matrix< bigfloat > & A,
948                       lidia_size_t& rank)
949 {
950 	debug_handler("lattice_gensys", "friend lll_trans_gensys(T, A, rank)");
951 	bigfloat_lattice_basis temp(A);
952 	temp.lll_trans_var_gensys(T, rank);
953 	A.assign(temp);
954 }
955 
mlll(math_matrix<bigint> & A,const math_matrix<bigint> & B,base_vector<bigint> & v)956 void mlll(math_matrix< bigint > & A,
957           const math_matrix< bigint > & B,
958           base_vector< bigint > & v)
959 {
960 	debug_handler("lattice_gensys", "friend mlll(A, B, v)");
961 	bigint_lattice_basis temp(B);
962 	temp.mlll(v);
963 	A.assign(temp);
964 }
965 
mlll(math_matrix<bigfloat> & A,const math_matrix<bigfloat> & B,base_vector<bigint> & v)966 void mlll(math_matrix< bigfloat > & A,
967           const math_matrix< bigfloat > & B,
968           base_vector< bigint > & v)
969 {
970 	debug_handler("lattice_gensys", "friend mlll(A, B, v)");
971 	bigfloat_lattice_basis temp(B);
972 	temp.mlll(v);
973 	A.assign(temp);
974 }
975 
mlll(math_matrix<bigfloat> & A,const math_matrix<bigfloat> & B,base_vector<bigfloat> & v)976 void  mlll(math_matrix< bigfloat > & A,
977            const math_matrix< bigfloat > & B,
978            base_vector< bigfloat > & v)
979 {
980 	debug_handler("lattice_gensys", "friend lll_gensys(A, B, rank)");
981 	bigfloat_lattice_basis temp(B);
982 	temp.mlll(v);
983 	A.assign(temp);
984 }
985 
mlll(math_matrix<bigint> & A,const math_matrix<bigint> & B,bigint * & v)986 void mlll(math_matrix< bigint > & A,
987           const math_matrix< bigint > & B,
988           bigint*& v)
989 {
990 	debug_handler("lattice_gensys", "friend mlll(A, B, v)");
991 	bigint_lattice_basis temp(B);
992 	temp.mlll(v);
993 	A.assign(temp);
994 }
995 
mlll(math_matrix<bigfloat> & A,const math_matrix<bigfloat> & B,bigint * & v)996 void mlll(math_matrix< bigfloat > & A,
997           const math_matrix< bigfloat > & B,
998           bigint*& v)
999 {
1000 	debug_handler("lattice_gensys", "friend mlll(A, B, v)");
1001 	bigfloat_lattice_basis temp(B);
1002 	temp.mlll(v);
1003 	A.assign(temp);
1004 }
1005 
mlll(math_matrix<bigfloat> & A,const math_matrix<bigfloat> & B,bigfloat * & v)1006 void mlll(math_matrix< bigfloat > & A,
1007           const math_matrix< bigfloat > & B,
1008           bigfloat*& v)
1009 {
1010 	debug_handler("lattice_gensys", "friend mlll(A, B, v)");
1011 	bigfloat_lattice_basis temp(B);
1012 	temp.mlll(v);
1013 	A.assign(temp);
1014 }
1015 
lin_gen_system(math_matrix<bigint> & Tr,const math_matrix<bigint> & A,lidia_size_t & rank)1016 void lin_gen_system(math_matrix< bigint > & Tr,
1017                     const math_matrix< bigint > & A,
1018                     lidia_size_t& rank)
1019 {
1020 	debug_handler("lattice_gensys", "friend lin_gen_system(Tr, A, rank)");
1021 	bigint_lattice_gensys TrBi(A);
1022 	TrBi.lin_gen_system(Tr, rank);
1023 }
1024 
lin_gen_system(math_matrix<bigint> & Tr,const math_matrix<bigfloat> & A,lidia_size_t & rank)1025 void lin_gen_system(math_matrix< bigint > & Tr,
1026                     const math_matrix< bigfloat > & A,
1027                     lidia_size_t& rank)
1028 {
1029 	debug_handler("lattice_gensys", "friend lin_gen_system(Tr, A, rank)");
1030 	bigfloat_lattice_gensys TrBf(A);
1031 	TrBf.lin_gen_system(Tr, rank);
1032 }
1033 
lin_gen_system(math_matrix<bigfloat> & Tr,const math_matrix<bigfloat> & A,lidia_size_t & rank)1034 void lin_gen_system(math_matrix< bigfloat > & Tr,
1035                     const math_matrix< bigfloat > & A,
1036                     lidia_size_t& rank)
1037 {
1038 	debug_handler("lattice_gensys", "friend lin_gen_system(Tr, A, rank)");
1039 	bigfloat_lattice_gensys TrBi(A);
1040 	TrBi.lin_gen_system(Tr, rank);
1041 }
1042 
1043 
1044 
1045 #ifdef LIDIA_NAMESPACE
1046 }	// end of namespace LiDIA
1047 #endif
1048