| | 20 | |
| | 21 | cdef extern from "NTL/LLL.h": |
| | 22 | cdef long mat_ZZ_LLL_FP "LLL_FP"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 23 | cdef long mat_ZZ_LLL_FP_U "LLL_FP"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 24 | cdef long mat_ZZ_LLL_QP "LLL_QP"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 25 | cdef long mat_ZZ_LLL_QP_U "LLL_QP"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 26 | cdef long mat_ZZ_LLL_XD "LLL_XD"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 27 | cdef long mat_ZZ_LLL_XD_U "LLL_XD"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 28 | cdef long mat_ZZ_LLL_RR "LLL_RR"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 29 | cdef long mat_ZZ_LLL_RR_U "LLL_RR"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 30 | |
| | 31 | cdef long mat_ZZ_G_LLL_FP "G_LLL_FP"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 32 | cdef long mat_ZZ_G_LLL_FP_U "G_LLL_FP"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 33 | cdef long mat_ZZ_G_LLL_QP "G_LLL_QP"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 34 | cdef long mat_ZZ_G_LLL_QP_U "G_LLL_QP"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 35 | cdef long mat_ZZ_G_LLL_XD "G_LLL_XD"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 36 | cdef long mat_ZZ_G_LLL_XD_U "G_LLL_XD"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 37 | cdef long mat_ZZ_G_LLL_RR "G_LLL_RR"(mat_ZZ_c B, double delta, int deep, int check , int verbose) |
| | 38 | cdef long mat_ZZ_G_LLL_RR_U "G_LLL_RR"(mat_ZZ_c B, mat_ZZ_c U, double delta, int deep, int check , int verbose) |
| | 39 | |
| | 375 | |
| | 376 | def LLL_FP(self, delta=0.75 , return_U=False, verbose=False): |
| | 377 | r""" |
| | 378 | Performs approximate LLL reduction of self (puts self in an |
| | 379 | LLL form) subject to the following conditions: |
| | 380 | |
| | 381 | The precision is double. |
| | 382 | |
| | 383 | The return value is the rank of B. |
| | 384 | |
| | 385 | Classical Gramm-Schmidt Orthogonalization is used: |
| | 386 | |
| | 387 | This choice uses classical methods for computing the |
| | 388 | Gramm-Schmidt othogonalization. It is fast but prone to |
| | 389 | stability problems. This strategy was first proposed by |
| | 390 | Schnorr and Euchner [C. P. Schnorr and M. Euchner, |
| | 391 | Proc. Fundamentals of Computation Theory, LNCS 529, pp. 68-85, |
| | 392 | 1991]. The version implemented here is substantially |
| | 393 | different, improving both stability and performance. |
| | 394 | |
| | 395 | If return_U is True, then also U is returned which is |
| | 396 | the transition matrix: $U * self_{old} = self_{new}$ |
| | 397 | |
| | 398 | The optional argument 'delta' is the reduction parameter, and |
| | 399 | may be set so that 0.50 <= delta < 1. Setting it close to 1 |
| | 400 | yields shorter vectors, and also improves the stability, but |
| | 401 | increases the running time. Recommended value: delta = |
| | 402 | 0.99. |
| | 403 | |
| | 404 | The optional parameter 'verbose' can be set to see all kinds |
| | 405 | of fun things printed while the routine is executing. A |
| | 406 | status report is also printed every once in a while. |
| | 407 | |
| | 408 | INPUT: |
| | 409 | delta -- as described above (0.5 <= delta < 1.0) (default: 0.75) |
| | 410 | return_U -- return U as described above |
| | 411 | verbose -- if True NTL will produce some verbatim messages on |
| | 412 | what's going on internally (default: False) |
| | 413 | |
| | 414 | OUTPUT: |
| | 415 | (rank,[U]) where rank and U are as described above and U |
| | 416 | is an optional return value if return_U is True. |
| | 417 | |
| | 418 | EXAMPLE: |
| | 419 | sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9]) |
| | 420 | sage: M.LLL_FP() |
| | 421 | 2 |
| | 422 | sage: M |
| | 423 | [[0 0 0] |
| | 424 | [2 1 0] |
| | 425 | [-1 1 3] |
| | 426 | ] |
| | 427 | sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M |
| | 428 | [[-6 9 -15 -18] |
| | 429 | [4 -6 10 12] |
| | 430 | [10 -16 18 35] |
| | 431 | [-24 36 -46 -82] |
| | 432 | ] |
| | 433 | sage: M.LLL_FP() |
| | 434 | 3 |
| | 435 | sage: M |
| | 436 | [[0 0 0 0] |
| | 437 | [0 -2 0 0] |
| | 438 | [-2 1 -5 -6] |
| | 439 | [0 -1 -7 5] |
| | 440 | ] |
| | 441 | |
| | 442 | WARNING: This method modifies self. So after applying this method your matrix |
| | 443 | will be a vector of vectors. |
| | 444 | """ |
| | 445 | cdef ntl_mat_ZZ U |
| | 446 | if return_U: |
| | 447 | U = PY_NEW(ntl_mat_ZZ) |
| | 448 | _sig_on |
| | 449 | rank = int(mat_ZZ_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 450 | _sig_off |
| | 451 | return rank, U |
| | 452 | else: |
| | 453 | _sig_on |
| | 454 | rank = int(mat_ZZ_LLL_FP(self.x,float(delta),0,0,int(verbose))) |
| | 455 | _sig_off |
| | 456 | return rank |
| | 457 | |
| | 458 | def LLL_QP(self, delta, return_U=False, verbose=False): |
| | 459 | r""" |
| | 460 | Peforms the same reduction as self.LLL_FP using the same |
| | 461 | calling conventions but with quad float precision. |
| | 462 | """ |
| | 463 | cdef ntl_mat_ZZ U |
| | 464 | if return_U: |
| | 465 | U = PY_NEW(ntl_mat_ZZ) |
| | 466 | _sig_on |
| | 467 | rank = int(mat_ZZ_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 468 | _sig_off |
| | 469 | return rank, U |
| | 470 | else: |
| | 471 | _sig_on |
| | 472 | rank = int(mat_ZZ_LLL_QP(self.x,float(delta),0,0,int(verbose))) |
| | 473 | _sig_off |
| | 474 | return rank |
| | 475 | |
| | 476 | def LLL_XD(self, delta, return_U=False, verbose=False): |
| | 477 | r""" |
| | 478 | Peforms the same reduction as self.LLL_FP using the same |
| | 479 | calling conventions but with extended exponent double |
| | 480 | precision. |
| | 481 | """ |
| | 482 | cdef ntl_mat_ZZ U |
| | 483 | if return_U: |
| | 484 | U = PY_NEW(ntl_mat_ZZ) |
| | 485 | _sig_on |
| | 486 | rank = int(mat_ZZ_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 487 | _sig_off |
| | 488 | return rank, U |
| | 489 | else: |
| | 490 | _sig_on |
| | 491 | rank = int(mat_ZZ_LLL_XD(self.x,float(delta),0,0,int(verbose))) |
| | 492 | _sig_off |
| | 493 | return rank |
| | 494 | |
| | 495 | def LLL_RR(self, delta, return_U=False, verbose=False): |
| | 496 | r""" |
| | 497 | Peforms the same reduction as self.LLL_FP using the same |
| | 498 | calling conventions but with arbitrary precision floating |
| | 499 | point numbers. |
| | 500 | """ |
| | 501 | cdef ntl_mat_ZZ U |
| | 502 | if return_U: |
| | 503 | U = PY_NEW(ntl_mat_ZZ) |
| | 504 | _sig_on |
| | 505 | rank = int(mat_ZZ_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 506 | _sig_off |
| | 507 | return rank, U |
| | 508 | else: |
| | 509 | _sig_on |
| | 510 | rank = int(mat_ZZ_LLL_RR(self.x,float(delta),0,0,int(verbose))) |
| | 511 | _sig_off |
| | 512 | return rank |
| | 513 | |
| | 514 | # Givens Orthogonalization. This is a bit slower, but generally |
| | 515 | # much more stable, and is really the preferred orthogonalization |
| | 516 | # strategy. For a nice description of this, see Chapter 5 of |
| | 517 | # [G. Golub and C. van Loan, Matrix Computations, 3rd edition, |
| | 518 | # Johns Hopkins Univ. Press, 1996]. |
| | 519 | |
| | 520 | def G_LLL_FP(self, delta, return_U=False, verbose=False): |
| | 521 | r""" |
| | 522 | Peforms the same reduction as self.LLL_FP using the same |
| | 523 | calling conventions but uses the Givens Orthogonalization. |
| | 524 | |
| | 525 | Givens Orthogonalization. This is a bit slower, but generally |
| | 526 | much more stable, and is really the preferred |
| | 527 | orthogonalization strategy. For a nice description of this, |
| | 528 | see Chapter 5 of [G. Golub and C. van Loan, Matrix |
| | 529 | Computations, 3rd edition, Johns Hopkins Univ. Press, 1996]. |
| | 530 | """ |
| | 531 | cdef ntl_mat_ZZ U |
| | 532 | if return_U: |
| | 533 | U = PY_NEW(ntl_mat_ZZ) |
| | 534 | _sig_on |
| | 535 | rank = int(mat_ZZ_G_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 536 | _sig_off |
| | 537 | return rank, U |
| | 538 | else: |
| | 539 | _sig_on |
| | 540 | rank = int(mat_ZZ_G_LLL_FP(self.x,float(delta),0,0,int(verbose))) |
| | 541 | _sig_off |
| | 542 | return rank |
| | 543 | |
| | 544 | def G_LLL_QP(self, delta, return_U=False, verbose=False): |
| | 545 | r""" |
| | 546 | Peforms the same reduction as self.G_LLL_FP using the same |
| | 547 | calling conventions but with quad float precision. |
| | 548 | """ |
| | 549 | cdef ntl_mat_ZZ U |
| | 550 | if return_U: |
| | 551 | U = PY_NEW(ntl_mat_ZZ) |
| | 552 | _sig_on |
| | 553 | rank = int(mat_ZZ_G_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 554 | _sig_off |
| | 555 | return rank, U |
| | 556 | else: |
| | 557 | _sig_on |
| | 558 | rank = int(mat_ZZ_G_LLL_QP(self.x,float(delta),0,0,int(verbose))) |
| | 559 | _sig_off |
| | 560 | return rank |
| | 561 | |
| | 562 | def G_LLL_XD(self, delta, return_U=False, verbose=False): |
| | 563 | r""" |
| | 564 | Peforms the same reduction as self.G_LLL_FP using the same |
| | 565 | calling conventions but with extended exponent double |
| | 566 | precision. |
| | 567 | """ |
| | 568 | cdef ntl_mat_ZZ U |
| | 569 | if return_U: |
| | 570 | U = PY_NEW(ntl_mat_ZZ) |
| | 571 | _sig_on |
| | 572 | rank = int(mat_ZZ_G_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 573 | _sig_off |
| | 574 | return rank, U |
| | 575 | else: |
| | 576 | _sig_on |
| | 577 | rank = int(mat_ZZ_G_LLL_XD(self.x,float(delta),0,0,int(verbose))) |
| | 578 | _sig_off |
| | 579 | return rank |
| | 580 | |
| | 581 | def G_LLL_RR(self, delta, return_U=False, verbose=False): |
| | 582 | r""" |
| | 583 | Peforms the same reduction as self.G_LLL_FP using the same |
| | 584 | calling conventions but with aribitrary precision floating |
| | 585 | point numbers. |
| | 586 | """ |
| | 587 | cdef ntl_mat_ZZ U |
| | 588 | if return_U: |
| | 589 | U = PY_NEW(ntl_mat_ZZ) |
| | 590 | _sig_on |
| | 591 | rank = int(mat_ZZ_G_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose))) |
| | 592 | _sig_off |
| | 593 | return rank, U |
| | 594 | else: |
| | 595 | _sig_on |
| | 596 | rank = int(mat_ZZ_G_LLL_RR(self.x,float(delta),0,0,int(verbose))) |
| | 597 | _sig_off |
| | 598 | return rank |