enumerate_base.h
Go to the documentation of this file.
1/* Copyright (C) 2008-2011 Xavier Pujol
2 (C) 2015 Michael Walter.
3 (C) 2016 Marc Stevens. (generic improvements, auxiliary solutions, subsolutions)
4 (C) 2016 Guillaume Bonnoron. (CVP improvements)
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_ENUMERATE_BASE_H
20#define FPLLL_ENUMERATE_BASE_H
21
23#include "fplll/fplll_config.h"
24#include "fplll/nr/nr.h"
25#include <array>
26#include <cfenv>
27#include <cmath>
28#include <numeric>
29#include <vector>
30
32
33inline void roundto(int &dest, const double &src) { dest = (int)round(src); }
34inline void roundto(double &dest, const double &src) { dest = round(src); }
35
36/* config */
37#define MAXTEMPLATEDDIMENSION 80 // unused
38//#define FORCE_ENUM_INLINE // not recommended
39/* end config */
40
41#ifndef __has_attribute
42#define __has_attribute(x) 0 // Compatibility with non - GCC/clang compilers.
43#endif
44#if __has_attribute(always_inline)
45#define ALWAYS_INLINE __attribute__((always_inline))
46#else
47#define ALWAYS_INLINE
48#endif
49
50#ifndef FORCE_ENUM_INLINE
51#define ENUM_ALWAYS_INLINE
52#else
53#define ENUM_ALWAYS_INLINE ALWAYS_INLINE
54#endif
55
57{
58public:
59 static const int maxdim = FPLLL_MAX_ENUM_DIM;
60
61 inline uint64_t get_nodes(const int level = -1) const
62 {
63 if (level == -1)
64 {
65 return std::accumulate(nodes.begin(), nodes.end(), 0);
66 }
67
68 return nodes[level];
69 }
70 virtual ~EnumerationBase() {}
71
72protected:
73 /* configuration */
74 bool dual;
75 bool is_svp; // only for SVP: exploit symmetry in enumeration to half search space
77
78 /* enumeration input */
80 array<enumf, maxdim> rdiag, partdistbounds;
81 int d, k_end; // dimension, subtreelevel
82
83 /* partial sum cache */
85 array<enumf, maxdim> center_partsum;
86 array<int, maxdim> center_partsum_begin;
87
88 /* enumeration data for each level */
89 array<enumf, maxdim> partdist, center, alpha;
90 array<enumxt, maxdim> x, dx, ddx;
91 array<enumf, maxdim> subsoldists;
92
93 /* CVP reset informations */
94 vector<int> _max_indices;
96
97 int k, k_max;
99
100 /* nodes count */
101 array<uint64_t, FPLLL_EXTENUM_MAX_EXTENUM_DIM> nodes;
102
103 template <int kk, int kk_start, bool dualenum, bool findsubsols, bool enable_reset> struct opts
104 {
105 };
106
107 /* need templated function argument for support of integer specialization for kk==-1 */
108 template <int kk, int kk_start, bool dualenum, bool findsubsols, bool enable_reset>
111 template <int kk_start, bool dualenum, bool findsubsols, bool enable_reset>
113 {
114 }
115
116 /* simple wrapper with no function argument as helper for dispatcher */
117 template <int kk, bool dualenum, bool findsubsols, bool enable_reset>
119 {
120 // kk < maxdim-1:
121 // kk < kk_end (see enumerate_loop(), enumerate_base.cpp)
122 // kk_end = d - subtree.size() <= d (see prepare_enumeration(), enumerate.cpp)
123 // d < maxdim (see enumerate(), enumerate.cpp)
125 opts<(kk < (maxdim - 1) ? kk : -1), 0, dualenum, findsubsols, enable_reset>());
126 }
127
128 template <bool dualenum, bool findsubsols, bool enable_reset>
129 inline void enumerate_recursive_dispatch(int kk);
130
131 template <bool dualenum, bool findsubsols, bool enable_reset> void enumerate_loop();
132
133 virtual void reset(enumf, int) = 0;
134 virtual void process_solution(enumf newmaxdist) = 0;
135 virtual void process_subsolution(int offset, enumf newdist) = 0;
136
139 {
140 rounding_backup = std::fegetround();
141 std::fesetround(FE_TONEAREST);
142 }
143 void restore_rounding() { std::fesetround(rounding_backup); }
144
145 inline bool next_pos_up()
146 {
147 ++k;
148 if (partdist[k] != 0.0)
149 {
150 x[k] += dx[k];
151 ddx[k] = -ddx[k];
152 dx[k] = ddx[k] - dx[k];
153 }
154 else
155 {
156 if (k >= k_end)
157 return false;
158 k_max = k;
159 if (is_svp)
160 {
161 // only for SVP: break symmetry at the top non-zero coefficient
162 ++x[k];
163 }
164 else
165 {
166 x[k] += dx[k];
167 ddx[k] = -ddx[k];
168 dx[k] = ddx[k] - dx[k];
169 }
170 }
171 return true;
172 }
173};
174
176
177#endif
Definition: enumerate_base.h:57
virtual void reset(enumf, int)=0
virtual void process_subsolution(int offset, enumf newdist)=0
bool dual
Definition: enumerate_base.h:74
int reset_depth
Definition: enumerate_base.h:95
int rounding_backup
Definition: enumerate_base.h:137
array< enumf, maxdim > center_partsum
Definition: enumerate_base.h:85
bool next_pos_up()
Definition: enumerate_base.h:145
array< enumf, maxdim > center
Definition: enumerate_base.h:89
void enumerate_recursive_wrapper()
Definition: enumerate_base.h:118
array< int, maxdim > center_partsum_begin
Definition: enumerate_base.h:86
void enumerate_loop()
int k_max
Definition: enumerate_base.h:97
void restore_rounding()
Definition: enumerate_base.h:143
array< enumf, maxdim > partdist
Definition: enumerate_base.h:89
bool resetflag
Definition: enumerate_base.h:76
virtual ~EnumerationBase()
Definition: enumerate_base.h:70
array< uint64_t, FPLLL_EXTENUM_MAX_EXTENUM_DIM > nodes
Definition: enumerate_base.h:101
array< enumxt, maxdim > x
Definition: enumerate_base.h:90
int k
Definition: enumerate_base.h:97
bool is_svp
Definition: enumerate_base.h:75
array< enumf, maxdim > rdiag
Definition: enumerate_base.h:80
int k_end
Definition: enumerate_base.h:81
array< enumf, maxdim > alpha
Definition: enumerate_base.h:89
int d
Definition: enumerate_base.h:81
enumf center_partsums[maxdim][maxdim]
Definition: enumerate_base.h:84
static const int maxdim
Definition: enumerate_base.h:59
bool finished
Definition: enumerate_base.h:98
void enumerate_recursive_dispatch(int kk)
array< enumf, maxdim > partdistbounds
Definition: enumerate_base.h:80
vector< int > _max_indices
Definition: enumerate_base.h:94
array< enumf, maxdim > subsoldists
Definition: enumerate_base.h:91
enumf mut[maxdim][maxdim]
Definition: enumerate_base.h:79
uint64_t get_nodes(const int level=-1) const
Definition: enumerate_base.h:61
array< enumxt, maxdim > ddx
Definition: enumerate_base.h:90
array< enumxt, maxdim > dx
Definition: enumerate_base.h:90
void save_rounding()
Definition: enumerate_base.h:138
void enumerate_recursive(opts<-1, kk_start, dualenum, findsubsols, enable_reset >)
Definition: enumerate_base.h:112
virtual void process_solution(enumf newmaxdist)=0
void enumerate_recursive(opts< kk, kk_start, dualenum, findsubsols, enable_reset >) ENUM_ALWAYS_INLINE
#define FPLLL_MAX_ENUM_DIM
Definition: config.h:11
#define FPLLL_END_NAMESPACE
Definition: defs.h:117
#define FPLLL_BEGIN_NAMESPACE
Definition: defs.h:114
FPLLL_BEGIN_NAMESPACE void roundto(int &dest, const double &src)
Definition: enumerate_base.h:33
#define ENUM_ALWAYS_INLINE
Definition: enumerate_base.h:51
fplll_extenum_enumf std::function< extenum_cb_set_config > std::function< extenum_cb_process_sol > std::function< extenum_cb_process_subsol > bool bool findsubsols
Definition: enumerate_ext_api.h:92
FPLLL_BEGIN_NAMESPACE typedef double enumf
Definition: nr.h:42
Definition: enumerate_base.h:104