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