[英]Fetching array for input return wrong result
I try to evaluate the pi value using Monte Carlo method. 我尝试使用蒙特卡洛方法评估pi值。 More precisely, using the circumference method. 更准确地说,使用周长法。
Initially I wrote a code that the number of iteration is fixed.Now, I'm trying to simulate the behavior of the code at the growing of the input. 最初,我编写了一个代码,该代码的迭代次数是固定的。现在,我试图在输入增加时模拟代码的行为。
To do this, I write this code, but it doesn't work: 为此,我编写了以下代码,但它不起作用:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
#define SEED time(NULL)
int main(int argc, char **argv) {
int rank, size;
unsigned int seed;
double x, y, start, end;
long long int i, j, all_point, points = 0, all_intern;
long long int dim[] = {5, 50, 500, 5000, 50000, 500000, 5000000, 50000000};
MPI_Init(&argc, &argv);
start = MPI_Wtime();
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
seed = SEED + rank;
for ( j = 0; j < 8; j++ ) {
for ( i = 0; i < dim[j]; i++ ) {
x = (double) rand_r(&seed) / RAND_MAX;
y = (double) rand_r(&seed) / RAND_MAX;
if ( x * x + y * y <= 1.0 ) points++;
}
MPI_Reduce(&points, &all_intern, 1, MPI_LONG_LONG_INT, MPI_SUM, 0, MPI_COMM_WORLD);
all_point = dim[j] * size;
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();
if ( rank == 0 ) {
printf("\u03C0 \u2248 %Lf\n", (long double) all_intern / all_point * 4.0);
printf("Time elapsed: %.4f\n", end - start);
}
}
MPI_Finalize();
return 0;
}
The issue is that the the value of points
is not reset to zero between each iteration, while all_point
counts only the total number of point of the current iteration. 问题在于,每次迭代之间points
的值不会重置为零,而all_point
只计算当前迭代中all_point
的总数。 So either you reset the value of points
, either you correctly compute all_point
. 因此,要么重置points
的值,要么正确计算all_point
。 Since it was no clear in the comments, below you find the two variants with comments in the code where I made modifications. 由于注释中不清楚,因此您可以在下面的代码中找到两个带有注释的变体,在其中进行了修改。 I removed all the MPI
content since it's not an MPI
issue. 我删除了所有MPI
内容,因为这不是MPI
问题。
Variant 1: Reset the counter of points in the circle 方案1:重置圆点的计数
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SEED time(NULL)
int main(int argc, char **argv) {
unsigned int seed;
double x, y, start, end;
long long int i, j, all_point, points = 0, all_intern;
long long int dim[] = {5, 50, 500, 5000,50000,500000,5000000,50000000};
seed = SEED + 1;
for ( j = 0; j < 8; j++ ) {
// reset points to 0 here
points=0;
for ( i = 0; i < dim[j]; i++ ) {
x = (double) rand_r(&seed) / RAND_MAX;
y = (double) rand_r(&seed) / RAND_MAX;
if ( x * x + y * y <= 1.0 ) points++;
}
all_point = dim[j];
printf("\u03C0 \u2248 %Lf\n", (long double) points / all_point * 4.0);
}
return 0;
}
Variant 2: Keep results from previous iterations but adjust the total count of points 方案2:保留先前迭代的结果,但调整点的总数
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SEED time(NULL)
int main(int argc, char **argv) {
unsigned int seed;
double x, y, start, end;
long long int i, j, all_point, points = 0, all_intern;
long long int dim[] = {5, 50, 500, 5000,50000,500000,5000000,50000000};
seed = SEED + 1;
for ( j = 0; j < 8; j++ ) {
for ( i = 0; i < dim[j]; i++ ) {
x = (double) rand_r(&seed) / RAND_MAX;
y = (double) rand_r(&seed) / RAND_MAX;
if ( x * x + y * y <= 1.0 ) points++;
}
// Correctly count the total of points used
// since the beginning
all_point=0;
for ( int k = 0; k <= j; k++ ) {
all_point += dim[k];
}
printf("\u03C0 \u2248 %Lf\n", (long double) points / all_point * 4.0);
}
return 0;
}
In both cases, the output is similar and correct. 在这两种情况下,输出都是相似且正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.