Commit 87106c29 authored by Sergey Kireev's avatar Sergey Kireev
Browse files

find_groups_sqr8 is deployed in cpp

parent eb8b17c2
......@@ -226,7 +226,7 @@ void CA2D<State,hood_type>::fix_group_labels() {
template<class State,Neighborhood_type hood_type>
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 (LOG_CA2D) printf("CA2D<State,%s>::find_groups_sqr4()\n",hood.name().c_str());
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;
......@@ -331,7 +331,7 @@ int CA2D<State,hood_type>::find_groups_sqr4(std::function<bool(const State &)> m
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 (LOG_CA2D) printf("CA2D<State,%s>::find_groups_sqr8()\n",hood.name().c_str());
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;
......@@ -492,7 +492,7 @@ int CA2D<State,hood_type>::find_groups_sqr8(std::function<bool(const State &)> m
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 (LOG_CA2D) printf("CA2D<State,%s>::find_groups_hex()\n",hood.name().c_str());
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,8 +12,8 @@
#include<functional>
#include<algorithm>
#ifndef DEBUG
#define DEBUG 0
#ifndef LOG_CA2D
#define LOG_CA2D 0
#endif
namespace ca2d {
......@@ -32,7 +32,6 @@ struct XY {
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; };
......@@ -85,6 +84,7 @@ class Neighborhood_base {
bool isSquare() const { return false; }
bool isHex() const { return false; }
std::string name() { return "hood_base"; }
};
template<Neighborhood_type t>
......@@ -98,6 +98,7 @@ class Neighborhood<hood_vonNeumann> : public Neighborhood_base<Neighborhood_valu
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_vonNeumann>::nmovedirs>() {}
bool isSquare() const { return true; }
std::string name() { return "hood_vonNeumann"; }
};
template<>
......@@ -105,6 +106,7 @@ class Neighborhood<hood_Moore> : public Neighborhood_base<Neighborhood_value<hoo
public:
Neighborhood():Neighborhood_base<Neighborhood_value<hood_Moore>::nmovedirs>() {}
bool isSquare() const { return true; }
std::string name() { return "hood_Moore"; }
};
template<>
......@@ -119,6 +121,7 @@ class Neighborhood<hood_hex> : public Neighborhood_base<Neighborhood_value<hood_
}
XY &fix(XY &xy,int nx,int ny) const { fix(xy.x,xy.y,nx,ny); return xy; }
bool isHex() const { return true; }
std::string name() { return "hood_hex"; }
};
template<class State,Neighborhood_type hood_type>
......
......@@ -87,7 +87,7 @@ int main(int argc,char *argv[]) {
p.print();
if (p.is_hex()) count<NLE_hex_CA>(p);
else if (p.is_square4()) count<NLE_sqr_CA>(p);
else if (p.is_square4()) count<NLE_sqr4_CA>(p);
else if (p.is_square8()) count<NLE_sqr8_CA>(p);
return 0;
......
#include "ca2d.h"
// TODO: check what parameter values are set (use LOG to print in constructors, setData(), etc.)
#define LOG 0
// TODO: check what parameter values are set (use LOG_NLE_CA to print in constructors, setData(), etc.)
#define LOG_NLE_CA 0
#define logfn(C,X) if (LOG) fprintf(stderr,"%s::%s(%s)\n",C,__FUNCTION__,X)
#define logfn(C,X) if (LOG_NLE_CA) fprintf(stderr,"%s::%s(%s)\n",C,__FUNCTION__,X)
#define logfn_scc(C,X) if (LOG_NLE_CA) fprintf(stderr,"%s::%s(%s)\n",(C).c_str(),__FUNCTION__,X)
using namespace ca2d;
......@@ -17,7 +18,9 @@ class NLE_CA_base : public CA2D<int,hood_type> {
using ca = CA2D<int,hood_type>;
using nle = NLE_CA_base<hood_type>;
int nsize; // size of N side
static constexpr int ndirs = Neighborhood_value<hood_type>::nmovedirs;
const int nsize; // size of N side
int nnsize; // number of cells in N
int ngroups; // number of groups, set by find_groups()
double en,el,enl,kT,mu,evap,cond,pgroup;
......@@ -25,14 +28,20 @@ class NLE_CA_base : public CA2D<int,hood_type> {
std::vector<int> sN,xN,yN;
std::vector<int> oppdir;
std::vector<XY> side[ndirs]; // outer sides coordinates
std::vector<int> ctx[ndirs]; // test coordinates: X
std::vector<int> cty[ndirs]; // test coordinates: Y
std::vector<int> st[ndirs]; // test states
std::vector<double> dh; // values to append if positive test
bool groups_found;
bool test_move_NL_dH;
std::stringstream debug_message;
NLE_CA_base(int nx,int ny,int ns = 1):ca(nx,ny),nsize(ns),nnsize(ns*ns),groups_found(false),maxgroupsize(0) {
logfn("NLE_CA_base","int,int,int");
NLE_CA_base(const int nx,const int ny,const int ns = 1):ca(nx,ny),nsize(ns),nnsize(ns*ns),groups_found(false),maxgroupsize(0) {
logfn_scc(std::string("NLE_CA_base<")+ca::hood.name()+std::string(">"),"int,int,int");
en = 1.0;
el = 0.3;
enl = 0.8;
......@@ -43,22 +52,23 @@ class NLE_CA_base : public CA2D<int,hood_type> {
test_move_NL_dH = false;
}
void setXYS() { logfn("NLE_CA_base",""); }
void allocateData() { logfn("NLE_CA_base",""); }
virtual void setData() { logfn("NLE_CA_base",""); }
//void setXYS() { logfn("NLE_CA_base",""); }
//void allocateData() { logfn("NLE_CA_base",""); }
virtual void setData() { logfn_scc(std::string("NLE_CA_base<")+ca::hood.name()+std::string(">"),""); }
public:
static constexpr int L = 0;
static constexpr int E = -1;
/*
static NLE_CA_base<hood_type>* create(int nx,int ny,int ns = 1) {
NLE_CA_base<hood_type>* nle = new NLE_CA_base<hood_type>(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
}*/
void set_test_move_NL_dH(bool value=true) { test_move_NL_dH = value; }
......@@ -165,9 +175,21 @@ class NLE_CA_base : public CA2D<int,hood_type> {
return ca::rnd01() < exp(-dH/kT);
}
virtual double count_dH_move_NL(int bx,int by,int dir) {
if (test_move_NL_dH) debug_message << " NLE_CA_base::count_dH_move_NL\n";
return 0.0;
double count_dH_move_NL(int bx,int by,int dir) {
double dH = 0;
for (int i=0;i<st[dir].size();i++) {
int state = ca::getfix(bx + ctx[dir][i],by + cty[dir][i]);
if (state == st[dir][i]) {
dH += dh[i];
if (test_move_NL_dH) {
debug_message << " NLE_CA_base<" << ca::hood.name() << ">::count_dH_move_NL: [" << ctx[dir][i] << " " << cty[dir][i] << "] =";
if (isL(state)) debug_message << " L: ";
if (isN(state)) debug_message << " N(" << s2x(state) << " " << s2y(state) << "): ";
debug_message << dh[i] << std::endl;
}
}
}
return dH;
}
virtual void test_count_nl(int bx,int by,int dir,int count[3]) { count[0] = 0; count[1] = 0; count[2] = 0; }
......@@ -181,7 +203,7 @@ class NLE_CA_base : public CA2D<int,hood_type> {
test_count_nl(nb.x,nb.y,oppdir[dir],cnt2);
const int snn1 = cnt2[0], snl1 = cnt2[1], sll1 = cnt2[2];
if (test_move_NL_dH) {
debug_message << "NLE_CA_base::count_dH_move_NL_test: (nn,nl,ll) " << snn0 << " " << snl0 << " " << sll0
debug_message << "NLE_CA_base<" << ca::hood.name() << ">::count_dH_move_NL_test: (nn,nl,ll) " << snn0 << " " << snl0 << " " << sll0
<< " -> " << snn1 << " " << snl1 << " " << sll1
<< " : " << (snn1-snn0) << " " << (snl1-snl0) << " " << (sll1-sll0) << std::endl;
}
......@@ -357,23 +379,27 @@ class NLE_CA_base : public CA2D<int,hood_type> {
////////////////////////////////////////////////////////////////////////////////////////////////////
class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
template<Neighborhood_type hood_type>
class NLE_sqr_CA : public NLE_CA_base<hood_type> {
protected:
std::vector<XY> side[4]; // outer sides coordinates
std::vector<int> ctx[4]; // test coordinates: X
std::vector<int> cty[4]; // test coordinates: Y
std::vector<int> st[4]; // test states
std::vector<double> dh; // values to append if positive test
using ca = CA2D<int,hood_type>;
using nle = NLE_CA_base<hood_type>;
using nle::nsize;
using nle::nnsize;
using nle::xN;
using nle::yN;
using nle::sN;
using nle::oppdir;
using nle::side;
int td[4][6][7]; // test data: x,y,dx,dy,n,first_state,final_state
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"); }
NLE_sqr_CA(const int nx,const int ny,const int ns = 1) : NLE_CA_base<hood_type>(nx,ny,ns) { logfn_scc(std::string("NLE_sqr_CA<")+ca::hood.name()+std::string(">"),"int,int,int"); }
void setXYS() { //!!!
logfn("NLE_sqr_CA","");
void setXYS() {
logfn_scc(std::string("NLE_sqr_CA<")+ca::hood.name()+std::string(">"),"");
const int ns = nsize;
nnsize = ns*ns;
sN.resize(nnsize);
......@@ -382,7 +408,7 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
oppdir.resize(4);
for (int i=0,k=0;i<nsize;i++)
for (int j=0;j<nsize;j++,k++) {
sN[k] = xy2s(i,j);
sN[k] = nle::xy2s(i,j);
xN[k] = i;
yN[k] = j;
}
......@@ -400,9 +426,46 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
}
}
}
virtual bool may_move_NL(int bi,int bj,int dir) const { //!!!
for (int k=0;k<nsize;k++)
if (!nle::isL(ca::getfix(bi+side[dir][k].x,bj+side[dir][k].y))) return false;
return true;
}
virtual void print_neighbourhood(int bx,int by,int dir) {
int x0 = -1, x1 = nsize+1;
int y0 = -1, y1 = nsize+1;
switch(dir) {
case 0: y0--; break;
case 1: x1++; break;
case 2: y1++; break;
case 3: x0--; break;
}
for (int j=y0;j<y1;j++) {
printf("%4d ",by+j);
for (int i=x0;i<x1;i++) {
int s = ca::getfix(bx+i,by+j);
if (nle::isL(s)) printf("L");
else if (nle::isE(s)) printf("*");
else printf("N");
}
printf("\n"); fflush(stdout);
}
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
class NLE_sqr4_CA : public NLE_sqr_CA<hood_vonNeumann> {
protected:
NLE_sqr4_CA(const int nx,const int ny,const int ns = 1) : NLE_sqr_CA<hood_vonNeumann>(nx,ny,ns) { logfn("NLE_sqr4_CA","int,int,int"); }
void allocateData() {
logfn("NLE_sqr_CA","");
logfn("NLE_sqr4_CA","");
const int ns = nsize;
const int szn = 8*ns-2;
const int szl = 2*ns+4;
......@@ -487,7 +550,7 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
}
virtual void setData() {
logfn("NLE_sqr_CA","");
logfn("NLE_sqr4_CA","");
const int ns = nsize;
const int szn = 8*nsize-2;
const int szl = 2*nsize+4;
......@@ -602,31 +665,6 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
*/
}
public:
static NLE_sqr_CA* create(int nx,int ny,int ns = 1) {
NLE_sqr_CA* nle = new NLE_sqr_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
~NLE_sqr_CA() {}
void print_internal_data() const {
for (int d=0;d<ca::hood.count;d++) {
//printf("Corner: (%2d,%2d) Side:",corner[d].x,corner[d].y);
for (int k=0;k<nsize;k++) printf(" (%2d,%2d)",side[d][k].x,side[d][k].y);
}
}
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;
}
///
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;
......@@ -656,7 +694,7 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
const int snl = c0[1] + c1[1] + c2[1] + c3[0] + c4[0] + c5[0];
const int sll = c3[1] + c4[1] + c5[1];
if (test_move_NL_dH)
debug_message << "NLE_sqr_CA::test_count_nl: nn: " << snn << " snl: " << snl << " sll: " << sll
debug_message << "NLE_sqr4_CA::test_count_nl: nn: " << snn << " snl: " << snl << " sll: " << sll
<< " | " << c0[0] << " " << c0[1] << " | " << c1[0] << " " << c1[1]
<< " | " << c2[0] << " " << c2[1] << " | " << c3[0] << " " << c3[1]
<< " | " << c4[0] << " " << c4[1] << " | " << c5[0] << " " << c5[1] << std::endl;
......@@ -666,23 +704,6 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
count[2] = sll;
}
virtual double count_dH_move_NL(int bx,int by,int dir) {
double dH = 0;
for (int i=0;i<st[dir].size();i++) {
int state = ca::getfix(bx + ctx[dir][i],by + cty[dir][i]);
if (state == st[dir][i]) {
dH += dh[i];
if (test_move_NL_dH) {
debug_message << " NLE_sqr_CA::count_dH_move_NL: [" << ctx[dir][i] << " " << cty[dir][i] << "] =";
if (isL(state)) debug_message << " L: ";
if (isN(state)) debug_message << " N(" << s2x(state) << " " << s2y(state) << "): ";
debug_message << dh[i] << std::endl;
}
}
}
return dH;
}
virtual void do_move_NL(int bi,int bj,int dir) {
ca::hood.move(bi,bj,dir);
int opp = oppdir[dir];
......@@ -741,37 +762,28 @@ class NLE_sqr_CA : public NLE_CA_base<hood_vonNeumann> {
groups_found = false;
}
virtual void print_neighbourhood(int bx,int by,int dir) {
int x0 = -1, x1 = nsize+1;
int y0 = -1, y1 = nsize+1;
switch(dir) {
case 0: y0--; break;
case 1: x1++; break;
case 2: y1++; break;
case 3: x0--; break;
}
for (int j=y0;j<y1;j++) {
printf("%4d ",by+j);
for (int i=x0;i<x1;i++) {
int s = ca::getfix(bx+i,by+j);
if (isL(s)) printf("L");
else if (isE(s)) printf("*");
else printf("N");
}
printf("\n"); fflush(stdout);
}
public:
static NLE_sqr4_CA* create(int nx,int ny,int ns = 1) {
NLE_sqr4_CA* nle = new NLE_sqr4_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
~NLE_sqr4_CA() {}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
class NLE_sqr8_CA : public NLE_sqr_CA {
class NLE_sqr8_CA : public NLE_sqr_CA<hood_Moore> {
protected:
int tc[4][4][2];
NLE_sqr8_CA(int nx,int ny,int ns = 1) : NLE_sqr_CA(nx,ny,ns) { logfn("NLE_sqr8_CA","int,int,int"); }
NLE_sqr8_CA(const int nx,const int ny,const int ns = 1) : NLE_sqr_CA<hood_Moore>(nx,ny,ns) { logfn("NLE_sqr8_CA","int,int,int"); }
void allocateData() {
logfn("NLE_sqr8_CA","");
......@@ -988,16 +1000,6 @@ class NLE_sqr8_CA : public NLE_sqr_CA {
// }
}
public:
static NLE_sqr8_CA* create(int nx,int ny,int ns = 1) {
NLE_sqr8_CA* nle = new NLE_sqr8_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
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;
......@@ -1072,6 +1074,16 @@ class NLE_sqr8_CA : public NLE_sqr_CA {
count[1] = snl;
count[2] = sll;
}
public:
static NLE_sqr8_CA* create(int nx,int ny,int ns = 1) {
NLE_sqr8_CA* nle = new NLE_sqr8_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -1080,19 +1092,13 @@ class NLE_hex_CA : public NLE_CA_base<hood_hex> {
protected:
std::vector<XY> side[6]; // outer sides coordinates
XY corner[6]; // outer corners coordinates
int stcorner[6]; // corner states
std::vector<int> ctx[6]; // test coordinates: X
std::vector<int> cty[6]; // test coordinates: Y
std::vector<int> st[6]; // test states
std::vector<double> dh; // values to append if positive test
int td[6][8][7]; // test data - lines: x,y,dx,dy,n,first_state,final_state
int tc[6][6][2]; // test data - corners: x,y
NLE_hex_CA(int nx,int ny,int ns = 1):NLE_CA_base<hood_hex>(nx,ny,ns) { logfn("NLE_hex_CA",""); }
NLE_hex_CA(const int nx,const int ny,const int ns = 1):NLE_CA_base<hood_hex>(nx,ny,ns) { logfn("NLE_hex_CA",""); }
void setXYS() {
logfn("NLE_hex_CA","");
......@@ -1387,25 +1393,6 @@ class NLE_hex_CA : public NLE_CA_base<hood_hex> {
}
}
public:
static NLE_hex_CA* create(int nx,int ny,int ns = 1) {
NLE_hex_CA* nle = new NLE_hex_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
~NLE_hex_CA() {}
void print_internal_data() const {
for (int d=0;d<ca::hood.count;d++) {
printf("Corner: (%2d,%2d) Side:",corner[d].x,corner[d].y);
for (int k=0;k<nsize-1;k++) printf(" (%2d,%2d)",side[d][k].x,side[d][k].y);
}
}
virtual bool may_move_NL(int bx,int by,int dir) const {
int d0 = (dir+ca::hood.count-1)%ca::hood.count;
for (int k=0;k<nsize-1;k++)
......@@ -1495,23 +1482,6 @@ class NLE_hex_CA : public NLE_CA_base<hood_hex> {
count[2] = sll;
}
virtual double count_dH_move_NL(int bx,int by,int dir) {
double dH = 0;
for (int i=0;i<st[dir].size();i++) {
int state = ca::getfix(bx + ctx[dir][i],by + cty[dir][i]);
if (state == st[dir][i]) {
dH += dh[i];
if (test_move_NL_dH) {
debug_message << " NLE_hex_CA::count_dH_move_NL: [" << ctx[dir][i] << " " << cty[dir][i] << "] =";
if (isL(state)) debug_message << " L: ";
if (isN(state)) debug_message << " N(" << s2x(state) << " " << s2y(state) << "): ";
debug_message << dh[i] << std::endl;
}
}
}
return dH;
}
virtual void do_move_NL(int bx,int by,int dir) {
XY nb(bx,by);
ca::hood.move(nb,dir);
......@@ -1628,6 +1598,26 @@ class NLE_hex_CA : public NLE_CA_base<hood_hex> {
groups_found = false;
}
public:
static NLE_hex_CA* create(int nx,int ny,int ns = 1) {
NLE_hex_CA* nle = new NLE_hex_CA(nx,ny,ns);
nle->setXYS();
nle->allocateData();
nle->setData();
return nle;
}
~NLE_hex_CA() {}
void print_internal_data() const {
for (int d=0;d<ca::hood.count;d++) {
printf("Corner: (%2d,%2d) Side:",corner[d].x,corner[d].y);
for (int k=0;k<nsize-1;k++) printf(" (%2d,%2d)",side[d][k].x,side[d][k].y);
}
}
void print_neighbourhood(int bx,int by,int dir) {
int x0 = -1, x1 = 2*nsize;
int y0 = -1, y1 = 2*nsize;
......
......@@ -109,7 +109,7 @@ public:
std::string get_groups_prefix() const { return groupfile_prefix; }
std::string get_groups_suffix() const { return groupfile_suffix; }
bool is_square() const { return squhex == 4; }
bool is_square() const { return squhex == 4 || squhex == 8; }
bool is_square4() const { return squhex == 4; }
bool is_square8() const { return squhex == 8; }
bool is_hex() const { return squhex == 6; }
......
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