evaluator.h
Go to the documentation of this file.
1/* Copyright (C) 2008-2011 Xavier Pujol.
2
3 This file is part of fplll. fplll is free software: you
4 can redistribute it and/or modify it under the terms of the GNU Lesser
5 General Public License as published by the Free Software Foundation,
6 either version 2.1 of the License, or (at your option) any later version.
7
8 fplll is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU Lesser General Public License for more details.
12
13 You should have received a copy of the GNU Lesser General Public License
14 along with fplll. If not, see <http://www.gnu.org/licenses/>. */
15
16#ifndef FPLLL_EVALUATOR_H
17#define FPLLL_EVALUATOR_H
18
19#include <cassert>
20#include <fplll/gso_interface.h>
21#include <fplll/util.h>
22#include <functional>
23#include <map>
24#include <queue>
25
27
29{
34};
35
37{
38 /*
39 * Strategies for updating the enumeration bound as solutions are found.
40 * Possible values are:
41 *
42 * EVALSTRATEGY_BEST_N_SOLUTIONS
43 * Starting with the max_sols-th solution, every time a new solution is found
44 * the enumeration bound is updated to the length of the longest solution. If
45 * more than max_sols were found, the longest is dropped.
46 * EVALSTRATEGY_OPPORTUNISTIC_N_SOLUTIONS
47 * Every time a solution is found, update the enumeration distance to the length
48 * of the solution. If more than max_sols were found, the longest is dropped.
49 * EVALSTRATEGY_FIRST_N_SOLUTIONS
50 * The enumeration bound is not updated. As soon as max_sols are found, enumeration
51 * stops.
52 */
56};
57
65template <class FT> class Evaluator
66{
67public:
68 Evaluator(size_t nr_solutions = 1,
70 bool find_subsolutions = false)
71 : max_sols(nr_solutions), strategy(update_strategy), findsubsols(find_subsolutions),
72 sol_count(0)
73 {
74 FPLLL_CHECK(nr_solutions > 0, "Evaluator: nr_solutions must be strictly positive!");
75 FPLLL_CHECK(strategy <= 2, "Evaluator: invalid strategy");
76 }
77 virtual ~Evaluator() {}
78
80 size_t max_sols;
83
85 // multimap storing solutions mapped by their length
86 // the longest solution is the first, the shortest solution last
87 typedef std::multimap<FT, std::vector<FT>, std::greater<FT>> container_t;
89 size_t sol_count;
90
92 std::vector<std::pair<FT, std::vector<FT>>> sub_solutions;
93
95 typename container_t::const_reverse_iterator begin() const { return solutions.rbegin(); }
96 typename container_t::const_reverse_iterator end() const { return solutions.rend(); }
97 typename container_t::reverse_iterator begin() { return solutions.rbegin(); }
98 typename container_t::reverse_iterator end() { return solutions.rend(); }
99 size_t size() const { return solutions.size(); }
100 bool empty() const { return solutions.empty(); }
101
103 virtual void eval_sol(const vector<FT> &new_sol_coord, const enumf &new_partial_dist,
104 enumf &max_dist) = 0;
105
106 virtual void eval_sub_sol(int offset, const vector<FT> &new_sub_sol_coord,
107 const enumf &sub_dist) = 0;
108
109 virtual void set_normexp(long norm_exp) { normExp = norm_exp; }
111
112protected:
114 virtual enumf calc_enum_bound(const FT &dist) const
115 {
116 FT tmp;
117 tmp.mul_2si(dist, -normExp);
118 return tmp.get_d(GMP_RNDU);
119 }
120
122 void process_sol(const FT &dist, const vector<FT> &coord, enumf &max_dist)
123 {
124 ++sol_count;
125 solutions.emplace(dist, coord);
126 switch (strategy)
127 {
129 if (solutions.size() < max_sols)
130 return;
131 // remove the longest solution, and use the new longest dist to update max_dist
132 if (solutions.size() > max_sols)
133 solutions.erase(solutions.begin());
134 max_dist = calc_enum_bound(solutions.begin()->first);
135 break;
136
138 // always use dist to update max_dist
139 max_dist = calc_enum_bound(dist);
140 if (solutions.size() <= max_sols)
141 return;
142 // remove longest solution
143 solutions.erase(solutions.begin());
144 break;
145
147 if (solutions.size() < max_sols)
148 return;
149 // when desired nr of solutions has been reached, set enum bound to zero
150 max_dist = 0;
151 break;
152
153 default:
154 FPLLL_CHECK(false, "Evaluator: invalid strategy switch!");
155 }
156 }
157};
158
164template <class FT> class FastEvaluator : public Evaluator<FT>
165{
166public:
167 using Evaluator<FT>::max_sols;
168 using Evaluator<FT>::strategy;
169 using Evaluator<FT>::findsubsols;
170 using Evaluator<FT>::normExp;
171 using Evaluator<FT>::sub_solutions;
172
173 FastEvaluator(size_t nr_solutions = 1,
175 bool find_subsolutions = false)
176 : Evaluator<FT>(nr_solutions, update_strategy, find_subsolutions)
177 {
178 }
179 virtual ~FastEvaluator() {}
180
181 virtual void eval_sol(const vector<FT> &new_sol_coord, const enumf &new_partial_dist,
182 enumf &max_dist)
183 {
184 FT dist = new_partial_dist;
185 dist.mul_2si(dist, normExp);
186
187 // store solution and update max_dist according to strategy
188 this->process_sol(dist, new_sol_coord, max_dist);
189 }
190
191 virtual void eval_sub_sol(int offset, const vector<FT> &new_sub_sol_coord, const enumf &sub_dist)
192 {
193 FT dist = sub_dist;
194 dist.mul_2si(dist, normExp);
195
196 sub_solutions.resize(std::max(sub_solutions.size(), std::size_t(offset + 1)));
197
198 if (sub_solutions[offset].second.empty() || dist < sub_solutions[offset].first)
199 {
200 sub_solutions[offset].first = dist;
201 sub_solutions[offset].second = new_sub_sol_coord;
202 for (int i = 0; i < offset; ++i)
203 sub_solutions[offset].second[i] = 0.0;
204 }
205 }
206};
207
213typedef bool(callback_evaluator_callback)(size_t n, enumf *new_sol_coord, void *ctx);
214
222template <class FT> class CallbackEvaluator : public FastEvaluator<FT>
223{
224
225 std::function<callback_evaluator_callback> callbackf;
226 void *ctx;
227 enumf new_sol_coordf[FPLLL_MAX_ENUM_DIM];
228
229public:
230 using FastEvaluator<FT>::max_sols;
231 using FastEvaluator<FT>::strategy;
233 using FastEvaluator<FT>::normExp;
235
236 CallbackEvaluator(std::function<callback_evaluator_callback> callbackf, void *ctx = NULL,
237 size_t nr_solutions = 1,
239 bool find_subsolutions = false
240
241 )
242 : FastEvaluator<FT>(nr_solutions, update_strategy, find_subsolutions), callbackf(callbackf),
243 ctx(ctx)
244 {
245 }
247
248 virtual void eval_sol(const vector<FT> &new_sol_coord, const enumf &new_partial_dist,
249 enumf &max_dist)
250 {
251 assert(new_sol_coord.size() <= FPLLL_MAX_ENUM_DIM);
252 for (size_t i = 0; i < new_sol_coord.size(); i++)
253 {
254 new_sol_coordf[i] = new_sol_coord[i].get_d();
255 }
256 if (!callbackf(new_sol_coord.size(), new_sol_coordf, this->ctx))
257 return;
258
259 FastEvaluator<FT>::eval_sol(new_sol_coord, new_partial_dist, max_dist);
260 }
261};
262
267class ErrorBoundedEvaluator : public Evaluator<FP_NR<mpfr_t>>
268{
269public:
271 EvaluatorMode evalmode, size_t nr_solutions = 1,
273 bool find_subsolutions = false)
274 : Evaluator(nr_solutions, update_strategy, find_subsolutions), eval_mode(evalmode), d(dim),
275 mu(mmu), r(mr), input_error_defined(false)
276 {
277 max_dr_diag.resize(d);
278 max_dm_u.resize(d);
279 }
280
282
285 int d;
288
289 /* To enable error estimation, the caller must set
290 input_error_defined=true and fill max_dr_diag and max_dm_u */
292 vector<FP_NR<mpfr_t>> max_dr_diag, max_dm_u; // Error bounds on input parameters
293 // FP_NR<mpfr_t> last_partial_dist; // Approx. squared norm of the last solution
294
295 void init_delta_def(int prec, double rho, bool withRoundingToEnumf);
296
302 virtual bool get_max_error(FP_NR<mpfr_t> &max_error, const FP_NR<mpfr_t> &sol_dist) = 0;
303
304 // Internal use
305 bool get_max_error_aux(const FP_NR<mpfr_t> &max_dist, bool boundOnExactVal, FP_NR<mpfr_t> &maxDE);
306};
307
315{
316public:
319 EvaluatorMode eval_mode = EVALMODE_SV, size_t nr_solutions = 1,
321 bool find_subsolutions = false)
322 : ErrorBoundedEvaluator(d, mu, r, eval_mode, nr_solutions, update_strategy, find_subsolutions)
323 {
324 }
326
327 virtual bool get_max_error(FP_NR<mpfr_t> &max_error, const FP_NR<mpfr_t> &sol_dist);
328 virtual void eval_sol(const vector<FP_NR<mpfr_t>> &new_sol_coord, const enumf &new_partial_dist,
329 enumf &max_dist);
330 virtual void eval_sub_sol(int offset, const vector<FP_NR<mpfr_t>> &new_sub_sol_coord,
331 const enumf &sub_dist);
332};
333
339{
340public:
342 EvaluatorMode eval_mode, size_t nr_solutions = 1,
344 bool find_subsolutions = false)
345 : ErrorBoundedEvaluator(d, _gso.get_mu_matrix(), _gso.get_r_matrix(), eval_mode, nr_solutions,
346 update_strategy, find_subsolutions),
347 gso(_gso)
348 {
349 int_max_dist = -1;
350 }
351
353
357 virtual bool get_max_error(FP_NR<mpfr_t> &max_error, const FP_NR<mpfr_t> &sol_dist);
358
359 virtual void eval_sol(const vector<FP_NR<mpfr_t>> &new_sol_coord, const enumf &new_partial_dist,
360 enumf &max_dist);
361
362 virtual void eval_sub_sol(int offset, const vector<FP_NR<mpfr_t>> &new_sub_sol_coord,
363 const enumf &sub_dist);
364
365 Z_NR<mpz_t> int_max_dist; // Exact norm of the last vector
366
367 Z_NR<mpz_t> exact_sol_dist(const vector<FP_NR<mpfr_t>> &sol_coord);
368 Z_NR<mpz_t> exact_subsol_dist(int offset, const vector<FP_NR<mpfr_t>> &sol_coord);
369
370private:
371 FP_NR<mpfr_t> int_dist2Float(Z_NR<mpz_t> int_dist);
373};
374
376
377#endif
Definition: evaluator.h:223
virtual ~CallbackEvaluator()
Definition: evaluator.h:246
virtual void eval_sol(const vector< FT > &new_sol_coord, const enumf &new_partial_dist, enumf &max_dist)
Definition: evaluator.h:248
CallbackEvaluator(std::function< callback_evaluator_callback > callbackf, void *ctx=NULL, size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:236
Definition: evaluator.h:268
ErrorBoundedEvaluator(int dim, const Matrix< FP_NR< mpfr_t > > &mmu, const Matrix< FP_NR< mpfr_t > > &mr, EvaluatorMode evalmode, size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:270
EvaluatorMode eval_mode
Definition: evaluator.h:284
int d
Definition: evaluator.h:285
bool get_max_error_aux(const FP_NR< mpfr_t > &max_dist, bool boundOnExactVal, FP_NR< mpfr_t > &maxDE)
Definition: evaluator.cpp:75
const Matrix< FP_NR< mpfr_t > > & r
Definition: evaluator.h:287
vector< FP_NR< mpfr_t > > max_dm_u
Definition: evaluator.h:292
bool input_error_defined
Definition: evaluator.h:291
const Matrix< FP_NR< mpfr_t > > & mu
Definition: evaluator.h:286
void init_delta_def(int prec, double rho, bool withRoundingToEnumf)
Definition: evaluator.cpp:20
vector< FP_NR< mpfr_t > > max_dr_diag
Definition: evaluator.h:292
virtual bool get_max_error(FP_NR< mpfr_t > &max_error, const FP_NR< mpfr_t > &sol_dist)=0
virtual ~ErrorBoundedEvaluator()
Definition: evaluator.h:281
Definition: evaluator.h:66
long normExp
Definition: evaluator.h:110
container_t::const_reverse_iterator end() const
Definition: evaluator.h:96
size_t max_sols
Definition: evaluator.h:80
void process_sol(const FT &dist, const vector< FT > &coord, enumf &max_dist)
Definition: evaluator.h:122
size_t sol_count
Definition: evaluator.h:89
container_t::reverse_iterator begin()
Definition: evaluator.h:97
virtual ~Evaluator()
Definition: evaluator.h:77
bool findsubsols
Definition: evaluator.h:82
container_t::reverse_iterator end()
Definition: evaluator.h:98
virtual void eval_sol(const vector< FT > &new_sol_coord, const enumf &new_partial_dist, enumf &max_dist)=0
bool empty() const
Definition: evaluator.h:100
container_t::const_reverse_iterator begin() const
Definition: evaluator.h:95
container_t solutions
Definition: evaluator.h:88
std::vector< std::pair< FT, std::vector< FT > > > sub_solutions
Definition: evaluator.h:92
std::multimap< FT, std::vector< FT >, std::greater< FT > > container_t
Definition: evaluator.h:87
size_t size() const
Definition: evaluator.h:99
virtual enumf calc_enum_bound(const FT &dist) const
Definition: evaluator.h:114
virtual void eval_sub_sol(int offset, const vector< FT > &new_sub_sol_coord, const enumf &sub_dist)=0
virtual void set_normexp(long norm_exp)
Definition: evaluator.h:109
Evaluator(size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:68
EvaluatorStrategy strategy
Definition: evaluator.h:81
Definition: evaluator.h:339
Z_NR< mpz_t > exact_subsol_dist(int offset, const vector< FP_NR< mpfr_t > > &sol_coord)
virtual void eval_sol(const vector< FP_NR< mpfr_t > > &new_sol_coord, const enumf &new_partial_dist, enumf &max_dist)
Definition: evaluator.cpp:277
ExactErrorBoundedEvaluator(int d, MatGSOInterface< Z_NR< mpz_t >, FP_NR< mpfr_t > > &_gso, EvaluatorMode eval_mode, size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:341
virtual void eval_sub_sol(int offset, const vector< FP_NR< mpfr_t > > &new_sub_sol_coord, const enumf &sub_dist)
Definition: evaluator.cpp:311
virtual ~ExactErrorBoundedEvaluator()
Definition: evaluator.h:352
Z_NR< mpz_t > int_max_dist
Definition: evaluator.h:365
virtual bool get_max_error(FP_NR< mpfr_t > &max_error, const FP_NR< mpfr_t > &sol_dist)
Definition: evaluator.cpp:271
Z_NR< mpz_t > exact_sol_dist(const vector< FP_NR< mpfr_t > > &sol_coord)
Definition: evaluator.h:315
virtual void eval_sub_sol(int offset, const vector< FP_NR< mpfr_t > > &new_sub_sol_coord, const enumf &sub_dist)
Definition: evaluator.cpp:229
virtual ~FastErrorBoundedEvaluator()
Definition: evaluator.h:325
FastErrorBoundedEvaluator(int d=0, const Matrix< FP_NR< mpfr_t > > &mu=Matrix< FP_NR< mpfr_t > >(), const Matrix< FP_NR< mpfr_t > > &r=Matrix< FP_NR< mpfr_t > >(), EvaluatorMode eval_mode=EVALMODE_SV, size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:317
virtual void eval_sol(const vector< FP_NR< mpfr_t > > &new_sol_coord, const enumf &new_partial_dist, enumf &max_dist)
Definition: evaluator.cpp:213
virtual bool get_max_error(FP_NR< mpfr_t > &max_error, const FP_NR< mpfr_t > &sol_dist)
Definition: evaluator.cpp:247
Definition: evaluator.h:165
virtual void eval_sol(const vector< FT > &new_sol_coord, const enumf &new_partial_dist, enumf &max_dist)
Definition: evaluator.h:181
virtual void eval_sub_sol(int offset, const vector< FT > &new_sub_sol_coord, const enumf &sub_dist)
Definition: evaluator.h:191
FastEvaluator(size_t nr_solutions=1, EvaluatorStrategy update_strategy=EVALSTRATEGY_BEST_N_SOLUTIONS, bool find_subsolutions=false)
Definition: evaluator.h:173
virtual ~FastEvaluator()
Definition: evaluator.h:179
Definition: gso_interface.h:60
Definition: matrix.h:118
#define FPLLL_MAX_ENUM_DIM
Definition: config.h:11
#define FPLLL_CHECK(x, y)
Definition: defs.h:81
#define FPLLL_END_NAMESPACE
Definition: defs.h:117
#define FPLLL_BEGIN_NAMESPACE
Definition: defs.h:114
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
EvaluatorStrategy
Definition: evaluator.h:37
@ EVALSTRATEGY_OPPORTUNISTIC_N_SOLUTIONS
Definition: evaluator.h:54
@ EVALSTRATEGY_BEST_N_SOLUTIONS
Definition: evaluator.h:53
@ EVALSTRATEGY_FIRST_N_SOLUTIONS
Definition: evaluator.h:55
EvaluatorMode
Definition: evaluator.h:29
@ EVALMODE_COUNT
Definition: evaluator.h:32
@ EVALMODE_SV
Definition: evaluator.h:30
@ EVALMODE_CV
Definition: evaluator.h:31
@ EVALMODE_PRINT
Definition: evaluator.h:33
bool() callback_evaluator_callback(size_t n, enumf *new_sol_coord, void *ctx)
Callback function used by CallbackEvaluator.
Definition: evaluator.h:213
FPLLL_BEGIN_NAMESPACE typedef double enumf
Definition: nr.h:42