Fortran (Force 2.0) и число «Пи»

от автора

Здравствуйте, хотелось бы рассказать немного о программировании на Fortran в среде Force 2.0 ( далее фортран) и, собственно, о нахождении числа «Пи».
Сразу бы хочу определить цель данного поста: по моему опыту нет подобных постов для фортрана, поделится опытом исчисления числа «Пи», подробно показать метод, получить опыт в написании постов ( без шуток, поэтому прошу не судить строго).

Итак, как оказалось, Force 2.0 " не отличается умом и сообразительностью ". Это выяснялось опытом работы длинную в 5-7 месяцев, что по-моему не мало ( до фортрана у меня было 2 года отношений с Pascal и полгода C/C++/C#, и все это благодаря учебе). Достаточно капризный язык и более капризная среда. Нельзя не заметить, что во внимание не берутся дополнительное подключение библиотек и других настроек (опций).


Началось все того, что компилятор имеют какие-то «психические расстройства», иногда цикл отказывался работать при некоторых значений данных, например, при построении матрицы 13:13, причем этот же код с таким же значением нормально работал на Visual Studio 2005. Потом оказалось ( а может быть это не компилятор ), что если «закомментировать» строку вывода чего-либо, то он изменит выводимое значение после:

Как это было

... READ*,N                                                                      READ*,N N1=N                                                                         N1=N N2=N                                                                         N2=N WRITE(*,*) N1                                                                WRITE(*,*) N1 WRITE(*,*) 'lalalala'                                                        ! WRITE(*,*) 'lalalala' WRITE(*,*) N2                                                                WRITE(*,*) N2 ...                                                                                          тут получалось, что N1 равно N2                             а тут получалось, что N1 не равно N2                 

Видимо, дело все с выделением памяти и т.д. Ну, и подобные нелогичные мелочи.
Конечно, это расстраивало каждый раз, так код не хотел работать нормально, но мысль, что на другом компиляторе это все-таки работает, радовала.

Так как я знаю, что с фортраном мне еще придется работать ( по программированию у меня фортран ), то я решил начать сам разбираться с языком, занимаясь различным внеучебным программированием ( программы, которые нас просят написать на учебе, достаточные легкие для меня ). Началось все с попытки посчитать число «Пи».

Зная несколько способов нахождения числа «Пи», и «потребности» языка, и особенности среды, я выбрал самый простой метод — посчитать интеграл методом прямоугольников (работая выяснилось, что у фортрана все не очень хорошо со случайными числами). Расскажу немного про математику для понимания. Внесу некоторые определения для простоты понимания:
— tan(x) — тангенс от «x»
— arctan (x) — арктангенс от «x»
— Pi — число «Пи»
— Pi/2 — «Пи» на «x»
, где x — некоторое число.

График tax(x) выглядит так ( tan(x) лежит в пределах от -Pi/2 до Pi/2 — вертикальные асимптоты ):

График arctan(x) так:

Мы знаем, что tan(Pi/4)=1, отсюда следует, что arctan(1)=Pi/4. Это дает нам все для того, чтобы найти Pi. Мы посчитаем площадь (arctan(x)) и возьмем эту площадь 4 раза.

Не вижу смысла более подробного описания нахождения методов прямоугольников

Далее, используя численный метод, можно написать код ( мы делаем это на фортране ):

Код

 program pi        real*8 p,iter,x        real t1,t2        integer*4 i,n,j,k        n=10        WRITE(*,*) 'kol-vo podchetov  = 10'        do j=1,10        p=0        iter=1./n        write(*,11)'nomer podcheta ',j  ! "Fortran не присутствует в ниспадающем списке языков для этого тега и не подсвечивается."        11 format(a,1i2)   ! "Используйте для этого языка тег <code>здесь_ваш_код</code> " - не очень удобно        call CPU_TIME(t1)             do i=1,n              x=(i+.5)*iter              p=p+4*(1/(1+x*x))             enddo        p=p/n        call CPU_TIME(t2)        t1=t2-t1        write(*,*)'time = ',t1,'sec'        write(*,*)'N = ',n        write(*,*) 'Pi = ',p        write(*,*) ' '        n=n*10        enddo        print*,'poschitali'        read* end 

Некоторые характеристики машины: ЦП Intel Core 2 Duo E6750 @ 2.66GHz ( в программе используется только 1 ядро ), ОЗУ 4,00ГБ 2-канальная DDR2 @ 332 МГц, СП Foxconn G31MXP (Socket 775)

Полученные результаты:
<spoiler title=«Нажми, чтобы просмотреть»

Не сложно заметить, что кол-во операций «ограничено» языком. Поэтому кол-во прогонов было равно 10, на 11 точность становилась только хуже (время тоже уменьшалось)

Вывод
Думаю, что время проведенное за нахождением «Пи» было проведено не зря, так как я получил не только само число «Пи» ( с очень хорошей точностью для практических целей, например, 1 нм = 10^-9 м, а мы получили 9 значащих цифр в числе «Пи» ), но и опыт в написании программ с использованием численных методов.

ссылка на оригинал статьи http://habrahabr.ru/post/216611/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *