numvect.h
Go to the documentation of this file.
1/* Copyright (C) 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_NUMVECT_H
17#define FPLLL_NUMVECT_H
18
19#include "fplll/nr/nr.h"
20#include <vector>
21
23
25template <class T> void extend_vect(vector<T> &v, int size)
26{
27 if (static_cast<int>(v.size()) < size)
28 {
29 v.resize(size);
30 }
31}
32
34template <class T> void reverse_by_swap(vector<T> &v, int first, int last)
35{
36 for (; first < last; first++, last--)
37 v[first].swap(v[last]);
38}
39
41template <class T> void rotate_by_swap(vector<T> &v, int first, int middle, int last)
42{
43 // Algorithm from STL code
44 reverse_by_swap(v, first, middle - 1);
45 reverse_by_swap(v, middle, last);
46 for (; first < middle && middle <= last; first++, last--)
47 {
48 v[first].swap(v[last]);
49 }
50 if (first == middle)
51 reverse_by_swap(v, middle, last);
52 else
53 reverse_by_swap(v, first, middle - 1);
54}
55
57template <class T> void rotate_left_by_swap(vector<T> &v, int first, int last)
58{
59 FPLLL_DEBUG_CHECK(0 <= first && first <= last && last < static_cast<int>(v.size()));
60 for (int i = first; i < last; i++)
61 {
62 v[i].swap(v[i + 1]);
63 }
64}
65
67template <class T> void rotate_right_by_swap(vector<T> &v, int first, int last)
68{
69 FPLLL_DEBUG_CHECK(0 <= first && first <= last && last < static_cast<int>(v.size()));
70 for (int i = last - 1; i >= first; i--)
71 {
72 v[i].swap(v[i + 1]);
73 }
74}
75
77template <class T> ostream &operator<<(ostream &os, const vector<T> &v)
78{
79 os << "[";
80 int n = v.size();
81 for (int i = 0; i < n; i++)
82 {
83 if (i > 0)
84 os << " ";
85 os << v[i];
86 }
87 os << "]";
88 return os;
89}
90
92template <class T> istream &operator>>(istream &is, vector<T> &v)
93{
94 char c;
95 v.clear();
96 if (!(is >> c))
97 return is;
98 if (c != '[')
99 {
100 is.setstate(ios::failbit);
101 return is;
102 }
103 while (is >> c && c != ']')
104 {
105 is.putback(c);
106 v.resize(v.size() + 1);
107 if (!(is >> v.back()))
108 {
109 v.pop_back();
110 return is;
111 }
112 }
113 return is;
114}
115
117template <class T> void gen_zero_vect(vector<T> &v, int n)
118{
119 v.resize(n);
120 fill(v.begin(), v.end(), 0);
121}
122
123template <class T> class NumVect;
124
125template <class T> ostream &operator<<(ostream &os, const NumVect<T> &v);
126
127template <class T> istream &operator>>(istream &is, NumVect<T> &v);
128
129template <class T> class NumVect
130{
131public:
132 typedef typename vector<T>::iterator iterator;
136 NumVect(const NumVect &v) : data(v.data) {}
138 NumVect(const vector<T> &v) : data(v) {}
141 NumVect(int size) : data(size) {}
142 NumVect(int size, const T &t) : data(size, t) {}
144 void operator=(const NumVect &v)
145 {
146 if (this != &v)
147 data = v.data;
148 }
150 void swap(NumVect &v) { data.swap(v.data); }
152 const iterator begin() { return data.begin(); }
154 iterator end() { return data.end(); }
156 int size() const { return data.size(); }
158 bool empty() const { return data.empty(); }
160 void resize(int size) { data.resize(size); }
162 void resize(int size, const T &t) { data.resize(size, t); }
164 void gen_zero(int size)
165 {
166 data.resize(size);
167 fill(0);
168 }
169
173 bool operator==(NumVect<T> &other) { return other.data == data; }
174
176 void push_back(const T &t) { data.push_back(t); }
178 void pop_back() { data.pop_back(); }
180 T &front() { return data.front(); }
183 const T &front() const { return data.front(); }
185 T &back() { return data.back(); }
188 const T &back() const { return data.back(); }
190 void extend(int maxSize)
191 {
192 if (size() < maxSize)
193 data.resize(maxSize);
194 }
195 void clear() { data.clear(); }
197 T &operator[](int i) { return data[i]; }
200 const T &operator[](int i) const { return data[i]; }
202 void add(const NumVect<T> &v, int n);
204 void add(const NumVect<T> &v) { add(v, size()); }
206 void sub(const NumVect<T> &v, int n);
208 void sub(const NumVect<T> &v) { sub(v, size()); }
210 void mul(const NumVect<T> &v, int b, int n, T c);
212 void mul(const NumVect<T> &v, int n, T c);
214 void mul(const NumVect<T> &v, T c) { mul(v, size(), c); }
216 void div(const NumVect<T> &v, int b, int n, T c);
218 void div(const NumVect<T> &v, int n, T c);
220 void div(const NumVect<T> &v, T c) { div(v, size(), c); }
223 void addmul(const NumVect<T> &v, T x, int beg, int n);
226 void addmul(const NumVect<T> &v, T x, int n);
229 void addmul(const NumVect<T> &v, T x) { addmul(v, x, size()); }
230 void addmul_2exp(const NumVect<T> &v, const T &x, long expo, T &tmp)
231 {
232 addmul_2exp(v, x, expo, size(), tmp);
233 }
234 void addmul_2exp(const NumVect<T> &v, const T &x, long expo, int n, T &tmp);
235 void addmul_si(const NumVect<T> &v, long x) { addmul_si(v, x, size()); }
236 void addmul_si(const NumVect<T> &v, long x, int n);
237 void addmul_si_2exp(const NumVect<T> &v, long x, long expo, T &tmp)
238 {
239 addmul_si_2exp(v, x, expo, size(), tmp);
240 }
241 void addmul_si_2exp(const NumVect<T> &v, long x, long expo, int n, T &tmp);
242
244 void rotate_left(int first, int last) { rotate_left_by_swap(data, first, last); }
245
247 void rotate_right(int first, int last) { rotate_right_by_swap(data, first, last); }
248
250 long get_max_exponent();
251
253 void fill(long value);
254
256 bool is_zero(int fromCol = 0) const;
257
259 int size_nz() const;
260
261 friend ostream &operator<< <T>(ostream &os, const NumVect<T> &v);
262 friend istream &operator>><T>(istream &is, NumVect<T> &v);
263
264private:
265 vector<T> data;
266};
267
268template <class T> void NumVect<T>::add(const NumVect<T> &v, int n)
269{
270 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
271 for (int i = n - 1; i >= 0; i--)
272 data[i].add(data[i], v[i]);
273}
274
275template <class T> void NumVect<T>::sub(const NumVect<T> &v, int n)
276{
277 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
278 for (int i = n - 1; i >= 0; i--)
279 data[i].sub(data[i], v[i]);
280}
281
282template <class T> void NumVect<T>::mul(const NumVect<T> &v, int b, int n, T c)
283{
284 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
285 for (int i = n - 1; i >= b; i--)
286 data[i].mul(v[i], c);
287}
288
289template <class T> void NumVect<T>::mul(const NumVect<T> &v, int n, T c) { mul(v, 0, n, c); }
290
291template <class T> void NumVect<T>::div(const NumVect<T> &v, int b, int n, T c)
292{
293 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
294 for (int i = n - 1; i >= b; i--)
295 data[i].div(v[i], c);
296}
297
298template <class T> void NumVect<T>::div(const NumVect<T> &v, int n, T c) { div(v, 0, n, c); }
299
300template <class T> void NumVect<T>::addmul(const NumVect<T> &v, T x, int beg, int n)
301{
302 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
303 for (int i = n - 1; i >= beg; i--)
304 data[i].addmul(v[i], x);
305}
306
307template <class T> void NumVect<T>::addmul(const NumVect<T> &v, T x, int n)
308{
309 this->addmul(v, x, 0, n);
310}
311
312template <class T>
313void NumVect<T>::addmul_2exp(const NumVect<T> &v, const T &x, long expo, int n, T &tmp)
314{
315 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
316 for (int i = n - 1; i >= 0; i--)
317 {
318 tmp.mul(v[i], x);
319 tmp.mul_2si(tmp, expo);
320 data[i].add(data[i], tmp);
321 }
322}
323
324template <class T> void NumVect<T>::addmul_si(const NumVect<T> &v, long x, int n)
325{
326 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
327 for (int i = n - 1; i >= 0; i--)
328 data[i].addmul_si(v[i], x);
329}
330
331template <class T>
332void NumVect<T>::addmul_si_2exp(const NumVect<T> &v, long x, long expo, int n, T &tmp)
333{
334 FPLLL_DEBUG_CHECK(n <= size() && size() == v.size() && v.is_zero(n));
335 for (int i = n - 1; i >= 0; i--)
336 {
337 tmp.mul_si(v[i], x);
338 tmp.mul_2si(tmp, expo);
339 data[i].add(data[i], tmp);
340 }
341}
342
343template <class T> long NumVect<T>::get_max_exponent()
344{
345 long max_expo = 0;
346 for (int i = 0; i < size(); i++)
347 {
348 max_expo = max(max_expo, data[i].exponent());
349 }
350 return max_expo;
351}
352
353template <class T> void NumVect<T>::fill(long value)
354{
355 for (int i = 0; i < size(); i++)
356 {
357 data[i] = value;
358 }
359}
360
361template <class T> bool NumVect<T>::is_zero(int fromCol) const
362{
363 for (int i = fromCol; i < size(); i++)
364 {
365 if (!data[i].is_zero())
366 return false;
367 }
368 return true;
369}
370
371template <class T> int NumVect<T>::size_nz() const
372{
373 int i;
374 for (i = data.size(); i > 0; i--)
375 {
376 if (data[i - 1] != 0)
377 break;
378 }
379 return i;
380}
381
385template <class T>
386inline void dot_product(T &result, const NumVect<T> &v1, const NumVect<T> &v2, int beg, int n)
387{
388 FPLLL_DEBUG_CHECK(beg >= 0 && n > beg && n <= v1.size() && n <= v2.size());
389 //(v1.is_zero(n) || v2.is_zero(n))); tested previously
390 result.mul(v1[beg], v2[beg]);
391 for (int i = beg + 1; i < n; i++)
392 {
393 result.addmul(v1[i], v2[i]);
394 }
395}
396
397template <class T>
398inline void dot_product(T &result, const NumVect<T> &v1, const NumVect<T> &v2, int n)
399{
400 FPLLL_DEBUG_CHECK(n <= v1.size() && v1.size() == v2.size() && (v1.is_zero(n) || v2.is_zero(n)));
401 dot_product(result, v1, v2, 0, n);
402}
403
404template <class T> inline void dot_product(T &result, const NumVect<T> &v1, const NumVect<T> &v2)
405{
406 dot_product(result, v1, v2, v1.size());
407}
408
409template <class T> inline void squared_norm(T &result, const NumVect<T> &v)
410{
411 dot_product(result, v, v);
412}
413
415template <class T> ostream &operator<<(ostream &os, const NumVect<T> &v) { return os << v.data; }
416
418template <class T> istream &operator>>(istream &is, NumVect<T> &v) { return is >> v.data; }
419
421
422#endif
Definition: numvect.h:130
const T & operator[](int i) const
Definition: numvect.h:200
int size_nz() const
Definition: numvect.h:371
T & front()
Definition: numvect.h:180
void swap(NumVect &v)
Definition: numvect.h:150
void div(const NumVect< T > &v, int b, int n, T c)
Definition: numvect.h:291
void fill(long value)
Definition: numvect.h:353
NumVect(int size)
Definition: numvect.h:141
void pop_back()
Definition: numvect.h:178
void mul(const NumVect< T > &v, int b, int n, T c)
Definition: numvect.h:282
void addmul(const NumVect< T > &v, T x)
Definition: numvect.h:229
int size() const
Definition: numvect.h:156
void resize(int size)
Definition: numvect.h:160
void clear()
Definition: numvect.h:195
NumVect()
Definition: numvect.h:134
bool empty() const
Definition: numvect.h:158
void add(const NumVect< T > &v, int n)
Definition: numvect.h:268
void div(const NumVect< T > &v, T c)
Definition: numvect.h:220
bool is_zero(int fromCol=0) const
Definition: numvect.h:361
void sub(const NumVect< T > &v, int n)
Definition: numvect.h:275
iterator end()
Definition: numvect.h:154
void operator=(const NumVect &v)
Definition: numvect.h:144
void addmul_2exp(const NumVect< T > &v, const T &x, long expo, T &tmp)
Definition: numvect.h:230
void add(const NumVect< T > &v)
Definition: numvect.h:204
void rotate_right(int first, int last)
Definition: numvect.h:247
void rotate_left(int first, int last)
Definition: numvect.h:244
const iterator begin()
Definition: numvect.h:152
void extend(int maxSize)
Definition: numvect.h:190
NumVect(const vector< T > &v)
Definition: numvect.h:138
void sub(const NumVect< T > &v)
Definition: numvect.h:208
void resize(int size, const T &t)
Definition: numvect.h:162
void push_back(const T &t)
Definition: numvect.h:176
T & back()
Definition: numvect.h:185
NumVect(const NumVect &v)
Definition: numvect.h:136
void addmul_si_2exp(const NumVect< T > &v, long x, long expo, T &tmp)
Definition: numvect.h:237
const T & front() const
Definition: numvect.h:183
void gen_zero(int size)
Definition: numvect.h:164
NumVect(int size, const T &t)
Definition: numvect.h:142
void addmul(const NumVect< T > &v, T x, int beg, int n)
Definition: numvect.h:300
T & operator[](int i)
Definition: numvect.h:197
bool operator==(NumVect< T > &other)
Definition: numvect.h:173
vector< T >::iterator iterator
Definition: numvect.h:132
const T & back() const
Definition: numvect.h:188
void addmul_si(const NumVect< T > &v, long x)
Definition: numvect.h:235
void mul(const NumVect< T > &v, T c)
Definition: numvect.h:214
long get_max_exponent()
Definition: numvect.h:343
#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
void dot_product(T &result, const NumVect< T > &v1, const NumVect< T > &v2, int beg, int n)
Definition: numvect.h:386
void rotate_right_by_swap(vector< T > &v, int first, int last)
Definition: numvect.h:67
void squared_norm(T &result, const NumVect< T > &v)
Definition: numvect.h:409
void gen_zero_vect(vector< T > &v, int n)
Definition: numvect.h:117
istream & operator>>(istream &is, vector< T > &v)
Definition: numvect.h:92
FPLLL_BEGIN_NAMESPACE void extend_vect(vector< T > &v, int size)
Definition: numvect.h:25
void rotate_by_swap(vector< T > &v, int first, int middle, int last)
Definition: numvect.h:41
ostream & operator<<(ostream &os, const vector< T > &v)
Definition: numvect.h:77
void rotate_left_by_swap(vector< T > &v, int first, int last)
Definition: numvect.h:57
void reverse_by_swap(vector< T > &v, int first, int last)
Definition: numvect.h:34