Post

Monte Carlo simulation


Main code to run simulations about evolutionary game theory in C.

Download file

Packages

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include "pointers.h"
#include "regular_lattices.h"

Definitions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//------------------------------------------------------

#define fps 0000.01000000005 // fps^-1
//#define densidade_arquivo
#define densidade_terminal	

/********************************************************************
***                 		Global variables                   	  ***
********************************************************************/	
const int tmax=9999;//5000;

long long int N;
int L;
int G; // =4 (rede hexagonal) =5 (rede quadrada / kagome) =7 (rede triangular / quadrada 3D) =9 (rede moore / quadrada 4D)
double RUIDO;

/********************************************************************
***                 			 GSL                    		 ***
********************************************************************/	
unsigned long rseed;
const gsl_rng_type * T;
gsl_rng * rand_vec;

//#define DEBUG
	
void set_gsl_rng(void)
{
	#ifdef DEBUG
		rseed=1681248046;
	#else
		rseed=time(NULL);
	#endif

	gsl_rng_env_setup();
	T    = gsl_rng_default;
	rand_vec = gsl_rng_alloc (T);
	gsl_rng_set (rand_vec, rseed);
}

Initial distributions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/********************************************************************
***                  distribuição dos estados                     ***
********************************************************************/		
void calculo_ci_rand(int strategy[N], int **viz)
{	
	int n;
	for(n=0; n < N; n++)
	{	
		double aa = gsl_rng_uniform(rand_vec);
		
		if(aa < 0.5 ) {strategy[n] = 1;}
		else {strategy[n] = 0;}
	}
}

Payoff calculation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/********************************************************************
***                          Payoff                               ***
********************************************************************/
void calculo_payoff_pd ( double *payoff, double r, double gama, double delta, int x, int strategy[N], int **viz )
{

	// x: sitio central do grupo que o jogo ocorre
	// y: sitio que esta jogando

	int nd=0;
	int nc=0;
	int np=0;
	int i=0;

	for(i=0;i<G;i++) // vizinho 0 e o proprio sitio
	{
		switch(strategy[viz[x][i]])
		{
			case 0: ++nd; break;
			case 1: ++nc; break;
			case 2: ++np; break;
			default: 
				fprintf(stderr,"ERRO calculo vizinhos\n");
				fflush(stderr);
		}
	}

	double S = -r;
	double P = 0;
	double R = 1;		
	double T = 1+r;

	payoff[1] = R*(nc-1) + S*nd;
	payoff[0] = T*nc + P*nd;

}
void calculo_payoff_pgg ( double *payoff, double r, double gama, double delta, int x, int strategy[N], int **viz )
{

	// x: sitio central do grupo que o jogo ocorre
	// y: sitio que esta jogando

	int nd, nc, np, i, j, focal_node;

	payoff[1] = 0;
	payoff[0] = 0;

	for(j=0;j<G;j++) // set only first term for FPGG (loop between groups)
	{
		nd = 0;
        nc = 0;
        np = 0;
		focal_node = viz[x][j];

		for(i=0;i<G;i++) // loop inside a group
		{
			switch(strategy[viz[focal_node][i]])
			{
				case 0: ++nd; break;
				case 1: ++nc; break;
				case 2: ++np; break;
				default: 
					fprintf(stderr,"ERRO calculo vizinhos\n");
					fflush(stderr);
			}
		}

		payoff[1] += (r/G)*nc - 1;
		payoff[0] += (r/G)*nc; 
	}
}

Update rule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/********************************************************************
***                         Update rule                           ***
********************************************************************/
void update_rule( int x, int vizinho, int strategy[N], double Px, double Py , int t)
{

	double Wxy = 1.0/(1.0 + exp(-(Py-Px)/RUIDO));

	double l = gsl_rng_uniform(rand_vec);

	//printf("Px=%lf Py=%lf delta=%lf W=%lf \n",Px,Py,Py-Px,Wxy);

	//troca de estado
	if(Wxy > l)
	{   
		strategy[x] = strategy[vizinho];
	}
}

Monte Carlo Step

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/********************************************************************
***                            MCS                                ***
********************************************************************/
void calculo_mcs(double *payoff, int strategy[N], int **viz, double r, double gama, double delta, int t)
{

	int n;
	for(n=0; n<N; n++)
	{					

		int x = (int) N*gsl_rng_uniform(rand_vec);
   		int sitio = x;

		int y = 1 + (int) (G-1)*gsl_rng_uniform(rand_vec); 
		int vizinho = viz[x][y];

		calculo_payoff_pgg(payoff,r,gama,delta,sitio,strategy,viz);
		double Px = payoff[strategy[sitio]];

		calculo_payoff_pgg(payoff,r,gama,delta,vizinho,strategy,viz);
		double Py = payoff[strategy[vizinho]];
		//printf("%d %f %f\n", t, Px, Py);
		update_rule(x,vizinho,strategy,Px,Py,t);
		
  	}
}

Densities calculation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/********************************************************************
***                          Densidades                           ***
********************************************************************/
int calculo_densidades(int strategy[N], double *payoff, int **viz, double r, double gama, double delta, int t, FILE *fp)
{

	int k;
	int ND=0;
	int NC=0;
	int NP=0;

	for(k=0;k<N;k++)
	{
		switch (strategy[k])
		{
			case 1: ++NC; break;
			case 2: ++NP; break;
			case 0: ++ND; break;
			default: 
				fprintf(stderr,"ERRO - tipo de estrategia\n");
				fflush(stderr);
		}	
	}	

	#ifdef densidade_terminal
	printf("%d %lf %lf\n", t, (double)NC/(N), (double)ND/(N));
	#endif

	#ifdef densidade_arquivo
	fprintf(fp,"%d %lf %lf\n", t, (double)NC/(N), (double)ND/(N));		
	#endif

   // Return 1 if any strategy dominates, 0 otherwise
   // used to stop simulation in the first scenario
    if (NC == N || ND == N || NP == N) {
        return 1;  
    } else {
        return 0;  
    }
}

Main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/********************************************************************
***                          Main                                 ***
********************************************************************/
/*
- initial conditions
- time dynamics
	- calculate payoffs
	- update strategy
	- compute densities
*/
void main(int argc, char *argv[])
{	
	//------------------------------------------------------------------------------
	// gcc dilema.c -lm -lgsl -lgslcblas -O3 ---- 							   //***
	// ./a.out r gama delta L ruido								   			   //***
								   											   //***
	double payoff[2], gama, delta, r;								  		   //***
	int **viz;								   								   //***
								   											   //***
	r=atof(argv[1]);														   //***
	gama=atof(argv[2]);														   //***
	delta=atof(argv[3]);													   //***
	L=atoi(argv[4]);														   //***
	RUIDO=atof(argv[5]); 													   //***
																			   //***
	set_gsl_rng(); // gsl   												   //***
								 											   //***
	//gera arquivo										  					   //***
	char filename[200];														   //***
	FILE *fp;																   //***
	#ifdef densidade_arquivo									   			   
	sprintf(filename,"dados_r%f_g%f_d%f_seed%ld.txt",r,gama,delta,rseed);	   //***
	#endif																	   //***
	fp=fopen(filename,"w"); //abre .dat									       //***
																			   //***					
	// --------------------------------------								   //***
	// specify depending on regular_lattices.h								   //***
	N = L*L; 																   //***
	G = 5;								   									   //***
	viz = create_2d_int_pointer_h(N,G);									       //***
	square_lattice(viz,L);													   //***
	int strategy[N]; // sempre depois de declarar N							   //***
	//-------------------C.I.-------------------------------------------------------

	calculo_ci_rand(strategy,viz);
	calculo_densidades(strategy,payoff,viz,r,gama,delta,0,fp);
	
	//-------------------MCS--------------------------------------------------------
	int t;	
	for(t=1; t < tmax; t++)
	{	
		
		calculo_mcs(payoff,strategy,viz,r,gama,delta,t);
		calculo_densidades(strategy,payoff,viz,r,gama,delta,t,fp);

		// stop the simulation if one strategy dominates
		int stop = calculo_densidades(strategy, payoff, viz, r, gama, delta, t, fp);
		if (stop == 1) 
		{
			while (t < tmax) 
			{
				calculo_densidades(strategy, payoff, viz, r, gama, delta, t, fp);
				t++; 
			} 
			break;
		}	
	}//MCS

fclose(fp);
free_2d_int_pointer(viz,N,G);

} //main

Other functions

Gnuplot snapshots

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void snap_gnuplot(int state[N], int topologia[N], double *investimento, int label[N], int t)	
//    ./a.out | gnuplot
{
	// plota de cima pra baixo, esquerda pra direita
	// gnuplot inverte baixo e cima
	int i,j;
	
	printf("set title \"MCS = %d\" \n",t);
	printf("set autoscale keepfix\n");
	printf("set palette model RGB\n");
	printf("unset border\n");
	//printf("unset colorbox\n");	
	printf("unset xtics\n");
	printf("unset ytics\n");
	//printf("set palette defined ( 0 \"dark-red\", 0.5 \"light-red\",  1  \"#0000B3\", 2 \"#000057\")\n");
	printf("set palette defined ( 0 \"red\", 1 \"blue\", 2 \"yellow\")\n");
	//printf("set palette defined ( 0 \"#a6611a\", 0.5 \"#dfc27d\",  1  \"#80cdc1\", 2 \"#018571\")\n");
	printf("set cbrange[0:2]\n");
	printf("set xrange[0:%d]\n",L);
	printf("set yrange[0:%d]\n",L);
	printf("set size square\n");
			
	printf("plot \"-\" matrix with image\n");
			

	for(i=0;i<L;i++)
	{
		for(j=0;j<L;j++)
		{
			printf("%d ",state[j+i*L]);
		
		}
		/*for(j=0;j<L;j++)
		{
			printf("%d ",state[j+i*L]);
		}*/
		printf("\n");
	}
	printf("\n"); 
	printf("e\n");    printf("pause(%lf)\n",fps);
}

Gnuplot gif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void snap_gif(int state[N], int topologia[N], int t)
{

	int i,j;
	
	for(i=0;i<L;i++)
	{
		for(j=0;j<L;j++)
		{
			printf("%d ",state[j+i*L]);
		
		}
		/*for(j=0;j<L;j++)
		{
		printf("%d ",topologia[j+i*L]);
		}*/
		printf("\n");
	}
	printf("\n"); 

}

Hoshen-Kopelman

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void calculo_percolacao( int state[N], int **viz, int label[N])
{
	int largest_label = 0;
	int n,i;

	for(n=0;n<N;n++)
	{
		label[n] = state[n]*(n+1);
	}
	
	for(n=0;n<N;n++)
	{
		if(state[n]==1)
		{
			if(state[viz[n][1]] == 0 && state[viz[n][4]] != 0)
			{
				int a = label[n];
				label[n] = label[viz[n][4]];
			
				for(i=0;i<N;i++)
				{
					if(label[i]==a)
					{label[i]=label[n];}
				}
			}
			else if(state[viz[n][1]] != 0 && state[viz[n][4]] == 0)
			{
				int a = label[n];
				label[n] = label[viz[n][1]];
			
				for(i=0;i<N;i++)
				{
					if(label[i]==a)
					{label[i]=label[n];}
				}
			}
			else if(state[viz[n][1]] != 0 && state[viz[n][4]] != 0)
			{
				int a = label[viz[n][1]];
				int b = label[n];
				label[viz[n][1]] = label[viz[n][4]];
				label[n] = label[viz[n][4]];
			
				for(i=0;i<N;i++)
				{
					if(label[i]==a || label[i]==b)
					{label[i]=label[n];}
				}
			}
		}
	}
}

Other Initial distributions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void calculo_ci_square1(int strategy[N], int **viz)
{
	int n;
	for(n=0; n < N; n++)
	{	
		int i,j;
		j=n%L;
		i=n/L;
		//if(j<L/2){strategy[j+i*L] = COOPERATOR; investimento[j+i*L] = 0.5;}
		//else{strategy[j+i*L] = COOPERATOR; investimento[j+i*L] = 2.0;}
		strategy[j+i*L] = 0; investimento[j+i*L] = 0.0;
		//if(j==L/3 || j==2*L/3 || i==L/3 || i==2*L/3){strategy[j+i*L] = COOPERATOR;investimento[j+i*L] = 0.;}
		if(j>L/3 && j<2*L/3 && i>L/3 && i<2*L/3){strategy[j+i*L] = 1;investimento[j+i*L] = 1.;}
	}
}
void calculo_ci_square2(int strategy[N], int **viz)
{
	int n;
	for(n=0; n < N; n++)
	{	
		int i,j;
		j=n%L;
		i=n/L;
		strategy[n] = 0;

		if(j>1*L/5 && j<2*L/5 && i>1*L/5 && i<2*L/5){strategy[j+i*L] = 1;investimento[j+i*L] = 0.55;}
		
		if(j>3*L/5 && j<4*L/5 && i>1*L/5 && i<2*L/5)
		{
			double temp = gsl_rng_uniform(rand_vec);
			if(temp < 0.5) {investimento[j+i*L] = 3.25;strategy[j+i*L] = 1;}
			else{investimento[j+i*L] = 3.25;strategy[j+i*L] = 1;}
		}
		if(j>1*L/5 && j<2*L/5 && i>3*L/5 && i<4*L/5)
		{
			double temp = gsl_rng_uniform(rand_vec);
			if(temp < 1./3) {strategy[j+i*L] = 1;investimento[j+i*L] = 0.;}
			else if(temp < 2./3) {strategy[j+i*L] = 1;investimento[j+i*L] = 2.45;}			
			else{strategy[j+i*L] = 1;investimento[j+i*L] = 3.25;}
		}
		if(j>3*L/5 && j<4*L/5 && i>3*L/5 && i<4*L/5){strategy[j+i*L] = 1;investimento[j+i*L] = 2.45;}
	
	}
}
void calculo_ci_stripes(int strategy[N], int **viz)
{
	int n;
	for(n=0; n < N; n++)
	{	
		int i,j;
		j=n%L;
		i=n/L;
		if(i<L/4)				{strategy[j+i*L] = 0;investimento[j+i*L] = 0;}
		if(i>=L/4 && i<2*L/4)	{strategy[j+i*L] = 1;investimento[j+i*L] = 0.4;}	
		if(i>=2*L/4 && i<3*L/4)	{strategy[j+i*L] = 1;investimento[j+i*L] = 0.7;}	
		if(i>=3*L/4)			{strategy[j+i*L] = 1;investimento[j+i*L] = 0.0;}
	}
}
This post is licensed under CC BY 4.0 by the author.