Skip to content

Commit 3268a9e

Browse files
committed
.
1 parent 2a22805 commit 3268a9e

File tree

1 file changed

+328
-0
lines changed

1 file changed

+328
-0
lines changed

src/powerful.cpp

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,305 @@
55
#include "NumbTh.h"
66

77
#include <cassert>
8+
#include <iomanip>
89

910
using namespace std;
1011
using namespace NTL;
1112

1213

14+
class CubeSignature {
15+
private:
16+
vector<long> dims; // dims[i] is the size along the i'th diemnsion
17+
vector<long> prods; // prods[i] = \prod_{j=i}^{n-1} dims[i]
18+
long ndims;
19+
long size;
20+
21+
CubeSignature(); // disabled
22+
23+
public:
24+
CubeSignature(const vector<long>& _dims)
25+
{
26+
dims = _dims;
27+
ndims = dims.size();
28+
assert(ndims > 0);
29+
30+
31+
prods.resize(ndims+1);
32+
prods[ndims] = 1;
33+
for (long i = ndims-1; i >= 0; i--) {
34+
assert(dims[i] > 0);
35+
prods[i] = dims[i]*prods[i+1];
36+
}
37+
38+
size = prods[0];
39+
}
40+
41+
long getSize() const { return size; }
42+
long getNumDims() const { return ndims; }
43+
long getDim(long d) const { return dims.at(d); }
44+
long getProd(long d) const { return prods.at(d);}
45+
46+
// get coordinate in dimension d of index i
47+
long getCoord(long i, long d) const {
48+
assert(i >= 0 && i < size);
49+
50+
return (i % prods.at(d)) / prods.at(d+1);
51+
}
52+
53+
// add offset to coordinate in dimension d of index i
54+
long addCoord(long i, long d, long offset) const {
55+
assert(i >= 0 && i < size);
56+
57+
offset = offset % dims.at(d);
58+
if (offset < 0) offset += dims.at(d);
59+
60+
long i_d = getCoord(i, d);
61+
long i_d1 = (i_d + offset) % dims.at(d);
62+
63+
long i1 = i + (i_d1 - i_d) * prods.at(d+1);
64+
65+
return i1;
66+
}
67+
68+
};
69+
70+
71+
72+
class HyperCube; // forward reference
73+
74+
75+
// A ConstCubeSlice acts like a pointer to a lower dimensional
76+
// constant subcube of a hypercube. It is initialized using a reference
77+
// to a hypercube, which must remain alive duriring the lifetime
78+
// of the slice, to prevent dangling pointers.
79+
80+
// The subclass CubeSlice works with non-constant cubes and subcubes.
81+
82+
class ConstCubeSlice {
83+
private:
84+
const HyperCube* cube;
85+
long dimOffset;
86+
long sizeOffset;
87+
88+
ConstCubeSlice(); // disabled
89+
90+
public:
91+
92+
// initialize the slice to the full cube
93+
explicit ConstCubeSlice(const HyperCube& _cube);
94+
95+
// initialize the slice to point to the i-th subcube
96+
// of the cube pointed to by other
97+
ConstCubeSlice(const ConstCubeSlice& other, long i);
98+
99+
// use default copy constructor and assignment operators,
100+
// which means shallow copy
101+
102+
103+
// the following mimic the corresponding methods
104+
// in the HyperCube class, restricted to the slice
105+
106+
long getSize() const;
107+
long getNumDims() const;
108+
long getDim(long d) const;
109+
long getProd(long d) const;
110+
long getCoord(long i, long d) const;
111+
long addCoord(long i, long d, long offset) const;
112+
113+
const double& at(long i) const;
114+
const double& operator[](long i) const;
115+
116+
};
117+
118+
class CubeSlice : public ConstCubeSlice {
119+
private:
120+
CubeSlice(); // disabled
121+
public:
122+
123+
// initialize the slice to the full cube
124+
explicit CubeSlice(HyperCube& _cube);
125+
126+
CubeSlice(const CubeSlice& other, long i);
127+
128+
// deep copy of a slice
129+
void copy(const ConstCubeSlice& other) const;
130+
131+
double& at(long i) const;
132+
double& operator[](long i) const;
133+
134+
};
135+
136+
137+
class HyperCube {
138+
private:
139+
const CubeSignature& sig;
140+
vector<double> data;
141+
142+
HyperCube(); // disable default constructor
143+
144+
public:
145+
HyperCube(const CubeSignature& _sig) : sig(_sig) {
146+
data.resize(sig.getSize());
147+
}
148+
149+
// use default copy constructor
150+
151+
HyperCube& operator=(const HyperCube& other)
152+
{
153+
assert(&this->sig == &other.sig);
154+
data = other.data;
155+
}
156+
157+
158+
const CubeSignature& getSig() const { return sig; }
159+
160+
long getSize() const { return sig.getSize(); }
161+
long getNumDims() const { return sig.getNumDims(); }
162+
long getDim(long d) const { return sig.getDim(d); }
163+
long getProd(long d) const { return sig.getProd(d);}
164+
long getCoord(long i, long d) const { return sig.getCoord(i, d); }
165+
long addCoord(long i, long d, long offset) const { return sig.addCoord(i, d, offset); }
166+
167+
double& at(long i) { return data.at(i); }
168+
double& operator[](long i) { return data[i]; }
169+
170+
const double& at(long i) const { return data.at(i); }
171+
const double& operator[](long i) const { return data[i]; }
172+
173+
};
174+
175+
176+
177+
// Implementation of ConstCubeSlice
178+
179+
ConstCubeSlice::ConstCubeSlice(const HyperCube& _cube)
180+
{
181+
cube = &_cube;
182+
dimOffset = 0;
183+
sizeOffset = 0;
184+
}
185+
186+
187+
ConstCubeSlice::ConstCubeSlice(const ConstCubeSlice& other, long i)
188+
{
189+
cube = other.cube;
190+
dimOffset = other.dimOffset + 1;
191+
192+
assert(dimOffset <= cube->getNumDims());
193+
// allow zero-dimensional slice
194+
195+
assert(i >= 0 && i < cube->getDim(other.dimOffset));
196+
197+
sizeOffset = other.sizeOffset + i*cube->getProd(dimOffset);
198+
}
199+
200+
201+
long ConstCubeSlice::getSize() const
202+
{
203+
return cube->getProd(dimOffset);
204+
}
205+
206+
207+
long ConstCubeSlice::getNumDims() const
208+
{
209+
return cube->getNumDims() - dimOffset;
210+
}
211+
212+
213+
long ConstCubeSlice::getDim(long d) const
214+
{
215+
return cube->getDim(d + dimOffset);
216+
}
217+
218+
219+
long ConstCubeSlice::getProd(long d) const
220+
{
221+
return cube->getProd(d + dimOffset);
222+
}
223+
224+
long ConstCubeSlice::getCoord(long i, long d) const
225+
{
226+
assert(i >= 0 && i < getSize());
227+
return cube->getCoord(i + sizeOffset, d + dimOffset);
228+
}
229+
230+
long ConstCubeSlice::addCoord(long i, long d, long offset) const
231+
{
232+
assert(i >= 0 && i < getSize());
233+
return cube->addCoord(i + sizeOffset, d + dimOffset, offset);
234+
}
235+
236+
237+
const double& ConstCubeSlice::at(long i) const
238+
{
239+
assert(i >= 0 && i < getSize());
240+
return (*cube)[i + sizeOffset];
241+
}
242+
243+
const double& ConstCubeSlice::operator[](long i) const
244+
{
245+
return (*cube)[i + sizeOffset];
246+
}
247+
248+
249+
// Implementation of CubeSlice
250+
251+
CubeSlice::CubeSlice(HyperCube& _cube) : ConstCubeSlice(_cube) {}
252+
CubeSlice::CubeSlice(const CubeSlice& other, long i) : ConstCubeSlice(other, i) {}
253+
254+
double& CubeSlice::at(long i) const
255+
{
256+
return const_cast<double&>(this->ConstCubeSlice::at(i));
257+
}
258+
259+
double& CubeSlice::operator[](long i) const
260+
{
261+
return const_cast<double&>(this->ConstCubeSlice::operator[](i));
262+
}
263+
264+
void CubeSlice::copy(const ConstCubeSlice& other) const
265+
{
266+
long n = getSize();
267+
268+
// we only check that the sizes match
269+
assert(n == other.getSize());
270+
271+
double *dst = &(*this)[0];
272+
const double *src = &other[0];
273+
274+
for (long i = 0; i < n; i++)
275+
dst[i] = src[i];
276+
}
277+
278+
279+
280+
void print3D(const HyperCube& c)
281+
{
282+
assert(c.getNumDims() == 3);
283+
284+
ConstCubeSlice s0(c);
285+
286+
for (long i = 0; i < s0.getDim(0); i++) {
287+
288+
ConstCubeSlice s1(s0, i);
289+
for (long j = 0; j < s1.getDim(0); j++) {
290+
291+
ConstCubeSlice s2(s1, j);
292+
for (long k = 0; k < s2.getDim(0); k++)
293+
cout << setw(3) << s2.at(k);
294+
295+
cout << "\n";
296+
}
297+
298+
cout << "\n";
299+
}
300+
}
301+
302+
303+
304+
305+
306+
13307
long computePhi(const Pair<long, long>& x)
14308
{
15309
long p = x.a;
@@ -112,6 +406,40 @@ void usage()
112406

113407
int main(int argc, char *argv[])
114408
{
409+
410+
vector<long> dims;
411+
dims.resize(3);
412+
413+
dims[0] = 3;
414+
dims[1] = 4;
415+
dims[2] = 5;
416+
417+
CubeSignature sig(dims);
418+
419+
HyperCube c(sig);
420+
421+
for (long i = 0; i < c.getSize(); i++)
422+
c.at(i) = i;
423+
424+
print3D(c);
425+
426+
CubeSlice s0(c);
427+
428+
CubeSlice s1(s0, 0);
429+
CubeSlice s2(s0, 2);
430+
431+
s2.copy(s1);
432+
433+
print3D(c);
434+
435+
436+
exit(0);
437+
438+
439+
440+
441+
442+
115443
argmap_t argmap;
116444

117445
argmap["q"] = "101";

0 commit comments

Comments
 (0)