Сначала я напишу код, а затем объясню:
Program integral
implicit none
real f
integer, parameter:: a=1, b=5, Nmc=10000000 !a the lower bound, b the upper bound, Nmc the size of the sampling (the higher, the more accurate the result)
real:: x, SUM=0
do i=1,Nmc !Starting MC sampling
call RANDOM_NUMBER(x) !generating random number x in range [0,1]
x=a+x*(b-a) !converting x to be in range [a,b]
SUM=SUM+f(x) !summing all values of f(x). EDIT: SUM is also an instrinsic function in Fortran so don't call your variable this, I named it so, to illustrate its purpose
enddo
print*, (b-a)*(SUM/Nmc) !final result of your integral
end program integral
function f(x) !defining your function
implicit none
real, intent(in):: x
real:: f
f=sqrt(1+x**2)
end function f
Итак, что происходит:
Интеграл можно записать как .где:
(это g (x) - равномерное распределение вероятности переменной x в [a, b]).И мы можем записать интеграл как:
, где .
Итак, наконец, мы получаем, что интеграл должен быть:
Итак, все, что вам нужно сделать, это сгенерировать случайное число в диапазоне [a, b], а затем вычислить значение вашей функции для этого x.Затем сделайте это много раз (раз Nmc) и вычислите сумму.Затем просто разделите на Nmc, чтобы найти среднее, а затем умножьте на (ba).И это то, что делает код.
В интернете есть много материала для этого. вот один пример, который довольно хорошо это визуализирует
РЕДАКТИРОВАТЬ: Второй способ, такой же, как метод Пи:
Nin=0 !Number of points inside the function (under the curve)
do i=1,Nmc
call random_number(x)
call random_number(y)
x=a+x*(b-a)
y=f_min+y(f_max-f_min)
if (f(x)<y) Nin=Nin+1
enddo
print*, (f_max-f_min)*(b-a)*(real(Nin)/Nmc)
Все это вы могли бы затемзаключите его во внешний цикл do, суммируя (f_max-f_min) (ba) (real (Nin) / Nmc), и в конце выведите его среднее значение.В этом примере вы по сути создаете вмещающий прямоугольник от a до b (измерение x) и от f_min до f_max (измерение y), а затем делаете выборку точек внутри этой области и подсчитываете точки в функции (Nin). Очевидно, вам нужно знать минимальное (f_min) и максимальное (f_max) значение вашей функции в диапазоне [a, b].В качестве альтернативы вы можете использовать произвольно низкие / высокие значения для вашего f_min f_max, но тогда вы будете тратить много очков и ваша ошибка будет больше.