Skip to content

Commit f3a451d

Browse files
Implementing ctest-friendly tests for /maths/numerical_integration. Tests for monte_carlo.f90
1 parent fea97c9 commit f3a451d

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
!> Test program for the Monte Carlo Integration module
2+
!!
3+
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
4+
!! in Pull Request: #32
5+
!! https://github.com/TheAlgorithms/Fortran/pull/32
6+
!!
7+
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
8+
!! addressing bugs/corrections to this file. Thank you!
9+
!!
10+
!! This program provides test cases to validate the monte_carlo_integration module against known integral values.
11+
12+
program test_monte_carlo_integration
13+
use monte_carlo_integration
14+
implicit none
15+
16+
! Run test cases
17+
call test_integral_x_squared_0_to_1()
18+
call test_integral_e_x_0_to_1()
19+
call test_integral_sin_0_to_pi()
20+
call test_integral_cos_0_to_pi_over_2()
21+
call test_integral_1_over_x_1_to_e()
22+
call test_integral_x_cubed_0_to_1()
23+
call test_integral_sin_squared_0_to_1()
24+
25+
print *, "All tests completed."
26+
27+
contains
28+
29+
! Test case 1: ∫ x^2 dx from 0 to 1 (Exact result = 1/3 ≈ 0.3333)
30+
subroutine test_integral_x_squared_0_to_1()
31+
real(dp) :: a, b, integral_result, error_estimate, expected
32+
integer :: n
33+
a = 0.0_dp
34+
b = 1.0_dp
35+
n = 1000000
36+
expected = 1.0_dp / 3.0_dp
37+
38+
call monte_carlo(integral_result, error_estimate, a, b, n, f_x_squared)
39+
call assert_test(integral_result, expected, error_estimate, "Test 1: ∫ x^2 dx from 0 to 1")
40+
41+
end subroutine test_integral_x_squared_0_to_1
42+
43+
! Test case 2: ∫ e^x dx from 0 to 1 (Exact result = e - 1 ≈ 1.7183)
44+
subroutine test_integral_e_x_0_to_1()
45+
real(dp) :: a, b, integral_result, error_estimate, expected
46+
integer :: n
47+
a = 0.0_dp
48+
b = 1.0_dp
49+
n = 1000000
50+
expected = exp(1.0_dp) - 1.0_dp
51+
52+
call monte_carlo(integral_result, error_estimate, a, b, n, exp_function)
53+
call assert_test(integral_result, expected, error_estimate, "Test 2: ∫ e^x dx from 0 to 1")
54+
55+
end subroutine test_integral_e_x_0_to_1
56+
57+
! Test case 3: ∫ sin(x) dx from 0 to π (Exact result = 2)
58+
subroutine test_integral_sin_0_to_pi()
59+
real(dp) :: a, b, integral_result, error_estimate, expected
60+
real(dp), parameter :: pi = 4.D0*DATAN(1.D0) ! Define Pi. Ensure maximum precision available on any architecture.
61+
integer :: n
62+
a = 0.0_dp
63+
b = pi
64+
n = 1000000
65+
expected = 2.0_dp
66+
67+
call monte_carlo(integral_result, error_estimate, a, b, n, sin_function)
68+
call assert_test(integral_result, expected, error_estimate, "Test 3: ∫ sin(x) dx from 0 to π")
69+
70+
end subroutine test_integral_sin_0_to_pi
71+
72+
! Test case 4: ∫ cos(x) dx from 0 to π/2 (Exact result = 1)
73+
subroutine test_integral_cos_0_to_pi_over_2()
74+
real(dp) :: a, b, integral_result, error_estimate, expected
75+
real(dp), parameter :: pi = 4.D0*DATAN(1.D0) ! Define Pi. Ensure maximum precision available on any architecture.
76+
integer :: n
77+
a = 0.0_dp
78+
b = pi / 2.0_dp
79+
n = 1000000
80+
expected = 1.0_dp
81+
82+
call monte_carlo(integral_result, error_estimate, a, b, n, cos_function)
83+
call assert_test(integral_result, expected, error_estimate, "Test 4: ∫ cos(x) dx from 0 to π/2")
84+
85+
end subroutine test_integral_cos_0_to_pi_over_2
86+
87+
! Test case 5: ∫ (1/x) dx from 1 to e (Exact result = 1)
88+
subroutine test_integral_1_over_x_1_to_e()
89+
real(dp) :: a, b, integral_result, error_estimate, expected
90+
integer :: n
91+
a = 1.0_dp
92+
b = exp(1.0_dp)
93+
n = 1000000
94+
expected = 1.0_dp
95+
96+
call monte_carlo(integral_result, error_estimate, a, b, n, log_function)
97+
call assert_test(integral_result, expected, error_estimate, "Test 5: ∫ (1/x) dx from 1 to e")
98+
99+
end subroutine test_integral_1_over_x_1_to_e
100+
101+
! Test case 6: ∫ x^3 dx from 0 to 1 (Exact result = 1/4 = 0.25)
102+
subroutine test_integral_x_cubed_0_to_1()
103+
real(dp) :: a, b, integral_result, error_estimate, expected
104+
integer :: n
105+
a = 0.0_dp
106+
b = 1.0_dp
107+
n = 1000000
108+
expected = 0.25_dp
109+
110+
call monte_carlo(integral_result, error_estimate, a, b, n, f_x_cubed)
111+
call assert_test(integral_result, expected, error_estimate, "Test 6: ∫ x^3 dx from 0 to 1")
112+
113+
end subroutine test_integral_x_cubed_0_to_1
114+
115+
! Test case 7: ∫ sin(x^2) dx from 0 to 1 (Approximate value)
116+
subroutine test_integral_sin_squared_0_to_1()
117+
real(dp) :: a, b, integral_result, error_estimate, expected
118+
integer :: n
119+
a = 0.0_dp
120+
b = 1.0_dp
121+
n = 1000000
122+
expected = 0.31026_dp ! Approximate value, adjust tolerance as needed
123+
call monte_carlo(integral_result, error_estimate, a, b, n, sin_squared_function)
124+
call assert_test(integral_result, expected, error_estimate, "Test 7: ∫ sin(x^2) dx from 0 to 1")
125+
126+
end subroutine test_integral_sin_squared_0_to_1
127+
128+
! Function for x^2
129+
real(dp) function f_x_squared(x)
130+
real(dp), intent(in) :: x
131+
f_x_squared = x**2
132+
end function f_x_squared
133+
134+
! Function for e^x
135+
real(dp) function exp_function(x)
136+
real(dp), intent(in) :: x
137+
exp_function = exp(x)
138+
end function exp_function
139+
140+
! Function for 1/x
141+
real(dp) function log_function(x)
142+
real(dp), intent(in) :: x
143+
log_function = 1.0_dp/x
144+
end function log_function
145+
146+
! Function for cos(x)
147+
real(dp) function cos_function(x)
148+
real(dp), intent(in) :: x
149+
cos_function = cos(x)
150+
end function cos_function
151+
152+
! Function for x^3
153+
real(dp) function f_x_cubed(x)
154+
real(dp), intent(in) :: x
155+
f_x_cubed = x**3
156+
end function f_x_cubed
157+
158+
! Function for sin(x^2)
159+
real(dp) function sin_squared_function(x)
160+
real(dp), intent(in) :: x
161+
sin_squared_function = sin(x**2)
162+
end function sin_squared_function
163+
164+
! Function for sin(x)
165+
real(dp) function sin_function(x)
166+
real(dp), intent(in) :: x
167+
sin_function = sin(x)
168+
end function sin_function
169+
170+
!> Subroutine to assert the test results
171+
subroutine assert_test(actual, expected, error_estimate, test_name)
172+
real(dp), intent(in) :: actual, expected, error_estimate
173+
character(len=*), intent(in) :: test_name
174+
real(dp) :: tol
175+
176+
! Set the tolerance based on the error estimate
177+
tol = max(1.0e-5_dp, 10.0_dp * error_estimate) ! Adjust as needed
178+
179+
if (abs(actual - expected) < tol) then
180+
print *, test_name, " PASSED"
181+
else
182+
print *, test_name, " FAILED"
183+
print *, " Expected: ", expected
184+
print *, " Got: ", actual
185+
stop 1
186+
end if
187+
end subroutine assert_test
188+
189+
end program test_monte_carlo_integration

0 commit comments

Comments
 (0)