Approximate π Using a Monte Carlo Method in C

CCBeginner
Practice Now

Introduction

In this lab, we will learn how to approximate the value of π using a Monte Carlo method in the C programming language. We will start by generating random points within a unit square, then count the points that fall inside a quarter circle to compute an approximation of π. Finally, we will print the calculated approximation.

The lab covers the key steps of the Monte Carlo method for estimating π, including generating random points, counting points inside the quarter circle, and using the ratio of points inside to the total points to compute the approximation. This lab provides a practical application of calculus and analytical geometry concepts in the C programming language.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("`C`")) -.-> c/UserInteractionGroup(["`User Interaction`"]) c(("`C`")) -.-> c/BasicsGroup(["`Basics`"]) c(("`C`")) -.-> c/ControlFlowGroup(["`Control Flow`"]) c(("`C`")) -.-> c/FunctionsGroup(["`Functions`"]) c/UserInteractionGroup -.-> c/output("`Output`") c/BasicsGroup -.-> c/variables("`Variables`") c/ControlFlowGroup -.-> c/for_loop("`For Loop`") c/FunctionsGroup -.-> c/math_functions("`Math Functions`") subgraph Lab Skills c/output -.-> lab-435134{{"`Approximate π Using a Monte Carlo Method in C`"}} c/variables -.-> lab-435134{{"`Approximate π Using a Monte Carlo Method in C`"}} c/for_loop -.-> lab-435134{{"`Approximate π Using a Monte Carlo Method in C`"}} c/math_functions -.-> lab-435134{{"`Approximate π Using a Monte Carlo Method in C`"}} end

Generate Random Points in a Unit Square

In this step, we will learn how to generate random points within a unit square using the C programming language, which is a crucial part of the Monte Carlo method for approximating π.

First, let's create a new C file in the ~/project directory to implement our random point generation:

cd ~/project
nano random_points.c

Now, let's write the code to generate random points:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_POINTS 10000

int main() {
    // Seed the random number generator
    srand(time(NULL));

    // Generate random points in the unit square
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        printf("Point %d: (%.4f, %.4f)\n", i + 1, x, y);
    }

    return 0;
}

Let's break down the code:

  • srand(time(NULL)) seeds the random number generator with the current time
  • (double)rand() / RAND_MAX generates a random number between 0 and 1
  • We generate 10,000 random points in the unit square (0,0) to (1,1)

Compile and run the program:

gcc random_points.c -o random_points
./random_points

Example output:

Point 1: (0.7234, 0.5678)
Point 2: (0.2345, 0.9876)
...
Point 10000: (0.1122, 0.3344)

Count Points Inside Quarter Circle and Compute π Approx

In this step, we will modify our previous program to count the points inside a quarter circle and use this information to approximate the value of π.

Let's update the random_points.c file:

cd ~/project
nano random_points.c

Replace the previous code with the following implementation:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 100000

int main() {
    // Seed the random number generator
    srand(time(NULL));

    int points_inside_circle = 0;

    // Generate random points and count those inside the quarter circle
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Check if point is inside the quarter circle
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // Approximate π
    double pi_approximation = 4.0 * points_inside_circle / NUM_POINTS;

    printf("Total points: %d\n", NUM_POINTS);
    printf("Points inside quarter circle: %d\n", points_inside_circle);
    printf("Approximation of π: %.6f\n", pi_approximation);
    printf("Actual π value:    %.6f\n", M_PI);
    printf("Difference:        %.6f\n", fabs(pi_approximation - M_PI));

    return 0;
}

Compile the program with the math library:

gcc random_points.c -o random_points -lm
./random_points

Example output:

Total points: 100000
Points inside quarter circle: 78540
Approximation of π: 3.141600
Actual π value:    3.141593
Difference:        0.000007

Let's break down the key changes:

  • Increased number of points to improve accuracy
  • Added logic to count points inside the quarter circle
  • Used the formula: π ≈ 4 * (points inside circle) / (total points)
  • Included comparison with actual π value

Print the Approximation

In this final step, we'll enhance our π approximation program by creating a function to print the results and improve the output formatting.

Let's modify the random_points.c file:

cd ~/project
nano random_points.c

Update the code with a new print function and improved output:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 1000000

// Function to print approximation results
void print_pi_approximation(int total_points, int points_inside_circle) {
    double pi_approximation = 4.0 * points_inside_circle / total_points;

    printf("π Approximation Results\n");
    printf("=====================\n");
    printf("Total Points Generated:        %d\n", total_points);
    printf("Points Inside Quarter Circle:  %d\n", points_inside_circle);
    printf("Approximated π Value:          %.8f\n", pi_approximation);
    printf("Actual π Value:                %.8f\n", M_PI);
    printf("Absolute Difference:           %.8f\n", fabs(pi_approximation - M_PI));
    printf("Approximation Accuracy:        %.4f%%\n",
           (1 - fabs(pi_approximation - M_PI) / M_PI) * 100);
}

int main() {
    // Seed the random number generator
    srand(time(NULL));

    int points_inside_circle = 0;

    // Generate random points and count those inside the quarter circle
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // Check if point is inside the quarter circle
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // Print the approximation results
    print_pi_approximation(NUM_POINTS, points_inside_circle);

    return 0;
}

Compile and run the program:

gcc random_points.c -o random_points -lm
./random_points

Example output:

π Approximation Results
=====================
Total Points Generated:        1000000
Points Inside Quarter Circle:  785398
Approximated π Value:          3.14159200
Actual π Value:                3.14159265
Absolute Difference:           0.00000065
Approximation Accuracy:        99.9998%

Key improvements:

  • Created a dedicated function print_pi_approximation()
  • Increased points to 1,000,000 for better accuracy
  • Added more detailed output formatting
  • Included approximation accuracy percentage

Summary

In this lab, we first learned how to generate random points within a unit square using the C programming language, which is a crucial part of the Monte Carlo method for approximating π. We seeded the random number generator with the current time and then generated 10,000 random points in the unit square (0,0) to (1,1) using the rand() function.

Next, we modified the program to count the points inside a quarter circle and used this information to approximate the value of π. We generated 100,000 random points and checked which ones fell within the quarter circle. By calculating the ratio of points inside the circle to the total number of points, we were able to estimate the value of π.

Other C Tutorials you may like