// // Model with differentiation and de-differentiation. // #include #include #include #include #include #include #include #include #include // for setprecision() //random number generator definitions #define MBIG 1000000000 #define MSEED 161803398 #define MZ 0 #define FAC (1.0/MBIG) #define MAXPLEXlength 5 #define SMALL 1.0e-10 //end of random number generator definitions #define N 4 //number of levels in hierarchy #define M 2*2*2*2 //number of spins in the lowest level of hierarchy (largest level) #define beta 0.2 //1/T for epigenetic lattice was 0.1 #define betaGen 0.01 //1/T for genetic lattice #define Param1 25 //strength of protein acting on epigenetic lattice (G) #define Param2 3000 //strength the two neigboring proteins don't like each other #define Param3 2000 //strength of action from epigentic to genetic network #define Param4 20 //strength of methylation (H/2) #define Nruns 50000 // # of runs to make in each lattice for averaging #define TotalTraj 1 using namespace std; //******************************************************** // Random Number generator //******************************************************** double ran3(long *idum) { static int inext, inextp; static long ma[56]; static int iff=0; long mj, mk; int i, ii, k; if (*idum < 0 || iff == 0) { iff=1; mj=labs(MSEED-labs(*idum)); mj %= MBIG; ma[55]=mj; mk=1; for (i=1;i<=54;i++) { ii=(21*i) % 55; ma[ii]=mk; mk=mj-mk; if (mk < MZ) mk += MBIG; mj=ma[ii]; } for (k = 1; k <= 4; k++) for (i = 1; i <= 55; i++) { ma[i] -= ma[1+(i+30) % 55]; if (ma[i] < MZ) ma[i] += MBIG; } inext = 0; inextp = 31; *idum = 1; } if (++inext == 56) inext = 1; if (++inextp == 56) inextp = 1; mj = ma[inext]-ma[inextp]; if (mj < MZ) mj += MBIG; ma[inext] = mj; return mj*FAC; } //*********************************************************************** //****Exponentiation subroutine int exp (int b, int e) { int result; result = 1; while (e != 0) { result = result * b; e = e - 1; } return(result); } //*********************************************************************** // Epigenetic variables int Spin [N][M]; //spin state - can be -1,0,+1 int Meth[N][M]; //methylation constraint int cons; //magnitude of methylation constraint int Constraint [N][M][N][M]; //indicator of the presence of the constraint on the spin - can be 0,1 double SpinAverage [N][M]; double rdm1,rdm2,rdm3,rdm4; //random numbers int i,j,ii,iii,jj,father; //loop counters int n,m,k,l,kkk; //point to position of the spin int ok; double U[N][M]; //energy of a spin double Utotal=0; //total energy of the lattice double Eold; double F[N][M]; //field of external stimuli. // Genetic variables int SpinGen [N][M]; //spin state - can be 0, +1 double SpinAverageGen[N][M]; //average value of spin in the run double statA=0.0, statB=0.0; //percentage of differentiation let or right int traj; //trajectory number double SpinSum; //**********Energy function per site for epigenetic lattice double Energy(int i, int j){ double E=0.0; //contribution from the upper neighbor if (i!=0) { if (j%2==0) father=j/2; if (j%2==1) father=(j-1)/2; E=E+SpinAverageGen[i-1][father]*abs(Spin[i][j])*Param1; // E=E-Param1*0.5*SpinAverageGen[i-1][father]*Spin[i][j]; } //contribution from sibling if (i!=0) { if (j%2==0) E=E+SpinAverageGen[i][j+1]*Spin[i][j]*Param1; if (j%2==1) E=E+SpinAverageGen[i][j-1]*Spin[i][j]*Param1; } //contribution from progenitors if (i!=N-1) { E=E+(SpinAverageGen[i+1][2*j]+SpinAverageGen[i+1][2*j+1])*Spin[i][j]*Param1; } //contribution from genetics E=E-Param1*(SpinAverageGen[i][j])*(Spin[i][j]); //contribution from external stimuli E=E+F[i][j]*(2*Spin[i][j]-1); //contribution from methylation constraint E=E+Meth[i][j]*(2*Spin[i][j]-0.); return(E); } //****Local Interaction Energies for genetic lattice double UsiblingGen(int a,int b) { if (a==0 && b==0) return(0); if (a==0 && b==+1) return(0); if (a==+1 && b==0) return(0); if (a==+1 && b==+1) return(Param2); } double UprogenitorGen(int a, int b) { if (a==0 && b==0) return(0); if (a==0 && b==+1) return(0); if (a==+1 && b==0) return(0); if (a==+1 && b==+1) return(Param2); } //**********Energy function per site for genetic lattice double EnergyGen(int i, int j){ double E=0.0; //contribution from the upper neighbor if (i!=0) { if (j%2==0) father=j/2; if (j%2==1) father=(j-1)/2; E=E+UprogenitorGen(SpinGen[i-1][father],SpinGen[i][j]); } //contribution from sibling if (i!=0) { if (j%2==0) E=E+UsiblingGen(SpinGen[i][j],SpinGen[i][j+1]); if (j%2==1) E=E+UsiblingGen(SpinGen[i][j],SpinGen[i][j-1]); } //contribution from progenitors if (i!=N-1) { E=E+UprogenitorGen(SpinGen[i][j],SpinGen[i+1][2*j])+UprogenitorGen(SpinGen[i][j],SpinGen[i+1][2*j+1]); } if (i==N-1) { E=E+UprogenitorGen(SpinGen[i][j],0)+UprogenitorGen(SpinGen[i][j],0); } //contribution from epigenetics E=E-Param3*(SpinAverage[i][j]-0.3)*(SpinGen[i][j]); return(E); } //********************************************************* int main () { using namespace std; ofstream resfile; resfile.open("stemcell.dat"); long * idum; idum = new long[1]; idum[0] = -(long)time(NULL); for (traj=0;traj0) //Create constraint of methylating-out from the site [i][j] { for (ii=0;iii) {if ( ((exp(2,ii-i)*j<=jj)&&(jj<=exp(2,ii-i)*(j+1)-1)) ) Meth[ii][jj]=Meth[ii][jj]-cons;} } } } } } //*********************************** //****** EPIGENETIC SPINS *********** //*********************************** cout<<"EPIGENETIC "<2 && kkk%2==1) // perturb the epigenetic state of randomly chosen spin // at every odd cell cycle starting from 3 (i.e. 3,5,7,9..) { //choose site in random rdm1=ran3(idum); if (rdm1==0) rdm1=ran3(idum); rdm2=ran3(idum); if (rdm2==0) rdm2=ran3(idum); i=N-1; while (i>-1) { if (rdm1<((double)exp(2,i)/(double)(exp(2,N)-1))) {n=i;i=-1;} else rdm1=rdm1-(double)exp(2,i)/(double)(exp(2,N)-1); --i; } j=exp(2,n)-1;while (j>-1) { if (rdm2<1/(double)exp(2,n)) {m=j;j=-1;} else {rdm2=rdm2-1/(double)exp(2,n);--j;} } i=n;j=m; //flip the epigenetic spin at the chosen site F[i][j]=-80; } //******* Random update of spins in the hierarchy for(iii=0;iii-1) { if (rdm1<((double)exp(2,i)/(double)(exp(2,N)-1))) {n=i;i=-1;} else rdm1=rdm1-(double)exp(2,i)/(double)(exp(2,N)-1); --i; } j=exp(2,n)-1;while (j>-1) { if (rdm2<1/(double)exp(2,n)) {m=j;j=-1;} else {rdm2=rdm2-1/(double)exp(2,n);--j;} } i=n;j=m; rdm1=ran3(idum); if (rdm1==0) rdm1=ran3(idum); rdm2=ran3(idum); if (rdm2==0) rdm2=ran3(idum); Eold=Energy(i,j); if (Spin[i][j]==0) //spin can go to +1 or -1 { if (rdm1<0.5) //flip spin 0 -> +1 { Spin[i][j]=1; if (rdm2 -1 { Spin[i][j]=-1; if (rdm2 0 { Spin[i][j]=0; if (rdm2 -1 if (rdm2 0 { Spin[i][j]=0; if (rdm2-1) { if (rdm1<((double)exp(2,i)/(double)(exp(2,N)-1))) {n=i;i=-1;} else rdm1=rdm1-(double)exp(2,i)/(double)(exp(2,N)-1); --i; } j=exp(2,n)-1;while (j>-1) { if (rdm2<1/(double)exp(2,n)) {m=j;j=-1;} else {rdm2=rdm2-1/(double)exp(2,n);--j;} } i=n;j=m; rdm3=ran3(idum); if (rdm3==0) rdm3=ran3(idum); Eold=EnergyGen(i,j); if (SpinGen[i][j]==0) //spin can go to +1 { SpinGen[i][j]=1; if (rdm31) SpinAverageGen[i][j]=1; SpinSum=SpinAverageGen[i][j]+SpinSum; } } for (i=0;i>i; cout<<"\n"; } } return 0; }