Написание программ на Fortran
Программирование на языке Fortran (FORmula TRANslation) широко используется для научных и инженерных вычислений.
Язык Fortran был создан в 1950-х для программирования на IBM. Fortran широко применяется и сегодня, поскольку он позволяет выполнять сложные вычисления.
Данное руководство поможет установить Fortran и научит разрабатывать простые программы.
Требования
Установка Fortran
Обновите индекс пакетов:
sudo apt-get update
Затем нужно установить компилятор gfortran, который работает с Fortran 95, Fortran 2003, Fortran 2008.
sudo apt-get install gfortran
Терминал запросит подтверждения. Чтобы продолжить, введите y.
После этого введите команду:
Поскольку в команде не указан файл Fortran, она выдаст ошибку:
gfortran: fatal error: no input files
compilation terminated.
Однако это предсказуемое поведение, ошибка исчезнет, если указать в команде файл. Теперь вы знаете, что установка прошла успешно.
Создание программы «O, World!»
Теперь попробуйте написать простую программу. Создайте новый файл в текстовом редакторе nano для программы под названием OWorld (при желании вы можете выбрать другое имя). Последней версией языка Fortran является Fortran 2008, её нужно указать в расширении:
Добавьте в файл ключевое слово program и укажите затем имя программы. Имя, указанное в ключевом слове program, и имя файла программы не должны обязательно совпадать. Например, несмотря на то, что файл называется OWorld, в ключевом слове program можно указать o_world.
После этого добавьте в программу строку implicit none, чтобы компилятор мог проверять типы переменных.
program o_world
implicit none
После этого можно добавить в файл строку, которая будет отображать фразу O, world!:
program o_world
implicit none
print *, «Good morrow, and well met, O world!»
Оператор print считывает параметры и передаёт их в вывод. Символ звёздочки (*) в команде будет подбирать наиболее удобный способ отображения передаваемых данных (в данном случае они будут передаваться в виде строки).
В конце программы нужно поместить оператор end, указать ключевое слово program и имя программы:
program o_world
implicit none
print *, «Good morrow, and well met, O world!»
end program o_world
Компилирование программы
Теперь программу OWorld.f08 нужно скомпилировать.
В этой команде указан исполняемый файл. Чтобы просмотреть содержимое, введите:
Запустите файл a.out:
На экране появится фраза:
Good morrow, and well met, O world!
Программа работает правильно.
Вы можете переименовать a.out и выбрать более описательное имя файла:
Снова запустите программу:
Good morrow, and well met, O world!
Рекомендации
При написании программ на Fortran помните:
О бедном Фортране замолвите слово
Попробовать написать здесь свой первый пост меня подтолкнула статья о выборе первого языка программирования, где vt4a2h предлагает использовать для обучения C++. Да, на данную тему было сломано множество копий.
Я, как и наверное большинство школьников на просторах нашей необъятной Родины, начинал постигать азы через синий экран, но не смерти, а Turbo Pascal 7.0. Был конечно и Basic, с котором я впервые столкнулся в дошкольном возрасте на советском компьютере «Электроника». Тогда он казался странным текстовым редактором, ведь компьютер глазами ребенка создан для игр. Однако уже в институте я познакомился с языком Fortran, познав который, я до сих пор недоумеваю, почему он не используется для обучения.
Да, многие скажут, что язык мертвый, не соответствует современным реалиям, а учебники с названием, как на картинке, вызывают лишь улыбку. Я попробую объяснить, чем же так замечателен этот язык и почему я его рекомендую в качестве первого языка. Если заинтересовало, добро пожаловать под кат.
Я считаю, что базис по основам программирования должен закладываться еще в школьные годы, хотя бы в старших классах. Даже если в жизни компьютер будет использоваться только для набора текста в Word’е или для общения в социальных сетях, минимальные знания о том, что такое алгоритм и как структурировать последовательность действий, чтобы получить нужный результат, по крайней мере не повредят молодому отроку во взрослой жизни, а скорей всего помогут сформировать особый склад ума.
Для того, чтобы уроки информатики были в радость, а не снились в кошмарных снах, обучаемый должен понимать, что он делает, как он это делает и почему получается так, а не иначе. Ведь по сути нужно правильно донести информацию о цикле и условном операторе, чтобы человек мог писать программы самостоятельно. При этом, чем проще синтаксис языка, тем легче понять логику написания кода. Если же человек научится составлять правильный алгоритм, то для программирования на других языках, ему понадобится только узнать синтаксис этого языка, а базис уже будет заложен.
Чем же так замечателен Фортран?
Обратимся к истории создания этого языка. Появился он в далекие 50-е годы прошлого века, когда компьютеры еще были большие, программистов было мало, а информатика не преподавалась в школе, да и вообще считалась лженаукой. Нужен был простой язык, который помогал бы инженерам и ученым «скармливать» ЭВМ формулы, написанные на бумаге, пусть даже через перфокарты.
Отсюда и название самого языка: Formula Translator или же «переводчик формул». Т.е. изначально язык был ориентирован на людей без специальной подготовки, а значит должен был быть максимально простым.
Что ж, простота создателям удалась. Классическая первая программа выглядит следующим образом:
Синтаксис даже чуть проще Паскаля, нет необходимости ставить в конце строки «;» или «:» перед знаком равенства. Более того, людям, обладающих минимальным знанием английского языка, понять смысл простейшей программы не составит труда.
Тут я хочу отметить, что Фортран имеет несколько ревизий стандартов, основными из которых являются 77 и 90 (при этом сохраняется преемственность). 77 Фортран действительно архаичен, есть ограничение на длину строки, и необходимо делать отступ в начале строки, что может вызвать у молодого кандидата в программисты культурный шок. Недаром программы, написанные на 77 Фортране, получили из уст моего знакомого емкое название «Брежневский код». Поэтому весь мой текст относится к стандарту языка 90 и новее.
Для примера, приведу код для вычисления суммы неотрицательных целых чисел от 1 до n, вводимого с клавиатуры, написанный моей дипломницей при обучении её программированию с нуля. Именно на ней я испытал преподавание Фортрана в качестве первого языка. Надеюсь, что для неё это пошло на пользу, а мой экперимент удался. По крайней мере основы она усвоила за пару занятий, первое из которых ушло на лекцию про язык.
Нетрудно заметить, что как мы думаем, так и записываем код. Никаких сложностей у обучаемого не может возникнуть в принципе. Внимательный читатель конечно же спросит, что за implicit none и две звездочки в скобках через запятую. implicit none говорит нам, что мы явно указываем тип переменных, тогда как без данной записи компилятор будет сам угадывать тип. Первая звездочка означает, что ввод и вывод происходят на экран, а вторая говорит о том, что формат ввода-вывода определяется автоматически. Собственно, программы на Фортране выглядит не сложнее, чем написанный выше кусок кода.
А что насчет программной среды?
В школах, да и в любых госучреждениях, часто встает вопрос о программном обеспечении, в частности об его лицензионности. Потому как деньги на эти нужды особо не выделяются. По крайней мере в мое время, с этим была проблема, может сейчас ситуация изменилась в лучшую сторону.
Для написания программ на Фортране подойдет любой текстовый редактор. Если хочется подсветки синтаксиса, то можно использовать Notepad++ (поддерживает синтаксис только 77 стандарта) или SublimeText. Программу написали, чем будем компилировать? Тут все просто, можно использовать свободный GNU Fotran. Если использование планируется некоммерческое, то разрешается замахнуться и на компилятор от Intel, который хорошо оптимизирован под одноименные процессоры и поставляется с минимально необходимым IDE. Т.е. порог вхождения весьма льготный.
Лучшей средой разработки под Фортран по мнению многих пользователей остается Compaq Visual Fortran 6.6, последняя версия которого увидела свет в начале 2000-х. Почему же так сложилось, что среда, основанная на Visual Studio 6.0, которая без танцев с бубном заводится максимум на Windows XP 32 bit, и имеет ограничение на используемую память, снискала такую популярность среди фортранщиков. Ответ приведен на рисунке ниже.
Это Compaq Array Visualizer, который представляет собой очень удобный инструмент по визуализации 1, 2 и 3-х мерных массивов в процессе отладки программы непосредственно из дебаггера. Как говорится, попробовав раз, ем и сейчас. Дело в том, что Фортран сейчас используется в основном в науке (о чем будет сказано позже), в частности в той области, с которой я имею дело, а именно в физике атмосферы. При отладке программ массивы представляют собой различные метеорологические поля, такие как температура, давление, скорость ветра. Искать ошибку в графических полях гораздо проще, чем в наборе цифр, тем более, обычно известно, как примерно должно выглядеть поле, поэтому очевидные ошибки отсекаются моментально.
К сожалению, все наработки по компилятору перешли от Compaq к Intel. Intel первоначально поддерживала Array Visualizer, правда, уже те версии были бледным отражением продукта от Compaq, работать с ними было не так удобно, как прежде, но хотя бы минимальная работоспособность поддерживалась. Увы, Intel перестала разрабатывать новые версии Array Visualizer’а, поставив крест на этом удобнейшем инструменте. Именно поэтому фортрановское сообщество в основной своей массе пишет программы и занимается их отладкой под Compaq Visual Fortran на Windows, а боевые расчеты запускает на серверах под Linux, используя Intel-овские компиляторы. Интел, пожалуйста, услышь мольбы пользователей, верни нормальный инструмент для визуализации массивов в свой дебаггер!
Место Фортрана в современном мире
А сейчас мы подошли к той самой теме, которая обычно вызывает бурную дискуссию с моими коллегами, использующими Matlab, которые утверждают, что описанный в данном посте раритетный язык ни на что не годится. Тут я с ними не соглашусь. Дело в том, что Фортран исторически использовался в инженерных или научных расчетах, а потому со временем обрастал множеством готовых библиотек и кодами программ решения той или иной задачи.
Код в буквальном смысле передается из поколения в поколение, да еще и хорошо документируется. Можно найти множество готовых решений уравнений математической физики, линейной алгебры (здесь следует отметить удачную реализацию работы с матрицами), интегральных и дифференциальных уравнений и многого-многого другого. Наверное тяжело найти задачу из области физмат наук, для которой не был бы реализован алгоритм на языке Фортран. А если учесть отличную оптимизацию интеловских компиляторов под интеловские же процессоры, поддержку параллельных вычислений на высокопроизводительных кластерах, то становится понятно почему в научной среде этот язык занимает заслуженное первое место. Думаю, на любом суперкомпьютере можно найти установленный фортрановский компилятор.
Большинство серьезных моделей, по крайней мере из области физики атмосферы, написаны именно на Фортране. Да-да, прогноз погоды, которым каждый интересуется время от времени, получается в ходе расчетов моделей, написанных на этом языке. Более того, язык не находится в стагнации, а постоянно совершенствуется. Так, после описанных раннее стандартов 77 и 90, появились новые редакции 95, 2003, 2008, поддержка которых внедрена в актуальные компиляторы. Последние версии Фортрана несколько освежили старый проверенный временем язык, превнеся поддержку современного стиля, добавив объектно-ориентированное программирование, отсутствие которого было чуть ли не самым главным козырем противников этого языка. Более того, The Portland Group выпустила PGI CUDA Fortran Compiler, позволяющий проводить высокопараллельные расчеты на видеокартах. Таким образом, пациент более чем жив, а значит программисты на Фортран остаются востребованными до сих пор.
Вместо послесловия
А теперь я хотел бы вернуться к изначально затронутой теме об обучении программированию, и попытаться тезисно сформулировать основные плюсы Фортрана при выборе его в качестве первого языка.
Фортран — основной синтаксис
Программа на Фортране состоит из набора программных модулей, таких как основная программа, модули и внешние подпрограммы или процедуры.
Каждая программа содержит одну основную программу и может содержать или не содержать другие программные блоки. Синтаксис основной программы следующий:
Простая программа на фортране
Давайте напишем программу, которая добавляет два числа и печатает результат —
Когда вы компилируете и запускаете вышеуказанную программу, она дает следующий результат —
Пожалуйста, обратите внимание, что —
Все программы на Фортране начинаются с ключевого слова program и заканчиваются ключевым словом end program, за которым следует название программы.
Неявный оператор none позволяет компилятору проверить, что все ваши типы переменных объявлены правильно. Вы должны всегда использовать неявное none в начале каждой программы.
Комментарии в Фортране начинаются с восклицательного знака (!), Так как все символы после этого (кроме строки символов) игнорируются компилятором.
Команда print * отображает данные на экране.
Отступы строк кода — хорошая практика для сохранения читабельности программы.
Фортран допускает как прописные, так и строчные буквы. Фортран нечувствителен к регистру, за исключением строковых литералов.
Все программы на Фортране начинаются с ключевого слова program и заканчиваются ключевым словом end program, за которым следует название программы.
Неявный оператор none позволяет компилятору проверить, что все ваши типы переменных объявлены правильно. Вы должны всегда использовать неявное none в начале каждой программы.
Комментарии в Фортране начинаются с восклицательного знака (!), Так как все символы после этого (кроме строки символов) игнорируются компилятором.
Интероперабельность: Фортран и C#
Как известно, в мире миллионы и миллионы строк легаси-кода. Первое место в легаси, разумеется, принадлежит Коболу, но и на долю Фортрана досталось немало. Причём, в основном, вычислительных модулей.
Не так давно мне принесли небольшую программку (менее 1000 строк, более четверти — комментарии и пустые строки) с задачей «сделать что-нибудь красивое, например, графики и интерфейс». Хоть программа и небольшая, а переделывать её не хотелось — дядька её ещё два месяца будет старательно обкатывать и вносить коррективы.
Результаты работы в виде нескольких кусков кода и вагона текста старательно изложены под катом.
Постановка задачи
Есть программа на фортране, которая что-то считает. Задача: минимально её скорректировать, желательно — не залезая в логику работы, — и вынести в отдельный модуль задание входных параметров, а также вывод результатов.
Окружение
Для начала подготовим окружение.
В качестве компилятора я использовал gfortran из пакета GCC (взять можно отсюда). Также нам пригодится GNU make (это лежит неподалёку). В качестве редактора исходного кода можно использовать что угодно; я поставил эклипс с плагином Photran.
Установка плагина на эклипс производится из стандартных репозиториев через пункт меню «Help»/«Install New Software. » из базового репозитория Juno (в фильтре ввести Photran).
После установки всего софта требуется прописать пути к бинарникам gfortran и make в стандартный path.
Программы все написаны на старом диалекте фортрана, то есть требуют обязательный отступ в 6 пробелов в начале каждой строки. Строки ограничены 72 знакоместами. Расширение файла — for. Не то чтобы я настолько олдскулен и хардкорен, но что есть, с тем и работаем.
С C# всё понятно — студия. Я работал в VS2010.
Первая программа
Фортран
Для начала соберём простую программу на фортране.
Деталей разбирать не будем, мы тут не фортран всё-таки учим, но кратко освещу моменты, с которыми нам придётся столкнуться.
В-третьих, диалекты f90 и f95 не требуют отступов в начале строк. Тут всё опять-таки зависит от того, что к вам пришло.
Но ладно, вернёмся к программе. Компилируется она или из эклипса (если правильно настроен makefile), или из командной строки. Для начала поработаем из командной строки:
Запущенный exe-файл будет а) требовать run-time dll от фортрана, и б) выводить строку «Hello, world».
На этом с фортраном пока что закончим, и перейдём в C#.
Создадим полностью стандартное консольное приложение. Сразу добавим ещё один класс — TestWrapper и напишем немного кода:
Входная точка в процедуру определяется при помощи стандартной VS-утилиты dumpbin :
Эта команда даёт длинный дамп, в котором можно найти интересующие нас строчки:
Дальше — проще. В основном модуле Program.cs делаем вызов:
Запустив консольное приложение, можно видеть нашу строчку «Hello, world», выводимую средствами фортрана. Разумеется, надо не забыть подкинуть скомпилированный в фортране test.dll в папку bin/Debug (или bin/Release ).
Атомарные параметры
Но это всё неинтересно, интересно — передать данные туда и получить что-то обратно. С этой целью проведём вторую итерацию. Пусть это будет, например, процедура, добавляющая число 1 к первому параметру, и передающая результат во второй параметр.
Фортран
Процедура проста до безобразия:
В фортране вызов выглядит как-то так:
Теперь нам надо данный код скомпилировать и протестировать. В общем-то можно так и продолжать компилировать из консоли, но у нас же есть makefile. Давайте его пристроим к делу.
Так как мы делаем exe (для тестирования) и dll (для «продакшн-варианта»), то имеет смысл сначала компилировать в объектный код, после чего из него собирать dll/exe. Для этого открываем в эклипсе makefile и пишем что-то в духе:
Теперь мы можем по-человечески компилировать и очищать проект по кнопке из эклипса. Но для этого требуется, чтобы путь к make был установлен в переменных окружения.
Следующее на очереди — доработка нашей оболочки в C#. Для начала импортируем ещё один метод из dll в проект:
В основной программе пишем примерно следующее:
В общем-то всё, задача решена. Если бы не одно «но» — опять требуется копировать test.dll из папки фортрана. Процедура механическая, надо бы её автоматизировать. Для этого нажимаем правой кнопкой на проект, «Свойства», выбираем вкладку «События построения», и пишем в окне «Командная строка события перед построением» что-то в духе
Пути, понятное дело, надо бы свои подставить.
Итого, после компиляции и запуска, если всё прошло нормально, получаем работающую программу второй версии.
Строки
Положим, для передачи начальных параметров в вызываемый dll-модуль написанного кода нам будет довольно. Но зачастую требуется так или иначе закинуть внутрь строку. Тут есть одна засада, с которой я не разбирался — кодировки. Потому все мои примеры приведены для латиницы.
Фортран
Тут всё просто (ну, для хардкорщиков):
Если бы мы писали внутрифортрановский метод, без dll и прочей интероперабельности, то длину можно было бы и не передавать. А так как нам надо передавать данные между модулями, придётся работать с двумя переменными, указателем на строку и её длиной.
Вызов метода тоже не составляет сложностей:
len(trim()) указан с целью обрезания пробелов в конце (т.к. выделено на строку 50 символов, а используется только 12).
Теперь надо вызвать этот метод из C#. С этой целью доработаем TestWrapper :
Вызов при этом выглядит банально, за исключением многословности, вызванной требованием все параметры передавать по ссылке ( ref ):
Колбэки
Мы подошли к самому интересному — колбэкам, или передаче методов внутрь dll для отслеживания происходящего.
Фортран
Для начала напишем собственно метод, принимающий функцию как параметр. В фортране это выглядит примерно так:
Тут нам следует обратить внимание на новую секцию interface описания прототипа передаваемого метода. Изрядно многословно, но, в общем-то, ничего нового.
Вызов же данного метода абсолютно банален:
Переходим в C#. Тут нам требуется провести дополнительную работу — объявить в классе TestWrapper делегат с правильным атрибутом:
После этого можно определить прототип вызываемого метода run :
Точку входа традиционно определяем из выдачи dumpbin ; остальное нам тоже знакомо.
Итак, мы уже обладаем достаточным инструментарием для того, чтобы переделать код таким образом, чтобы передавать внутрь метода колбэк для вывода прогресса исполнения ёмких операций. Единственное, чего мы пока не умеем — передавать массивы.
Массивы
С ними чуть сложнее, чем со строками. Если для строк достаточно написать пару атрибутов, то для массивов придётся поработать немного ручками.
Фортран
Для начала напишем процедуру печати массива, с небольшим заделом на будущее в виде передачи строки:
Добавляется объявление массива из double (или real двойной точности), а также передаём его размер.
Вызов из фортрана тоже банален:
На выходе получаем отпечатанную строку и массив.
В TestWrapper ничего особого нет:
А вот внутри программы придётся немного поработать и задействовать сборку System.Runtime.InteropServices :
Это связано с тем, что внутрь фортрановской программы должен передаваться указатель на массив, то есть требуется копирование данных из управляемой области в неуправляемую, и, соответственно, выделение памяти в ней. В связи с этим имеет смысл написание оболочек типа такой:
Собираем всё вместе
Полные исходные коды всех итераций (и ещё немного бонуса в виде передачи массива в колбэк-функцию) лежат в репозитории на битбакете (hg). Если у кого-то есть дополнения — милости прошу в комменты.
Традиционно благодарю всех, кто дочитал до конца, ибо что-то очень уж много текста получилось.
Фортран 90
Формат записи исходного текста
В свободном формате записи все позиции строки равноправны, ее длина составляет 132 символа.
Структура программы
Программа на Фортране состоит из главной программы и, возможно, некоторого числа подпрограмм.Подпрограммы могут быть функциями или процедурами,внешними, внутренними или модульными. Различные программные компоненты могут компилироваться раздельно.
Имя программы обязательно начинается с буквы, затем могут идти буквы, цифры и символы подчеркивания, например:
END PROGRAM ИМЯ_ПРОГРАММЫ
ИМЯ_ПРОГРАММЫ является необязательной частью оператора.
После заголовка следуют описания переменных, констант, меток, подпрограмм и других объектов, используемых в программе. Эта ее часть называется разделом описаний.После раздела описаний следует раздел операторов.
Базовые типы данных
Перечень встроенных типов в порядке возрастания их ранга дан ниже.
У каждого встроенного типа Фортрана есть несколько разновидностей, которые отличаются друг от друга диапазоном значений и некоторыми другими характеристиками.
Значение символьного типа CHARACTER представляет собой строку символов. Длина строкового значения в Фортране может быть произвольной и задается с помощью параметра LEN в предложении описания строковой переменной, например:
CHARACTER(LEN = 430) :: Shakespeare_sonet
Предложение описания
Предложение описания переменных в Фортране 90 имеет вид:
ТИП[, АТРИБУТЫ] :: СПИСОК_ПЕРЕМЕННЫХ
В списке имена переменных разделяются запятыми, а ТИП задает общий тип переменных, являясь идентификатором типа:
REAL, PARAMETER :: salary = 2000
В Фортране 90 используются следующие атрибуты объектов:
Буквальные константы
Буквальные числовые константы записываются обычным образом. Комплексная буквальная константа записывается в круглых скобках:
Имеются две буквальные логические константы:
Буквальная символьная константа обрамляется апострофами, которые не входят в значение, а являются ограничителями значения. Вместо апострофов могут быть использованы кавычки.
Арифметические и логические операции
Арифметические операции Фортрана (в порядке убывания приоритета):
Минус (-) и плюс (+) используются также как знаки унарных операций: В Фортране поддерживаются следующие операции отношения :
Массивы
Массивы описываются с помощью атрибута DIMENSION :
REAL, DIMENSION(1:100) :: C
Число экстентов определяет ранг массива. Каждый экстент записывается в виде:
Если значение нижней границы опущено, ее значение полагается равным 1. В некоторых случаях, список экстентов сводится к списку разделенных запятыми двоеточий, число которых равно рангу массива. Только число экстентов задается при объявлении динамического массива :
REAL, ALLOCATABLE, DIMENSION(:, 🙂 :: BE_LATER
REAL X(10, 20, 30), Y(100), Z(2, 300, 2, 4)
Пример программы
Решение нелинейного уравнения методом Ньютона