gso_interface.h
Go to the documentation of this file.
1/* Copyright (C) 2005-2008 Damien Stehle.
2 Copyright (C) 2007 David Cade.
3 Copyright (C) 2011 Xavier Pujol.
4 Copyright (C) 2019 Koen de Boer
5
6 This file is part of fplll. fplll is free software: you
7 can redistribute it and/or modify it under the terms of the GNU Lesser
8 General Public License as published by the Free Software Foundation,
9 either version 2.1 of the License, or (at your option) any later version.
10
11 fplll is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with fplll. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifndef FPLLL_GSOInterface_H
20#define FPLLL_GSOInterface_H
21
22#include "nr/matrix.h"
23
25
27{
32};
33
48template <class FT>
49void adjust_radius_to_gh_bound(FT &max_dist, long max_dist_expo, int block_size, const FT &root_det,
50 double gh_factor);
51
59template <class ZT, class FT> class MatGSOInterface
60{
61public:
97
98 MatGSOInterface(Matrix<ZT> &arg_u, Matrix<ZT> &arg_uinv_t, int flags)
100 enable_transform(arg_u.get_rows() > 0), enable_inverse_transform(arg_uinv_t.get_rows() > 0),
101 row_op_force_long(flags & GSO_OP_FORCE_LONG), u(arg_u), u_inv_t(arg_uinv_t),
103 gptr(nullptr)
104 {
105#ifdef DEBUG
106 row_op_first = row_op_last = -1;
107#endif
108 }
109
114 int d;
115
119 // Matrix<ZT> &b;
120
130 virtual ZT &sqnorm_coordinates(ZT &sqnorm, vector<ZT> coordinates) = 0;
131
137 virtual long get_max_exp_of_b() = 0;
138
143 virtual bool b_row_is_zero(int i) = 0;
144
149 virtual int get_cols_of_b() const = 0;
150
156 virtual int get_rows_of_b() const = 0;
157
161 virtual void negate_row_of_b(int i) = 0;
162
167 vector<long> row_expo;
168
172 inline void row_op_begin(int first, int last);
173
178 void row_op_end(int first, int last);
179
189 virtual FT &get_gram(FT &f, int i, int j) = 0;
190
199 virtual ZT &get_int_gram(ZT &z, int i, int j) = 0;
200
207 const Matrix<FT> &get_mu_matrix() const { return mu; }
208
214 const Matrix<FT> &get_r_matrix() const { return r; }
215
222 {
223 if (gptr == nullptr)
224 {
225 throw std::runtime_error("Error: gptr == nullpointer.");
226 }
227 return *gptr;
228 }
229
239 inline const FT &get_mu_exp(int i, int j, long &expo) const;
240 inline const FT &get_mu_exp(int i, int j) const;
241
247 inline FT &get_mu(FT &f, int i, int j);
248
252 ZT get_max_gram();
253
257 FT get_max_bstar();
258
267 inline const FT &get_r_exp(int i, int j, long &expo) const;
268 inline const FT &get_r_exp(int i, int j) const;
269
275 inline FT &get_r(FT &f, int i, int j);
276
281 long get_max_mu_exp(int i, int n_columns);
282
289 bool update_gso_row(int i, int last_j);
290
297 inline bool update_gso_row(int i);
298
302 inline bool update_gso();
303
307 inline void discover_all_rows();
308
314 void set_r(int i, int j, FT &f);
315
320 virtual void move_row(int old_r, int new_r) = 0;
321
331 virtual inline void row_addmul(int i, int j, const FT &x);
332
343 virtual void row_addmul_we(int i, int j, const FT &x, long expo_add) = 0;
344
345 // b[i] += b[j] / b[i] -= b[j] (i > j)
346 virtual void row_add(int i, int j) = 0;
347 virtual void row_sub(int i, int j) = 0;
348
354 void lock_cols();
355 void unlock_cols();
356
363 inline void create_row();
364 virtual void create_rows(int n_new_rows) = 0;
365
370 inline void remove_last_row();
371 virtual void remove_last_rows(int n_removed_rows) = 0;
372
378 void apply_transform(const Matrix<FT> &transform, int src_base, int target_base);
379
380 void apply_transform(const Matrix<FT> &transform, int src_base)
381 {
382 apply_transform(transform, src_base, src_base);
383 }
384
395 inline void dump_mu_d(double *mu, int offset = 0, int block_size = -1);
396 inline void dump_mu_d(vector<double> mu, int offset = 0, int block_size = -1);
397
408 inline void dump_r_d(double *r, int offset = 0, int block_size = -1);
409 inline void dump_r_d(vector<double> &r, int offset = 0, int block_size = -1);
410
422 double get_current_slope(int start_row, int stop_row);
423
431 FT get_root_det(int start_row, int end_row);
432
440 FT get_log_det(int start_row, int end_row);
441
450 FT get_slide_potential(int start_row, int end_row, int block_size);
451
456 inline void print_mu_r_g(ostream &os);
457
466 void virtual babai(vector<ZT> &v, int start = 0, int dimension = -1);
467
477 void virtual babai(vector<ZT> &w, const vector<FT> &v, int start = 0, int dimension = 1);
478
480 const bool enable_int_gram;
481
483 const bool enable_row_expo;
484
487
494
500
501protected:
505 virtual void size_increased() = 0;
506
507 /* Increases known rows and invalidates the last
508 * gram row (gf) when enable_int_gram is false.
509 * When enable_int_gram is true, it computes
510 * the new inner products for the last gram
511 * row (g).
512 */
513 virtual void discover_row() = 0;
514
515 // Marks mu(i, j) and r(i, j) as invalid for j >= new_valid_cols
516 void invalidate_gso_row(int i, int new_valid_cols = 0);
517 /* Upates the i-th row of bf. It does not invalidate anything, so the caller
518 * must take into account that it might change row_expo.
519 */
520 virtual void update_bf(int i) = 0;
521 /* Marks g(i, j) for all j <= i (but NOT for j > i) */
522 virtual void invalidate_gram_row(int i) = 0;
523
524 // b[i] <- b[i] + x * b[j] (i > j)
525 virtual void row_addmul_si(int i, int j, long x) = 0;
526 // b[i] <- b[i] + (2^expo * x) * b[j] (i > j)
527
528 // TODO check if these must be scratched here!
529 // virtual void row_addmul_si_2exp(int i, int j, long x, long expo) = 0;
530 // virtual void row_addmul_2exp(int i, int j, const ZT &x, long expo) = 0;
531
532public:
533 // made public for lll.cpp and bkz.cpp
535
536 // Made public for bkz.cpp (dbkz_postprocessing)
537 // b[i] <-> b[j] (i < j)
538 virtual void row_swap(int i, int j) = 0;
539
540protected:
541 inline ZT &sym_g(int i, int j);
542
543 /* Floating-point representation of the basis. It is used when
544 enable_int_gram=false. */
546
547 Matrix<ZT> &u; // Transform
548 Matrix<ZT> &u_inv_t; // Transposed inverse transform
549
550 // init_row_size[i] = (last non-zero column in the i-th row of b) + 1
551 vector<int> init_row_size;
552
553 // bf[i], g[i], gf[i], mu[i] and r[i] are invalid for i >= n_known_rows
555 int n_source_rows; // Known rows before the beginning of early reduction
559
573
587
588public:
595 /* Gram matrix (dot products of basis vectors, lower triangular matrix)
596 g(i, j) is valid if 0 <= i < n_known_rows and j <= i */
598 // Matrix<ZT> g;
599
600protected:
602
603 /* Number of valid columns of the i-th row of mu and r.
604 Valid only for 0 <= i < n_known_rows */
605 vector<int> gso_valid_cols;
606
607 /* Used by update_gso_row (+ update_gso), get_max_mu_exp and row_addmul_we. */
609 /* Used by row_add, row_sub, row_addmul_si_2exp, row_addmul_2exp and
610 indirectly by row_addmul. */
612 /* Used by row_addmul. */
614 /* Used by update_bf. */
615 vector<long> tmp_col_expo;
616
617#ifdef DEBUG
618 /* Used only in debug mode. */
619 int row_op_first, row_op_last;
620 bool in_row_op_range(int i) { return i >= row_op_first && i < row_op_last; }
621#endif
622};
623
624template <class ZT, class FT> inline MatGSOInterface<ZT, FT>::~MatGSOInterface()
625{
626 // delete gptr;
627}
628
629template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::symmetrize_g()
630{
631 if (gptr == nullptr)
632 {
633 throw std::runtime_error("Error: gptr is equal to the nullpointer.");
634 }
635 Matrix<ZT> &gr = *gptr;
636 for (int i = 0; i < d; i++)
637 {
638 for (int j = 0; j < d; j++)
639 {
640 gr(i, j) = sym_g(i, j);
641 }
642 }
643}
644
645template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::print_mu_r_g(ostream &os)
646{
647 os << "mu = " << endl;
648 mu.print(os);
649 os << endl << "r = " << endl;
650 r.print(os);
651 os << endl;
652 if (gptr != nullptr)
653 {
654 os << "g = " << endl;
655 symmetrize_g();
656 gptr->print(os);
657 os << endl << endl;
658 }
659}
660
661template <class ZT, class FT> inline ZT &MatGSOInterface<ZT, FT>::sym_g(int i, int j)
662{
663 if (gptr == nullptr)
664 {
665 throw std::runtime_error("Error: gptr is equal to the nullpointer.");
666 }
667 Matrix<ZT> &gr = *gptr;
668 return (i >= j) ? gr(i, j) : gr(j, i);
669}
670
671template <class ZT, class FT>
672inline const FT &MatGSOInterface<ZT, FT>::get_mu_exp(int i, int j, long &expo) const
673{
674 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < i && j < gso_valid_cols[i] &&
675 !in_row_op_range(i));
676 if (enable_row_expo)
677 expo = row_expo[i] - row_expo[j];
678 else
679 expo = 0;
680 return mu(i, j);
681}
682
683template <class ZT, class FT>
684inline const FT &MatGSOInterface<ZT, FT>::get_mu_exp(int i, int j) const
685{
686 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < i && j < gso_valid_cols[i] &&
687 !in_row_op_range(i));
688 return mu(i, j);
689}
690
691template <class ZT, class FT> inline FT &MatGSOInterface<ZT, FT>::get_mu(FT &f, int i, int j)
692{
693 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < i && j < gso_valid_cols[i] &&
694 !in_row_op_range(i));
695 f = mu(i, j);
696 if (enable_row_expo)
697 f.mul_2si(f, row_expo[i] - row_expo[j]);
698 return f;
699}
700
701template <class ZT, class FT>
702inline const FT &MatGSOInterface<ZT, FT>::get_r_exp(int i, int j, long &expo) const
703{
704 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < gso_valid_cols[i] &&
705 !in_row_op_range(i));
706 if (enable_row_expo)
707 expo = row_expo[i] + row_expo[j];
708 else
709 expo = 0;
710 return r(i, j);
711}
712
713template <class ZT, class FT>
714inline const FT &MatGSOInterface<ZT, FT>::get_r_exp(int i, int j) const
715{
716 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < gso_valid_cols[i] &&
717 !in_row_op_range(i));
718 return r(i, j);
719}
720
721template <class ZT, class FT> inline FT &MatGSOInterface<ZT, FT>::get_r(FT &f, int i, int j)
722{
723 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && j >= 0 && j < gso_valid_cols[i] &&
724 !in_row_op_range(i));
725 f = r(i, j);
726 if (enable_row_expo)
727 f.mul_2si(f, row_expo[i] + row_expo[j]);
728 return f;
729}
730
731template <class ZT, class FT> inline bool MatGSOInterface<ZT, FT>::update_gso_row(int i)
732{
733 return update_gso_row(i, i);
734}
735
736template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::set_r(int i, int j, FT &f)
737{
738 FPLLL_DEBUG_CHECK(i >= 0 && i < n_known_rows && gso_valid_cols[i] >= j && j >= 0 &&
739 j < n_source_rows);
740 r(i, j) = f;
741 if (gso_valid_cols[i] == j)
742 gso_valid_cols[i]++;
743}
744
745template <class ZT, class FT>
746inline void MatGSOInterface<ZT, FT>::row_addmul(int i, int j, const FT &x)
747{
748 row_addmul_we(i, j, x, 0);
749}
750
751template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::create_row() { create_rows(1); }
752
753template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::remove_last_row()
754{
755 remove_last_rows(1);
756}
757
758template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::discover_all_rows()
759{
760 while (n_known_rows < d)
761 discover_row();
762}
763
764template <class ZT, class FT> inline bool MatGSOInterface<ZT, FT>::update_gso()
765{
766 for (int i = 0; i < d; i++)
767 {
768 if (!update_gso_row(i))
769 return false;
770 }
771 return true;
772}
773
774#ifdef DEBUG
775template <class ZT, class FT> inline void MatGSOInterface<ZT, FT>::row_op_begin(int first, int last)
776{
777 FPLLL_DEBUG_CHECK(row_op_first == -1);
778 row_op_first = first;
779 row_op_last = last;
780}
781#else
782template <class ZT, class FT>
783inline void MatGSOInterface<ZT, FT>::row_op_begin(int /*first*/, int /*last*/)
784{
785}
786#endif
787
788template <class ZT, class FT>
789inline void MatGSOInterface<ZT, FT>::dump_mu_d(double *mu, int offset, int block_size)
790{
791 FT e;
792 if (block_size <= 0)
793 {
794 block_size = get_rows_of_b();
795 }
796
797 for (int i = 0; i < block_size; ++i)
798 {
799 for (int j = 0; j < block_size; ++j)
800 {
801 get_mu(e, offset + i, offset + j);
802 mu[i * block_size + j] = e.get_d();
803 }
804 }
805}
806
807template <class ZT, class FT>
808inline void MatGSOInterface<ZT, FT>::dump_mu_d(vector<double> mu, int offset, int block_size)
809{
810 FT e;
811 if (block_size <= 0)
812 {
813 block_size = get_rows_of_b();
814 }
815
816 mu.reserve(mu.size() + block_size * block_size);
817 for (int i = 0; i < block_size; ++i)
818 {
819 for (int j = 0; j < block_size; ++j)
820 {
821 get_mu(e, offset + i, offset + j);
822 mu.push_back(e.get_d());
823 }
824 }
825}
826
827template <class ZT, class FT>
828inline void MatGSOInterface<ZT, FT>::dump_r_d(double *r, int offset, int block_size)
829{
830 FT e;
831 if (block_size <= 0)
832 {
833 block_size = get_rows_of_b();
834 }
835
836 for (int i = 0; i < block_size; ++i)
837 {
838 get_r(e, offset + i, offset + i);
839 r[i] = e.get_d();
840 }
841}
842
843template <class ZT, class FT>
844inline void MatGSOInterface<ZT, FT>::dump_r_d(vector<double> &r, int offset, int block_size)
845{
846 FT e;
847 if (block_size <= 0)
848 {
849 block_size = get_rows_of_b();
850 }
851
852 r.reserve(r.size() + block_size * block_size);
853 for (int i = 0; i < block_size; ++i)
854 {
855 get_r(e, offset + i, offset + i);
856 r.push_back(e.get_d());
857 }
858}
859
861
862#endif
Definition: gso_interface.h:60
vector< long > row_expo
Definition: gso_interface.h:167
int alloc_dim
Definition: gso_interface.h:558
virtual void row_addmul(int i, int j, const FT &x)
Definition: gso_interface.h:746
ZT get_max_gram()
Definition: gso_interface.cpp:55
void apply_transform(const Matrix< FT > &transform, int src_base)
Definition: gso_interface.h:380
bool cols_locked
Definition: gso_interface.h:557
vector< int > gso_valid_cols
Definition: gso_interface.h:605
const bool enable_int_gram
Definition: gso_interface.h:480
virtual void size_increased()=0
const Matrix< FT > & get_r_matrix() const
Definition: gso_interface.h:214
virtual long get_max_exp_of_b()=0
Matrix< FT > mu
Definition: gso_interface.h:572
Matrix< FT > bf
Definition: gso_interface.h:545
FT ftmp2
Definition: gso_interface.h:608
FT get_slide_potential(int start_row, int end_row, int block_size)
Return slide potential of the basis.
Definition: gso_interface.cpp:251
FT & get_r(FT &f, int i, int j)
Definition: gso_interface.h:721
const bool enable_inverse_transform
Definition: gso_interface.h:493
bool update_gso()
Definition: gso_interface.h:764
const FT & get_r_exp(int i, int j, long &expo) const
Definition: gso_interface.h:702
int n_known_rows
Definition: gso_interface.h:554
virtual void move_row(int old_r, int new_r)=0
MatGSOInterface(Matrix< ZT > &arg_u, Matrix< ZT > &arg_uinv_t, int flags)
Definition: gso_interface.h:98
void invalidate_gso_row(int i, int new_valid_cols=0)
Definition: gso_interface.cpp:26
virtual int get_cols_of_b() const =0
int n_source_rows
Definition: gso_interface.h:555
virtual ~MatGSOInterface()
Definition: gso_interface.h:624
bool update_gso_row(int i)
Definition: gso_interface.h:731
bool update_gso_row(int i, int last_j)
Definition: gso_interface.cpp:131
virtual void remove_last_rows(int n_removed_rows)=0
const FT & get_r_exp(int i, int j) const
Definition: gso_interface.h:714
FT get_log_det(int start_row, int end_row)
Return log of the (squared) determinant of the basis.
Definition: gso_interface.cpp:236
const FT & get_mu_exp(int i, int j, long &expo) const
Definition: gso_interface.h:672
virtual int get_rows_of_b() const =0
void row_op_end(int first, int last)
Definition: gso_interface.cpp:32
void dump_r_d(double *r, int offset=0, int block_size=-1)
Definition: gso_interface.h:828
Matrix< FT > gf
Definition: gso_interface.h:601
long get_max_mu_exp(int i, int n_columns)
Definition: gso_interface.cpp:88
void dump_mu_d(double *mu, int offset=0, int block_size=-1)
Definition: gso_interface.h:789
int n_known_cols
Definition: gso_interface.h:556
Matrix< ZT > * gptr
Definition: gso_interface.h:597
virtual void row_addmul_si(int i, int j, long x)=0
void remove_last_row()
Definition: gso_interface.h:753
FT ftmp1
Definition: gso_interface.h:608
void discover_all_rows()
Definition: gso_interface.h:758
void dump_mu_d(vector< double > mu, int offset=0, int block_size=-1)
Definition: gso_interface.h:808
virtual void babai(vector< ZT > &v, int start=0, int dimension=-1)
Definition: gso_interface.cpp:284
const Matrix< FT > & get_mu_matrix() const
Definition: gso_interface.h:207
const bool enable_row_expo
Definition: gso_interface.h:483
const FT & get_mu_exp(int i, int j) const
Definition: gso_interface.h:684
virtual ZT & sqnorm_coordinates(ZT &sqnorm, vector< ZT > coordinates)=0
FT & get_mu(FT &f, int i, int j)
Definition: gso_interface.h:691
virtual ZT & get_int_gram(ZT &z, int i, int j)=0
ZT ztmp1
Definition: gso_interface.h:611
double get_current_slope(int start_row, int stop_row)
Return slope of the curve fitted to the lengths of the vectors from start_row to stop_row.
Definition: gso_interface.cpp:198
virtual void row_swap(int i, int j)=0
Matrix< ZT > & u_inv_t
Definition: gso_interface.h:548
void row_op_begin(int first, int last)
Definition: gso_interface.h:783
vector< int > init_row_size
Definition: gso_interface.h:551
const bool row_op_force_long
Definition: gso_interface.h:499
int d
Definition: gso_interface.h:114
vector< long > tmp_col_expo
Definition: gso_interface.h:615
virtual void discover_row()=0
virtual void update_bf(int i)=0
void set_r(int i, int j, FT &f)
Definition: gso_interface.h:736
void create_row()
Definition: gso_interface.h:751
Matrix< FT > r
Definition: gso_interface.h:586
void print_mu_r_g(ostream &os)
Definition: gso_interface.h:645
virtual void invalidate_gram_row(int i)=0
void unlock_cols()
Definition: gso_interface.cpp:168
FT get_max_bstar()
Definition: gso_interface.cpp:79
void symmetrize_g()
Definition: gso_interface.h:629
virtual void negate_row_of_b(int i)=0
ZT & sym_g(int i, int j)
Definition: gso_interface.h:661
FT get_root_det(int start_row, int end_row)
Return (squared) root determinant of the basis.
Definition: gso_interface.cpp:226
void dump_r_d(vector< double > &r, int offset=0, int block_size=-1)
Definition: gso_interface.h:844
const Matrix< ZT > & get_g_matrix() const
Definition: gso_interface.h:221
const bool enable_transform
Definition: gso_interface.h:486
virtual bool b_row_is_zero(int i)=0
virtual void row_add(int i, int j)=0
virtual void row_sub(int i, int j)=0
Matrix< ZT > & u
Definition: gso_interface.h:547
virtual FT & get_gram(FT &f, int i, int j)=0
void lock_cols()
Definition: gso_interface.cpp:166
virtual void row_addmul_we(int i, int j, const FT &x, long expo_add)=0
void apply_transform(const Matrix< FT > &transform, int src_base, int target_base)
Definition: gso_interface.cpp:175
ZT ztmp2
Definition: gso_interface.h:613
virtual void create_rows(int n_new_rows)=0
#define FPLLL_END_NAMESPACE
Definition: defs.h:117
#define FPLLL_DEBUG_CHECK(x)
Definition: defs.h:109
#define FPLLL_BEGIN_NAMESPACE
Definition: defs.h:114
MatGSOInterfaceFlags
Definition: gso_interface.h:27
@ GSO_OP_FORCE_LONG
Definition: gso_interface.h:31
@ GSO_ROW_EXPO
Definition: gso_interface.h:30
@ GSO_INT_GRAM
Definition: gso_interface.h:29
@ GSO_DEFAULT
Definition: gso_interface.h:28
void adjust_radius_to_gh_bound(FT &max_dist, long max_dist_expo, int block_size, const FT &root_det, double gh_factor)
Use Gaussian Heuristic to compute a bound on the length of the shortest vector.
Definition: gso_interface.cpp:267