// Generates random instances. // num: number of instances to be generated. // dataSize: number of features to be generated. // eSize: number of expected outputs. // strLen: length of random strings generated. // instances: input/output vector of instances void genRandInsts( const int& num, const int& dataSize, const int& eSize, const int& strLen, std::vector<Instance>& instances ){ std::shared_ptr<std::vector<std::string> > features(new std::vector<std::string>()); std::shared_ptr<std::vector<std::string> > classes(new std::vector<std::string>()); // Generate sudo names for features and classes for( int i = 0; i < dataSize; ++i){ features->push_back(randS(strLen)); } for( int i = 0; i < eSize; ++i){ classes->push_back(randS(strLen)); } // Generate instances for( int i = 0; i < num; ++i ){ // Generate sudo data for each instance std::vector<double>* data = new std::vector<double>(); std::vector<double>* expected = new std::vector<double>(); for( int j = 0; j < dataSize; ++j ){ data->push_back(randD()); } for( int j = 0; j < dataSize; ++j ){ expected->push_back(randD()); } instances.push_back( Instance( randS(strLen), data, expected, features, classes )); } }
int main(int argc, char* argv[]) { MPI_Init(&argc, &argv); // Start up MPI int process_rank; int process_count; MPI_Comm_rank(MPI_COMM_WORLD, &process_rank); // Find process rank MPI_Comm_size(MPI_COMM_WORLD, &process_count); // Stores the number of processes int x1 = 1; int x2 = 3; int runs = 0; int samplesPerProcess = 10000; double a = ((double)x1 + (double)x2) / 2; double dx = x2 - x1; double r = dx/2; double fx = 0.0; double usingPi = 0.0; double totalArea = 0.0; double area = 0.0; double sum = 0.0; double fault = 0.01; double* randomNumbers = malloc(sizeof(double) * process_count * samplesPerProcess); if(process_rank == 0) srand(time(NULL)); do{ // Fill the array with random numbers between x1 and x2 if(process_rank == 0) { printf("\nFinding the area of a circle from x1 = %d to x2 = %d with %d samples per process and %d processes.", x1, x2, samplesPerProcess, process_count); printf("\nThe integrated area will be recalculated if the actual area differs by more than %f.", fault); for(runs = 0; runs < process_count * samplesPerProcess; runs++) { randomNumbers[runs] = randD(x1, x2); } } // Send the array to all processes from process 0 MPI_Bcast(randomNumbers, samplesPerProcess * process_count, MPI_DOUBLE, 0, MPI_COMM_WORLD); // Math for calculating sum for process 0 if(process_rank == 0) { for(runs = 0; runs < samplesPerProcess; runs++) { fx = 2 * sqrt(((dx/2) * (dx/2)) - ((randomNumbers[runs] - a) * (randomNumbers[runs] - a))); sum = sum + (fx * dx); } area = (sum / samplesPerProcess); } else // Math for calculating sum for other processes { for(runs = (process_rank * samplesPerProcess) - 1; runs < (process_rank * samplesPerProcess) + samplesPerProcess; runs++) { fx = 2 * sqrt(((dx/2) * (dx/2)) - ((randomNumbers[runs] - a) * (randomNumbers[runs] - a))); sum = sum + (fx * dx); } area = (sum / samplesPerProcess); } // Im process 0, add all areas together and store in the totalArea variable MPI_Reduce(&area, &totalArea, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); // Print and compare results if(process_rank == 0) { usingPi = PI * r * r; totalArea = totalArea / (double)process_count; printf("\nThe area of a circle between %d and %d calculated using Monte Carlo Integration is %f.", x1, x2, totalArea); printf("\nUsing the formula A = Pi*r*r, the calculated area is %f.\n\n", usingPi); } }while( sqrt((usingPi - totalArea) * (usingPi - totalArea)) > fault); free(randomNumbers); MPI_Finalize(); return 0; }