/usr/include/fplll/enum/enumerate_base.h is in libfplll-dev 5.0.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* Copyright (C) 2008-2011 Xavier Pujol
(C) 2015 Michael Walter.
(C) 2016 Marc Stevens. (generic improvements, auxiliary solutions, subsolutions)
This file is part of fplll. fplll is free software: you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation,
either version 2.1 of the License, or (at your option) any later version.
fplll is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with fplll. If not, see <http://www.gnu.org/licenses/>. */
#ifndef FPLLL_ENUMERATE_BASE_H
#define FPLLL_ENUMERATE_BASE_H
#include <array>
#include <cfenv>
#include <cmath>
#include "fplll/fplll_config.h"
#include "fplll/nr/nr.h"
FPLLL_BEGIN_NAMESPACE
inline void roundto(int& dest, const double& src) { dest = std::lrint(src); }
inline void roundto(double& dest, const double& src) { dest = std::rint(src); }
/* config */
#define FPLLL_WITH_RECURSIVE_ENUM 1
#define MAXTEMPLATEDDIMENSION 80 // unused
//#define FORCE_ENUM_INLINE // not recommended
/* end config */
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non - GCC/clang compilers.
#endif
#if __has_attribute(always_inline)
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
#ifndef FORCE_ENUM_INLINE
#define ENUM_ALWAYS_INLINE
#else
#define ENUM_ALWAYS_INLINE ALWAYS_INLINE
#endif
class EnumerationBase
{
public:
static const int maxdim = FPLLL_MAX_ENUM_DIMENSION;
inline uint64_t get_nodes() const { return nodes; }
virtual ~EnumerationBase() {}
protected:
/* configuration */
bool dual;
/* enumeration input */
enumf mut[maxdim][maxdim];
array<enumf, maxdim> rdiag, partdistbounds;
int d, k_end; // dimension, subtreelevel
/* partial sum cache */
enumf center_partsums[maxdim][maxdim];
array<enumf, maxdim> center_partsum;
array<int, maxdim> center_partsum_begin;
/* enumeration data for each level */
array<enumf, maxdim> partdist, center, alpha;
array<enumxt,maxdim> x, dx, ddx;
array<enumf, maxdim> subsoldists;
int k, k_max;
/* nodes count */
uint64_t nodes;
template<int kk, int kk_start, bool dualenum, bool findsubsols>
struct opts
{};
/* need templated function argument for support of integer specialization for kk==-1 */
template<int kk, int kk_start, bool dualenum, bool findsubsols>
inline void enumerate_recursive( opts<kk, kk_start, dualenum, findsubsols> ) ENUM_ALWAYS_INLINE;
template<int kk_start, bool dualenum, bool findsubsols>
inline void enumerate_recursive( opts<-1, kk_start, dualenum, findsubsols> )
{
}
/* simple wrapper with no function argument as helper for dispatcher */
template<int kk, bool dualenum, bool findsubsols>
void enumerate_recursive_wrapper()
{
// kk < maxdim-1:
// kk < kk_end (see enumerate_loop(), enumerate_base.cpp)
// kk_end = d - subtree.size() <= d (see prepare_enumeration(), enumerate.cpp)
// d < maxdim (see enumerate(), enumerate.cpp)
enumerate_recursive( opts<(kk<(maxdim-1) ? kk : -1),0,dualenum,findsubsols>() );
}
template<bool dualenum, bool findsubsols>
inline void enumerate_recursive_dispatch(int kk);
template<bool dualenum, bool findsubsols>
void enumerate_loop();
virtual void process_solution(enumf newmaxdist) = 0;
virtual void process_subsolution(int offset, enumf newdist) = 0;
int rounding_backup;
void save_rounding()
{
rounding_backup = std::fegetround();
std::fesetround(FE_TONEAREST);
}
void restore_rounding()
{
std::fesetround(rounding_backup);
}
inline bool next_pos_up()
{
++k;
if (partdist[k] != 0.0)
{
x[k] += dx[k];
ddx[k] = -ddx[k];
dx[k] = ddx[k] - dx[k];
}
else
{
if (k >= k_end)
return false;
k_max = k;
++x[k];
}
return true;
}
};
FPLLL_END_NAMESPACE
#endif
|