|
|
53488e |
#ifndef NNLAYER2_CONV_INC_CPP
|
|
|
53488e |
#define NNLAYER2_CONV_INC_CPP
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
#include "nnlayer2.inc.cpp"
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
Layer* createConv(Layer &prev, int psx, int psy, int psz, int sx, int sy, int sz, int lsize) {
|
|
|
53488e |
struct Point {
|
|
|
53488e |
int x, y, r;
|
|
|
53488e |
inline bool operator<(const Point &b) const { return r < b.r; }
|
|
|
53488e |
};
|
|
|
53488e |
|
|
|
53488e |
static const int hs = 256;
|
|
|
53488e |
static const int s = hs*2 + 1;
|
|
|
53488e |
static const int rnd[] = { 9, 12, 4, 6, 0, 15, 13, 8, 2, 3, 10, 1, 5, 11, 14, 7 };
|
|
|
53488e |
static std::vector<point> points;</point>
|
|
|
53488e |
|
|
|
53488e |
if (points.empty()) {
|
|
|
53488e |
points.resize(s*s);
|
|
|
53488e |
Point *p = points.data();
|
|
|
53488e |
for(int y = -hs, r = 0; y <= hs; ++y)
|
|
|
53488e |
for(int x = -hs; x <= hs; ++x, ++r, ++p)
|
|
|
53488e |
{ p->x = x, p->y = y, p->r = (x*x + y*y)*16 + rnd[r%16]; }
|
|
|
53488e |
std::sort(points.begin(), points.end());
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
Layer &pl = prev.back();
|
|
|
53488e |
assert(psx > 0 && psy > 0 && psz > 0);
|
|
|
53488e |
assert(sx > 0 && sy > 0 && sz > 0);
|
|
|
53488e |
assert(psx*psy*psz == pl.size);
|
|
|
53488e |
assert(lsize > 0 && lsize <= psx*psy);
|
|
|
53488e |
|
|
|
53488e |
Layer &cl = *new Layer(&pl, sx*sy*sz, lsize*psz);
|
|
|
53488e |
assert(cl.size && cl.lsize);
|
|
|
53488e |
|
|
|
53488e |
const Point *pb = points.data();
|
|
|
53488e |
int *order = new int[lsize];
|
|
|
53488e |
|
|
|
53488e |
for(int y = 0; y < sy; ++y) {
|
|
|
53488e |
for(int x = 0; x < sx; ++x) {
|
|
|
53488e |
int cx = (int)((x + 0.5)/(sx + 1)*(psx + 1));
|
|
|
53488e |
int cy = (int)((y + 0.5)/(sy + 1)*(psy + 1));
|
|
|
53488e |
|
|
|
53488e |
const Point *p = pb;
|
|
|
53488e |
for(int l = 0; l < lsize; ++l) {
|
|
|
53488e |
int px, py;
|
|
|
53488e |
do { assert(p < pb + points.size()); px = cx + p->x; py = cy + p->y; ++p; }
|
|
|
53488e |
while(px < 0 || py < 0 || px >= psx || py >= psy);
|
|
|
53488e |
order[l] = py*psx + px;
|
|
|
53488e |
}
|
|
|
53488e |
std::sort(order, order + lsize);
|
|
|
53488e |
|
|
|
53488e |
for(int z = 0; z < sz; ++z) {
|
|
|
53488e |
for(int l = 0; l < lsize; ++l) {
|
|
|
53488e |
for(int pz = 0; pz < psz; ++pz) {
|
|
|
53488e |
int i = (((y*sx + x)*sz + z)*lsize + l)*psz + pz;
|
|
|
53488e |
int pi = order[l]*psz + pz;
|
|
|
53488e |
assert(i >= 0 && i < cl.size*cl.lsize);
|
|
|
53488e |
assert(pi >= 0 && pi < pl.size);
|
|
|
53488e |
cl.links[i].nprev = pi;
|
|
|
53488e |
}
|
|
|
53488e |
}
|
|
|
53488e |
}
|
|
|
53488e |
}
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
delete[] order;
|
|
|
53488e |
cl.prepareBackLinks();
|
|
|
53488e |
|
|
|
53488e |
return &cl;
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
#endif
|