Monte Carlo Methods

This is the code I created to calculate in C ++ using Monte Carlo methods, the average distance between the points evenly distributed in a cube. I do not understand why in the output file "distancia_media_quando_se_varia_o_numero_de_configuracoes.txt", the value of the second column is always the same. I wanted the value to vary until it stabilized at a value. The goal is that with the txt file I can create a graph where the x-axis is the logarithm of the left values of the txt file and the y-axis is the value of the right column of the txt file . How can I change the cpp file to get the mean value of the average distance over time (right column of the txt file)?

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include<iostream>
#include<cstdlib>
#include<math.h>
#include<fstream>
#include<iomanip>

using namespace std;

void distanciamediatotal(int &numero_configuracoes, int &numero_de_pontos, const char* name_of_file, int &semente, int caso){
        double x[numero_de_pontos];
        double y[numero_de_pontos];
        double z[numero_de_pontos];
        double dmedia_auxiliar;
        double dij = 0.0;
        double dijsomatorio_quando_i_menor_j = 0.0;
        double distancia_media_total = 0.0;
        double somatorio_d_media = 0.0;
        long long int i;
        long long int j;
        long long int k;
        long long int m;

        ofstream file;
        file.open(name_of_file);

        switch(caso){
                case 0:
                        for(k=0;k<numero_configuracoes;k++){
                                dijsomatorio_quando_i_menor_j=0.0;
                                distancia_media_total = 0.0;
                                srand48(semente);

                                for(i=0;i<numero_de_pontos;i++){
                                        x[i]=drand48();
                                        y[i]=drand48();
                                        z[i]=drand48();
                                }

                        for(j=1;j<numero_de_pontos;j++){
                                for (i=0; i<j;i++){

                                        dij=sqrt(pow((x[j]-x[i]),2)+pow((y[j]-y[i]),2)+pow((z[j]-z[i]),2));

                                        dijsomatorio_quando_i_menor_j+=dij;
                                }
                        }


           dmedia_auxiliar=dijsomatorio_quando_i_menor_j*2/(double)(numero_de_pontos*(numero_de_pontos-1));
                                somatorio_d_media+= dmedia_auxiliar;
                                distancia_media_total = somatorio_d_media/(k+1);

                                file << k+1 << "\t" << setprecision(10) << distancia_media_total << endl;
                }
                file.close();
                break;
                    case 1:
                        for(m=2;m<=numero_de_pontos;m++){
                                somatorio_d_media = 0.0;

                                for (k=0;k<numero_configuracoes;k++){
                                        srand48(semente);
                                        dijsomatorio_quando_i_menor_j=0.0;
                                        distancia_media_total = 0.0;

                                        for(i=0;i<numero_de_pontos;i++){
                                                x[i]=drand48();
                                                y[i]=drand48();
                                                z[i]=drand48();
                                        }
                                        for(j=1;j<m;j++){
                                                for (i=0; i<j;i++){

dij=sqrt(pow((x[j]-x[i]),2)+pow((y[j]-y[i]),2)+pow((z[j]-z[i]),2));
                                                    dijsomatorio_quando_i_menor_j+=dij;
                                            }
                                    }
                                    dmedia_auxiliar=dijsomatorio_quando_i_menor_j*2/(double)(m*(m-1));
                                    somatorio_d_media+= dmedia_auxiliar;
                            }
                            distancia_media_total = somatorio_d_media/numero_configuracoes;
                            file << m << "\t" << setprecision(10) << distancia_media_total << endl;
                    }
                    file.close();
            break;
                            default:
                            cout << "Teste nao identificado \n" << endl;
    }
}

int main (){

    long long int numero=1;
    long long int numerototal=10;
    long long int Nd;
    long long int i;
    int semente=17;
    srand48(semente);
    double x=0.0;
    double y=0.0;
    double distancia;
    double pi=0.0;
    double errocomlogaritmo=0.0;

    // Exercicio 1 - Calculo do valor de pi

    //Gerar pontos distribuidos uniformemente num quadrado unitario;
    //Calculo da distancia de cada ponto a origem;
    //Determinacao dos pontos que se encontram dentro do semicirculo
    //Estimar o valor de pi;
    //Fazer dois graficos: o primeiro do valor da estimativa de pi
    //em funcao do numero de pontos gerados; o segundo da dependencia
    //funcional em funcao do numero de pontos gerados.


    /*ofstream file;
    file.open("Dados_para_o_numero_pi.txt");

    for(int k=0;k<numerototal;k++){
            numero*=10;
            Nd=0;
            for(i=0;i<numero;i++){
                    x = drand48();
                    y = drand48();
                    distancia = pow(x,2)+pow(y,2);
                    //Se os pontos que estão no quadrado estao tambem dentro do
                    //semicirculo, soma mais uma unidade a Nd
                    if(distancia<=1.0)
                       Nd++;
            }

            pi = 4*Nd/(double)numero;
            errocomlogaritmo = log10(fabs(M_PI-pi));


            file << numero << "\t" << setprecision(10) << pi << "\t" << k+1 << "\t" << setprecision(8) <<
            errocomlogaritmo << "\t" << endl;
    }
    file.close();*/

    //Exercicio 2 - Pontos numa caixa

    //Resolucao do integral usando o Metodo de Monte Carlo

    //varia-se o numero de configuracoes, mantendo fixo o numero de pontos
    int numero_configuracoes_maximo = 100000;
    int numero_de_pontos=1000;
    distanciamediatotal(numero_configuracoes_maximo, numero_de_pontos, "distancia_media_quando_se_varia_o_numero_de_configuracoes.txt", semente, 0);

    //Varia-se o numero de pontos, mantendo fixo o numero de configuracoes
    int numero_configuracoes = 1000;
    //distanciamediatotal(numero_configuracoes, numero_de_pontos, "distancia_media_quando_se_varia_o_numero_de_pontos.txt", semente, 1);

    return 0;
}
You're calling srand48() at the top of each iteration. It should be called once, at the start of the program.

There are a number of other problems.
1. Don't use dynamic array allocation in C++ as it's not part of the langauge. Don't use in C either. It was a stupid idea to add it to the language in the first place.
1
2
3
4
void distanciamediatotal(int &numero_configuracoes, int &numero_de_pontos, const char* name_of_file, int &semente, int caso) {
    std::vector<double> x(numero_de_pontos);    // double x[numero_de_pontos];
    std::vector<double> y(numero_de_pontos);    // double y[numero_de_pontos];
    std::vector<double> z(numero_de_pontos);    // double z[numero_de_pontos]; 


2. In a Monte-Carlo simulation to calcuate Pi, you don't need to find the distance of the point to the origin. If the radius is 1, you just check that x2 + y2 <= 1.
Thanks for the advice. My problem with this code is that in switch -> case 0, when I create the file, it returns in the second column of the file corresponding to distancia_media_total, always the same value at each iteration. This should not give the same value, it should give different values ​​until converging. You can check this out if you compile and execute the file. You will see that when you compile the cpp file and executes it appears "distancia_media_quando_se_varia_o_numero_de_configuracoes.txt" and in the second column always gives the same value. How can I get the variation of distancia_media_total over time in switch -> case 0, so that in the second column of the file different values ​​appear until converging?
My problem with this code is that in switch -> case 0, when I create the file, it returns in the second column of the file corresponding to distancia_media_total, always the same value at each iteration.
I'm not sure if was clear in my answer, but you're reseeding the PRNG with srand48(semente) at the top of each iteration of the loop, so calls to drand48() will always return the same values thoroughout the loop, and so you'll always have the same value for your final calculation, distancia_media_total.
Topic archived. No new replies allowed.