Commit eb8b17c2 authored by Sergey Kireev's avatar Sergey Kireev
Browse files

Neighborhood classes restructured, find_groups_sqr8 added, but not used

parent c0887701
......@@ -225,7 +225,8 @@ void CA2D<State,hood_type>::fix_group_labels() {
}
template<class State,Neighborhood_type hood_type>
int CA2D<State,hood_type>::find_groups_sqr(std::function<bool(const State &)> match) {
int CA2D<State,hood_type>::find_groups_sqr4(std::function<bool(const State &)> match) {
if (DEBUG) printf("CA2D<State,hood_type>::find_groups_sqr4()\n");
if (group.size() != nx*ny) group.resize(nx*ny);
if (groupsize.size() != groups_max) groupsize.resize(groups_max);
for (int ixy=0;ixy<nx*ny;ixy++) group[ixy] = 0;
......@@ -328,8 +329,170 @@ int CA2D<State,hood_type>::find_groups_sqr(std::function<bool(const State &)> ma
return k;
}
template<class State,Neighborhood_type hood_type>
int CA2D<State,hood_type>::find_groups_sqr8(std::function<bool(const State &)> match) {
if (DEBUG) printf("CA2D<State,hood_type>::find_groups_sqr8()\n");
if (group.size() != nx*ny) group.resize(nx*ny);
if (groupsize.size() != groups_max) groupsize.resize(groups_max);
for (int ixy=0;ixy<nx*ny;ixy++) group[ixy] = 0;
for (int i=0;i<groupsize.size();i++) groupsize[i] = 0;
int k = 1;
for (int ix=0;ix<nx-1;ix++)
for (int iy=0;iy<ny-1;iy++)
if (match(get(ix,iy))) {
XY n1(ix-1,iy-1); hood.fix(n1,nx,ny);
XY n2(ix ,iy-1); hood.fix(n2,nx,ny);
XY n4(ix-1,iy ); hood.fix(n4,nx,ny);
XY n6(ix-1,iy+1); hood.fix(n6,nx,ny);
int label = k;
int sum = 1;
int lbl1 = group[xy1d(n1.x,n1.y)];
int lbl2 = group[xy1d(n2.x,n2.y)];
int lbl4 = group[xy1d(n4.x,n2.y)];
int lbl6 = group[xy1d(n6.x,n2.y)];
group_traverse(sum,label,lbl1,{});
group_traverse(sum,label,lbl2,{lbl1});
group_traverse(sum,label,lbl4,{lbl1,lbl2});
group_traverse(sum,label,lbl6,{lbl1,lbl2,lbl4});
int dk = 1;
group[xy1d(ix,iy)] = label;
if (lbl1 != 0) { groupsize[lbl1] = -label; dk = 0; }
if (lbl2 != 0) { groupsize[lbl2] = -label; dk = 0; }
if (lbl4 != 0) { groupsize[lbl4] = -label; dk = 0; }
if (lbl6 != 0) { groupsize[lbl6] = -label; dk = 0; }
groupsize[label] = sum;
k += dk;
}
{ const int ix = nx-1;
for (int iy=0;iy<ny-1;iy++)
if (match(get(ix,iy))) {
XY n1(ix-1,iy-1); hood.fix(n1,nx,ny);
XY n2(ix ,iy-1); hood.fix(n2,nx,ny);
XY n3(ix+1,iy-1); hood.fix(n3,nx,ny);
XY n4(ix-1,iy ); hood.fix(n4,nx,ny);
XY n5(ix+1,iy ); hood.fix(n5,nx,ny);
XY n6(ix-1,iy+1); hood.fix(n6,nx,ny);
XY n8(ix+1,iy+1); hood.fix(n8,nx,ny);
int label = k;
int sum = 1;
int lbl1 = group[xy1d(n1.x,n1.y)];
int lbl2 = group[xy1d(n2.x,n2.y)];
int lbl3 = group[xy1d(n3.x,n3.y)];
int lbl4 = group[xy1d(n4.x,n3.y)];
int lbl5 = group[xy1d(n5.x,n3.y)];
int lbl6 = group[xy1d(n6.x,n3.y)];
int lbl8 = group[xy1d(n8.x,n3.y)];
group_traverse(sum,label,lbl1,{});
group_traverse(sum,label,lbl2,{lbl1});
group_traverse(sum,label,lbl3,{lbl1,lbl2});
group_traverse(sum,label,lbl4,{lbl1,lbl2,lbl3});
group_traverse(sum,label,lbl5,{lbl1,lbl2,lbl3,lbl4});
group_traverse(sum,label,lbl6,{lbl1,lbl2,lbl3,lbl4,lbl5});
group_traverse(sum,label,lbl8,{lbl1,lbl2,lbl3,lbl4,lbl5,lbl6});
int dk = 1;
group[xy1d(ix,iy)] = label;
if (lbl1 != 0) { groupsize[lbl1] = -label; dk = 0; }
if (lbl2 != 0) { groupsize[lbl2] = -label; dk = 0; }
if (lbl3 != 0) { groupsize[lbl3] = -label; dk = 0; }
if (lbl4 != 0) { groupsize[lbl4] = -label; dk = 0; }
if (lbl5 != 0) { groupsize[lbl5] = -label; dk = 0; }
if (lbl6 != 0) { groupsize[lbl6] = -label; dk = 0; }
if (lbl8 != 0) { groupsize[lbl8] = -label; dk = 0; }
groupsize[label] = sum;
k += dk;
}
}
{ const int iy = ny-1;
for (int ix=0;ix<nx-1;ix++)
if (match(get(ix,iy))) {
XY n1(ix-1,iy-1); hood.fix(n1,nx,ny);
XY n2(ix ,iy-1); hood.fix(n2,nx,ny);
XY n3(ix+1,iy-1); hood.fix(n3,nx,ny);
XY n4(ix-1,iy ); hood.fix(n4,nx,ny);
XY n6(ix-1,iy+1); hood.fix(n6,nx,ny);
XY n7(ix ,iy+1); hood.fix(n7,nx,ny);
XY n8(ix+1,iy+1); hood.fix(n8,nx,ny);
int label = k;
int sum = 1;
int lbl1 = group[xy1d(n1.x,n1.y)];
int lbl2 = group[xy1d(n2.x,n2.y)];
int lbl3 = group[xy1d(n3.x,n3.y)];
int lbl4 = group[xy1d(n4.x,n3.y)];
int lbl6 = group[xy1d(n6.x,n3.y)];
int lbl7 = group[xy1d(n7.x,n3.y)];
int lbl8 = group[xy1d(n8.x,n3.y)];
group_traverse(sum,label,lbl1,{});
group_traverse(sum,label,lbl2,{lbl1});
group_traverse(sum,label,lbl3,{lbl1,lbl2});
group_traverse(sum,label,lbl4,{lbl1,lbl2,lbl3});
group_traverse(sum,label,lbl6,{lbl1,lbl2,lbl3,lbl4});
group_traverse(sum,label,lbl7,{lbl1,lbl2,lbl3,lbl4,lbl6});
group_traverse(sum,label,lbl8,{lbl1,lbl2,lbl3,lbl4,lbl6,lbl7});
int dk = 1;
group[xy1d(ix,iy)] = label;
if (lbl1 != 0) { groupsize[lbl1] = -label; dk = 0; }
if (lbl2 != 0) { groupsize[lbl2] = -label; dk = 0; }
if (lbl3 != 0) { groupsize[lbl3] = -label; dk = 0; }
if (lbl4 != 0) { groupsize[lbl4] = -label; dk = 0; }
if (lbl6 != 0) { groupsize[lbl6] = -label; dk = 0; }
if (lbl7 != 0) { groupsize[lbl7] = -label; dk = 0; }
if (lbl8 != 0) { groupsize[lbl8] = -label; dk = 0; }
groupsize[label] = sum;
k += dk;
}
}
{ const int ix = nx-1;
const int iy = ny-1;
if (match(get(ix,iy))) {
XY n1(ix-1,iy-1); hood.fix(n1,nx,ny);
XY n2(ix ,iy-1); hood.fix(n2,nx,ny);
XY n3(ix+1,iy-1); hood.fix(n3,nx,ny);
XY n4(ix-1,iy ); hood.fix(n4,nx,ny);
XY n5(ix+1,iy ); hood.fix(n5,nx,ny);
XY n6(ix-1,iy+1); hood.fix(n6,nx,ny);
XY n7(ix ,iy+1); hood.fix(n7,nx,ny);
XY n8(ix+1,iy+1); hood.fix(n8,nx,ny);
int label = k;
int sum = 1;
int lbl1 = group[xy1d(n1.x,n1.y)];
int lbl2 = group[xy1d(n2.x,n2.y)];
int lbl3 = group[xy1d(n3.x,n3.y)];
int lbl4 = group[xy1d(n4.x,n3.y)];
int lbl5 = group[xy1d(n5.x,n3.y)];
int lbl6 = group[xy1d(n6.x,n3.y)];
int lbl7 = group[xy1d(n7.x,n3.y)];
int lbl8 = group[xy1d(n8.x,n3.y)];
group_traverse(sum,label,lbl1,{});
group_traverse(sum,label,lbl2,{lbl1});
group_traverse(sum,label,lbl3,{lbl1,lbl2});
group_traverse(sum,label,lbl4,{lbl1,lbl2,lbl3});
group_traverse(sum,label,lbl5,{lbl1,lbl2,lbl3,lbl4});
group_traverse(sum,label,lbl6,{lbl1,lbl2,lbl3,lbl4,lbl5});
group_traverse(sum,label,lbl7,{lbl1,lbl2,lbl3,lbl4,lbl5,lbl6});
group_traverse(sum,label,lbl8,{lbl1,lbl2,lbl3,lbl4,lbl5,lbl6,lbl7});
int dk = 1;
group[xy1d(ix,iy)] = label;
if (lbl1 != 0) { groupsize[lbl1] = -label; dk = 0; }
if (lbl2 != 0) { groupsize[lbl2] = -label; dk = 0; }
if (lbl3 != 0) { groupsize[lbl3] = -label; dk = 0; }
if (lbl4 != 0) { groupsize[lbl4] = -label; dk = 0; }
if (lbl5 != 0) { groupsize[lbl5] = -label; dk = 0; }
if (lbl6 != 0) { groupsize[lbl6] = -label; dk = 0; }
if (lbl7 != 0) { groupsize[lbl7] = -label; dk = 0; }
if (lbl8 != 0) { groupsize[lbl8] = -label; dk = 0; }
groupsize[label] = sum;
k += dk;
}
}
fix_group_labels();
group_labels_upper_bound = k;
return k;
}
template<class State,Neighborhood_type hood_type>
int CA2D<State,hood_type>::find_groups_hex(std::function<bool(const State &)> match) {
if (DEBUG) printf("CA2D<State,hood_type>::find_groups_hex()\n");
if (group.size() != nx*ny) group.resize(nx*ny);
if (groupsize.size() != groups_max) groupsize.resize(groups_max);
for (int ixy=0;ixy<nx*ny;ixy++) group[ixy] = 0;
......
......@@ -12,6 +12,10 @@
#include<functional>
#include<algorithm>
#ifndef DEBUG
#define DEBUG 0
#endif
namespace ca2d {
struct XY {
......@@ -26,11 +30,27 @@ struct XY {
XY &move(const XY &d) { x += d.x; y += d.y; return *this; }
};
enum Neighborhood_type { hood_default, hood_vonNeumann, hood_hex };
enum Neighborhood_type { hood_default, hood_vonNeumann, hood_Moore, hood_hex };
template<Neighborhood_type t> struct Neighborhood_value { static constexpr int value = 0, nmovedirs = 0; };
template<> struct Neighborhood_value<hood_vonNeumann> { static constexpr int ndirs = 4, nmovedirs = 4; };
template<> struct Neighborhood_value<hood_Moore> { static constexpr int ndirs = 8, nmovedirs = 4; };
template<> struct Neighborhood_value<hood_hex> { static constexpr int ndirs = 6, nmovedirs = 6; };
template<int ndirs> struct Neighborhood_dirs { static constexpr std::array<int,ndirs> dx(),dy(); };
template<> struct Neighborhood_dirs<4> { static constexpr std::array<int,4> dx = {0,1,0,-1},dy = {-1,0,1,0}; };
template<> struct Neighborhood_dirs<8> { static constexpr std::array<int,8> dx = {0,1,1,1,0,-1,-1,-1},dy = {-1,-1,0,1,1,1,0,-1}; };
template<> struct Neighborhood_dirs<6> { static constexpr std::array<int,6> dx = {0,1,1,0,-1,-1},dy = {-1,-1,0,1,1,0}; };
template <int ndirs>
class Neighborhood_base {
private:
const std::array<int,ndirs> _dx = Neighborhood_dirs<ndirs>::dx;
const std::array<int,ndirs> _dy = Neighborhood_dirs<ndirs>::dy;
protected:
std::default_random_engine generator;
......@@ -38,24 +58,11 @@ class Neighborhood_base {
public:
static constexpr int count = ndirs;
const int count = ndirs;
Neighborhood_base():distribution(0,ndirs-1) {}
int rnd() { return distribution(generator); }
};
template<Neighborhood_type t>
class Neighborhood : public Neighborhood_base<4> {
//using it = Neighborhood<t>;
const int _dx[4] = { 0, 1, 0,-1};
const int _dy[4] = {-1, 0, 1, 0};
public:
Neighborhood():Neighborhood_base<4>() {}
void move(int &ix,int &iy,int dir) const {
ix += _dx[dir];
......@@ -63,6 +70,11 @@ class Neighborhood : public Neighborhood_base<4> {
}
XY &move(XY &xy,int dir) const { move(xy.x,xy.y,dir); return xy; }
int opposite(int dir) const { return (dir+count/2)%count; }
int dx(int dir) { return _dx[dir]; }
int dy(int dir) { return _dy[dir]; }
void fix(int &ix,int &iy,int nx,int ny) const {
while (ix < 0) ix += nx;
while (ix >= nx) ix -= nx;
......@@ -71,34 +83,34 @@ class Neighborhood : public Neighborhood_base<4> {
}
XY &fix(XY &xy,int nx,int ny) const { fix(xy.x,xy.y,nx,ny); return xy; }
int opposite(int dir) const { return (dir+count/2)%count; }
bool isSquare() const { return true; }
bool isSquare() const { return false; }
bool isHex() const { return false; }
};
int dx(int dir) { return _dx[dir]; }
int dy(int dir) { return _dy[dir]; }
template<Neighborhood_type t>
class Neighborhood : public Neighborhood_base<Neighborhood_value<t>::nmovedirs> {
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_vonNeumann>::nmovedirs>() {}
};
template<>
class Neighborhood<hood_hex> : public Neighborhood_base<6> {
//using it = Neighborhood<hood_hex>;
const int _dx[6] = { 0, 1, 1, 0,-1,-1};
const int _dy[6] = {-1,-1, 0, 1, 1, 0};
class Neighborhood<hood_vonNeumann> : public Neighborhood_base<Neighborhood_value<hood_vonNeumann>::nmovedirs> {
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_vonNeumann>::nmovedirs>() {}
bool isSquare() const { return true; }
};
Neighborhood():Neighborhood_base<6>() {}
void move(int &ix,int &iy,int dir) const {
ix += _dx[dir];
iy += _dy[dir];
}
XY &move(XY &xy,int dir) const { move(xy.x,xy.y,dir); return xy; }
template<>
class Neighborhood<hood_Moore> : public Neighborhood_base<Neighborhood_value<hood_Moore>::nmovedirs> {
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_Moore>::nmovedirs>() {}
bool isSquare() const { return true; }
};
template<>
class Neighborhood<hood_hex> : public Neighborhood_base<Neighborhood_value<hood_hex>::nmovedirs> {
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_hex>::nmovedirs>() {}
void fix(int &ix,int &iy,int nx,int ny) const {
while (iy < 0) { iy += ny; ix -= ny/2; }
while (iy >= ny) { iy -= ny; ix += ny/2; }
......@@ -106,14 +118,7 @@ class Neighborhood<hood_hex> : public Neighborhood_base<6> {
while (ix >= nx) ix -= nx;
}
XY &fix(XY &xy,int nx,int ny) const { fix(xy.x,xy.y,nx,ny); return xy; }
int opposite(int dir) const { return (dir+count/2)%count; }
bool isSquare() const { return false; }
bool isHex() const { return true; }
int dx(int dir) { return _dx[dir]; }
int dy(int dir) { return _dy[dir]; }
};
template<class State,Neighborhood_type hood_type>
......@@ -148,7 +153,8 @@ private:
}
}
int find_groups_sqr(std::function<bool(const State &)> match);
int find_groups_sqr4(std::function<bool(const State &)> match);
int find_groups_sqr8(std::function<bool(const State &)> match);
int find_groups_hex(std::function<bool(const State &)> match);
template<typename ItemType> bool load_binary_array_sqr(const std::string &filename,ItemType *data);
......@@ -213,7 +219,8 @@ public:
int find_groups(std::function<bool(const State &)> match) {
if (hood_type == hood_hex) return find_groups_hex(match);
return find_groups_sqr(match);
if (hood_type == hood_Moore) return find_groups_sqr8(match);
return find_groups_sqr4(match);
}
//void save_char(const std::string &fn,int it=-1,const std::string &ext="") const;
......
......@@ -3,8 +3,8 @@ SOURCES = main.cpp param.cpp
HEADERS = ca2d.h ca2d.cpp nle_ca.h param.h
#directions.h
CPP = g++
CPPFLAGS = -g -std=c++14 -O3 -march=native
CPPFLAGS_DEBUG = -g -std=c++14 -O0
CPPFLAGS = -g -std=c++17 -O3 -march=native
CPPFLAGS_DEBUG = -g -std=c++17 -O0
all: $(EXECUTABLE)
......
......@@ -372,7 +372,7 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
NLE_sqr_CA(int nx,int ny,int ns = 1) : NLE_CA_base<hood_vonNeumann>(nx,ny,ns) { logfn("NLE_sqr_CA","int,int,int"); }
void setXYS() {
void setXYS() { //!!!
logfn("NLE_sqr_CA","");
const int ns = nsize;
nnsize = ns*ns;
......@@ -621,7 +621,7 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
}
}
virtual bool may_move_NL(int bi,int bj,int dir) const {
virtual bool may_move_NL(int bi,int bj,int dir) const { //!!!
for (int k=0;k<nsize;k++)
if (ca::getfix(bi+side[dir][k].x,bj+side[dir][k].y) != L) return false;
return true;
......@@ -767,7 +767,6 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
////////////////////////////////////////////////////////////////////////////////////////////////////
class NLE_sqr8_CA : public NLE_sqr_CA {
protected:
int tc[4][4][2];
......@@ -999,12 +998,6 @@ class NLE_sqr8_CA : public NLE_sqr_CA {
return nle;
}
// virtual void allocateData(int ns) {
// logfn("int ns");
// nsize = ns;
// allocateData();
// }
void test_count_nle_on_line_l(int x,int y,int dx,int dy,int n,int initial_state,int final_state,int count[3]) {
int count_n = 0;
int count_l = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment