Текст
                    А.Б.Самохин
А.С.Самохина
[
&1РИААЭ*М+С
гфИАЛЭ
для персонального компьютера
Москва
«Радио и связь»
1996


ББК 32.973 С 17 УДК 681.3.068 Самохин А, Б., Самохина А. С. С 17 Численные методы и программирование на Фортране для персонального компьютера. - М.: Радио и связь, 1996. - 224 с: ил. ISBN 5-256-01232-0. Описывается алгоритмический язык Фортран и особенности его применения на персональных компьютерах. Подробно излагаются численные методы, применяемые при решении практических задач. Изложение сопровождается отлаженными программами на Фортране, которые можно использовать в реальных вычислениях. Для широкого круга читателей. 242404010000-005 С Без объявл. ББК 32.973 046(01)96 Производственное издание Самохин Александр Борисович Самохина Анна Сергеевна ЧИСЛЕННЫЕ МЕТОДЫ И ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ ДЛЯ ПЕРСОНАЛЬНОГО КОМПЬЮТЕРА Заведующий редакционным отделом Ю. Г. Ивашов Редактор М. М. Лисина Обложка художника В. Г. Ситникова Художественный и технический редактор Т. Н. Зыкина Корректор Т. Г. Тертышная ИБ № 2641 ЛР № 010164 от 04.01.92 Подписано в печать с оригинал-макета 5.01.96. Формат 60x88/16. Бумага офс. № 1. Гарнитура Тайме. Печать офсетная. Усл.печ. л. 13,72. Усл. кр.-отт. 14,18. Уч.-изд. л. 9,69. Тираж 7000 экз' Изд. №23946. Зак. №1909 С-005 Издательство "Радио и связь", 101000 Москва, Почтамт, а/я 693 Ордена Трудового Красного Знамени Чеховский полиграфический комбинат Комитета Российской ФедСрации п печати. 142300, г. Чехов, Московской обл. ° ISBN 5-256-01232-0 © Самохин А. Б., Самохина А. С
ПРЕДИСЛОВИЕ Эта книга адресована, главным образом, пользователям персональных компьютеров, желающим изучить алгоритмический язык Фортран и численные методы для своей работы или учебы. Для понимания данной книги не требуется специальных знаний в области программирования, а минимальный уровень математической подготовки не превосходит первого курса технического вуза. Однако и более подготовленный читатель найдет немало интересного в этой книге. Книга состоит из двух частей. В первой части излагается алгоритмический язык. Фортран и особенности его применения на IBM-совместимых персональных компьютерах. В первых трех разделах этой части описывается устройство компьютера с точки зрения пользователя, показывается эволюция языка Фортран и обсуждается процедура создания удобной для пользователя программной среды Фортрана на базе трансляторов Fortran-Microsoft и NDP-Fortran. В разделах 1.4 — 1.8 излагается собственно алгоритмический язык Фортран, реализованный в рассматриваемых трансляторах. Изложение сопровождается большим количеством примеров, иллюстрирующих особенности применения конструкций языка. В разделе 1.9 описывается отладчик программ CodeView, входящий в состав транслятора Fortran-Microsoft, который является очень удобным и эффективным средством поиска ошибок в Фортран-программах. В разделе 1.10 приводится список стандартных библиотечных функций Фортрана, а в разделе 1.11 описывается процедура создания библиотек программ для трансляторов Fortran-Microsoft и NDP-Fortran. В последнем разделе первой части приводятся задачи с решениями, которые дополняют основной текст и помогают в изучении алгоритмического языка. Во второй части книги излагаются численные методы, используемые при решении научно-технических и экономических задач. Изложение сопровождается отлаженными программами на Фортране, которые можно использовать в реальных вычисле-
4 ПРЕДИСЛОВИЕ ниях. В первых трех разделах этой части описываются этапы решения задач с использованием компьютеров, обсуждаются возможные погрешности вычислений при решении задач, а также дается определение вычислительных алгоритмов и рассматриваются их особенности. В разделах 2.4 — 2.13 излагаются численные методы: вычисления функций; интерполяции функций, как одной, так и нескольких переменных; нахождения экстремума функций; решения уравнений; решения систем линейных уравнений; нахождения собственных чисел матрицы; вычисления статистических- величин; интегрирования функций, как одной, так и нескольких переменных; решения дифференциальных и интегральных уравнений. Необходимые математические понятия объясняются по ходу изложения. Большое внимание уделяется точности получаемых результатов и построению эффективных алгоритмов, которые для своей реализации требуют наименьших вычислительных ресурсов. В последнем разделе второй части описывается технология программирования сложных вычислительных задач с использованием методов модульного и структурного программирования. Авторы надеются, что после прочтения этой книги читатель получит четкое и ясное представление о численных методах и сможет самостоятельно составлять программы на Фортране для решения прикладных задач. Авторы выражают благодарность рецензенту книги профессору А.С. Ильинскому за ценные советы и полезные замечания.
ЧАСТЬ 1 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ 1.1. УСТРОЙСТВО КОМПЬЮТЕРА С ТОЧКИ ЗРЕНИЯ ПОЛЬЗОВАТЕЛЯ Первые компьютеры (электронные вычислительные машины — ЭВМ) появились в начале 40-х годов XX века и представляли собой громадные конструкции с очень скромными, по сегодняшним меркам, возможностями. Они использовались для проведения больших объемов вычислений, а их количество измерялось единицами штук. С тех пор компьютерная техника развивалась невиданными в истории цивилизации темпами и в настоящее время компьютеры вошли практически во все сферы человеческой деятельности, а их производство измеряется десятками миллионов штук в год. При этом подавляющее большинство выпускаемых компьютеров, за исключением относительно небольшого количества дорогостоящих больших и супер ЭВМ, составляют персональные компьютеры (ПК). Персональные компьютеры представляют собой мощное средство для выполнения самых разнообразных задач, многие из которых еще несколько лет назад были не под силу большим ЭВМ. Персональные компьютеры постоянно совершенствуются и грань между ними и большими ЭВМ постепенно стирается. Современный компьютер имеет следующие основные компоненты:
6 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ • Центральный процессор, который выполняет арифметические и логические операции и организует процесс исполнения программ. • Память для хранения информации, в том числе программ и обрабатываемых данных. • Внешние устройства для управления компьютером и вводом-выводом информации. • Операционную среду, которая создает пользователю удобства при общении с компьютером. Первые три компоненты относятся к аппаратной части компьютера, которая в англо-американской терминологии называется hardware, дословно "твердое изделие", последняя компонента относится к программной части — software, в переводе "мягкое изделие". Принцип работы компьютера. В самых общих чертах работа компьютера выглядит следующим образом. С помощью внешнего устройства в память вводится программа, подлежащая исполнению. Центральный процессор считывает содержимое памяти, где находится первая команда (инструкция) программы и исполняет ее, затем выполняется вторая команда и т.д. до окончания работы программы. При этом последовательность выполнения команд может изменяться в зависимости от выполнения определенных условий, предусмотренных в программе, что позволяет реализовывать сложные алгоритмы, имеющие разветвления и циклы. Команды могут осуществлять чтение данных из памяти, арифметические и логические операции над данными, запись результатов выполнения в память, а также вывод результатов на внешние устройства. Все это осуществляется центральным процессором без вмешательства человека. Опишем более подробно основные компоненты ПК и укажем наиболее важные, с точки зрения пользователя, характеристики этих компонент.
УСТРОЙСТВО КОМПЬЮТЕРА 7 Центральный процессор или микропроцессор — это "мозг" ПК. Он непосредственно исполняет компьютерные программы, представленные в виде последовательности команд процессора. Полный набор команд образует систему команд микропроцессора, которую можно разбить на четыре основных типа: арифметические и логические команды; команды управления; команды внутренней пересылки; команды ввода-вывода. Все разнообразие программ, используемых на ПК, в конечном счете представляется в виде команд микропроцессора, т.е. на машинном языке, поскольку только в таком виде они могут быть выполнены. Каждая команда микропроцессора (например сложение) представляется в виде последовательности неделимых элементарных операций (тактов). Поэтому важнейшей характеристикой микропроцессора и компьютера в целом является тактовая частота, которая показывает сколько тактов микропроцессор выполняет в одну секунду. Тактовая частота измеряется в мегагерцах (МГц), т.е. в миллионах тактов в секунду. Для персональных IBM-совместимых компьютеров моделей 286, 386 SX и 386 DX, 486SX и 486 DX , Pentium тактовая частота изменяется в пределах от 6 до 150 МГц. Разные типы микропроцессоров выполняют одни и те же команды (например сложение) за разное число тактов и чем выше модель, тем, как правило, меньшее число тактов требуется. Например, микропроцессор модели 386 DX работает в два раза быстрее микропроцессора модели 286 с такой же тактовой частотой. В системе команд микропроцессоров моделей 286, 386 SX и 386 DX, 486 SX не предусмотрены команды для работы с числами с плавающей точкой. Каждая операция с такими числами (например сложение или умножение) осуществляется с помощью многих десятков элементарных операций (тактов) микропроцессора, что существенно снижает производительность компьютера при проведении научно-технических и экономических расчетов, при использовании машинной графики. Поэтому для этих моделей желательно использовать дополнительный математический сопроцессор, который увеличивает скорость выполнения опера-
8 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ ций над числами с плавающей точкой в 5 — 15 раз. Как правило, выпускаемые сейчас компьютеры указанных моделей снабжены математическим сопроцессором. Микропроцессоры моделей 486 DX и Pentium имеют в системе команд операции над числами с плавающей точкой, поэтому при их использовании математический сопроцессор не требуется. Память компьютера состоит из двух частей — оперативной и внешней памяти. Каждый тип памяти характеризуется двумя основными параметрами — объемом информации, которая может быть там размещена, и временем доступа к информации. Оперативная память имеет меньший объем и значительно меньшее время доступа к информации, нежели внешняя память. Любая информация в памяти, будь то данные или тексты программ, представлены в закодированном виде. Восемь бит информации, т.е. 8 двоичных разрядов, образуют 1 байт информации, Один байт является минимальным объемом информации, который может быть считан из памяти или записан в память. С помощью 1 байта можно закодировать любой символ из 256 различных символов. Поэтому 1 байта достаточно для кодирования алфавитов любых европейских языков, а также для кодирования ряда специальных символов, в частности знаков препинания. Например, одна страница текста стандартного формата имеет около 2000 знаков и занимает в памяти порядка 2000 байт. Для характеристики объема памяти используют следующие единицы: 1 Кбайт (килобайт)=1024байт, 1 Мбайт (мегабайт)=1024 Кбайт, 1 Гбайт (гигабайт)=1024 Мбайт, 1 Тбайт (терабайт)=1024 Гбайт. Оперативная память является очень важной частью компьютера. Перед выполнением программа загружается в оперативную память, поскольку микропроцессор непосредственно может взаимодействовать только с ней. Стандартный объем оперативной памяти компьютера IBM PC составляет 1 Мбайт, причем для пользователя доступно не более 640 Кбайт из них, поскольку остальные адреса памяти ("верхняя память") зарезервированы для служебных целей, в частности для хранения части операционной системы и для передачи изо-
УСТРОЙСТВО КОМПЬЮТЕРА 9 бражения на экран. В компьютерах моделей 386 , 486 и Pentium, как правило, присутствует расширение оперативной памяти до величин 2,4,8 и даже 32 Мбайт. Однако использование оперативной памяти свыше 640 Кбайт для прикладных программ не происходит автоматически, а требует специальной настройки. Это связано с тем, что операционные системы MS-DOS фирмы Microsoft, которые чаще всего используется в ПК, являются 16- разрядными и обеспечивают непосредственный доступ только к памяти объемом 640 Кбайт. Однако микропроцессоры моделей 386 и выше являются 32-разрядными и могут обеспечивать непосредственный доступ к памяти объемом до 4 Гбайт. Для того чтобы полноценно использовать всю оперативную память необходимо иметь 32-разрядную операционную систему. В настоящее время наиболее известны такие системы как Windows NT, OS/2 Warp и, появившаяся совсем недавно, Windows'95. Важнейшей характеристикой, влияющей на быстродействие компьютера, является время доступа к информации в оперативной памяти, поскольку при выполнении программ идет постоянный процесс записи и считывания из памяти. Поэтому при большой тактовой частоте и относительно большом времени доступа реальное быстродействие определяется временем доступа и практически не зависит от тактовой частоты. В компьютерах IBM время доступа к оперативной памяти приблизительно равно 10~6 — 10~7 с. Поэтому для ПК с тактовой частотой 25 МГц и выше для обеспечения более быстрого доступа к памяти используется "сверхоперативная" или кэш-память относительно небольшого объема (обычно от 64 до 512 Кбайт), которая имеет время доступа значительно меньше, нежели оперативная память. В кэш-памяти хранится наиболее часто используемая информация и при обращении микропроцессора к памяти сначала производится поиск данных в кэш-памяти, в результате чего среднее время доступа к памяти уменьшается. Внешняя память на ПК реализована в виде накопителя на жестком магнитном диске (винчестере) и предназначена для постоянного хранения информации: программ операционной си-
10 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ стемы, прикладных программ, текстовых редакторов, трансляторов с языков программирования и т.д. Для компьютеров IBM объем внешней памяти (диска), как правило, не менее 40 Мбайт и может достигать 500 Мбайт и выше. Для использования больших пакетов программ (например Windows) желательно иметь диски с объемом памяти не менее 80 Мбайт. Время доступа к информации на диске приблизительно 10~2 с. Поэтому частое обращение к диску может существенно увеличить время выполнения программ. Опишем основные внешние устройства компьютера: • Клавиатура предназначена для управления и ввода символов в компьютер. • Монитор (или дисплей) служит для изображения текстовой и графической информации. • Мышь — специальное устройство, упрощающее ввод информации в компьютер. • Принтер осуществляет вывод на печать текстовой и графической информации. • Накопители на гибких магнитных дисках (дискетах) предназначены для ввода-вывода информации в компьютер, создания резервных копий текстов, программ и т.д., переноса информации между ПК. На компьютере обычно имеется два дисковода для дискет. В настоящее время приняты стандарты — дискеты диаметром 5.25 и 3.5 дюйма. Дискеты размером 5.25 дюйма имеют емкости 360 Кбайт или 1.2 Мбайта, дискеты размером 3.5 дюйма — емкость 1.44 Мбайта. В последнее время появились накопители на съемных дисках большой емкости: CD-ROM — для постоянного хранения информации (без перезаписи) объемом около 600 Мбайт; магнитно- оптические диски — для считывания и записи информации объ-
УСТРОЙСТВО КОМПЬЮТЕРА 11 емом от 128 Мбайт до 2.6 Гбайт. Для использования этих накопителей в компьютере необходимо установить соответствующие дисководы. Операционная среда состоит из программ операционной системы и дополнительных программ, устанавливаемых пользователем для создания удо0ных средств при проведении работы на компьютере. Программы операционной системы поставляются вместе с компьютером, загружаются в него после включения и предназначаются для обеспечения пользователю определенного способа общения (интерфейса) с компьютером. Необходимость в использовании операционной системы связана с тем, что операции управления компьютером и его ресурсами являются операциями очень низкого уровня, а команды, которые нужны пользователю, состоят из многих сотен таких операций. Команды операционной системы предоставляют пользователю возможность управления компьютером с помощью команд высокого уровня. В настоящее время на компьютерах IBM наиболее широко распространены операционные системы MS-DOS фирмы Microsoft. Все операционные системы имеют следующие основные компоненты: • файловую систему, • командный язык, • драйверы (программы) для взаимодействия с внешними устройствами. Кратко опишем файловую систему. Файл — это поименованная область на диске (винчестере) или дискете для постоянного хранения информации — программ, Данных, текстов, закодированных изображений и т.д. Информация на магнитных дисках хранится только в файлах. Каждый файл имеет имя, состоящее из двух частей: собственно имени и расширения. Имя файла может иметь от 1 до 8 символов, а расширение начинается^ точки, за которой следует от 1 до 3 символов. Например,
12 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ result.dat prog.for autoexec.bat Расширение имени файла необязательно, но только файлы, имеющие расширения .com, .exe, .bat., могут быть программами, которые непосредственно выполняются компьютером. Имена файлов регистрируются в каталогах (директориях), которые также имеют собственное имя, как правило, без расширения. В каждом каталоге может быть зарегистрировано сколько угодно файлов и других каталогов, которые также могут содержать файлы. На каждом магнитном диске имеется один корневой каталог. Для винчестера корневой каталог имеет имя С, имена дисководов для гибких магнитных дисках имеют имена А и В, соответственно. Каждый каталог доступен пользователю через командный язык операционной системы — его можно просматривать, переименовывать содержащиеся в нем файлы, переносить их в другие каталоги и удалять. Для того чтобы обеспечить более удобные средства работы с файловой системой, были разработаны специальные программы — оболочки. Наиболее популярной среди них является программа The Norton Commander фирмы Symantec. Широкое распространение получила операционная оболочка Windows фирмы Microsoft, которая в удобной графической форме предоставляет польэова- 1 телю ряд дополнительных возможностей, по сравнению с операционной системой. Помимо программ общего назначения, каждому пользователю для своей конкретной работы целесообразно также использовать специальные программы и/или создавать программную среду для облегчения и убыстрения процесса работы. Например, при работе с текстами целесообразно использовать специализированные программы-редакторы, при написании программ на алгоритмических языках необходимо иметь программы-трансляторы для данного языка и удобные средства для запуска и отладки программ.
ЭВОЛЮЦИЯ ЯЗЫКА ФОРТРАН 13 1#2. ЭВОЛЮЦИЯ ЯЗЫКА ФОРТРАН Даже при наличии огромного количества программ для ПК многим пользователям необходимо самостоятельно составлять программы — для решения инженерных, научно-технических, экономических задач и т.д. Для этого необходимо использовать языки программирования высокого уровня, поскольку написание программ непосредственно на машинном языке или близком к нему языке ассемблера чрезвычайно непроизводительно. Язык программирования Фортран (FORTRAN — FORmula TRANslator, дословно "переводчик формул") появился в числе первых языков программирования в 1956 г. С тех пор Фортран остается основным языком программирования при решении инженерных и научно-технических задач. Появлялась и проходила мода на другие языки. За прошедшие годы были разработаны языки программирования, которые, казалось, могли заставить уйти Фортран с арены программирования — в 60-е годы это был язык Алгол, в 70-е годы PL-1, в 80-е годы Паскаль и Си. Тем не менее, Алгол и PL-1 в настоящее время практически не используются, а языки Паскаль и Си не нашли широкого применения при решении сложных числовых задач. Долголетие Фортрана объясняется следующими причинами: • Постоянным развитием, т.е. появлением все более совершенных версий языка, которые включают предыдущие версии как свои подмножества, это делает возможным использовать старые Фортран-программы. • Эффективной трансляцией текста Фортран-программы в машинный язык, это обеспечивает высокую скорость обработки данных, которая имеет большое значение при решении вычислительных задач. • Разработкой и постоянной поддержкой Фортрана ведущей компьютерной фирмой IBM.
14 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ В процессе развития языка Фортран было создано много различных версий, но наиболее популярными и широко распространенными были следующие : Фортран-66, разработанный в 1966 г. и Фортран-77, разработанный в 1977 г. К настоящему времени сформировался последний стандарт языка — Фортран-90. Каждая версия языка включала в себя новые возможности, которые к моменту появления стандарта сложились в практике программирования, в том числе в других алгоритмических языках. Так, в стандарт Фортрана-77 были включены: конструкции IF THEN ELSE, символьный тип данных, новый вид описания массивов и др. В стандарт Фортрана-90 были включены: типы данных, которые задаются пользователем, новые способы обработки массивов и др. Транслятор Fortran-Microsoft и NDP-Fortran для ПК полностью включает стандарт Фортран-77 с некоторыми расширениями из стандарта Фортрана-90. В этой книге будем описывать конструкции языка, которые реализованы в обоих трансляторах. 1.3. ОСНОВНЫЕ ТРАНСЛЯТОРЫ ФОРТРАНА ДЛЯ ПЕРСОНАЛЬНЫХ КОМПЬЮТЕРОВ На IBM-совместимых ПК наибольшее распространение получил транслятор Fortran-Microsoft версий 5.0 или 5.1. Для программ, требующих предельного использования расурсов компьютера, т.е. памяти и быстродействия, применяется также транслятор Fortran-NDP фирмы MicroWay. Ниже опишем эти трансляторы и процедуру создания удобной для пользователя операционной среды. Рассмотрим сначала транслятор Fortran-Microsoft, который может быть реализован на любых IBM-совместимых компьютерах. Для создания среды Фортрана требуется приблизительно 4.0 Мбайта памяти на винчестере для хранения файлов транслятора (для версии 5.0 объем памяти несколько меньше), а также,
ТРАНСЛЯТОРЫ ФОРТРАНА 15 как правило, не менее 0.5 Мбайта памяти для хранения непосредственно программ на Фортране. После подготовки винчестера можно приступить к инсталляции. Для этого необходимо вставить в дисковод первую инсталляционную дискету, найти файл с именем SETUP.EXE и запустить его на выполнение. Дальнейший процесс состоит в ответе на достаточно простые вопросы, а также в том, чтобы вставлять по мере требования те или иные инсталляционные дискеты. В трансляторе может использоваться три модели памяти — Large (большая), Medium (средняя) и Huge (гигантская). Модель памяти устанавливается во время инсталяции при ответе на соответствующий вопрос. Обычно устанавливается модель памяти Large. Рекомендуем поместить исполняемые файлы транслятора в каталоги C:\FORTRAN\BIN C:\FORTRAN\BINB (для транслятора версии 5.0 выполняемые файлы помещаются только в первый каталог); файлы библиотеки Фортрана в каталог C:\FORTRAN\LIB графические файлы в каталог C:\F0RTRAN\INCLUDE & временно создаваемые файлы транслятора в каталог C:\FORTRAN\TMP Создание этих каталогов и помещение в них файлов выполняется инсталлятором автоматически после указания имен каталогов в ответ на соответствующие вопросы. После завершения процесса инсталляции транслятора Фортрана можно приступать к созданию удобной для пользователя операционной среды. Будем считать, что на компьютере есть
16 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ программа — оболочка The Norton Commander, которая в настоящее время устанавливается практически на всех компьютерах IBM PC. Любая Фортран-программа сначала записывается в виде тек> ста на алгоритмическом языке, затем с помощью программы- транслятора переводится в машинный код компьютера и представляется в виде исполняемого файла, запускаемого на выполнение. Текст Фортран-программы можно записать с помощью любого текстового редактора в стандартном коде ASCII, например с помощью встроенного редактора The Norton Commander. Файл текста программы должен иметь любое имя с обязательным расширением .for, например prog.for. Тогда имя соответствующего выполняемого файла будет prog.exe. Создадим в каталоге C:\F0RTRAN, в котором находятся каталоги с файлами транслятора, командный файл start.bat ©echo off path=c:\fortran\bin; с:\fortran\binb set lib=c:\fortran\lib set include=c:\fortran\include set tmp=c:\fortran\tmp fl /Fs /Ox 7,1. for Файл start.bat служит для запуска транслятора Фортрана и создания выполняемых файлов. Первая команда предназначена для того, чтобы следующие не выводились на экран при их исполнении. Вторая команда указывает путь в каталоги, где находятся исполняемые файлы транслятора (для версии 5.0 указывается только путь в первый каталог). Следующие три команды задают переменные окружения, которые указывают местоположение каталогов, в которых размещаются библиотечные, графические и временно создаваемые файлы. Следующая команда запускает программу транслятора fl.exe, которая на основе текстового файла с расширением .for создает исполняемый файл с расширением .ехе и файл объектного модуля с расширением .obj.
ТРАНСЛЯТОРЫ ФОРТРАНА 17 В команде на запуск транслятора присутствуют опции (указатели), которые дают пользователю возможность установки определенных режимов работы транслятора. Перед каждой опцией должна стоять косая черта /, а между опциями не менее одного пробела. При записи опций нельзя заменять строчные буквы на прописные и обратно. Опция /Ох предписывает транслятору проведение полной оптимизации в процессе создания выполняемого файла, а опция /Fs дает предписание на выдачу текстового листинга программы с расширением .1st. В этом текстовом файле записывается текст Фортран-программы с указанием синтаксических ошибок, если они есть. Заметим, что если в тексте Фортран-программы есть синтаксические ошибки, т.е. неправильное использование конструкций алгоритмического языка, то исполняемый файл не создается, а выводится только листинг программы. Для программ, у которых данные занимают большой объем памяти (свыше 64 Кбайт), целесообразно использовать опцию /Gt. Полный список опций обычно присутствует в текстовом файле readme.doc, входящем в состав файлов транслятора. Далее, в каталоге NC, где хранятся файлы программы-оболочки The Norton Commander, надо найти текстовый файл пс. ext и внести в него следующую строчку: for: c:\fortran\start ! Теперь, пусть в каком-либо каталоге создан текстовый файл Фортран-программы с расширением .for. Если в этом каталоге с помощью The Norton Commander выделить этот файл, а 3&тем нажать клавишу | Enter | , то запустится командный файл start.bat, в результате выполнения которого будет создан листинг программы с расширением .1st и, если ошибок нет, будет с°эдан и выполняемый файл с расширением . ехе. Далее, при Вь*Делении исполняемого файла и нажатии клавиши | Enter |, программа запускается на выполнение. Отметим, что при наличии командного файла start.bat не Требуется внесение каких-либо изменений в командный файл
18 ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ autoexec.bat, о чем упоминается при инсталляции. У транслятора версии 5.1 может присутствовать встроенная операционная среда, которую пользователь, при желании, также может применять. Для транслятора Fortran-Microsoft существует ограничение в 640 Кбайт на объем исполняемого файла программы, даже при наличии расширения оперативной памяти. Поэтому для программ, требующих больший объем памяти, целесообразно применять транслятор Fortran-NDP, который позволяет использовать всю оперативную память компьютера. Кроме того, время исполнения Фортран-программ с помощью транслятора Fortran-NDP приблизительно в 1.5 раза меньше, по сравнению со временем исполнения этих же программ с помощью транслятора Fortran-Microsoft. Это может оказаться весьма существенным для задач, требующих большого времени счета. Рассмотрим более подробно транслятор Fortran-NDP. Этот транслятор может быть реализован на IBM-совместимых компьютерах моделей 386, 486 и Pentium. Для каждой модели существует своя версия транслятора, причем любая из них может использоваться на более высоких моделях компьютеров. Например, версия транслятора для модели 486 может использоваться на компьютерах Pentium. Для создания операционной среды Фортрана на трансляторе версии 486 требуется приблизительно 4.5 Мбайта памяти на винчестере для хранения файлов транслятора, а также, как правило, не менее 0.5 Мбайта памяти для хранения Фортран-программ. Пусть исполняемые файлы транслятора находятся в каталогах C:\NDP\BIN C:\NDP\T00LS файлы библиотеки Фортрана в каталоге C:\NDP\LIB а вспомогательные файлы транслятора в каталоге C:\NDP\INC
ТРАНСЛЯТОРЫ ФОРТРАНА 19 файл текста Фортран-программы может иметь любое имя с обязательным расширением .f например prog.f. Создадим в каталоге C:\NDP, в котором находятся каталоги с файлами транслятора, командный файл comp.bat Qecho off path=c:\ndp\bin; c:\ndp\tools set lib=c:\ndp\lib set ndp=c:\ndp set tools=c:\ndp\tools set inc=c:\ndp\inc mf486 -list -vm '/.l.f Файл comp.bat предназначен для запуска транслятора. Вторая команда указывает пути в каталоги, где находятся исполняемые файлы транслятора, а последующие четыре команды задают переменные окружения. Последняя команда запускает программу транслятора mf486.exe, которая на основе текстового файла с расширением .f создает файл с расширением .ltl. Созданный файл запускается на исполнение программой транслятора ndprun. ехе. Заметим, что если в тексте Фортран-программы есть синтаксические ошибки, то файл с расширением .ltl не создается, а на экране компьютера появляется сообщение об ошибках. В команде на запуск транслятора присутствует опция -vm, которая дает предписание транслятору на использование виртуальной памяти на винчестере при создании файла с расширением .ltl. Дело в том, что при создании подобных файлов для больших программ может оказаться недостаточно оперативной памяти, хотя при выполнении программы и не требуется виртуальная память. Опция -list дает предписание транслятору на выдачу текстового листинга программы с расширением .1st. Полный список опций транслятора приведен в файле mf486.opt. 1Аеред каждой опцией должен стоять минус, а между опциями Д°лжно быть не менее одного пробела. Далее в каталоге NC, где хранятся файлы программы-ободки The Norton Commander, надо найти текстовый файл c-ext и внести в него следующие строки:
20 ПРОГРАММИРОВАНИЕ НА ФОРТРАН} f: с:\ndp\comp.bat ! It1: с:\ndp\tools\ndprun.ехе !.! Теперь, пусть в каком-либо каталоге создан текстовой фай; Фортран-программы с расширением . f. Если в этом каталог( с помощью The Norton Commander выделить этот файл, а за то запустится командный фай, Enter тем нажать клавишу comp.bat и, если ошибок нет, будет создан файл с расширение* .ltl. Далее, при выделении файла с расширением .ltl и нажа тии клавиши | Enter |, программа запускается на выполнение. 1.4. НАЧАЛЬНЫЕ СВЕДЕНИЯ О ФОРТРАНЕ Текст Фортран-программы представляет собой запись т языке программирования алгоритма решения поставленной за дачи. Для записи текста используются следующие символы: • Прописные или строчные буквы латинского алфавита от А дог. • Цифры от 0 до 9. • Специальные символы пробел ( левая скобка знак равенства ) правая скобка + плюс минус звездочка двоеточие знак доллара , запятая ' апостроф / косая черта . точка Буквы русского алфавита и другие символы могут использовать ся только в комментариях Фортран-программы. Любая программа состоит из операторов (предложений) язы ка, которые располагаются в строках длиной 80 символов. По ложение символа в строке нумеруется слева направо, начинал с
НАЧАЛЬНЫЕ СВЕДЕНИЯ 21 1-ой позиции. Операторы Фортрана могут находиться только с 7-й по 72-ю позиции строки, причем в этих пределах расположение произвольное. Любой оператор может быть помечен меткой —- целым десятичным числом, метка располагается в позициях 1 — 5 строки. В строке не должно быть более одного оператора, однако, если оператор не помещается в позициях 7 — 72 или желателен его перенос на следующую строку, то в каждой строке продолжения в 6-й позиции печатается символ звездочка *, либо любой другой символ, отличный от нуля. Если в первой позиции любой строки Фортран-программы напечатана буква С, то такая строка рассматривается как комментарий текста программы и транслятором игнорируется. Для записи комментария могут использоваться наравне с латинскими русские буквы, а сам текст комментария располагается в позициях 2 — 80 строки. Каждая величина, используемая в тексте программы может быть либо константой, либо переменной. Константа — величина, значение которой задается в тексте программы в явном виде и в дальнейшем не изменяется. Переменная — величина, к которой обращаются в программе, используя соответствующее имя. Переменные могут изменяться в процессе исполнения программы. Имена переменных могут содержать от одного до шести символов, причем первым Должна быть буква, а последующими либо буквы, либо цифры. Каждая величина, константа или переменная, должна относится к одному из типов данных. В этом разделе рассмотрим два основных типа данных Фортрана — целые и вещественные. Целые константы представляют собой последовательность цифр без десятичной точки. Перед отрицательным числом должен стоять знак минус, а перед положительным знак плюс может отсутствовать. Примеры целых констант: 92 -7619 0 371
22 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ +956748 В памяти компьютера целая константа занимает 4 байта и можеУ иметь значение от -2147483648(-232) до 2147483647 (232 - 1). ] Вещественная константа может быть представлена од * ним из следующих двух способов: I. Вещественная константа без порядка, т.е. число, записан' ное с десятичной точкой, например 74.95 -649.571 0.0 +4. 7.93 0.0041 II. Вещественная константа с порядком, которая записывается в виде пЕтп Здесь мантисса п — вещественная константа, порядок m — однозначное или двузначное целое число со знаком или без знака. Примеры: -0.02341Е2 (= -0.02341 • 102) 7.34Е+11 (=7.34.10п) 0.03Е-7(=0.03-10~7) В памяти компьютера вещественная константа занимает 4 байта и имеет внутреннее представление, как вещественная константа с порядком. Диапазон изменения порядка от —37 до +38, число цифр в мантиссе не более семи. Тип переменной должен быть определен в программе и не может изменяться в процессе ее исполнения. Переменная представляется и хранится в памяти компьютера также, как константа соответствующего типа. Если никаких указаний о типе переменной в программе нет, то переменная относится либо к целому,
АЧАЛЬНЫЕ СВЕДЕНИЯ 23 тбо к вещественному типу по следующему правилу: если перечная начинается с букв I,J,K,L,M,N, то данная переменная [итается переменной целого типа, если переменная начинается любой другой буквы латинского алфавита, то она считается пе- шенной вещественного типа. Такое описание типа называется тесанием типа по умолчанию. Описание по умолчанию перестает действовать, если тип временной задать с помощью операторов явного описания япа INTEGER <список переменных> REAL <список переменных> ервый оператор указывает целый тип данных, второй — веще- ^венный. Примеры: INTEGER XO,Y,NM,CLMPQ REAL KX,JMAX,ZZ,L Операторы описания являются невыполняемыми оператора- и, поскольку никаких команд в программе они не порождают. Арифметическое выражение — это запись математиче- :ой формулы с использованием констант, переменных, функций, 1аков арифметических операций и круглых скобок. Знаки арифметических операций + сложение — вычитание * умножение / деление ** возведение в степень °бки в арифметических выражениях имеют обычный матема- смысл. При написании арифметических выражений следует соблю- iTb Правила:
24 ПРОГРАММИРОВАНИЕ НА ФОРТРА} 1. Два знака операции не могут стоять рядом. Однако, ес4 это необходимо, то они должны быть разделены скобками. Та: запись вида X/-Y неверна, а запись X/(-Y) верна. ) 2. Если в арифметическом выражении отсутствуют кругл *: скобки, то порядок выполнения операций будет следующим: вычисление функций; возведение в степень; умножение и деление; сложение и вычитание. Операции одного ранга выполняются последовательно слева н право, за исключением операции возведения в степень, котор; выполняется справо налево. . При написании арифметических выражений во избежаш ошибок, а также для удобства прочтения, целесообразно исполь зовать скобки. С помощью скобок можно устанавливать любо] порядок выполнения операций. Пример: X*Y/(X**2+7.5)+C0S(X) [ < В математической записи это выглядит как XY (X2 + 7.5) + cos(X). В приведенном примере происходит обращение к библиотечно функции Фортрана COS, полный список которых содержится разделе 1.10. При обращении к библиотечным функциям нео^> ходимо указать имя функции, а после имени в скобках — af гументы. При этом аргументы могут быть арифметические выражениями. : Величины разных типов в памяти компьютера кодируютсл по разному, и, следовательно, арифметические операции над ншл выполняются, вообще говоря, также по разному. Для целых величин определены все операции, однако резуль* тат не должен выходить из множества целых чисел. Поэтом?
д дАЛЬНЫЕ СВЕДЕНИЯ 25 >зультатом деления двух целых величин будет целая часть порченного частного. Например, если J=9, 1=4, то J/I=2. Любая чцественная величина может быть возведена в целую степень, перация возведения вещественных величин в вещественную сте- >нь вида А**В выполняется только в том случае, если А>0. Когда в арифметическом выражении все операнды (переменке и константы) одного типа, то величина, являющаяся резуль- iTou выполнения этого выражения, будет того же типа. Если е в арифметическом выражении присутствуют целые и веще- гвенные величины, то результат будет относиться к типу REAL. В любой Фортран-программе должен присутствовать, по эайней мере, один выполняемый оператор. Простейшим выполняемым оператором является арифме- ический оператор присваивания, который имеет следую- ,ий вид: V=A десь V — имя переменной, А — арифметическое выражение, равило выполнения: переменной с именем V присваивается эна- эние арифметического выражения А. Если переменная V — целая,а тип А — вещественный, то V ^Дет присвоено значение целой части результата А. Примеры: Y=(X**2+5.2)/(X+l) 1=1+1 А=7.5 Пусть во втором примере 1=3. Тогда после выполнения этого пеРатора получим 1=4. Важное замечание: все переменные, находящиеся справа от яака равенства в операторе присваивания, должны иметь кон- Ретные значения, которые задаются в предыдущей части про- Р^Ммы либо с помощью других операторов присваивания, либо ри эадании исходных данных с помощью операторов ввода. В любых программах, за исключением простейших, порядок °лнения операторов, как правило, изменяется в зависимости Каких-то условий.
26 ПРОГРАММИРОВАНИЕ НА ФОРТРА\ Условный арифметический оператор имеет следуюгц вид: IF(A) ni,n2,n3 Здесь А — арифметическое выражение целого или веществ^ ного типа, ni, п2, пз — метки операторов. Правило выпол* ния: если значение арифметического выражения меньше ну/. то следующим выполняется оператор с меткой ni, если значен выражения равно нулю, то выполняется оператор с меткой ? если значение выражения больше нуля, то выполняется операт^ с меткой пз- Две метки из трех могут совпадать. Примеры: ( IFU+Y-7.5)5,16,3 IF(I-N)2,2,1 Оператор безусловного перехода имеет вид GO ТО п Здесь п — метка оператора. Правило выполнения: следу ющ* выполняется оператор с меткой п. Пример: GO ТО 15 В каждой Фортран-программе должны присутствовать в ходные данные, которые в процессе ее исполнения преобразуют в искомые результаты. Исходные данные могут задаваться тексте программы с помощью операторов присваивания, напр мер М=28 GG=7.35 Однако более целесообразно задавать их с помощью специаЛ ных операторов ввода. Результаты выполнения программы U1 гут стать доступными только с помощью операторов вывода. Операторы ввода и вывода по своей структуре близки имеют следующий вид:
яАЧАЛЬНЫЕ СВЕДЕНИЯ 27 READ(n,m) <список переменных> WRITE(n,m) <список переменных> Здесь первый оператор — оператор ввода, второй оператор — оператор вывода; п — номер устройства ввода или вывода; m — метка оператора FORMAT, который определяет порядок расположения данных в строке при вводе или выводе; <список перемен- ных> — вводимые или выводимые переменные. В разделе 1.7. будут описаны операции ввода-вывода с использованием номеров устройств и операторов FORMAT. Ниже рассмотрим простейшую запись этих операторов, которая имеет следующий вид: READ(*,*) <список переменных> WRITE(*, *) <список переменных> В этом случае исходные данные вводятся в компьютер путем на- Зора их на экране дисплея, а результаты после выполнения программы также появляются на экране дисплея. Примеры: READ(*,*) N,A1,B01,C WRITE(*,*) Z,FX Последним оператором любой Фортран-программы должен эьггь оператор END к°торый объявляет, что больше операторов в тексте программы нет. Оператор STOP выполнение программы. Перед оператором END опе- °Р STOP может отсутствовать. Фортран-программа состоит из операторов, которые выполол последовательно, начинал с первого оператора. Порядок
28 ПРОГРАММИРОВАНИЕ НА ФОРТРАН^ выполнения операторов может изменяться условными операт^ рами, например условным арифметическим оператором, коте; рый описан выше. Текст программы начинается с оператора заголовка видя PROGRAM имя программы 4 например PROGRAM MAIN П D Оператор заголовка в программе может отсутствовать. Дале^ идут невыполняемые операторы, например операторы описание типа, затем выполняемые операторы, в том числе ввода-вывода реализующие алгоритм решения задачи, а заканчивается про грамма оператором END. С помощью введенных операторов могут быть написаны про граммы, которые реализуют самые разнообразные алгорит^ мы. Приведем пример простейшей программы вычисления сум мы двух действительных чисел X и Y PROGRAM SUM i READ(*,*)X,Y S=X+Y : WRITE(*,*)S J END < В приведенной программе отсутствуют операторы описан^ типа и, согласно описанию типа по умолчанию, переменные X, \ и S относятся к величинам вещественного типа. Пусть на ком пьютере сконфигурирована среда транслятора Fortran-Microsoft так как это описано в предыдущем разделе. Создадим в каком' либо каталоге файл с именем, HanpHMep^PROG.FOR, в который за пишем приведенный выше текст (обратить внимание, что оп^ раторы Фортрана записываются с 7-й позиции строки). Поел* этого (см. предыдущий раздел) создадим выполняемый фай-'1 PROG.EXE. Если при наборе текста были допущены ошибки, т^
1АЧАЛЬНЫЕ СВЕДЕНИЯ 29 айл PROG.EXE создан не будет, а ошибки будут указаны в ли- тинге программы, который находится в текстовом файле PROG. ST. ПросмотРев этот файл и удалив ошибки в файле PROG.FOR, еобходимо повторно запустить транслятор для создания выпол- яемого файла PROG.EXE. Далее при выделении этого файла и наитии клавиши | Enter | программа запускается на выполнение картинка The Norton Commander пропадает. Поскольку для ыполнения программы необходимо задать исходные данные, то рограмма находится в ожидании их ввода. Для этого необхо- имо на экране набрать значения, соответствующие X ц Y, между оторыми должно быть не менее одного пробела, и снова нажать лавишу Enter например 3.574 -9.57 1осле выполнения программы картинка The Norton Commander нова появится. Поскольку результат находится на экране дис- лея, то для того чтобы он был виден необходимо убрать кар- инку The Norton Commander. Для этого следует нажать клавши I Ctrl I |F1 | и I Ctrl J J F2 J . Повторное нажатие этих кла- ищ возвращает привычную картинку. Если используется транслятор Fortran-NDP, то процедура апуска программы следующая. Создадим в каком-либо ката- огефайл с именем PR0G.F, в который запишем текст программы расширение имени файла должно быть .F). После этого ( см. РеДыдущий раздел) создадим файл PR0G.LTL. Теперь, при выде- ении этого файла и нажатии клавиши | Enter | программа запус- ается на выполнение. Дальнейшие действия, связанные с вводом анных и просмотром результата, такие же, как при испольэо- ании транслятора Fortran-Microsoft. Рассмотрим еще один пример. Пусть задана функция f(x) х + 7.5, х < — 5 f(x) = { х2/Ю, -5 < х < О sin ж, х > О
30 ПРОГРАММИРОВАНИЕ НА ФОРТРАН Программа, которая для любого действительного значения X В] числяет соответствующее значение функции F имеет вид READ(*,*)X IF(X+5)1,2,2 1 F=X+7.5 GO TO 10 2 F(X)3,4,4 3 F=(X**2)/10 GO TO 10 4 F=SIN(X) 10 WRITE(*,*)F STOP END Процедура запуска этой программы на выполнение такая ж как для предыдущей программы. 1.5. ТИПЫ И СТРУКТУРА ДАННЫХ В предыдущем разделе были рассмотрены два основных тип данных — целые и вещественные. Полный набор типов даннЫ в Фортране следующий: • целый; • вещественный; • вещественный двойной точности; • комплексный; • комплексный двойной точности; • логический;
ТйПЫИ СТРУКТУРА ДАННЫХ 31 ф символьный. □ зычислительных задачах последний тип данных используется эедко. Вещественная константа двойной точности записывается в виде nDm Здесь п — мантисса, m — порядок. Буква D используется для гого, чтобы было отличие от вещественной константы. Примеры: -7.24D2(=-7.24-102) 0.1234567891234 D-11 (= 0.1234567891234 • 10"11) В памяти компьютера константа занимает 8 байт. Диапазон изменения порядка от - 63 до + 63, число значащих цифр в мантиссе не более 14. Комплексная константа записывается в виде упорядоченной пары вещественных констант, разделенных запятой и заключенных в круглые скобки, т.е. (Хг, Хг) ^Десь Хг — действительная часть комплексного числа, Xt- — мнимая. Примеры: (12.35,-1.129) (-3.94, 2.0Е-13) к°торые в обычной математической записи имеют вид 12.35 - 1.129i -3.94 +2.-10~13г п^Мяти компьютера комплексная константа занимает 8 байт п^Мяти. Комплексная константа двойной точности состоит из PbI ВеЩественных констант двойной точности. Пример:
32 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ (2.12D1,-3.12D-3) [ В памяти компьютера константа занимает 16 байт. i Логическая константа может принимать только два зна чения — "истина" и "ложь", которые по правилам Фортрана за писываются, как .TRUE. .FALSE. Точки в записи являются обязательными. В памяти компьютер, константа занимает 4 байта. Символьная константа является последовательностью лк бых символов Фортрана, заключенных в апострафы. Пример: 'CHARACTER CONSTANT' В памяти компьютера константа занимает п байт, где п — коли чество символов, включая пробелы. Тип всех переменных должен быть определен в программе i не может изменяться в процессе ее исполнения, а сами перемен ные представляются и хранятся в памяти компьютера также, ка! константы соответствующего типа. Описание типа по умолчанию (см. предыдущий раздел) пе рестает действовать, если тип переменных задать с помощь* операторов явного описания типа INTEGER <список переменных> REAL <список переменных> REAL*8 <список переменных> COMPLEX <список переменных> COMPLEX* 16 <список переменных> LOGICAL <список переменных> CHARACTER*n <список переменных> Перечисленные операторы указывают в порядке следован**' следующие типы переменных: целый, вещественный, веществен ный двойной точности, комплексный, комплексный двойной то1*
*г0Гт[И_СТРУКТУРЫ ДАННЫХ 33 Тй логический, символьный. Величина п в последнем опера- является целой положительной константой, которая опреде- т длину символьных переменных. Примеры: COMPLEX S11,ZF,C0M INTEGER P,F0RM LOGICAL LQ,LIC,RQM CHARACTER+6 TX1,TX2,LET REAL*8 FF,X0,X1 Отметим, что все переменные, за исключением целого и вещественного типов, обязательно должны быть описаны с помощью операторов описания, которые являются невыполняемыми операторами. Переменные любого типа можно задавать с помощью операторов неявного описания типа IMPLICIT <тип 1> (<список 1>), <тип 2> (<список 2>),... Здесь <тип 1>, <тип 2> — наименования типов данных, приведенных выше; <список 1>, <список 2> — буквы, используемые в качестве начальных букв имен переменных для определения типа. Например, оператор IMPLICIT REAL(I,J,K,L,M,N) приводит к тому, что все переменные программы будут иметь вещественный тип, даже, если они начинаются с одной из букв °т I до N. Последовательность идущих друг за другом в порядке ^фавита букв можно задать символом —. Поэтому оператор IMPLICIT REAL(I-N) бывает такое же действие, как и предыдущий оператор. Приведем еще один пример. Оператор IMPLICIT REAL*8(A-C),L0GICAL(L),COMPLEX(F,G,Q) '" Самохин
34 ПРОГРАММИРОВАНИЕ НА ФОРТР^ приводит к тому, что переменные с именами, начинающим^ с букв А, В, С, будут вещественными двойной точности; L логическими; F, G, Q — комплексными. Если в программе используется оператор IMPLICIT, то должен предшествовать всем другим невыполняемым опера^ рам. Операторы явного описания типа подавляют неявное on сание типа IMPLICIT. Рассмотрим операции, которые могут выполняться над * личиными разных типов. Для числовых данных, к которым относятся целые величии вещественные, вещественные двойной точности, комплексна комплексные двойной точности, определены все арифметически операции. Для операции возведения в степень существует и, ключение: для вещественных величин операция А**В выполз ется только в том случае, если А > 0. Для смешанных тиш данных определены операции сложения, вычитания, умножен! и деления. Операция возведения в степень определена только гп( гда, когда показатель степени — целая величина. Рекомендуете проявлять особое внимание при смешении числовых величин р& ных типов. Все числовые величины могут быть операндами арифмети ческих выражений (см. предыдущий раздел). Когда в арифме тическом выражении все операнды одного типа, величина, явл4 ющаяся результатом этого выражения, будет того же типа. Ко гда операнды имеют разный тип, то тип результата будет опре деляться типом операнда максимального ранга. Ранг операнд2 определяется списком INTEGER REAL REAL*8 COMPLEX COMPLEX*16 Например, результатом арифметического выражения с операН дами REAL и COMPLEX будет величина, относящаяся к тип) COMPLEX.
иПЬ1 ^СТРУКТУРА ДАННЫХ 35 Особый случай: результатом операции над величинами EAL*8 и COMPLEX будет величина COMPLEX* 16, а не COMPLEX. Пусть задан арифметический оператор присваивания (см. редыдущий раздел) V = А де V — имя переменной, А — арифметическое выражение. Если переменная V — целого типа, а тип А — вещественный, •о V будет присвоено значение целой части результата А, а при :омплексном типе А переменной V будет присвоено значение целой [асти от действительной части результата. Если переменная V — вещественная, а тип А — комплексный, то V будет присвоено значение действительной части результата. Другие соотношения типов V и А являются очевидными. Рассмотрим логический тип данных. Логические выражения состоят из отношений, логиче- :ких переменных, логических констант и логических операций. Отношение — это простейшее логическое выражение вида А#В Здесь А и В — арифметические выражения целого или вещественного типа, # — знак отношения. Табл. 1.5.1 Знаки отношений .LT. .LE. .EQ. .NE. .GE. .GT. меньше < меньше или равно < равно — не равно ф больше или равно > больше > ^Ки в записи знаков отношений обязательны. Значением отменил может быть либо "истина", т.е. .TRUE., либо "ложь",
36 ПРОГРАММИРОВАНИЕ НА ФОРТРА\ т.е. .FALSE. Если отношение справедливо, то результатом бу^, значение .TRUE., а если ложно, то .FALSE. Пример: X**2+5*X.GE.Y I В математической записи это выглядит как х2 + Ъх > у В приведенном примере, если х = 1,у = 2, то результатом от ношения будет .TRUE., если х = 2, у = 20, то результатом буде .FALSE. Табл. 1.5.2 Знак операции .AND. .OR. .NOT. .EQV. .NEQV. Запись L1.AND.L2 L1.0R.L2 .NOT.L L1.EQV.L2 LI.NEQV.L2 Результат Выражение истинно, когда L1 и L2 истинны, в других случаях оно ложно Выражение ложно, когда L1 и L2 ложны, в других случаях оно истинно Выражение истинно, когда L ложно, выражение ложно, когда L истинно Выражение истинно, когда L1 и L2 оба истинны или оба ложны, в других случаях оно ложно Выражение истинно, когда L1 и L2 имеют разные значения, в других случаях оно ложно
нпы Я СТРУКТУРА ДАННЫХ 37 Лз отношении, логических переменных и констант можно тавить логические выражения вида LI @ L2 @ L3... лесь L1,L2,... — логические элементы, т.е. отношения, логи- еские переменные и константы; @ — знак логической операции. Точки в записи знаков логических операций обязательны, [римеры: X.LT.Y.AND.Y.LT.Z (X**2+Y**2.LE.R**2).AND.(Y.GE.0) В первом примере логическое выражение истинно, если Y удовлетворяет условию X<Y<Z и ложно в противном случае. Во угором примере выражение истинно, если X2+Y2 <R2 и, одновременно, Y>0. При написании логических выражений следует соблюдать правила: 1. Два знака логических операций не могут стоять рядом, а если это необходимо, то они должны быть разделены скобками. Так, запись вида Ll.AND..N0T.L2 неверна, а запись L1.AND. (-N0T.L2) верна. 2. Если в логическом выражении отсутствуют круглые скоб- ки> то порядок выполнения операций идет в следующей последо- в^тельности: отношения •NOT. • AND. • OR. •EQV., .NEQV. ПеРации одного ранга выполняются последовательно слева на- пРав0. При написании логических выражений во избежание оши- *» а также для удобства прочтения, целесообразно использо- Вать скобки.
38 ПРОГРАММИРОВАНИЕ НА ФОРТР^ S Логический оператор присваивания имеет следую^ вид: у V = L i ( Здесь V — имя логической переменной, L — логическое выра)} ние. Правило выполнения: логической переменной с именем присваивается значение выражения L. Примеры: ZL=X.LT.(Y+1.5) FQR=L1.0R.(Z.EQ.P) LC=.TRUE. Отметим, что все логические переменные, используемые программе, должны быть описаны с помощью операторов явно! описания типа L0GIAL или операторов неявного описания. Теперь рассмотрим символьный тип данных. Символьные выражения могут быть составлены из сю вольных констант и переменных с помощью только одной опер* ции конкатенации // (объединения), которая соединяет сю вольные величины в одну. Примеры: 'JAMES'//' SCOTT1 S1//S2//S3 В первом примере появится символьная константа МАМЕ SCOTT*. Если во втором примере символьные переменные SI, S2 S3 равны, соответственно, 'FORTRAN-', 'ALGORITHMIC' ' LANGUAGE', в результате операции обьединения появится сиМ вольная величина 'FORTRAN-ALGORITHMIC LANGUAGE'. Символьный оператор присваивания имеет вид: V = S Здесь V — имя символьной переменной, S — символьное выр^ жение. Правило выполнения: символьной переменной с именем * присваивается значение выражения S.
ЩПЫ И СТРУКТУРА ДАННЫХ 39 Бели длина символьного выражения не соответствует объ- ленной длине символьной переменной, то оно будет либо до- лнено пробелами справа, либо усечено справа в зависимости длины переменной. Пример: CHARACTER*11 NAME,TEXT NAME='JAMES'//' SCOTT' TEXT='FORTRAN-' //'ALGORITMIC 'II' LANGUAGE' В результате переменная NAME будет равна 'JAMES SCOTT', т.е. изменений не будет, переменная TEXT будет равна 'FORTRAN -ALG', т.е. выражение будет усечено справа. Выше рассматривались только простые переменные. Однако для решения многих задач необходимо использовать переменные с индексами. Массивом называется совокупность переменных одного типа, обозначаемая именем с индексами в круглых скобках. Например, вектор с компонентами щ, щ,..., и^ можно представить одномерным массивом U(I), 1<1<Н & матрицу с компонентами А{3 — двумерным массивом A(I,J), 1<I<N, 1<J<M Количество индексов в массиве определяет его размерность и м&ссивы могут быть, соответственно, одномерными, двухмер- нЬ1ми, трехмерными и т.д. Число индексов не может быть более семи. Массивы могут тНосится к любому из типов данных и описываются на основе Их имени. Каждый массив должен быть обьявлен в начале программы Яомощью невыполняемого оператора размерности вида DIMENSION <имя> (ki : Ц, к2 : 12,...)
40 ПРОГРАММИРОВАНИЕ НА ФОРТР^ Здесь <имя> — имя массива, ki и Ц — начальное и конечц значения первого индекса, кг и Ь — начальное и конечное эц чения второго индекса и т.д. Шаг индекса принимается равн^ единице. Величины кх, Ц, кг, Ь- • .должны быть целыми конст^, тами, причем ki <11} кг <h>- • В каждом операторе размерное-] можно объявить как один, так и несколько массивов. Пример* DIMENSION А(-3:5,0:20,1:10),В(2:40) DIMENSION С(1:100) - Здесь массив А — трехмерный, массивы В и С — одноме^ ные. Первый индекс массива А может принимать значения -За 2,-1,0,1,2,3,4,5, второй индекс изменяется от 0 до 20, третий и^ деке изменяется от 1 до 10. В массиве В единственный индек изменяется от 2 до 40, а в массиве С — от 1 до 100. t Если начальное значение индекса равно единице, то оно мо* жет быть опущено. Поэтому вышеприведенное объявление масс сивов эквивалентно следующему: DIMENSION А(-3:5,0:20,10),В(2:40) DIMENSION С(ЮО) Объявление массива может быть совмещено с описанием тип; Поэтому запись REAL KIM,XF INTEGER FR DIMENSION KLM(15,15),FR(2:100),XF(0:10) эквивалентна записи INTEGER FR(2:100) REAL KLM(15,15),XF(0:10) Однако следует подчеркнуть, что объявление массива, также как и описание типа переменной, может быть произведено я программе только один раз. Отметим, что объявление массива с помощью констант необходимо для того, чтобы зарезервировать соответствующий объеМ
ияьг Я СТРУКТУРА ДАННЫХ 41 тй Для хранения элементов массива. Массив размещается ледовательно расположенных ячейках памяти. Если массив омерный, то его элементы хранятся в памяти друг за другом, Пример, А(1),А(2),А(3),А(4),... Бели массив двумерный, например DIMENSION В(-1:2,3) о его элементы хранятся в памяти в таком порядке В(-1,1), (0,1), В(1,1), В(2,1), В(-1,2), В(0,2), В(1,2), В(2,2), (-1,3), В(0,3), В(1,3), В(2,3). Тот же принцип размещена сохраняется и для массивов большей размерности: быстрее ;сего изменяется первый индекс, затем второй и т.д. При обращении к элементу массива необходимо указать его [мя, а в круглых скобках через запятую — индексы, которые логут быть целыми арифметическими выражениями. Например, шератор S=A(2*K+8,3*L**2,7) присваивает переменной S значение элемента массива А. Если K=1,L=2, то первый индекс равен 10, второй 12, а третий 7. Для удобства использования, константам любого типа можно присвоить символические имена, соответствующие типу констант, с помощью оператора PARAMETER вида PARAMETER (<имя> — <константа>, <имя> = <константа>,...) Десь <константа> — любое постоянное выражение, содержащее константы и имена параметров, которые были объявлены ра*ее. Пример: COMPLEX IM PARAMETER (PI=3.14159265,IM=(0.О,1.0)) Оператор PARAMETER часто используется при объявлении мас- в°в- Так, объявление DIMENSION А1(100,200),А2(100,200),В(200,100)
42 ПРОГРАММИРОВАНИЕ НА ФОРТРАЦ эквивалентно объявлению PARAMETER (N1=100,N2=2*N1) DIMENSION A1(N1,N2),A2(N1,N2),B(N2,N1) I Последняя запись удобна тем, что при изменении величины гр^ ницы индексов необходимо изменить только соответствующе значения констант в операторе PARAMETER. Переменным программы можно присвоить начальные значе! ния с помощью оператора DATA вида « DATA <список> / <значения> /, <список> / <значения> /,... Здесь <список> — список переменных или имен массивов, <значения> — соответствующие значения, которые присваивав ются переменным. Пример: i DATA X,Y(l,l),K/-2.5,0.75,7/ ' Тогда переменной X будет присвоено значение -2.5, элементу массива Y(l,l) — значение 0.75, а переменной К — значение 7. В операторе DATA можно использовать указатель повторения, который состоит из целой константы и символа * и предшествует значению данных. Например, в фрагменте COMPLEX С DATA I,J,К,0/3*2,(1.5,2,5)/ целым переменным I,J,K присваивается значение 2, а комплексной переменной С — значение 1.5+2.5L С помощью оператора DATA можно присвоить начальные значения всем элементам массива. Например, во фрагменте программы DIMENSION А(20),В(10) DATA A,B,JK/20*1.5,10*(-3.5),18/ всем элементам массива А присваивается значение 1.5, всем элементам массива В — значение -3.5, а переменной JK — значение 18.
пЕТВЛЯЮЩИЕСЯ ПРОЦЕССЫ 43 б РАЗВЕТВЛЯЮЩИЕСЯ И ЦИКЛИЧЕСКИЕ [Р0ЦЕССЫ Разветвляющиеся и циклические участки присутствуют ктически во всех алгоритмах, за исключением простейших, иже опишем операторы Фортрана, с помощью которых можно существить их программирование. Условный логический оператор имеет вид IF(L) S 1десь L — логическое выражение, S — любой исполняемый опера- ор. Правило выполнения: если логическое выражение L истинно, о выполняется оператор S, если оно ложно, то выполняется сле- ующий за IF оператор, a S не выполняется. Примеры: IF(I.LE.N) GOTO 10 IF(X**2+Y**2.LE.R**2) A=I В первом случае, если L<N, то происходит переход к опера- °РУ с меткой 10, в противном случае выполняется следующий ператор. Во втором случае, если X2+Y2 <R2, то переменной А Рисваивается значение I. Рассмотренный оператор обладает существенным ограниче- ием, которое состоит в том, что за логической инструкцией IF ЯеДУет только один оператор. Следующий оператор является обобщением предыдущего. Расширенный оператор IF имеет вид IF(L) THEN SI S2 END IF
44 ПРОГРАММИРОВАНИЕ НА ФОРТР^ Здесь L — логическое выражение, S1,S2,...— исполняемые сц раторы, которых может быть любое количество. Правило выгц нения: если логическое выражение L — истинно, то выполняю^ операторы SI, S2,..., если оно ложно, то выполняется следую^ после END IF оператор. Пример: IF(L) THEN F=SIN(X) F1=X**2+5*X END IF Если L — истинно, то переменной F присваивается значещ SIN(X) и переменной F1 — значение Х2+5Х, если L — ложно, ъ выполняется оператор после END IF. Блочный оператор IF (оператор IF THEN ELSE) имеет ви IF(L) THEN <операторы 1> ELSE <операторы 2> END IF Правило выполнения: если логическое выражение L истинно, тс выполняются <операторы 1>, а если оно ложно, то выполняются <операторы 2>. В качестве примера рассмотрим задачу вычисления недель- ной зарплаты, обозначаемой переменной PAY. Пусть оплата часа работы при общей рабочей неделе, не превышающей 40 ч., за- дается переменной RATE. Если рабочая неделя превышает 40 ч., то каждый сверхурочный час оплачивается в полуторном раз- мере. Тогда, задавая время работы в неделю TIME и значение RATE, можно записать следующую программу: READ(*,*)RATE,TIME
изВЕТВЛЯЮЩИЕСЯ ПРОЦЕССЫ 45 IF(TIME.GT.40)THEN тТ=:Т1МЕ-40.0 PAY=40*RATE pAy=PAY+1.5*RATE*TT ELSE PAY=RATE*TIME END IF WRITE(*,*)PAY STOP END Более сложные логические конструкции могут быть реализованы с помощью структурного оператора IF (оператор IF THEN ELSE IF), который имеет вид IF(L1) THEN <операторы 1> ELSE IF(L2) THEN <операторы 2> ELSE <операторы 3> END IF гДе Ll и L2 — логические выражения. Правило выполнения: сли логическое выражение L1 истинно, то выполняются <опе- ра/ГоРЫ 1>; если выражение L1 ложно, a L2 истинно, то выполня- Тсл <операторы 2>; если выражение L1 ложно и L2 ложно, то Вьшолняются <операторы 3>. В качестве примера рассмотрим .. рамму вычисления функции /(х), заданной в конце раздела READ(*,*)x lF(X.LT.-5) THEN FaX+7.5
46 ПРОГРАММИРОВАНИЕ НА ФОРТР^ ELSE IF(X.LT.0) THEN F=X**2/10 : ELSE , F=SIN(X) END IF : WRITE(*,*)F STOP c END ! Очевидно, что данная программа является логически более Л( ной, нежели программа, помещенная в конце раздела 1.4. Между инструкциями ELSE IF THEN и ELSE может распола гаться любое количество других инструкций ELSE IF THEN. 0,d нако при этом может существенно усложниться логическая ков струкция и программисту необходимо проявлять особое внима ние при использовании подобных вложенных разветвлений. Операторы цикла предназначены для многократного вы полнения операторов (тело цикла), находящихся между заголов ком оператора DO и оператором CONTINUE с меткой или операто ром END DO. Оператор CONTINUE не порождает каких-либо команд и ис( пользуется для завершения оператора цикла или для ссылок i программе. Оператор цикла DO имеет вид DO n i=ml,m2,m3 <операторы> n CONTINUE Здесь п — метка последнего оператора тела цикла (оператора CONTINUE); i — переменная целого, вещественного или веществен- ного двойной точности типа, которая называется параметром цикла; ml, m2, m3 — константы, переменные или арифметические выражения целого, вещественного или вещественного двойной точности типов. После метки п в заголовке цикла может
ЯВЛЯЮЩИЕСЯ ПРОЦЕССЫ 47 ь необязательная запятая. Величина ml определяет началь- ачение параметра цикла, т2 — конечное значение, а тЗ — аг или приращение. Правило выполнения: Оператор DO автоматически исполняет операторы до оператора CONTINUE с меткой п для значений от ml Д° щ2 с шагом т3- Таким образом, вначале параметр i танавливается равным ml и с этим значением выполняются все 1ераторы тела цикла; затем i изменяется до величины ml+тЗ и этим значением также выполняются все операторы тела цикла, тот процесс продолжается до тех пор, пока параметр цикла не ерейдет границу значения т2, т.е. при положительном шаге тЗ икл повторяется при всех значениях i<m2, а при отрицатель- ом шаге тЗ цикл повторяется при всех значениях i>m2. Если в аписи цикла значение шагатЗ отсутствует, то оно принимается авным единице. После окончания цикла выполняется оператор, ледующий за оператором CONTINUE. Примеры заголовка цикла: DO 10 1=1, N-1 DO 5, A=K,X*Y+5,H При записи заголовка цикла необходимо следить за тем, что- >ы шаг не оказался равным нулю. Рассмотрим пример использования оператора цикла, иусть задана функция f(x) в виде ряда по степеням х г, ч х2 X3 XN f(x) = х Н 1 1 1 , № N ~ параметр. Программа, которая для любых X и N вычи- Яет соответствующее значение функции F, может иметь следу- Юц*ий вид: READ(*,*) X,N DO 5 1=1,N Б FaF+(X**I)/I C°NTINUE
48 ПРОГРАММИРОВАНИЕ НА ФОРТР^ WRITE (*,*)F STOP END В качестве оператора, завершающего тело цикла, можно ц, пользовать оператор END DO. В этом случае в заголовке цикл не указывается метка, а вместо оператора CONTINUE записыв; ется END DO. Последняя программа для этой формы записи цикл имеет вид DO 1=1,N END DO Здесь указаны только отличия от вышеприведенной записи. Оператор цикла DO WHILE имеет вид DO n WHILE(L) <операторы> n CONTINUE Здесь п — метка последнего оператора тела цикла (оператора CONTINUE); L — логическое выражение. После метки п в заголовке цикла может стоять необязательная запятая. Правило выполнения: Вычисляется логическое выражение I- Если оно принимает значение .TRUE., то выполняются все операторы тела цикла до оператора CONTINUE с меткой п. Этот процесс продолжается до тех пор, пока логическое выражение не примеГ значение .FALSE. Тогда ни один оператор тела цикла не исполняется и выполняется оператор следующий за CONTINUE. Примеры заголовка цикла
АЗрКТВЛЯЮЩИЕСЯ ПРОЦЕССЫ 49 DO 25 WHILE(X**2+Y**2.LE.R**2) DO Ю WHILE(Y.GE.A.OR.X.GE.B) рассмотрим пример использования оператора DO WHILE. Пусть задана функция f(x) в виде ряда по степеням х /м = 1-.+£-£+-(-и''£+- Суммирование членов ряда в программе будем производить до тех пор, пока модуль члена ряда не станет меньше заданной величины Е. Программа, реализующая данный алгоритм, может иметь следующий вид: READ(*,*)X,E F=1.0 А=-Х 1=1 DO 10 WHILE(ABS(A/I).GE.E) F=F+A/I 1=1+1 A=-X*A Ю CONTINUE WRITE(*,*)F STOP END Приведенной программе присутствует обращение к библиотеч- ФУнкции Фортрана ABS , которая вычисляет абсолютное зна- Ие вещественной величины. ° качестве оператора, завершающего тело цикла, можно так- сПользовать оператор END DO. В этом случае в заголовке ци- Не указывается метка, а вместо оператора CONTINUE запи- ц етсл END DO. Последняя программа для этой формы записи vJIa будет иметь вид
50 ПРОГРАММИРОВАНИЕ НА ФОРТРАИг DO WHILE(ABS(A/I).GE.E) END DO Здесь указаны только отличия от вышеприведенной записи. При использовании операторов цикла необходимо придержи^ ваться следующих правил: • Если оператор цикла указан внутри другого DO-цикла, его тело должно полностью содержаться внутри тела внешнего DO-цикла. • Если оператор DO указан внутри блока оператора IF, то тело цикла должно полностью содержаться внутри этого блока. • Если оператор IF указан внутри цикла, то связанный с ним оператор END IF должен находиться внутри тела цикла. • Переход в тело DO-цикла извне цикла не разрешен. • Два или более циклов DO или DO WHILE могут заканчиваться одним оператором CONTINUE. Однако оператор END DO может быть концом только одного цикла. • При выходе из цикла сохраняется текущее значение параметра цикла i для DO - цикла или значение логического выражения L для DO WHILE цикла. Приведем фрагмент прграммы с вложенными циклами на примере суммирования элементов прямоугольной матрицы A(I,J), 1=1,..,N; J=1,..,M; N,M<20. DIMENSION A(20,20)
звоД ^ВЫВОД ДАННЫХ 51 5=0.0 DO 5 1=1,N Dg 5 J=1,M S=S+A(I,J) CONTINUE В объявлении DIMENSION указаны предельные значения размеров матрицы, а конкретные значения N и М должны быть заданы при вводе исходных данных. 1.7. ВВОД-ВЫВОД ДАННЫХ Операторы ввода и вывода по своей структуре близки и имеют следующий вид: READ(n,m) <список переменных> WRITE(n,m) <список переменных> Здесь READ — оператор ввода, WRITE — оператор вывода, п — номер канала ввода или вывода, m — метка оператора FORMAT, который определяет порядок расположения данных в строке при вводе или выводе; <список переменных> — вводимые или выводимые переменные. В разделе 1.4 была описана простейшая система бесформат- Го ввода с клавиатуры и вывода на экран. Для этого в опера- Рах READ или WRITE вместо номера устройства ввода-вывода и ки оператора FORMAT располагаются символы "*" (звездочка). ъ впишем процедуру организации ввода-вывода с помощью л°в, которая очень удобна в использовании на ПК. В этом слу- файл, с которого будет осуществляться ввод-вывод, ^ н° связать с номером канала ввода-вывода. Для этого ис- У^тся оператор открытия файла вида 0PEN(n,FILE=' <имя файла>')
52 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ где п — номер канала, которым может быть целое числ0 п<32767 для транслятора Fortran-Microsoft и п<99 для транац тора NDP-Fortran, а имя файла подчиняется правилам, описац, ным в разделе 1.1. Примеры: Г 0PEN(10, FILE =' DANN.DAT') \ READ(10, *)X,Y,M 0PEN(15, FILE =' REZULT.DAT') WRITE(15,*)B0,C,K,DF В первом примере открывается канал ввода с номером 10, которым является файл DANN.DAT. Поскольку в операторе READ вместо метки оператора FORMAT указан символ "*", то осуществляется бесформатный ввод. Это означает, что в файле DANN.DAT в той же последовательности, что и в списке переменных должны быть записаны значения X,Y,M, между которыми должно стоять не менее одного пробела, например -7.35 0.5Е- 1189 Во втором примере открывается канал вывода с номером 15, ко торым является файл REZULT.DAT. Поскольку вывод также бесформатный, то значения переменных будут записаны в файл че- рез пробел в той же последовательности, что и в списке переменных. Файл может быть отсоединен от канала ввода-вывода с помощью оператора закрытия файла, который имеет вид CLOSE(п) где п — номер канала. Одновременно с закрытием канала фай^1 может быть удален, если использовать оператор CLOSE(n,STATUS*'DELETE') После закрытия канала его номер становится свободным и мож^ быть использован при открытии нового канала с другим файлов
ирП^ВЫВОД ДАННЫХ 53 g фортран-программе может быть любое количество ка- в вВода-вывода, которые могут открываться операторами EN в любой части программы. Файлы, связанные с каналами 0да-вывода, должны находится в том же каталоге, где пометен запускаемый файл Фортран-программы. Если файла с соответствующим именем в каталоге нет, то оператор OPEN создает пустой файл с этим именем. Ясно, что такой возможностью можно пользоваться только для каналов вывода. Если файл, предназначенный для канала вывода, не пустой, то перед записью выводимых данных его содержимое будет уничтожено. Исключение составляет случай, когда тот же канал был ранее использован для ввода исходных данных. Иногда бывает удобно не связывать номер канала ввода- вывода с именем конкретного файла, т.е. номер канала п присутствует в операторе READ или WRITE, но он не открыт оператором OPEN. Тогда в процессе выполнения программы с помощью транслятора Fortran-Microsoft на экране появляется сообщение file name missing or blank-please enter file name UNIT n? После этого вопроса на клавиатуре нужно набрать имя файла, которое вы хотите связать с номером п канала ввода-вывода, например REZ.TXT, и тогда программа продолжит свое выполне- НИе> а данные будут считаны с файла REZ.TXT или записаны в ЭТот файл. При использовании транслятора Fortran-NDP можно е открывать канал в операторе OPEN только для вывода данных. этом случае данные будут записаны в автоматически открытый файл с именем FORT.n, где в качестве расширения имени Пользуется номер канала, присутствующий в операторе WRITE. Для вывода данных на принтер можно использовать два спо- После выполнения программы распечатать файл с результа- и с помощью средств печати файлов, например в текстовом ^Кторе ЛЕКСИКОН; Указать номер канала вывода в операторе WRITE, который п с принтером.
54 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ Теперь перейдем к описанию оператора FORMAT, обеспечу вающего форматный ввод-вывод. В этом случае программист в явном виде указывает местоположение и форму вводимых илц" выводимых переменных в записи (строке). Общий вид оператор^ m FORMAT(S) ' где m — обязательная метка оператора, S — список спецификаций' формата, разделенных запятыми. Для каждого типа данных существует своя спецификация:1 для целых величин — спецификация I, для вещественных величин — F или Е, для вещественных величин двойной точности — D, для логических величин — L, для комплексных величин — две спецификации вещественных величин, для символьных величин — спецификация А. Общая форма спецификации I 1и где и — беззнаковая целая константа, показывающая число символов (длину поля), отводимых для ввода или вывода целых величин. Например, в спецификации 15 целые величины -5712 и 359 будут представлены -5712 U U359 в спецификации 14 первая величина не может быть представлена- вторая же будет иметь вид U359 Поэтому при задании спецификации I необходимо учитывать примерный порядок вводимых или выводимых величин. Здесь и ниже символ U означает пробел. Если число меньше длины поля а;, то при вводе и вывод6 левад часть поля заполняется пробелами. Если при вводе числ^
г^ВЫВОД ДАННЫХ 55 /эрт больше и символов, ,аНцМа „ мВолов. Например, запись то считываются только и левых -1352764 спецификации 15 будет считана как —1352. Если при выводе исло занимает больше и символов, то в отводимом для записи дола поле будут напечатаны звездочки *. Заметим,что с помощью спецификации 111 можно ввести или зывести любую целую величину, поскольку диапазон изменения целых чисел от -2147483648 до 2147483647. Общая форма спецификации F где и — общая длина поля, включая знак числа и десятичную точку, d — число цифр после десятичной точки. Спецификация F предназначена для вещественных чисел без показателя степени. Во всех случаях и > d для положительных чисел и и > d + 1 для отрицательных. Например, в спецификации F7.3 числа -72.591 и 24.52 будут представлены -72.591 U 24.52U ^сли при выводе целая часть числа занимает больше и - (d + 1) символов, то в отводимом для записи числа поле будут напечатаны звездочки *. Дробная часть числа при выводе будет округ- ена До d десятичных цифр. Вещественные числа с порядком представляются с помощью СПеВДфикации Е, которая имеет вид Eu;.d гДе to _ - , То общая длина поля, d — число цифр после десятичной 11 в мантиссе. обу еличины и и d связаны соотношением и > d + 6, которое ной °Влено необходимостью записи в поле знака числа, десятич- При 0Х1ки мантиссы, символа Е, порядка числа и его знака. На- *Ме^ в спецификации Е11.4 числа -0.256-КГ11 и 2.3-102 будут
56 ПРОГРАММИРОВАНИЕ НА ФОРТРАЩ представлены -0.2567Е - 11 U 2.3000Е U U2 В спецификации Е могут быть записаны любые вещественные чц. ела, поэтому эту спецификацию целесообразно использовать пр$ выводе, когда не известен порядок величины. При выводе веще ственное число округляется до значения, которое определяете;, числом значащих цифр в мантиссе при заданной спецификации, Спецификация вещественных величин двойной точности имеет вид Dcj.d где и — общая длина поля, d — число цифр после десятичной точки в мантиссе. Эта спецификация аналогична спецификацш Е и к ней применимы те же правила с учетом того, что символ I определяет показатель степени. Например, числа -2.356789012 • 10"24 и 1.345 • 102 в спецификации D 16.9 будут представлены в виде -2.356789012D - 24 U 0.134500000D U U2 Комплексные величины состоят из двух вещественных чисел первое из которых является действительной, а второе — мнимоИ частью. Эти числа представляются двумя последовательным^ спецификациями F, Е или D, которые могут быть различны д^ каждой части. Спецификация логических величин имеет вид Lu где и — длина поля. При вводе логических величин поле просматривается сле^ направо и если первым встречается символ Т или F, то перемер ной присваивается значение .TRUE, или .FALSE, соответствен*^
вв0^ШОДДАШЫХ 57 й же эти символы не присутствуют в поле, то переменной при- ивается значение .FALSE. При выводе символы Т или F распоются в крайней правой позиции поля, а остальная часть поля полняется пробелами. Например, в спецификации L4 логиче- ие значения .TRUE, и .FALSE, будут представлены при выводе как UUUT UUUF Спецификация символьных величин имеет вид ки где и — длина поля. Если длина поля не задана, т.е. записывается только А, то она будет автоматически равна длине вводимой или выводимой величины. Если длина символьной величины меньше длины поля и) то при вводе и выводе левая часть заполняется пробелами. Если длина символьной величины больше длины поля о;, то будут считываться и записываться только и левых символов. Отметим, что спецификации должны соответствовать типу вводимых или выводимых данных. Для создания ш пробелов между вводимыми или выводимыми величинами, используется спецификация апример, спецификация пробелов ЗХ обеспечит пропуск 3 пози- при вводе или выводе. Для записи текста между выводимыми данными использу- л спецификация комментариев, имеющая вид 'TEXT' п, ^Т — текст, состоящий из любых символов Фортрана и РУсс*их букв. Дан Пишем характер взаимодействия вводимых или выводимых СГ1 х из списка переменных в операторах READ или WRITE со иФикациями оператора FORMAT. Пусть
58 ПРОГРАММИРОВАНИЕ НА ФОРТР^ Pi,...,P* список переменных в операторе ввода или вывода, а Si, • • .,S/ список спецификаций в соответствующем операторе FORMAT, k торый связан с одной записью (строкой). Число символов в стр0 однозначно определяется списком спецификаций и, как прав^ не должно превышать 80. Каждой спецификации в порядке слева направо отводит соответствующее поле в строке. При этом спецификации пр белов при вводе-выводе и спецификации текста при выводе пр сутствуют в соответствующих местах строки без каких-либо i менений. Спецификации данных из списка Si,...,S/ в порядке еле направо ставятся в соответствие переменным Pi,..., Р*, котор согласно этим спецификациям представляются в строке. Еа список переменных меньше, чем количество спецификаций да ных, то последующие спецификации игнорируются. Если спис( переменных больше, чем количество спецификаций данных,' ввод-вывод осуществляется на первой строке до конца спис! спецификаций, а последующие переменные вводятся или выв дятся с новой строки вместе с переходом в начало списка cnefl фикаций и т.д. до конца списка переменных. Если одна спецификация или группа спецификаций повтор ется N раз подряд в операторе FORMAT, то можно использовать # эффициент повторения, который ставится перед специфика!^ или группой спецификаций, заключенных в скобки. Поэтому3 пись m F0RMAT(..., S,..., S,...) Npa3 эквивалентна записи mFORMAT(...,NS,...)
j-ВЫВОД ДАННЫХ 59 а запись m FORMAT(...,Sb ... ,Sn,.. .,Sb ..., Sn,...) Npa3 эквивалентна записи mFORMAT(...,N(Sb...,Sn),...) Рассмотрим примеры использования спецификаций. Пусть заданы операторы ввода OPEN (^FILE^ DAT. TXT') READ(1,5)A,X,M 5 F0RMAT(2F5.2,I3) В этом случае необходимо в файл DAT. TXT с помощью любого текстового редактора записать значения переменных А,Х,М, из которых первые две — переменные вещественного типа, а третья — переменная целого типа. Пусть А = 1.45, X = —0.56, М = 45. Тогда в первой строке файла, начиная с крайней левой позиции, нужно записать U1.45-0.56U45 Рассмотрим операторы вывода OPEN^FII^'REZ.DAT') WRITE(5,5)GX,K,P 5 FQRMAT(2X,,GX-,,F4.1,1X,'K=\I4,1X,,P=,,F5.2) огДа для переменных со значениями, например, GX = -7.4, К = 2Q d ' 359.6 будем иметь на строке файла REZ.DAT запись U U GX = -7.4 UK=UU29UP=***** Данном случае переменная Р не могла быть размещена в поле фикации F5.2 и были напечатаны символы *. - ^Усть в результате выполнения программы для аргументов , ^ 1.5 и Х2 = 3.0 были найдены соответствующие значения р^н*Ции F1 = 0.5632945 • 10"2, F2 = -0.1429123 • 10"14. Тогда ь,гаты можно вывести с помощью операторов вывода
60 ПРОГРАММИРОВАНИЕ НА ФОРТРАЦ OPENC^FILE^REZULT.DAT') WRITE(15,10)X1,F1,X2,F2 10 F0RMAT(2X,,X=,,F3.1,1X,,F=,,E10.3) При этом в файле REZULT.DAT будут следующие две строки: U U X = 1.5 U F = U0.563E U -2 U U X = 3.0 U F = -0.143Е - 14 При использовании бесформатного вывода также допустим* комментарии, которые заключаются в апострофы и выводято без изменения. Примеры: WRITE(*,*),A=,,A,,B=,,B WRITEС*,*)'ЗАДАТЬ ЗНАЧЕНИЕ М' READ(*,*)M В первом примере на экране появится текст А= , затем числова значение А, потом текст В= и числовое значение В. Во второй примере на экране появится текст ЗАДАТЬ ЗНАЧЕНИЕ И после чего на клавиатуре нужно набрать число, соответствующе М. Рассмотрим пример ввода комплексных величин. Пусть CIs 2.5 - г3.97, С2 = -0.345+ г4.5. Тогда при использовании операто ров ввода COMPLEX С1.С2 OPEN(1.FILEs1DAN.DAT') READ(1,2) C1.C2 2 FORMAT (4F6.3) необходимо, чтобы файл DAN.DAT имел вид U2.5 U U - 3.97 U -0.345 U 4.5 U U При использовании бесформатного ввода или вывода, к^1 плексные величины записываются в том же виде, что и компле#£ ные константы. Для рассмотренного выше примера, при опер* торах ввода
bboJ: .вывод ДАННЫХ 61 файл COMPLEX С1,С2 OPEN(1,FILE='DAN.DAT) READ(1,*) C1,C2 DAN. DAT будет иметь вид (2.5,-3.97) U (-0.345,4.5) Если использовать бесформатный ввод с клавиатуры, то операторы могут иметь вид COMPLEX С1,С2 WRITEC*,*) 'С1=?,С2=?> READ(*,*) С1,С2 В этом случае после появления на экране текста С1=?, С2=? необходимо набрать (2.5,3.97) (-0.345,4.5) и нажать клавишу | Enter При форматном выводе на экран или принтер, первый символ не печатается, а интерпретируется как символ управления кареткой. Действия, выполняемые при записи символов пробел, ' 1) +, указаны в таблице 1.7.1. Любой другой символ воспринимается как символ пробела. Символ Пробел ^0_ 1 L+^ Табл. 1.7.1 Действие Переход на следующую строчку Переход через две строчки Переход в начало следующей страницы Передвижения не происходит оп ^и выводе на экран символ "1" не действует. Следующие сц T°Pbi FORMAT соответствуют перечисленным управляющим в°лам
62 ПРОГРАММИРОВАНИЕ НА ФОРТРц m F0RMAT(1X,S) m FORMAT('0\S) m F0RMAT(,1,,S) m FORMAT(, + \S) где S — список спецификаций, m — метка оператора FORMAT. Пр бесформатном выводе управляющие символы не используются, переход на новую строку осуществляется транслятором автом< тически. Теперь рассмотрим процедуру ввода-вывода массивов. Дл этого используются два основных способа — ввод-вывод массив по имени или с помощью неявного цикла. Первый способ иллюстрируется примером DIMENSION А(10),В(3,4) READ(*,*)A,B В этом случае с клавиатуры должны быть последовательно вв( дены 10 чисел, которые соответствуют элементам массива А, з< тем введены 12 чисел, которые соответствуют элементам Ш сива В, согласно их последовательности расположени в памя^ (см. раздел 1.5.). Второй способ также ясен из примера DIMENSION А(10),В(3,4) READ(*,*)N,L,M,(A(I),I=1,N),((B(I,J),J=1,L)I=1,M) В этом случае числа N,L,M подчиняются ограничениям N<10, L^ М<3, поскольку в противном случае мы выйдем за границы рг' положения элементов массивов. Этот способ удобнее, когда программе используется меньшее количество элементов мас^ вов, нежели то, которое задано в операторах размерности, этом примере сначала вводятся три целых числа N,L,M, затем ^ следовательно N элементов массива А, и далее L*M элементов ^ сива В в последовательности В(1,1),В(1,2),...,В(2,1),В(2,2),...
врП1П№ВОЛ ДАННЫХ 63 b последовательность ввода элементов В не совпадает с по- якоМ их хранения в памяти. Если последний оператор записать как READ(*,*)N,L,M,(A(I),I=1,N),((B(I,J),I=1,M),>1,L) порядок ввода элементов массива В и порядок их размещения в памяти будет одинаковым. Рассмотрим пример форматного ввода одномерного целочисленного массива А с числом элементов не более 100 INTEGER А(100) OPEN (3,FILE=) DAN. DAT) READ(3,1)K READ(3,5)(A(I),I=1,K) 1 F0RMAT(I3) 5 FORMAT(4(12,IX)) Пусть значение K=9, (К не может превышать 100), а элементы массива следующие: А(1)=10, А(2)=24, А(3)=5, А(4)=7, А(5)=2, А(6)=29, А(7)=0, А(8)=44, А(9)=15. Тогда, для правильного ввода массива, файл DAN. DAT должен состоять из строк UU9 10U24UU5UU7 U2 U 29 U U0 U 44 15 Если использовать бесформатный ввод с клавиатуры, то фраг- €нт программы может быть следующий: INTEGER А(100) WRITE^,*)'^?' READ(*,*)K DO 1=1,К WRITE^^'ACI,^?' READ(*,*)A(I) END DO WRITE(*,*)'ввод массива А окончен' этом случае после появления на экране вопроса
64 ПРОГРАММИРОВАНИЕ НА ФОРТР^ К=? необходимо с клавиатуры ввести соответствующее значение например 9, а затем нажать клавишу | Enter | . После этого ] экране последовательно будут появляться вопросы А(1)=? А(2)=? и после каждого из них необходимо вводить с клавиатуры с< ответствующее значение элемента массива и нажимать клавиш Enter | . После ввода всех элементов на экране появится соо( щение ввод массива А окончен и начнет выполняться дальнейшая часть программы. Вывод массивов отличается от их ввода только заменой от ратора READ на оператор WRITE. При вводе данных, особенно массивов, рекомендуется пр( являть особую внимательность и следить за тем, чтобы вводимв величины соответствовали типу своих переменных. В составе трансляторов Фортрана имеются средства, с п< мощью которых можно строить графики. В ряде случаев э1 повышает наглядность результатов. Однако графические ере. ства Фортрана весьма ограничены и неудобны. Поэтому для Я1 строения графиков рекомендуется использовать другие паке! программ, например MATLAB фирмы MathWorks. 1.8. ОРГАНИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ При написании программ можно использовать стандарте библиотечные функции Фортрана (см. раздел 1.10). К библ^ течным функциям обращаются в арифметических или лог***1 ских выражениях. При этом указывается имя функции, а п°° имени в скобках соответствующие аргументы, которыми мо?- быть арифметические выражения. Примеры:
гАНИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 65 A*C0S(2.0*X+D)+FO SIN(X).LE.C0S(Y) (AMAXl(A,B,C)+AMINl(A,B,C))/2.0 Если в программе нужно выполнить какое-либо арифметическое, логическое или символьное выражение несколько раз, то можно использовать оператор формулы-функции, который имеет вид <имя> (S) = <выражение> здесь <имя> — имя функции, подчиняющееся обычным правилам образования имен в Фортране; S — список формальных параметров, 'разделенных запятыми и заключенных в круглые скобки; <выражение> — арифметическое, логическое или символьное выражение. Формула-функция располагается в программе после операторов описания типа и объявления размерности, но перед всеми исполняемыми операторами. К формулам-функциям обращаются в выражениях, указывая имя функции, а в скобках после имени ~~~ фактические параметры, которые замещают формальные параметры. Пример: WAD(X,Y)=X**2+2*Y**2 FlaQUAD(Xl,Yl) P2aQUAD(X2,Y2) ° этом примере, с помощью формулы-функции QUAD, будут делены значения Fx = х\ + 2у\ и F2 = х\ + 2у|. ел и И Записи формулы-функции никаких фактических вычи- Ий Не производится. Это — только определение, а вычисле- ^-амохин
66 ПРОГРАММИРОВАНИЕ НА ФОРТР^ ния осуществляются при обращении к ней в программе. Выра^ ние., стоящее справа от знака равенства в определении форму^> функции, может быть любым допустимым арифметическим, ^ гическим или символьным выражением Фортрана, включаюц^ константы, переменные и библиотечные функции. В выражещ может присутствовать обращение к другим формулам-функцил, определенным ранее, но не допустимо обращение к определяемо формуле-фу нкци и. Имена формальных параметров действуют только в опреде лении формулы-функции. Если такое же имя используется где либо еще в программе, то между этими именами нет никако! связи. Отметим, что формальный параметр может быть тольй переменной, но не константой или выражением. Между формаль ными и фактическими параметрами должно соблю даться соответствие по порядку следования и типу. Фактиче ские параметры могут быть переменными, константами и выра жениями. Если имя формулы-функции не соответствует типу выра жения по умолчанию (REAL или INTEGER), то данное имя должно быть описано в программе в операторах описания типа. Пример LOGICAL LF,L1,L2 LF(X,Y,B)=X**2+Y**2.LE.R**2 . L1=L^(X1,Y1,R1) L2=LF(A,B,C) В этом примере, с помощью логической формулы-функц*^ LF вычисляются логические величины L1 и L2. Соответств#е между формальными и фактическими параметрами следующее X <=> XI X <=> А Y 4=^ Yl Y <=> В R <=> Rl R <=> С
ргАНИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 67 Яо сих пор мы рассматривали программы Фортрана, со- ящие только из одного программного модуля. Программ- модулем называется последовательность операторов, задевающаяся оператором END. Однако помимо головных про- амм, которые рассматривались выше, в Фортране широко ис- ользуются другие программные модули — подпрограммы, которые оказываются весьма полезными при написании сложных программ, при наличии одинаковых последовательностей операторов в алгоритме и т.д. Отметим, что формула-функция, рассмотренная выше, действует в пределах только своего программного модуля. Общая форма записи подпрограммы-функции имеет вид <тип> FUNCTION <имя> (S) <операторы> RETURN END Здесь <тип> — определяет тип результата (INTEGER,REAL и т.д.) подпрограммы, <имя> — имя подпрограммы, подчиняющееся обычным правилам образования имен в Фортране, S — список Формальных параметров подпрограммы, который состоит из имен переменных и массивов, разделенных запятыми. Подпрограмма-функция может состоять из любого количе- СТВа операторов Фортрана, но последним выполняемым опера- °Ром должен быть оператор RETURN, обеспечивающий возврат взывающий программный модуль. Оператор RETURN имеет ^сл аналогичный оператору STOP в головной программе. По- Дним оператором подпрограммы должен быть оператор END. " подпрограмме обязательно должен быть оператор присва- Ивавия вида <имя> = < результат > в <имя> — имя подпрограммы, <результат> — результат Л1*ения подпрограммы-функции.
68 ПРОГРАММИРОВАНИЕ НА ФОРТРА^ Выполнение подпрограммы-функции происходит после у^ зания имени подпрограммы в арифметическом, логическом щ символьном выражении вызывающего программного моду^ Вместе с именем указывается список фактических параметров которые замещают формальные параметры. Между формам ными и фактическими параметрами должно соблюдаться coo-j ветствие по порядку следования и типу. Имя подпрограммы-функции должно быть указано в опера, торах описания типа вызывающего программного модуля. Ещ имя подпрограммы соответствует типу результата по умолча- нию (REAL или INTEGER), то указание типа в заголовке подпро. граммы и в операторах описания типа вызывающего модуля может быть опущено. Метки операторов и имена переменных в разных программных модулях определяются независимо друг от друга. В частности, в разных программных модулях можно использовать одинаковые метки, что недопустимо в пределах одного модуля. Последовательность расположения программных модулей в программе может быть любой. Пусть задана функция _ Г sin х , х < О, ~~ \ х + х2 , х > О и требуется вычислить ее значение при аргументах х\ и а?2- Соответствующая программа может иметь вид WRITEC*,*) ,Х1=?,Х2=?' READC*,*) XI,Х2 F1=FF(X1) F2=FF(X2) WRITEC*,*) ,F1=,,F1,,F2=,,F2 STOP END FUNCTION FF(X)
РАНИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 69 TF(X.LT.O) FF=SIN(X) lF(X.GE-0) FF=X+X**2 return END В головной программе дважды происходит обращение к подпрограмме FF. Соответствие формальных и фактических параметров следующее: X <=*• XI X «=► Х2 Резервирование памяти для хранения массива осуществляется в том программном модуле, где массив впервые объявлен. Поэтому при объявлении массива в подпрограмме, где он является формальным параметром, можно использовать целые переменные для указания пределов изменения его индексов. Рассмотрим пример вычисления суммы четных положительных элементов одномерного массива с числом элементов N < 200. Соответствующая программа может иметь вид INTEGER FUNCTION SUM(B.M) INTEGER BOO SUM*0 DO 5 >i,H lF(B(I).LE.O) GOTO 5 ' Ip(B(I)/2*2.EQ.B(D) SUM=SUM+B(I) 5 C°NTINUE RETURN END j^EGER A(200),SUM *AD(«,*) i,(a(I),I-1,M) STQp C*'*) 'SUMs''IS
70 ПРОГРАММИРОВАНИЕ НА ФОРТР^ END В головной программе имя подпрограммы-функции SUM ука^ вается в операторе описания INTEGER, поскольку по умолчанц соответствующая переменная счцтается вещественной. В э^ примере существует следующее соответствие формальных и фа, тических параметров: М «=» N При обращении к подпрограмме вместо имени массива в кг честве фактического параметра мсжно задавать элемент этог массива. Так, если в рассматриваемом примере вызов подпрс граммы из головной программы осуществляется оператором IS=SUM(A(1),N) то результат будет тот же, что в приведенной программе. Ecni же вызов осуществляется, например, оператором IS=SUM(A(K),N-K+1) с N > К > 1, то в подпрограмме SUM будут рассматриваться с# дующие элементы массива: А(К), А(К+1),..., A(N) Пусть в программном модуле объявлен одномерный масс# у которого начальное значение индекса не равно единице, напр*1 мер DIMENSION В(-5:100)
f/ЛИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 71 ямер PR°Gi У которой формальными параметрами являются Й Массива В, начальное и конечное значения индекса NM и NP, в подпрограмме присутствует оператор размерности DIMENSION B(NM:NP) Тогда, для того, чтобы элементы массива с одинаковыми индексами совпадали в вызывающем модуле и в подпрограмме при любых фактических значениях —5 < NM < NP < 100, достаточно при обращении к подпрограмме задать в качестве фактического параметра, соответствующего имени массива, элемент B(NM), т.е. вызов подпрограммы должен иметь вид PR0G(...,B(NM),...) Если NM=-5, то при вызове подпрограммы в качестве фактического параметра допустимо использовать имя массива, т.е. вызов подпрограммы может иметь вид PR0G(...,B,...) Описанные выше особенности связи массивов в вызывающем модуле и подпрограмме обусловлены тем, что при указании имени массива в качестве фактического параметра в под- Р°грамму передается массив с начального элемента, а при ука- ании элемента массива в качестве фактического параметра в ПоДПрограмму передается массив, начинал с этого элемента. Рассмотрим самый общий класс подпрограмм. Подпрограмма—процедура имеет следующий вид: SUBROUTINE <имя> (S) < операторы > RETURN END
72 ПРОГРАММИРОВАНИЕ НА ФОРТРл Здесь S — список формальных параметров, <имя> — имя ц. программы. Для обращения к подпрограмме в вызывающем ^ дуле используется оператор CALL, который имеет вид CALL <имя> (S) где S — список фактических параметров. Между формальными и фактическими параметрами дол^ соблюдаться соответствие по порядку следования и типу, приме все особенности связи формальных и фактических параметре такие же, как для подпрограмм-функций. Подпрограмма-функция может иметь большое количеств аргументов, но она всегда имеет один явный результат. Поэтом все формальные параметры имеют смысл "исходных данных' при обработке которых получается один результат Подпрограмма-процедура обладает более широкими возможно стями и может возвращать в вызывающий модуль много резуль татов, в том числе один, или ни одного. Поэтому имя подпро граммы SUBROUTINE никак не связано с типом получаемых ре зультатов, а среди формальных параметров находятся как "ис ходные данные", так и "результаты". Рассмотрим пример: сформировать массив С, являющийо суммой двух одномерных массивов А и В с числом элементов' каждом N<100. Соответствующая программа с использование! подпрограммы SUBROUTINE имеет вид DIMENSION А(100),В(100),С(100) READ(*,*) N,(A(I),B(I),I=1,N) CALL SUM(A,B,C,N) WRITE(*,*) (C(I),I=1,N) STOP END SUBROUTINE SUM(X,Y,Z,M) DIMENSION X(M),Y(M),Z(M) DO 5 1=1,M Z(I)=X(I)+Y(I)
г0ИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 73 5 CONTIN^ rEturn END r том примере осуществляется следующее соответствие факти- ких и формальных параметров: А«=* X В <=> Y С4=> Z N<=* М В разделе 1.5 отмечалось, что элементы одномерных массивов хранятся в памяти последовательно один за другим, а элементы многомерных массивов располагаются согласно правилу: быстрее всего изменяется первый индекс, затем второй и т.д. Так, элемент двумерного массива с индексами I, J будет занимать ячейку памяти с номером I+(J—1)N, считал от элемента массива с индексами,, равными единице (N — предельное значение индекса I в массиве, а начальные значения индексов равны единице). Поэтому ясно, что если предельные значения индексов МНог°мерного массива в подпрограмме не совпадают с их значениями в вызывающем программном модуле, то элементы массива °Динаковыми индексами в этих программных модулях не совпадают. Таким образом, если многомерный массив используется в Hbix программных модулях, то необходимо задавать одинако- е пРедельные значения их индексов в операторах размерности МассиВа. и а ассм°трим задачу умножения двух квадратных матриц А Но ^азмеРности N х N для значений N<50. Соответствующая Р^мма может иметь вид PARAMETER (NP=50) ^MENSIDN A(NP,NP),B(NP,NP),C(NP,NP) READ(*,*) N,((A(I,J),B(I,J),I=1,N),J=1,N)
74 ПРОГРАММИРОВАНИЕ НА ФОРТР^} NN=NP CALL MULTI(A,B,C,NN,N) WRITE(*,*) ((C(I,J),I=1,N),J=1,N) STOP END SUBROUTINE MULTI(A,B,C,NN,N) DIMENSION A(NN,NN),B(NN,NN),C(NN,NN) DO 5 1=1,N DO 5 J=1,N S=0 DO 10 K=1,N S=S+A(I,K)*B(K,J) 10 CONTINUE C(I,J)*S 5 CONTINUE RETURN END Здесь А и В —- заданные матрицы (двумерные массивы), С — искомая матрица. В головной программе переменная NN должна быть равна предельному значению индексов массивов, указанному в операторе размерности. Мы рекомендуем читателю провести эксперимент с заданием других значений NN и посмотреть, какие в этом случае получатся значения элементов массива С. Отметим, что для одномерных массивов вышеуказанных пр^ блем не существует и в подпрограммах в операторах размерности можно указывать любую целую величину в качестве коне^ ного значения индекса, например величину, равную начальному значению индекса или символ "*". В подпрграммах в качестве формальных параметров мож#° использовать одно или несколько имен других подпрограмм. " этом случае имена должны быть упомянуты в оператор6 EXTERNAL в вызывающем модуле. Оператор EXTERNAL имеет в#$ EXTERNAL S
ГАНИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 75 с ~- список имен подпрограмм, которые могут быть пере- я качестве фактических параметров в другие подпрограм- даЯЫ р мы- ПРимер: EXTERNAL SB1,SB2 CALL PR0G(X,Y,SB1) CALL PR0G(X,Y,SB2) SUBROUTINE PROG(X,Y,SUB) CALL SUB(X,Y) RETURN END При первом обращении к подпограм^е PROG будет вызываться подпрограмма SB1, а при втором — SB2. Отметим, что имена формул-функций не могут присутствовать в операторах EXTERNAL, поскольку формулы-функции действуют только в пределах того программного модуля, где они опРеделены. Выше была описана связь вызывающего модуля с подпрограммами с помощью фактических и формальных параметров. УЩествует другая форма связи, которая иногда бывает более уД°бной. Оператор COMMON определяет область памяти для хранения ^Их Данных для двух или нескольких программных модулей и аг11*сывается в каждом из этих модулей. Форма записи COMMON /<имя>/ S й <имя> — имя общей области, которое может отсутство- Ни ' S ~~~~ список переменных, который может включать объявле- Л м^ссивов. Примеры:
76 ПРОГРАММИРОВАНИЕ НА ФОРТРА COMMON /MEM/ X,Y,K2 COMMON A(100),ВО Последняя запись эквивалентна следующей: DIMENSION А(100) COMMON А,ВО Оператор COMMON относится к невыполняемым оператора и располагается в начале программного модуля до первого bi полняемого оператора. Если переменные указаны в оператор COMMON вызывающего модуля и подпрограммы, то они не должн присутствовать в списках формальных и фактических парам! тров. Между переменными, относящимися к одной области ш мяти, в операторах COMMON должно соблюдаться соответствие н порядку следования и типу. Пример: COMMON /S/ X,Y(20),L CALL PR0G(...) SUBROUTINE PROG(..'.) COMMON /S/ A,B(20),L В этом случае осуществляется следующая связь между перем^ ными в вызывающем модуле и подпрограмме Y <=> В L <=* L Приведенный фрагмент программы с использованием форма-/*1' ных и фактических параметров будет выглядеть
ГАЦИЗАЦИЯ СЛОЖНЫХ ПРОГРАММ 77 DIMENSION Y(20) CALL PR0G(...,X,Y,L) SUBROUTINE PR0G(...,A,B,L) DIMENSION В(20) Поименованных операторов COMMON в одном модуле может быть несколько и они могут использоваться для связи с разными подпрограммами. Имена общих областей не должны совпадать с именем какой-либо подпрограммы. С помощью операторов COMMON можно осуществлять передачу данных между программными модулями, которые непосредственно не связаны друг с другом. Например, программный модуль SB1 вызывает продпрограмму SB2, которая в свою очередь вызывает подпрограмму SB3. Далее, в программном модуле SB1 определяется величина А, которая не используется в подпрограмме SB2, а применяется в подпрограмме SB3. В этом случае Для передачи данных достаточно поместить, например, оператор COMMON /NM/ А в SB1 и SB3. Если же использовать формальные и фактические аРаметры, то величину А нужно передавать через все программ- НЫе модули, в том числе и через SB2. Переменным и элементам массивов, входящим в общие обла- и COMMON, могут быть присвоены начальные значения в опе- т°рах DATA, однако эти операторы обязательно должны быть Раны вместе в одной или нескольких подпрограммах BLOCK А- Эти подпрограммы имеют следующий вид: BLOCK DATA <имя> <операторы> END
78 ПРОГРАММИРОВАНИЕ НА ФОРТРдц Здесь <имя> — имя подпрограммы, которое может отсутст^, вать, <операторы> — операторы COMMON, DATA, размерно^ и описания типа, причем операторы COMMON и DATA обязятелц должны присутствовать в подпрограмме. Подпрограммы BLOCK DATA являются невыполняемыми, ц0 скольку начальные значения присваиваются на этапе трансляции и поэтому к ним не происходит обращение в программных моду лях. В программе может быть только одна неименованная под. программа BLOCK DATA и любое количество именованных. Пр& мер: BLOCK DATA COMMON /CI/ A(3),B COMMON /C2/ X,Y,Z,K INTEGER Z DATA A /3*2.5/ DATA X,Y /-0.5,2.3/ DATA Z,K /2*3/ END В операторах COMMON должны указываться все переменные, относящиеся к данной области памяти, даже, если не всем из них присваиваются начальные значения. 1.9. ОТЛАДКА ПРОГРАММ Составленная пользователем программа на Фортране може? содержать ошибки тем более вероятные, чем сложнее программ^ Существует два основных вида ошибок — синтаксические и семантические. Синтаксические ошибки обусловлены неправильным ис" пользованием конструкции алгоритмического языка. Э^ ошибки указываются после трансляции программы на экране #
отлаЯВ- ПРОГРАММ 79 кСтовом файле с расширением .1st (листинге программы). 3 павление этих ошибок, как правило, не вызывает трудностей /о для начинающих пользователей. Да>к ^ Семантические ошибки обусловлены неверным алгорит- решения или неправильным размещением обрабатываемых анных в памяти. Эти ошибки проявляются в том, что при за- уске программы на выполнение на экране компьютера может появиться сообщение о переполнении разрядной сетки в какой- т0 ячейке памяти, после которого выполнение программы прекращается, или полученные результаты абсолютно не соответствуют ожидаемым (например, очень большие или очень маленькие числа). Опишем наиболее часто встречающиеся семантические ошибки: • Деление на нуль. При составлении алгоритма и программы нужно внимательно следить за тем, чтобы при использовании операции деления знаменатель не обращался в нуль. При наличии такой ошибки в программе будет сообщение о переполнении разрядной сетки. • Недопустимое значение индекса массива. В процессе выполнения программы величина индекса массива выходит за границу предельного значения индекса. В этом случае последующие результаты оказываются абсолютно неверными. • Использование неопределенных величин. В процессе выполнения программы происходит обращение к переменным, которые не были определены ни в исходных данных, ни с помощью операторов присваивания. В этом случае последующие Результаты оказываются абсолютно неверными. т явление перечисленных ошибок часто вызывает большие ДНости, поскольку не известно их местонахождение в про- Лл Ме- Для облегчения поиска подобных ошибок в составе транс- F*a Fortran Microsoft имеется отладчик программ CodeView.
80 ПРОГРАММИРОВАНИЕ НА ФОРТР. Щ С помощью этого отладчика можно осуществлять пошаговое b^v полнение программы с выдачей значений любых переменных пра граммы на каждом шаге. Таким образом можно найти местон^ хождение ошибки в программе и устранить ее. Опишем процедуру запуска отладчика программ CodeView В каталоге, где размещаются текстовые и выполняемые файлы Фортран-программ, создадим командный файл code.bat Qecho off path=c: \f ortran\bin; с : \f ortran\binb set lib = с:\fortran\ lib set include=c:\fortran\include set tmp = с:\fortran\tmp fl /Fs /Zi /Od %l.for cv %1 Первые пять команд объяснены в разделе 1.3 при написании командного файла start.bat. Шестая команда запускает транслятор Фортрана с опциями /Zi и /Od, которые необходимы для работы отладчика CodeView. Седьмая команда запускает программу-отладчик. Пусть текстовый файл Фортран-программы имеет имя, например, prog. for. Тогда для запуска отладчика программ CodeView необходимо набрать в командной строке текущего каталога команду code prog Enter и нажать клавишу Если имя отлаживаемой Фортран-программы другое, то оно записывается вместо prog без расширения .for. После создания объектного файла с расширением . obj и выполняемого файла с расширением . ехе, будет произведен автоматический запуск отладчика и на экране появится текст Фортран" программы. Сверху на экране будет расположена строка меню» для входа в которую необходимо нажать клавишу | Alt | . Пр** повторном нажатии клавиши [Alt [ происходит выход из строк**
itfAjB. ПРОГРАММ 81 Внизу экрана находится командная строка отладчика. Пе- **е я из командной строки отладчика в окно Sourse, где распо- Р тСЙ текст Фортран-программы, осуществляется функциональной клавишей F6 Клавиша |F3 | переключает форму пред- П"" вления текста в окне Sourse, поскольку можно работать с ис- лным текстом программы и с ассемблерным представлением. Для пошагового выполнения программы используется функциональная клавиша \ьъ | , каждое нажатие которой производит выполнение одного оператора программы. Выполненная строка программы имеет цветовое выделение на экране. Если вы не хотите входить в подпрограмму, то для пошагового выполнения вместо клавиши F8 нужно использовать функциональную клавишу |F10 1 . В этом случае при вызове подпрограммы ее выполнение будет осуществлено одним нажатием клавиши |F10 | . Для того, чтобы программа автоматически выполнялась до какого- то оператора программы, в окне Sourse нужно просмотреть текст программы, перемещая курсор до интересующего места. Затем, после нажатия функциональной клавиши F7 программа будет выполнена до точки расположения курсора. Для установления в программе точки остановки достаточно подвести курсор к нужной строке и нажать клавишу [F9 I . Оточенная строка имеет цветовое выделение. Повторное нажатие клавиши Р^мме может быть несколько. Функциональная клавиша] F5 F9 1 отменяет точку остановки. Точек остановки в про- ис- Льзуется для выполнения программы до точки остановки или конца программы, если точек остановки нет. ^ помощью отладчика CodeView можно просматривать те- в е значения любых переменных программы в процессе ее °лнения. Для этого после начала пошагового выполнения У^иыг э*Ра: — тливится окно, в которое нужно ввести ш еРеменной. После нажатия клавиши | Enter | вверху экрана л*отся имя переменной и ее текущее значение. Аналогично 0 Указать вторую, третью и т.д. переменные. Чтобы убрать ш необходимо нажать клавиши Ctrl + W . В центре рана гг а появится окно, в которое нужно ввести имя интересую- п0 еРеменной. После нажатия клавиши | Enter' Mo; *Ц,
82 ПРОГРАММИРОВАНИЕ НЕ ФОРТРдщ переменную и ее текущее значение с экрана необходимо нажа^ _|, а затем в появившемся окне указать щ клавиши Ctrl + U переменной. Если программа выводит какую-либо информацию ц экран, то можно посмотреть результаты вывода, нажав клавицн воз. F4 I и выйдя в среду DOS. Повторное нажатие клавиши | F4 вращает в среду отладчика. Функциональная клавиша |F11 вызывает встроенный HELP, Для повторного запуска программы необходимо нажать клавишу Alt | и войти в меню отладчика. Затем перейти в меню Run и выполнить Restart. После этого возможно повторное выполнение пограммы в режиме отладки. Для завершения работы с отладчиком CodeView достаточно нажать клавиши Q + [Enter 1.10. СПИСОК ОСНОВНЫХ БИБЛИОТЕЧНЫХ ФУНКЦИЙ ФОРТРАНА При обращении к библиотечным функциям указывается имя, а в скобках — список фактических параметров. Примеры: F=A*SIN(X)+B*C0S(X) L=MAX(I1,I2,I3,I4) Если в программе есть подпрограмма-функция с именем, совпадающим с именем какой-либо библиотечной функции, то пр^ вызове происходит обращение к библиотечной функции. Одна*0 если это имя стоит в списке оператора EXTERNAL, то в этом пр0' граммном модуле подавляется вызов библиотечной функции ** происходит обращение к подпрограмме-функции. Принятые сокращения: int — INTEGER, cmp — COMPLEX, cmpl6 — C0MPLEX16, log — LOGICAL. При использовании транслятора Fortran-NDP, некоторые 6$' блиотечные функции, относящиеся к величинам двойной точН0' сти, т.е. COMPLEX* 16 или REAL*8, могут отсутствовать.
S0S9L 'ЕЧНЫЕ ФУНКЦИИ ФОРТРАНА 83 □ таблице 1.10.1 приведен список основных библиотечных фУ«к ций Фортрана. Табл. 1.10.1 г" Имя I ^~ [absCaT [acosCa) [AIMAG(A) |AL0G(A) Ilogio(a) AMAX0(A,B,..) AMAX1(A,B,. .) AMIN0(A,B,..) AHINKA.B,..) AMOD(A.B) ANINT(A) ASIN(A) JITAN(A) ^ABSQO _^OS(A) ^UABSU) ^CDcos(a) -ЛВ^Р(А) CDLOG(A) 2$SlN(A) C«PLX(A) prv^T;—— ife»A) L^Xpgy- Описание 2 Абсолютное значение Арккосинус Мнимая часть числа Натуральный логарифм Логарифм с основанием 10 Максимум Максимум Минимум Минимум Остаток от деления Округление Арксинус Арктангенс Абсолютное значение Косинус Абсолютное значение Косинус Экспонента Натуральный логарифм Синус Преобразование типов данных Квадратрный корень Экспонента Тип параметра 3 real real cmp real real int real int real real real real real cmp cmp cmpl6 cmpl6 cmpl6 cmpl6 cmpl6 int,real cmp cmpl6 cmp Тип функции 4 real real real real real real real real real real real real real real cmp real 8 cmpl6 cmpl6 cmpl6 cmpl6 cmp cmpl6 cmp
84 ПРОГРАММИРОВАНИЕ НЕ ФОРТРц Продолжение Табл. l.lOj 1 CLOG(A) CONJG(A) COS(А) COSH(A) COTAN(A) CSIN(A) CSQRT(A) DABS(A) DACOS(A) DASIN(A) DATAN(A) DBLE(A) DCMPLX(A) DCONJG(A) DCOS(A) DCOSH(A) DCOTAN(A) DEXP(A) DFLOAT(A) DIMAG(A) DLOG(A) DLOGIO(A) 2 Натуральный логарифм Комплексно- сопряженное число Косинус Гиперболический косинус Котангенс Синус Квадратный корень Абсолютное значение Арккосинус Арксинус Арктангенс Преобразование типов данных Преобразование типов данных Комплексно- сопряженное число Косинус Гиперболический косинус Котангенс Экспонента Преобразование типов данных Мнимая часть числа Натуральный логарифм Логарифм с основанием 10 3 стр стр real real real стр стр real 8 real 8 real 8 real 8 int,real,стр int,real,cmp cmpl6 real 8 real 8 real 8 real 8 int,real,cmp cmpl6 real 8 real 8 4^ cmp^4 cmp real ^ real ^1 real ^| cmp ~"] cmp ~"| real 8 "] real 8 j real 8 real 8 real 8 cmpl6 cmpl6 real 8 real 8 real 8 real 8 real 8 real 8^ real 8 real 8
0вмо_ ТЕЧНЫЕ ФУНКЦИИ ФОРТРАНА 85 Продолжение Табл. 1.10.1 г Г Пй5хГ(а,в,...) гдагкА.в,...) Seal (а) [dsinCa) feNHCA) [dsqrt(a) DTAN(A) DTANH(A) EXP(A) FLOAT(A) IABS(A) IDINT(A) IMAG(A) INT(A) LOG(A) ^«(A.B,...) LOGIO(A) ~*£!<A,B....) RKAL(A) ЗШаТ L^INHU) 2 Максимум Минимум Преобразование типов данных Синус Гиперболический синус Квадратный корень Тангенс Гиперболический тангенс Экспонента Преобразование типов данных Абсолютное значение Преобразование типов данных Мнимая часть числа Преобразование типов данных Натуральный логарифм максимум Логарифм с основанием 10 Минимум Преобразование типов данных Синус Гиперболический синус 3 real 8 real 8 cmpl6 real 8 real 8 real 8 real 8 real 8 real int int real 8 cmp int, real, cmp real int real int int,real, cmp real real 4 real 8 real 8 real 8 real 8 real 8 real 8 real 8 real 8 real real 1 int | int real | int real 1 int | real 1 int real real | real
86 ПРОГРАММИРОВАНИЕ НА ФОРТРАщ Окончание Табл. 1.10.1 1 SNGL(A) SQRT(A) TAN(A) TANH(A) 2 Преобразование типов данных Квадратный корень Тангенс Гиперболический тангенс 3 real 8 real real real 4 real real real real 1.11. СОЗДАНИЕ ПРОГРАММНЫХ БИБЛИОТЕК Помимо использования стандартной библиотеки программ Фортрана, каждый пользователь может самостоятельно создавать и использовать свои программные библиотеки. Процедура преобразования исходного текста Фортран- программы в исполняемый файл состоит из двух этапов — компиляции и редактирования. На этапе компиляции каждый программный модуль (головная программа и подпрограммы) независимо преобразуется в так называемый объектный модуль. Объектный модуль — это оттранслированная, т.е. переведенная в машинные команды, программа, для которой, однако, не проведено распределение памяти под переменные и массивы. На этапе редактирования из объектных модулей, входящих в состав программы, создается выполняемый файл. При этом происх^ дит окончательное распределение памяти и установление связей между модулями. Каждый объектный модуль может быть помещен в библии теку программ и тогда к нему можно обращаться в любой пр0' грамме без записи текста соответствующего модуля (подпро^ раммы-функции или подпрограммы-процедуры). Это дела^ текст исходной программы более компактным и удобным в ^с пользовании.
со?!* НИЕ ПРОГРАММНЫХ БИБЛИОТЕК 87 Опишем процедуру создания библиотеки программ с помо- ф транслятора Fortran-Microsoft. Библиотека программ — 0 файл, имя которого имеет обязательное расширение .lib который помещен в каталог c:\fortran\lib (см.раздел 1.3). Пусть имя библиотеки будет, например, user.lib. Создадим в каталоге, где находятся текстовые и выполняемые файлы Фортран-программ, командный файл mslb.bat (Oecho off path=c:\fortran\bin;с:\fortran\binb set lib=c:\fortran\lib set include=c:\fortran\include set tmp=c:\fortran\tmp if 7,2==del goto mark fl /c /Ox V.l.for lib c:\fortran\lib\user.lib+y,l.obj ; goto exit :mark lib с:\f ortran\lib\user. lib-7,1.obj ; :exit Файл mslb.bat предназначен для помещения в библиотеку User.lib или удаления из библиотеки объектных модулей. Пусть у нас есть текстовый файл программного модуля с ИМенем, например, sub .for и мы хотим поместить соответствующий объектный модуль в библиотеку. Тогда в командной строке Залога надо набрать команду mslb sub add аЖать клавишу | Enter | (последнее слово в команде может быть еНено пробелами). После выполнения в библиотеку user.lib 4ет записан объектный модуль sub. ob j. Если библиотеки с та- именем не было, то в процессе выполнения она будет создана. Удаления объектного модуля из библиотеки надо набрать ко- mslb sub del
88 ПРОГРАММИРОВАНИЕ НА ФОРТ. 'РАЩ Enter I (последнее слово в команде являет^ и нажать клавишу обязательным). Первые пять команд MS-DOS в файле mslb.bat были объяСч нены в разделе 1.3 при написании файла start.bat. Следуюцц команда является условной. Если второй параметр командного файла mslb.bat есть del, то происходит переход к метке mark. J) этом случае выполняется последняя команда lib, смысл которое заключается в том, что из библиотеки user.lib удаляется (сим. вол -) объектный модуль с расширением . obj. Если второй пара, метр файлаmslb .bat не совпадает с del, то выполняется команда на запуск транслятора fl. Опция /с предназначена для того, чтобы при трансляции текстового файла осуществлялся только этап компиляции. Следующая команда lib помещает (символ +) созданный объектный модуль в библиотеку. Команда безусловного перехода goto предназначена для того, чтобы после занесения объектного модуля в библиотеку он не был удален из нее следующей командой lib. Пусть в каком-либо каталоге находится текстовый файл Фортран-программы с именем, например, prog.for. В тексте этой программы происходит обращение к программному модулю sub, хотя текста этого модуля в программе нет. Для того чтобы библиотека программ user .lib, в которой находится объектный модуль sub.obj, была доступна для использования нужно в командном файле start.bat (см. раздел 1.3) вместо последней команды записать fl /с /Ox /Fs /Д.for link У,1, , ,user lib; Вторая команда осуществляет совместное редактирован^ созданного в предыдущей команде объектного модуля с требУ емыми объектными модулями, которые находятся в библиотек user.lib. В последней команде три запятые с пробелами меЖ$ ними являются обязательными. Теперь для создания выполняемого файла необходимо с ^ мощью Norton Commander выделить текстовый файл prog.
г0ЗДАНИЕ ПРОГРАММНЫХ БИБЛИОТЕК 89 нажать клавишу | Enter | . Помимо файлов с расширениями ъ],. ехе,. 1st появится файл с расширением .тар. В этом файле ходится информация о распределении памяти. Обычно для ользователя представляют интерес файлы с расширениями . ехе Опишем процедуру создания библиотеки программ с помощью транслятора Fortran-NDP. Пусть имя библиотеки будет, например, libuser.lib. Первые три буквы в имени совпадают с расширением и являются обязательными. Создадим в каталоге, где находятся текстовые и исполняемые файлы Фортран-программ, командный файл ndplb. bat Qecho off path=c:\ndp\bin;с:\ndp\tools set lib=c:\ndp\lib set ndp=c:\ndp set tools=c:\ndp\tools set inc=c:\ndp\inc if 7,2==del goto mark mf486 -c -vm Xl.f ndplib c:\ndp\lib\libuser.lib -add Xl.obj goto exit :mark ndplib c:\ndp\lib\libuser.lib -delete #/,l.obj :exit аил ndplb .bat предназначен для помещения в библиотеку и удалил из библиотеки объектных модулей. Пусть у нас есть текстовый файл программного модуля с енем, например, sub.f и мы хотим поместить соответствую- и объектный модуль в библиотеку! Тогда в командной строке ^ога надо набрать команду ndplb sub add *ать клавишу I Enter I (последнее слово в команде может быть Э-Ме а Нено пробелами). Если библиотеки с таким именем не было,
90 ПРОГРАММИРОВАНИЕ НА ФОРТРа^ то в процессе выполнения она будет создана. Для удаления обг ектного модуля из библиотеки надо набрать команду ndplb sub del и нажать клавишу | Enter | (последнее слово в команде являете» обязательным). Первые шесть команд в файле ndplb.bat были объясненыц разделе 1.3 при написании файла comp.bat. Условная команда работает точно также, как в написанном выше файле mslb.bat, В команде запуска транслятора mf486 опция -с предназначена для того, чтобы при трансляции текстового файла осуществляла только этап компиляции. Команда ndplib помещает (опция -add) объектный модуль в библиотеку libuser .lib или удаляет (опцш -delete) модуль из библиотеки. Для того чтобы библиотека программ была доступна дм использования нужно в командном файле comb.bat (см. раздел 1.3) вместо последней команды записать mf486 -list -vm -luser '/,l.f Опция luser (обратить внимание на запись) делает доступными объектные модули библиотеки libuser.lib в процессе редактирования программ. Теперь процедура транслирования текстового файла Фор ран-программы с расширением Л будет такой же, как это oV$ сано в конце раздела 1.3.
■ дачи И РЕШЕНИЯ 91 12. ЗАДАЧИ И РЕШЕНИЯ X. Дан одномерный массив с числом элементов N<100. Найти vM^y положительных элементов этого массива и число отрицательных элементов. Решение: DIMENSION А(ЮО) READO,*) N,(A(I),I=1,N) S=0 K0L=0 DO 10 1=1,N IF(AU).GT.O.O) S=S+A(I) IF(AU).LT.O.O) K0L=K0L+1 10 CONTINUE WRITE(*,1) S.KOL 1 F0RMAT(5X,'S=',E12.5,2X,'K0L=\I3) STOP END 2. Дан одномерный массив с числом элементов N<200. Напечатать все элементы этого массива в файле RESULT. DAT с указанием индекса элемента. Решение: DIMENSION А(200) READ (*,*) N,(A(I),I=1,N) °PEN (1, FILE='RESULT.DAT') D0 5 1=1,N 5 WWTE (1,25) I, A(I) 2 CONTINUE p0RMAT (5X, 'AC, 13,' ) = ' .E12.5) STOP END
92 ПРОГРАММИРОВАНИЕ НА ФОРТРЛ^ 3. Напечатать в файле NUMBER.DAT все простые числа не пр^ вышающие заданного положительного целого числа N, N>2. Решение: OPEN(10,FILE='NUMBER.DAT') WRITE(*,25) 25 FORMAT(5X,'N=?') READ(*,*) N IF (N.LT.2) THEN WRITE (10,1) 1 FORMAT (5X, 'НЕПРАВИЛЬНОЕ ЗАДАНИЕ N') STOP END IF WRITE (10,*)'2' IF (N.Eq.2) STOP WRITE (10,*)'3' IF (N.EQ.3) STOP DO 10 1=4,N NI=SqRT(FLOAT(I))+l С Если ни одно из чисел от 2 до N1 не С является делителем I, то число I - простое DO 15 J=2, N1 IF (I/J*J.EQ.I) GOTO 10 С Если данное условие выполняется, то С I - число составное 15 CONTINUE WRITE (10,*) I 10 CONTINUE STOP END 4. Напечатать в файл NUMBER.DAT все простые делители) учетом их кратности, для заданного положительного целого ч" ела N, N>4. Решение:
fff И РЕШЕНИЯ 93 DIMENSION IS(1000) Массив IS предназначен для хранения последовательности простых чисел С OPEN (Ю, FILE»» NUMBER. DAT') WRITE(*,*) 'N=?' READ(*,*) N IF (N.LT.4) THEN WRITEC*,*) 'НЕПРАВИЛЬНОЕ ЗАДАНИЕ N' STOP END IF ND=SQRT(FL0AT(N))+1 С Если ни одно из целых чисел от 2 до ND не является С делителем N, то число N - простое CALL SIMPLE(ND,IS,KOL) С Подпрограмма SIMPLE вычисляет и записывает в массив С IS все простые числа, не превышающие ND. С Величина K0L определяет число простых чисел DO 10 1=1,K0L CALL DEL(N,IS(I)) c Подпрограмма DEL проверяет, является ли простое с число IS(I) делителем числа N и если да, то N Делится на это число, а значение IS(I) записывается С в файл NUMBER.DAT IF (H.EQ.l) STOP 10 CONTINUE Если программа выходит из цикла, то получившееся значение N больше единицы и является простым Делителем исходного числа WRITEC10,*) N STOP END SUBROUTINE SIMPLE(N,IS,K0L) DIMENSION IS(1) IS(1).2
94 ПРОГРАММИРОВАНИЕ НА ФОРТР^ь IS(2)=3 K0L=2 IF (N.EQ.3) RETURN DO Б 1=4,N IN=SqRT(FLOAT(I))+l DO 10 J-2.IH IF (I/J*J.EQ.I) GO TO 5 Если данное условие выполняется, то I - число составное CONTINUE K0L=K0L+1 IS(K0L)=I CONTINUE RETURN END SUBROUTINE DEL(N.M) 10 IF (N/M*M.EQ.N) THEN N=N/M WRITE(10,*) M GO TO 10 END IF RETURN END 5. Дан одномерный массив с числом элементов N<1000. Н*"' максимальный элемент этого массива и его индекс. Решение: REAL МАХ DIMENTION А(ЮОО) READ(*,*) N,(A(I),I=1,N) МАХ=А(1) IND=1
,ЧИ И РЕШЕНИЯ 95 DO 5 1=1,N IF (A(I).GT.MAX) THEN MAX=A(I) IND=I CONTINUE WRITE(*,1) MAX,IND FORMAT (5X,,MAX=,,E12.5,2X,,IND=,I4) STOP END 6. Дан одномерный массив с числом элементов N<1000. Переставить элементы этого массива так, чтобы они были расположены по возрастанию (задача сортировки). Решение: а) Метод перебора SUBROUTINE MIN(A,M,IND,RES) С Подпрограмма MIN определяет индекс и значение с минимального элемента одномерного массива. С Формальные параметры: А - имя массива, М - число с элементов, IND - индекс минимального элемента, с RES - значение DIMENSION А(1) RES=A(1) IND=1 DO 5 1=1>М IF(AU).LT.RES) THEN *ES=A(I) IND=I s END IF CONTINUE RETURN END program sort
96 ПРОГРАММИРОВАНИЕ НА ФОРТР^ь С Головная программа с необязательным именем SORT DIMENSION А(1000) READO.*) N,(A(I),I=1,N) DO 5 1=1,N-l M=N-I+i CALL MIN(A(I),M,J,RES) С Подпрограмма MIN определяет индекс J и значение REs С минимального элемента среди элементов массива от A(i С до A(N). Индекс J считается от I - го элемента. J=J+(I-1) С Здесь восстанавливается исходная нумерация индекса J IF(J.NE.I) THEN A(J)=A(I) A(I)=RES END IF 5 CONTINUE WRITE(*,*) (A(I),I=1,N) STOP END б) метод "пузырька" LOGICAL LA DIMENSION A(1000) READ(*,*) N,(A(I),I=1,N) 10 LA=.FALSE. DO 5 1=1,N-l IF (A(I+1).LT.A(I))THEN С Если данное условие выполняется, то производится С перестановка соседних элементов массива В=А(1) А(1)=А(1+1) А(1+1)=В LA=.TRUE.
,ЧИ И РЕШЕНИЯ 97 CONTINUE 1F(LA) GOTO 10 Если LA=.TRUE., то происходит переход к оператору с меткой 10 и производится повторный просмотр массива А WRITEC*,*) (A(I),I=1,N) STOP END 7. На плоскости с декартовыми координатами х и у определена область V (на рис. 1.12.1 она заштрихована). Написать Рис. 1.12.1 Р°грамму, которая для любой пары чисел (ж, у) определяет прилежность или не принадлежность точки с этими координации области V. Решение: 4 л ' Ь- Свмохин
98 ПРОГРАММИРОВАНИЕ НА ФОРТРлп LOGICAL L1.L2.L3 WRITE(*,i) 1 F0RMAT(2X,*R"?,Rl«?,R2-?,X-?,Y-?O READO,*) R,R1,R2,X,Y Ll=(X**2+Y**2.LE.R**2).AND.(X.LE.O.0).ANDi(Y.GE.00) L2=(X**2+Y**2.LE.R2**2).AND.(X**2+Y**2.GE.Rl**2) L3=(X.GE.0.0).AND.(Y.GE.0.0) С Переменные LI, L2, L3 введены для удобства записи С логического выражения IF(L1.0R.(L2.AND.L3)) THEN WRITE(*,2) ELSE WRITE(*,3) END IF 2 FORMAT(5X,'ТОЧКА ПРИНАДЛЕЖИТ ОБЛАСТИ') 3 FORMAT(5X,'ТОЧКА HE ПРИНАДЛЕЖИТ ОБЛАСТИ') STOP END 8. Пусть функция f(x) задана в виде формулы ( х + х2/2\ + х3/3\ + ■■■ + xN/№ , х<0 ( sin х + sin3 я/3 + • • • + sin2M+1 х/(2М + 1) , х > О № = { где к\ = 1 -2- --к называется А;-факториалом. Написать пр0' грамму, которая для заданных параметров N и М вычисл.яе1 значение функции для любого аргумента х. Решение: READ(*,*) N,M,X IF(X.LE.O.O) THEN F=0 FACT=1.0 U=X
V4H И РЕШЕНИЯ 99 DO 5 1=1,N F=U/FACT u=u*x FACT=FACT*(I+1) г Переменная FACT определяет значение факториала 5 CONTINUE ELSE F=0 V=SIN(X)**2 U=SIN(X) DO 10 I=1,2*M+1,2 F=F+U/I U=U*V 10 CONTINUE END IF WRITE(*,1) F 1 F0RMAT(5X,'F=\E12.5) STOP END 9. Дан одномерный массиве числом элементов N<200. Сформировать два массива, один из которых состоит только из положительных элементов заданного массива, а другой — только из °тРицательных элементов. Решение: DIMENSION А(200),В(200),С(200) А - исходный массив, В и С - массивы, в которые будут записываться положительные и отрицательные элементы массива А READ(*,*) N,(A(I),I=1,N) N0=0 NP=o DO ю 1=1,N
100 ПРОГРАММИРОВАНИЕ НА ФОРТР^п IF(ACI).GT.O) THEN NP=NP+1 B(HP)-A(I) END IF IF(A(I).LT.O) THEN N0=N0+1 C(N0)=A(I) END IF 10 CONTINUE С NP - количество положительных элементов массива А, С а N0 - отрицательных IF(NP.GT.O) THEN WRITE(*,1) 1 FORMAT(5Х,'МАССИВ ИЗ ПОЛОЖИТЕЛЬНЫХ ЭЛЕМЕНТОВ') WRITE(*,*)(B(I),I=1,NP) END IF IF(NO.GT.O) THEN WRITE(*,2) 2 FORMAT(5X,'МАССИВ ИЗ ОТРИЦАТЕЛЬНЫХ ЭЛЕМЕНТОВ') WRITE(*,*)(C(I),I=1,N0) END IF STOP END 10. Дан двумерный массив с числом строк N<20 и числом столбцов М<15. Определить число строк, целиком состоящих из отрицательных элементов, и найти среднее арифметическое положительных элементов массива. Решение: DIMENSION А(20,15) READO,*) N,M,((A(I,J),I=1,N),J=1,M) K0L=0 SP=0.0
V4U И РЕШЕНИЯ 101 LP=0 DO 10 1=1,N L=0 DO 5 J=1,M IF(A(I,J).LT.O) L=L+1 IF(A(I,J).GT.O) THEN SP=SP+A(I,J) LP=LP+1 END IF 5 CONTINUE IF(L.Eq.M) KOL=KOL+l 10 CONTINUE WRITE(*,1) KOL 1 FORMAT(5X,'КОЛИЧЕСТВО СТРОК С ОТРИЦАТЕЛЬНЫМИ * ЭЛЕМЕНТАМИ =',12) IF(LP.GT.O) THEN SP=SP/LP WRITE(*,2) SP 2 FORMAT(5X,'СРЕДНЕЕ АРИФМЕТИЧЕСКОЕ ПОЛОЖИТЕЛЬНЫХ * ЭЛЕМЕНТ0В=',Е12.5) ELSE WRITE(*,3) 3 FORMAT(5X,'ПОЛОЖИТЕЛЬНЫХ ЭЛЕМЕНТОВ В МАССИВЕ НЕТ') END IF STOP END П. Дан двумерный массив с числом строк N<30 и числом толбцов М<20. Элемент этого массива назовем седловой точ- °И) если он является одновременно наименьшим в своей строке наибольшим в своем столбце. Найти все седловые точки мас- сЧва. Решение: FUNCTION NUMBER(В,N)
102 ПРОГРАММИРОВАНИЕ НА ФОРТР^ь С Подпрограмма-функция NUMBER определяет индекс С максимального элемента одномерного массива DIMENSION ВЦ) REAL МАХ NUMBER=1 МАХ=В(1) DO 5 1=1,N IF(MAX.LT.BCD) THEN MAX=B(I) NUMBER=I END IF 5 CONTINUE RETURN END PROGRAM SEDL С Головная программа с необязательным именем SEDL DIMENSION А(30,20) READ(*,*) N,M,((A(I,J),I=1,N),J=1,M) K0L=0 DO 5 J=1,M II=NUMBER(A(1,J),N) С Переменная II определяет индекс максимального С элемента в J-м столбце двумерного массива А DO 10 JJ=1,M IF(A(II,JJ).LT.A(II,J)) GOTO 5 10 CONTINUE С Нормальный выход из цикла означает, что элемент С A(II,J) является седловой точкой массива K0L=K0L+1 WRITE(*,1) II,J 1 FORMAT(2Х,'СЕДЛ0ВАЯ ТОЧКА ИНДЕКСАМИ 1=',12,'J=>,12) 5 CONTINUE С Переменная KOL определяет количество седловых С точек в массиве
3 а ДАЧИ И РЕШЕНИЯ 103 2 iF(KOL.Eq.O) WRITE(*,2) FORMAT(2Х,'СЕДЛ0ВЫХ ТОЧЕК НЕТ') STOP END 12. Дан трехмерный массив с числом элементов не более чем 10x20x30. Первый индекс массива определяет номер строки, второй индекс — номер столбца, третий — номер страницы. Определить номер страницы, сумма элементов которой является максимальной среди сумм элементов всех других страниц данного массива. Решение: DIMENSION А(10,20,30),В(30) С А - исходный массив, В - массив, предназначенный С для хранения сумм элементов всех страниц OPEN(1,FILE='DAN.DAT') READ(l.l) L.M.N READ(1,2),(((A(I,Y,K),I=1,L),J=1,M),K»1,N) 1 F0RMAT(3I2) 2 FORMAT(E12.5) DO 5 K=1,N S=0 DO 10 J=1,M DO 10 1=1,L S=S+A(I,J,K) *0 CONTINUE B(K)=S 5 CONTINUE KK=INDEX(B,N) Происходит обращение к подпрограмме-функции INDEX, которая определяет индекс максимального элемента одномерного массива WRITE(*,*)' НОМЕР СТРАНИЦЫ = *, КК
£4to 104 ПРОГРАММИРОВАНИЕ НА ФОРТ STOP END FUNCTION INDEX (A,N) DIMENSION A(N) INDEX=1 DO 5 1=1,N IF(A(I).GT.A(INDEX)) INDEX=I 5 CONTINUE RETURN END 13. Дан одномерный массив четырехзначных целых чисел с числом элементов не более ста. Определить, сколько различных чисел в этом массиве. Решение: INTEGER А(100),В(100) С А - исходный массив целых чисел, а В - массив, С предназначенный для хранения различных чисел С массива А OPEN(10,FILE= >DAN.DAT') READ(10,1) N READ(10,2) (A(I),I=1,N) 1 F0RMAT(I3) 2 FORMAT(14) K=l B(1)=A(1) DO 5 1=2,N DO 10 J=1,K IF(A(I)).EQ.B(J)) GOTO 5 С Если данное условие выполняется, то это означает, С что значение А(1) встречалось среди предыдущих С элементов массива и было записано в массив В
4 ПАЧИ И РЕШЕНИЯ 105 0 CONTINUE К=К+1 В(К)=А(1) 5 CONTINUE WRITE(*,20) К 20 FORMAT(2Х,' КОЛИЧЕСТВО РАЗНЫХ ЧИСЕЛ = ',13) STOP END 14. Даны два целых положительных числа Р и Q. Найти наибольший общий делитель этих чисел. Решение: INTEGER P,q WRITEC*,*) 'P=?,Q=?' READC*,*) P,Q M=N0D(P,Q) WRITEC*,*) 'НАИБОЛЬШИЙ ОБЩИЙ ДЕЛИТЕЛЬ = ',M STOP END FUNCTION NOD(M.N) 1 M1=MAX(M,N) N1=MIN(M,N) c Происходит обращение к библиотечным функциям МАХ и с MIN для расположения чисел в порядке N < М М=М1 N=N1 IF(M/N*N.EQ.M) THEN Если данное условие выполняется, то N является Нс^болыпим общим делителем чисел N0D=N RETURN ELSE
106 ПРОГРАММИРОВАНИЕ ИАФОРТРАДр M=M-N GO ТО 1 END IF RETURN END (*,yi) ' Рис. 1.12.2 15. На плоскости заданы N точек с декартовыми координатами X(I), Y(I), 1=1,... ,N, 3<N<50, которые являются последовательными вершинами выпуклого многоугольника, рис. 1.12.2. Написать программу, вычисляющую площадь этого многоугольника. Решение: DIMENSION X(50),Y(50) WRITE(*,*) 'N=?' READO,*) N WRITE(*,*)'ВВЕСТИ КООРДИНАТЫ ВЕРШИН МНОГОУГОЛЬНИКА' DO 5 1=1,N WRITEO,*) 'X(\I,')=?','Y(M,')=?' READ(*,*) X(I),Y(I) 5 CONTINUE С Осуществляется ввод координат вершин
д ПАЧИ И РЕШЕНИЯ 107 после появления на экране вопроса с номером соответствующей вершины S=0.0 DO 10 1=2,N-l ST=GER0N(X(1) ,Y(1) ,X(I) ,Y(I) ,X(I+1) ,Y(I+D) г Происходит вычисление площадей треугольников, С проходящих через 1-ю, 1-ю и (1+1)-ю вершшш S=S+ST Ю CONTINUE WRITEO.l) S 1 FORMAT (2Х,'ПЛОЩАДЬ = '.ЕЮ.'З) STOP END С Подпрограмма GER0N вычисляет полощадь треугольника С по известным координатам вершин FUNCTION GERON(X1,Y1,X2,Y2,X3,Y3) A=SQRT((X2-X1)**2+(Y2-Y1)**2) B=SQRT((X3-X2)**2+(Y3-Y2)**2) C=SqRT((X3-Xl)**2+(Y3-Yl)**2) P=(A+B+C)/2 GER0N=SqRT(P*(P-A)*(P-B)*(P-C)) С Используется формула Герона RETURN END
ЧАСТЬ 2 ЧИСЛЕННЫЕ МЕТОДЫ 2.1. ЭТАПЫ РЕШЕНИЯ ЗАДАЧ С ИСПОЛЬЗОВАНИЕМ КОМПЬЮТЕРА Можно выделить следующие основные этапы, показывающие логическую последовательность действий от постановки задачи до получения решения. 1. Общая формулировка задачи. Этот пункт, несмотря на кажущуюся простоту, чрезвычайно важен. Здесь необходимо сформулировать задачу в содержательных терминах и определить, что является "входными" данными задачи и что мы собираемся получить в результате решения. Недопустимо требование "найти то, сам не знаю что". 2. Математическая формулировка задачи. Здесь необходимо определить математические величины, которые будут описывать задачу, и получить математические связи между ними, т.е. составить математическую модель. Этот этап является критическим, поскольку неправильная или плохая модель сводит на нет все дальнейшие усилия. В то же время во многих случая* этот этап является очевидным, если есть общепринятые уравнения, описывающие рассматриваемый класс задач. 3. Выбор математического метода решения. Здесь необходимо на основе накопленного арсенала математических методов выбрать тот, который целесообразно использовать для ре~ шения поставленной задачи. Как правило, этот выбор осуШе" ствляется исходя как из субъективных причин (знание тех ил#
?ТАПЫ РЕШЕНИЯ ЗАДА Ч 109 лих математических методов), так и объективных причин, к которым в первую очередь необходимо отнести имеющиеся ре- гурсЫ компьютера (память, быстродействие). При этом если яЛя получения решения требуются ресурсы, которые превосходят имеющиеся в наличии (чрезмерное время счета или недоступный объем памяти), то необходим поиск других математических методов, либо упрощение математической модели. 4. Составление алгоритма решения. Этот этап тесно связан с предыдущим и должен быть направлен в первую очередь на разработку эффективных алгоритмов, т.е. таких, которые требуют наименьшего количества ресурсов компьютера для своей реализации. 5. Составление и отладка программы. Этот этап может быть весьма трудоемким, особенно для начинающих программистов. При отладке больших программ целесообразно использовать специальные программные средства, облегчающие процесс нахождения ошибок. 6. Тестирование программы. На этом этапе изучаются проверочные решения для того, чтобы удостовериться в правильности работы алгоритма. Для этого решаются задачи с такими исходными данными, для которых известно достоверное решение, либо используются какие-то косвенные свидетельства. Так в ряде задач существует связь между исходными данными и результатами, например закон сохранения энергии, импульса и т.д. 7. Решение поставленной задачи и представление ре- 3Ультатов. Здесь наиболее существенным является удобный и я&глядный вывод результатов. Во многих случаях целесообразно Использовать графические программные средства для визуализации полученных данных. При решении конкретных задач некоторые из этих этапов К1°гут исключаться самой постановкой задачи. Например, если требуется вычислить значение некоторой функции ^ == f(x) при различных значениях аргумента х, то формула Данной функции является математической формулировкой за- ^и и при этом определяет метод вычислений.
110 ЧИСЛЕННЫЕ МЕТОДи 2.2. ПОГРЕШНОСТИ ВЫЧИСЛЕНИЙ При численном решении задач одной из важнейших характе. ристик является погрешность результата. Она складывается из трех составных частей: • неустранимой погрешности решения, обусловленной неточ^ ностью исходных данных; • погрешности метода решения задачи; • вычислительной погрешности, являющейся результатом округлений в процессе счета. Прежде чем перейти к рассмотрению отдельных видов погрешностей, введем некоторые характеристики точности. Будем обозначать точные значения величин буквами ж, у, г,..., а соответствующие им приближенные значения х*,г/*, г*,... Разность между точным и приближенным значением назовем абсолютной погрешностью числа Ах = х — х*. Однако величина Ах не характеризует точность результата, если не указан сам результат. Относительной погрешностью назовем отношение абсолютной погрешности к абсолютному значению приближенной величины 6х = Ах/\х*\. В отличие от абсолютной погрешности, которая чаще всего бывает размерной величиной, относительная погрешность — величина безразмерная и поэтому наиболее полно отражает реальную точность. Для величин близких по значению к единице, абсолютная $ относительная ошибки почти одинаковы. Для очень больших ил# для очень малых величин относительная и абсолютная ошибке представляются совершенно разными числами. Например, есл#
пГрЕШНОСТИ ВЫЧИСЛЕНИЙ 111 яНое значение некоторой величины равно 0.00006, а прибли- енное значение 0.00005, то абсолютная ошибка составляет всего л-^ в то время как относительная ошибка равна 0.2 или 20%. л другой стороны, если точное значение равно 100500, а приближенное значение 100000, то абсолютная ошибка составляет 500, х0тя относительная ошибка равна всего 0.005 или 0.5%. Рассмотрим основные виды погрешностей. Неустранимая погрешность решения обусловлена неточностью исходных данных, которые возникают в результате неточности измерений (инструментальная ошибка) или из-за невозможности представить необходимую величину конечным числом значащих цифр (ошибка округления). Например, инструментальная ошибка всегда возникает при проведении физического измерения, поскольку оно не может быть выполнено абсолютно точно. Если указано, что напряжение равно 8.53473689 в, то можно с уверенностью сказать, что несколько младших цифр не достоверны, так как невозможно измерить напряжение с такой точностью. Если же экспериментальный результат содержит небольшое количество значащих цифр, то также очевидно, что величина дана с некоторой ошибкой. Например, если дается промежуток времени в 3.5 с, то подразумевается, что существуют некоторые границы, внутри которых эта величина должна находиться, например 3.5 ± 0.1 с. Иногда подразумевается, что если для экспериментального результата не Указаны его возможные границы, то результат имеет точность п°ловины единицы младшего разряда, например 5.63 ± 0.005. Ошибки округления при задании исходных данных возни- Ка*от в том случае, когда величину невозможно представить ограненным числом значащих цифр, например число 7г. Таким бРазом, во многих задачах исходные данные известны неточно, е Мы знаем не сами величины, а некоторые области, в которых **й помещаются. Тогда по окончании вычислений мы также по- Учим не точное значение результата, а некоторую область, в °торой он размещается, даже если все вычисления проводились °**Но и без округлений. Соответствующая погрешность называ-
112 ЧИСЛЕННЫЕ МЕТОд^ ется неустранимой погрешностью решения. Погрешности метода решения задач очень часто возникаю^ при использовании численных методов. Действительно, многце математические задачи могут быть решены только приближенно хотя и возможно со сколь угодно большой точностью, так как лю. бой численный метод предполагает использование конечного числа арифметических операций. Например, вычисление функций заданных в виде бесконечных рядов, может быть осуществлено только с некоторой точностью (см. раздел 2.4). Отметим, однако, что существуют численные методы, которые для своей реализации требуют конечного числа арифметических операций. К таким методам относится, например, метод Гаусса для решения систем линейных уравнений (см. раздел 2.8). При решении численных задач на компьютере всегда возникают вычислительные погрешности, обусловленные ошибками округления в процессе счета, даже если все другие виды погрешностей отсутствуют. Исключения составляют задачи, в которых операции над данными выполняются точно, например в целочисленной арифметике. Однако в подавляющем большинстве вычислительных задач используются вещественные числа, операций над которыми выполняются с ошибками округления. Любое вещественное число х можно записать следующим образом х = т- 10р, где \т\ < 1, р — целое число. Множитель га называется мантиссой, р — порядком числа х. Запись числа х называется нормализованной, если 0.1 < \т\ < 1. В памяти компьютера действительные числа представляются я нормализованном виде, т.е. первая значащая цифра мантиссЫ не равна нулю. Записи чисел с одинарной точностью (четыре байта) соответствует для компьютеров IBM PC примерно 7 цифр в десятичном представлении мантиссы (0.1234567), а записи с двойной точностью (8 байт) соответствует 14 цифр в мантисс6
ПОГРЕШНОСТИ ВЫЧИСЛЕНИЙ 113 (0.12345678901234). Порядок р изменяется от -37 до +37 для одинарной точности и от -63 до.+63 для двойной точности. При сложении и вычитании действительных чисел происходит следующее. Порядки чисел сначала выравниваются, а за- ^ем мантисса меньшего по абсолютной величине числа сдвигается вправо на столько разрядов, сколько необходимо, чтобы порядки стали одинаковыми. После этого происходит сложение или вычитание мантисс. Например, предположим, что необходимо сложить два действительных числа и что в памяти компьютера мантисса может представляться четырьмя значащими цифрами, а порядок одной цифрой 1-е число 0.2567 • 103 = 256.7, 2-е число 0.1569 • 101 = 1.569. После выравнивания порядков имеем 0.2567 • 103, 0.001569 • 103. Очевидно, что сумма будет иметь больше четырех значащих Цифр в мантиссе. Результат до округления можно представить в виде суммы двух действительных чисел 0.2567 • 103 + 0.001569 -103 0.258269 • 103 = 0.2582 • 103 +0.6900 • 10"1. Большинство трансляторов Фортрана устроено таким об- Р&эом, что младшие разряды, не вошедшие в разрядную сетку, ^Расываются, что вносит ошибку отбрасывания, но экономит ^Шинное время. Относительная ошибка отбрасывания равна , где t — число значащих цифр в мантиссе. Если же в Р^Нсляторе применяется симметричное округление, то к самому ^аДщему разряду прибавляется 1, если отброшенное число на- Нается с ДИФРЫ 5 или с большей. Максимально возможная от- еИтельная ошибка округления в этом случае равна 1/2 • 10"t+1.
114 ЧИСЛЕННЫЕ МЕТОДА В следующих разделах будет показано, что округление пр^ сложении или вычитании чисел может приводить к значительной потере точности. Заметим, что умножение и деление веществен, ных чисел приводит, вообще говоря, к меньшей потере точности поскольку в этих случаях выравнивание порядков не происходит, Очень существенным является вопрос о том как ошибка возникшая в определенном месте программы, распространяется дальше, т.е. будет ли ее влияние больше или меньше в процессе выполнения последующих операций. Критическим случаем является вычитание двух почти равных чисел: даже при очень небольших ошибках в этих числах относительная ошибка результата может оказаться очень большой. Полученная ошибка будет распространяться дальше при выполнении программы и может привести к катастрофической потере точности решения задачи. Рассмотрим выражения для абсолютной и относительной ошибок результата четырех арифметичеких операций. Пусть имеются две величины х и у, а соответствующие им абсолютные ошибки — Ах и Ау. Тогда в результате сложения имеем х + у = х* + Ах + у* + Ау = (ж* + у*) + (Дяг + Ау). Отсюда ясно, что абсолютная ошибка суммы А(х + у) = Ах + Ау. (2.2.1) Абсолютная ошибка разности А(х -у) = Ах- Ау. (2.2.2) При умножении имеем ху = (ж* + Ах)(у* + Ау) = х*у* + Аху* + Дуя* + АхАу. Поскольку ошибки обычно гораздо меньше самих величин, то> пренебрегая произведением ошибок, получаем абсолютную ошибку умножения А(ху) « х*Ау + у*Ах. (2.2.3)
ПОГРЕШНОСТИ ВЫЧИСЛЕНИЙ 115 ггри делении имеем абсолютную ошибку j{3 приведенных формул несложно вывести соответствующие формулы для относительных ошибок: сложение # # 6(х + у) = — <fo + —^ 8у, (2.2.5) вычитание умножение деление Ч* -у) = ~г^6х - -1г—;6у> (2-2-6) х* — у* ж* — у* ф • у) = 8х + 8у, (2.2.7) £(ж :у) = 8х- 8у. (2.2.8) Следует отметить, что знак ошибки бывает известен в очень редких случаях, поэтому не следует думать, что, например, абсолютная ошибка увеличивается при сложении и уменьшается при вычитании. Если ошибки двух чисел имеют разные знаки, то все бУдет как раз наоборот. Ошибки округления в вышеприведенных формулах не учитываются, поэтому, если необходимо будет подсчитать, как распространяется в последующих арифметических операциях ошибка Результата, то следует к вычисленной по одной из формул ошибке пРйбавить ошибку округления. Рассмотрим распространение ошибки на конкретном при- 1 еРе. Пусть необходимо вычислить выражение V ={х- у)*, гДе Величины x,y,z имеют абсолютные ошибки Дх,Ду, Az со- ^тственно. Относительная ошибка разности согласно (2.2.6) ^Нивается формулой |As| + |Ay) |я-у| &х-у < —; ; h 8\.
116 ЧИСЛЕННЫЕ МЕТОДА Здесь (Si — ошибка округления, которая возникает при выпод. нении операции вычитания, а модули взяты потому, что не из. вестны знаки ошибок. Далее, из формулы (2.2.7) для относитель. ной ошибки V получим выражение 6v<S^y + — + 62< ]х_у{ + — + 61 + 62. Здесь #2 — ошибка округления, которая возникает при выполни нии операции умножения. Для величин 8\ и ^2 справедливы оценки 5\ < 10~*+1, 82 < 10~*+1, где t — число значащих цифр в мантиссе. Число в правой части неравенств является верхним пределом относительной ошибки округления при любой арифметической операции. Отметим, что даже если ошибки Ах, Ау и Az равны нулю, то, согласно полученной формуле, в величину V может быть внесена ошибка округления. Читателю самостоятельно предлагается рассмотреть вопрос, когда в этом случае значение V вычисляется абсолютно точно. Для сложных цепочек вычислений также могут быть получены оценки для распространения ошибок, причем, если последовательность вычислений длинная, то это может быть выполнено на компьютере. Однако в этом случае оценки оказываются очень завышенными и поэтому не представляют практического интереса. В заключение этого раздела приведем некоторые рекоменД^' ции, которые позволяют уменьшить погрешность вычислений: • если необходимо произвести сложение-вычитание длинной последовательности чисел, работайте сначала с наимеЯЬ' шими числами; • избегайте вычитания двух почти равных чисел, по возмо*' ности преобразуя формулы; • если необходимо сложить длинную последовательность ч^ сел, то общая ошибка уменьшается, если числа сначала сЛ° жить группами, а потом сложить частные суммы;
яЬ1ЧИСЛИТЕЛЬНЫЕ АЛГОРИТМЫ 117 • в любом случае сводите к минимуму число необходимых арифметических операций. 2.3. ВЫЧИСЛИТЕЛЬНЫЕ АЛГОРИТМЫ В процессе решения научно-технических задач на компьютере центральным звеном является вычислительный алгоритм. Дадим сначала общее определение. Алгоритмом называется конечная последовательность предписаний (правил), однозначно определяющая процесс преобраэованиия исходных данных в результат решения задачи. Вычислительные алгоритмы должны удовлетворять ряду требований. Во-первых, численное решение задачи, полученное с помощью построенного алгоритма, должно иметь требуемую точность, а во-вторых, используемый алгоритм должен быть численно устойчивым. Рассмотрим сначала первое требование, хотя оно, зачастую, связано со вторым. При фиксированных исходных данных точность решения задачи складывается из двух составных частей: а) погрешности метода решения задачи; б) вычислительной по- гРешности, являющейся результатом округления в процессе счета (см. раздел 2.2). Первая причина может отсутствовать, если ме- ТоД решения является математически точным, например процедура решения систем линейных уравнений методом Гаусса (см. Р^дел 2.8). Однако в большинстве случаев метод решения за- ^Чи обеспечивает только приближенное решение, например при Числении функций, заданных бесконечным рядом (см. раз- ^ 2.4). При этом, как правило, точность приближенного решетя Можно оценить не заранее, а только после получения реэуль- ^й. Вычислительные погрешности возникают практически в б°м алгоритме, поскольку арифметические операции с веще- Энными данными осуществляются с некоторой конечной точ- г Стью (см. раздел 2.2). При этом вычислительные погрешно- ** Могут приводить к катастрофическому падению точности, о
118 ЧИСЛЕННЫЕ МЕТОДА чем в следующих разделах будет рассказано на конкретных пр^ мерах. Поэтому при построении алгоритмов необходимо, пек возможности, стремиться к уменьшению влияния вычислитель, ных погрешностей на точность результата. Для этого участки алгоритма, где может происходить значительная потеря точно- сти, записываются особым образом, например, изменяется порядок выполнения арифметических операций или испольэуетсл двойная точность вычислений. Значит при построении алгоритмов необходимо учитывать наличие двух видов ошибок и стремиться к тому, чтобы вычислительный алгоритм давал решение поставленной задачи с требуемой точностью. Для реальных вычислительных задач исходные данные всегда известны с какой-то конечной точностью, хотя, возможно, и очень малой, поэтому построенный алгоритм должен быть численно устойчивым или хорошо обусловленным, т.е. при небольших изменениях исходных данных результат изменяется также незначительно. Будем называть небольшими такие изменения исходных данных, которые лежат в пределах ошибок их задания. Будем называть небольшими такие изменения результата, которые лежат в пределах допустимой точности решения. Требование численной устойчивости алгоритма является чрезвычайно важным и, если оно не выполняется, то алгоритм не имеет смысла. Приведем пример численно неустойчивой задачи. Пусть задана система двух уравнений с двумя неизвестными ЗООх + 400у = 700 100х + 133у = 233, (2.3.1) которая имеет решение х = 1,у = 1. Рассмотрим три системе которые получаются из исходной системы малым изменением #0' эффициентов ЗООх + 400у = 700 ЮОж + 133у = 232 , Г 300z + 400y = 700 \ ЮОж + 132у = 233 ,
^ЧИСЛИТЕЛЬНЫЕ АЛГОРИТМЫ 119 Г 300х + 400у = 700 (2.3.2) \ 100х + 132у = 234. оти системы имеют решения (х = — 3,у = 4), (х = 2, у = 1/4) и /д; = 3, у = —1/2) соответственно. Мы видим, что при изменении коэффициентов уравнения (2.3-1) на доли процента относительные изменения решения составляют сотни процентов. Причина численной неустойчивости решения геометрически интерпретируется тем, что на плоскости (х,у) прямые, определяемые уравнениями (2.3.1), почти параллельны друг другу и поэтому их точка пересечения, являющаяся решением, очень сильно зависит от изменения исходных данных. В приведенном примере причина численной неустойчивости заключена в математической формулировке задачи и не может быть устранена выбором метода и алгоритма решения. В дальнейшем будут приведены примеры задач, для которых могут быть построены как численно устойчивые, так и численно неустойчивые алгоритмы. Отметим, что заранее не всегда можно определить, является ли данный алгоритм численно устойчивым. В этом случае целесообразно проведение вычислительных экспериментов, в которых исходные данные изменяются в определенных пРеделах и исследуются соответствующие изменения решения. Проведение подобных численных экспериментов желательно во В(*х случаях, в том числе и для численно устойчивых алгорит- м°в, поскольку это позволяет сделать вывод о диапазоне измене- йя решения при неточном задании исходных данных. Введем понятие числа обусловленности, которое характери- Ует чувствительность алгоритма к неточностям в задании ис- АЦьсх данных. Любой вычислительный алгоритм можно трак- Вать как процесс преобразования некоторого конечного 7V- РНого вектора исходных данных А = (х\,..., xjy) в М-мерный , ^°Р результатов У — (уь...,ум) ( N и М, в частности, к Ут равняться единице). Отметим, что подобная трактовка л ^ место и при решении непрерывных задач, например диф- ^Циальных уравнений, поскольку при численном решении
120 ЧИСЛЕННЫЕ ME т0ДЫ необходимо вначале провести дискретизацию задачи, т.е. Не прерывную задачу приближенно заменить задачей с конечны^ числом данных. Определим норму векторов исходных данных и результате^ следующими формулами N 1/2 || ? ||= (Х>*?) , (2.3.3) г=1 М 1/2 11^11=(Е6^2) < (2-3.4) г'=1 где а,{ и Ь{ — заданные положительные числа. Весовые const в (2.3.3), (2.3.4) задаются, исходя из значимости данных по отношению друг к другу. Например, во многих случаях аг = 1/|^*|2, Ь{ — 1/|у*|2, где ж*, у* — характерные значения величин Х{ и у:. Пусть 8х = (5xi,..., 5ждг) — вектор погрешностей исходных данных. Тогда норма относительной погрешности задаета формулой D{8?, ?) = №$1, (2.3.5) 11*11 причем, как правило, D <С 1. Пусть вектору X соответствуй вектор результатов У , а вектору X + 5Х = (х\ + Sxi,..., ху^ 8xn) — вектор f + sf = (t/i + &уг, • • •, Ум + Ьум) • Норму относительной погрешности результата определим формулой II У II Рассмотрим все возможные векторы погрешностей 5Х , для # торых имеет место < г = const. Очевидно, что в ^ мерном пространстве точки, соответствующие таким вектор
^ЧИСЛИТЕЛЬНЫЕ АЛГОРИТМЫ 121 5Л , образуют шар, который обозначим fir. Причем для реальных задач г<1. Величина К (it) = lim r-»0 E{6lt, it) еПг D(6lt,lt) max sx (2.3.7) называется числом обусловленности вычислительного алгоритма. Цз (2.3.7) следует, что чем меньше К (л), тем меньше ошибки в исходных данных влияют на результат. Число обусловленности является важной характеристикой вычислительного алгоритма, хотя одно число не может в полной мере отразить чувствительность вычислительного процесса ко всем видам ошибок и неопределенностей. Теоретическое определение К(х) возможно далеко не для всех задач, поэтому часто используется приближенное значение числа обусловленности, которое находится решением нескольких задач с погрешностями из &пг <С 1 по формуле К(2)ъ max Щ^Ё1. (2.3.8) sxl--'SXn^D(SJt,f) Месь п — число решаемых задач, определяемое количеством наи- °°лее характерных типов погрешностей. Сделаем важное замечание. Пусть 5Х — вектор погрешностей исходных данных А . Тогда относительная точность решетя задачи меньше чем К (it) || 5~lt || / || it Улучшает суммарную точность. Для численного решения исследуемой задачи, как правило, ^Но построить несколько вычислительных алгоритмов, пос- ■г ьКу могут рассматриваться различные математические ме- ^ решения и, соответственно, различные алгоритмы, а кроме
122 ЧИСЛЕННЫЕ МЕТОд^ того, даже при реализации одного метода можно построить р^ ные алгоритмы. Встает вопрос: какой алгоритм из всех воз можных целесообразно выбрать? Однозначного ответа на этсь вопрос нет. Тем не менее, при выборе алгоритма нужно ру^а водствоваться двумя основными критериями: 1) алгоритм должен обеспечивать требуемую точность ре^ шения задачи и быть численно устойчивым, о чем говорилось выше; 2) алгоритм должен быть эффективным при использовании вычислительных ресурсов. Поскольку время счета зависит от типа компьютера, для характеристики алгоритма будем использовать требуемое для его реализации количество арифметических операций Т. Объем памяти, необходимый для реализации алгоритма, будем характеризовать максимальным количеством чисел М, которые одновременно хранятся в памяти машины. Отметим, что не существует четких правил построения эффективных алгоритмов, однако определенные приемы позволяют сделать алгоритм более экономичным. В следующих разделах на конкретных примерах будут рассмотрены некоторые из них. 2.4. ВЫЧИСЛЕНИЕ ФУНКЦИЙ Функция является фундаментальным математическим поя*' тием и присутствует в формулировках многих вычислительны* задач. Вычисление функции у = f(x) для заданного аргумента существенно зависит от вида функциональной зависимости. ^а правило, используются два основных способа задания функИ**} с помощью конечной формулы, которая может включать ст^ дартные функции sin(x), cos(x) и т.д., и с помощью бесконечно ряда по степеням ж, например в результате использования р*> Тейлора, или других степенных разложений. При этом станДаР ные функции — синус, косинус, экспонента, логарифм и т.Д- являются внутренними функциями языка программирован^*
^ЧИСЛЕНИЕ ФУНКЦИЙ 123 «счисляются с максимально возможной точностью. В первой ча- сТй книги приведен список библиотечных функций Фортрана. Число обусловленности для задачи вычисления функции У = f(x) для заданного аргумента (исходного данного) я определяется (см. (2.3.5) - (2.3.7)) формулой вд-да (ил, Тогда, если относительная точность аргумента К^\ « 8 , то относительная точность определения функции f(x) оценивается Например, для функции у = ехр(Юя) при х = 1, S ~ ю-4 величина е ~ 10~3. Пусть в задании функции присутствуют также параметры, которые задаются с некоторой ошибкой, т.е. у = (я, <*i,..., cw), где ai,...,aw — параметры. Тогда формулы для числа обусловленности и относительной ошибки результата усложняются. Этот случай желательно разобрать самостоятельно. Если функция задается с помощью конечной формулы, то погрешность вычисления функции при заданном значении аргумента определяется только вычислительными погрешностями и, к^к правило, значительно меньше величины (2.4.2). Однако и в Зтих случаях может быть существенная потеря точности, свя- За-нная с распространением ошибок, (см. раздел 2.2), которую °бычно можно устранить вычислениями с двойной точностью Нл** изменениями порядка вычислений. Пусть функция /(я) определяется бесконечным степенным РяДом оо /(z) = £a(n)x", (2.4.3) 71=0 ^е a(n) — заданная функция целочисленного аргумента п. Предлагается, что ряд (2.4.3) сходится при значениях аргумента я,
124 ЧИСЛЕННЫЕ МЕТОДА принадлежащих заданному отрезку [с, d]. Существует несколько достаточных условий сходимости степенных рядов, например . i ,. |а(п+1)| х lim ' , '" = g<l. (2.4.4) n-4oo |a(72j| V Для оценки числа обусловленности функции (2.4.3) необходимо иметь оценки для значения функции и ее производной. Эти ве- личины можно получить, исходя из априорных данных о поведении функции (если они известны), либо используя мажорирующие ряды |/(а?)| > аг + а2 + • • • + ап + • • • = Sa, (2.4.5) оо \f(x)\ = \J2па^х71-11 < ft + fa + • • • + /3n + • • • = Sp, n=0 для которых известны или могут быть найдены SQ и Sp. Тогда для числа обусловленности справедлива оценка К(х) < ^-\х\. (2.4.6) При вычислении ряда (2.4.3) нецелесообразно стремиться к большей точности вычисления чем (2.4.2), поскольку это не повышает конечную точность результата из-за неточности исходных данных. Пусть мы хотим вычислить при фиксированном х ря# (2.4.3) с точностью е. Это значит, что требуется просуммир0' вать N членов ряда (2.4.3), чтобы имело место |/0О - Е а(п)х"\ 2=2 < е. (2.4.7) Очевидно, что N зависит от е, т.е. N = N(e). Однако аналитй^ ское нахождение этой зависимости, как правило, вызывает боЛь шие трудности. Поэтому в практических вычислениях можно $а ступать следующим образом — суммировать члены ряда до Vе
0ЧИСЛЕНИЕ ФУНКЦИЙ 125 0р? пока отношение текущего члена ряда к предыдущей сумме fle станет меньше е. Соответствующая программа при заданном аргументе X и точности Е может иметь следующий вид READ (*,*)Х,Е F=FUNC1(X,E) WRITE 0,4) F 4 FORMAT (2X,'F=',E10.3) STOP END FUNCTION FUNC1(X,E) 1=0 FUNC1=0.0 1 V=C0EF(I)*X**I FUNC1=FUNC1+V 1=1+1 IF(V.GT.E) GOTO 1 RETURN END FUNCTION COEF(I), C0EF=1.0/(1+1) RETURN END Здесь присутствует обращение к подпрограмме-функции ^EF, которая вычисляет значение коэффициентов а(п) из (2.4.3) Рй любом целочисленном значении п. Конкретный вид этой про- Р^ммы для нас сейчас не существенен. Для контроля точности вычислений рекомендуется произве- и суммирование ряда с точностью Е и точностью Е/2 и срав- р^ь получившиеся результаты Fi и F<i- Если величина \F\ — 21/|^2| будет порядка Е или меньше, то с большой долей уве- ^Ности можно считать, что требуемая точность (2.4.7) достиг-
126 ЧИСЛЕННЫЕ МЕТОДА Подсчитаем число операций умножения действительных ^ сел 7\ по программе FUNC1 без учета арифметических операций осуществляемых в подпрограмме COEF. Пусть N — число членов ряда (2.4.3), которое требуется для получения точности Е. То. гда, поскольку операция возведения в степень выполняется мне гократным умножением, имеем лг N(N-1) N(N + 1) Tl~N+ { 2 ; = -±——Lm (2.4.8) Запишем подпрограмму FUNC2 для вычисления ряда другим способом ^ FUNCTION FUNC2(X,E) 1=0 U=1.0 FUNC2=0.0 1 V=C0EF(I)*U FUNC2=FUNC2+V 1=1+1 U=U*X IF (ABS(V).GT.E) GOTO 1 RETURN END В этом случае число операций умножения оценивается Г2 - 27V. (2.4.9) В реальных задачах величина N достаточно велика и, ^ скольку Т2/Т\ = 4/(7V + 1) , второй вариант программы знач**' тельно более эффективный по быстродействию. Конечно, & однократного вычисления ряда разница в быстродействии ^° жет оказаться ничтожной, но, как правило, функции вычис-Я ются для большого количества аргументов, и тогда это ыоУ^е оказаться критическим. Этот пример показывает, что даже Д
^ЧИСЛЕНИЕ ФУНКЦИЙ 127 простых алгоритмов могут быть написаны программы, существенно отличающиеся по эффективности. Поэтому при написании любых программ всегда нужно на это обращать внимание 0 стремиться к минимизации выполняемых арифметических операций. Рассмотрим вопрос о точности вычисления ряда (2.4.3) при фиксированном ж, не учитывая погрешности, обусловленные неточностью задания аргумента. Сделаем важное замечание: с точки зрения вычислений на ПК почти все ряды вида (2.4.3) оказываются "сходящимися". Действительно, если n-ik член ряда относится к предыдущей сумме членов меньше чем 10~8, то в результате их сложения сумма ряда не изменится (см. раздел 2.2). В этом смысле "сходится" сумма членов натурального ряда Sn = 1 + 2Н \-п при п —> оо. Соответствующий предел оценивается 5 = ,2П ,ч ~ Ю"8 -> п ~ 2 • 108 и S ~ 1014. 5 п(п+1) Поэтому, прежде чем проводить вычисления суммы ряда на компьютере, необходимо убедиться, что ряд является сходящимся. Для этого используются достаточные условия сходимости, например (2.4.4). Далее, если ряд сходится медленно, то для контроля точности результата можно использовать двойную точ- н°сть вычислений. В приведенных выше программах суммирование ряда будет Проводиться до тех пор, пока не выполнится условие прекращения суммирования. Однако при реальных вычислениях на компьютере достижение указанного условия может оказаться невы- °лнимым для медленно сходящихся рядов. Пример подобного ^яДа предлагается привести читателю. Поэтому в программу ™*Мирования ряда целесообразно вводить величину МАХ, зада- *ЧУю максимальное количество членов ряда, которое суммиру- Сл> например МАХ=10.000. Кроме того, в этом случае целесо- Р^эно ввести параметр ошибки IER, который принимает знание 0, если заданная точность достигнута, и значение 1, если
128 ЧИСЛЕННЫЕ МЕТОДА точность не достигнута при максимальном числе членов ряда. Соответствующая программа может иметь следующий вид READ(*,*)X,E,MAX CALL FUNC(F,X,E,MAX,IER) WRITE(*,4)F,IER 4 F0RMAT(2X,,F=,,E10.3,2X,,IER=,,I1) STOP END SUBROUTINE FUNC(F,X,E,MAX,IER) 1=0 U=1.0 F=0.0 IER=0 1 IF(I.GT.MAX) THEN IER=1 RETURN END IF V=C0EF(I)*V F=F+V 1=1+1 V=V*X IF(ABS(V).GT.E) GOTO 1 RETURN END Если ряд (2.4.3) медленно сходится, то иногда применяв преобразование ряда, которое позволяет улучшить сходимость Рассмотрим один из способов ускорения сходимости. Пусть р^ (2.4.3) можно представить в виде суммы двух рядов, один $ которых медленно сходится, но его сумма известна, а втор01 сходится достаточно быстро. Тогда ясно, что численно ну>^ просуммировать только быстросходящийся ряд и к получен^0 сумме прибавить аналитическое выражение для суммы друг°г ряда.
0ЧИСЛЕНИЕ ФУНКЦИЙ 129 В качестве примера рассмотрим следующую функцию: 00 1 /(*) = £(! + -)*". (2.4.10) 71° 71=1 Этот ряд, согласно (2.4.4), сходится, если \х\ < 1. Пусть х = 0.9999. В этом случае сходимость будет чрезвычайно плохой и даже для достижения относительной точности е — 10~3 требуется просуммировать огромное количество членов ряда. Перепишем (2.4.10) в следующем виде оо X № = Е*п+Е^- (2-4-и) 71=1 71=1 Первый ряд (2.4.10) является бесконечно убывающей геометрической прогрессией и поэтому 5>" = гЬ 71=1 а второй ряд (2.4.11) сходится очень быстро. В вычислительной практике помимо степенных рядов широко используются бесконечые ряды с тригонометрическими или Другими специальными функциями, например оо f[x) = \^ а{п) sin nz, 71=0 со f(x) = ]Pa(n)c5sn:z. (2.4.12) 71=0 ЛДЬ1 (2.4.12) называются рядами Фурье. Для численного сум- ^Рования этих рядов следует принимать во внимание сообразил, изложенные выше. *' Б. Самохин
130 ЧИСЛЕННЫЕ МЕТОдц 2.5. ИНТЕРПОЛЯЦИЯ В вычислительной практике часто приходится иметь дело функциями, значения которых известны только в заданных то^ч ках (узловых точках), например х 1 Лш хо 1 /ы хх /(«!) х2 /Ы хз /Ы ; Вместе с тем, в процессе решения многих задач возникает необходимость использовать значения функции для промежуточных аргументов. Для этого строят функцию <£(я), значения которой совпадают в узловых точках ж0, a?i,... со значением функции /(ж),а в других точках приближаются к ней. В дальнейшем, при решении задачи оперируют уже не функцией /(ж), а функцией ф(х). Задача построения такой функции ф(х) называется задачей интерполяции. К интерполяции можно прибегать и тогда, когда функция f(x) задана аналитически, но ее вычисление столь сложно, что вычисляются только несколько значений и по ним строят простую интерполирующую функцию, с помощью которой находят приближенные значения во всех остальных точках. Рассмотрим наиболее известные методы интерполяции. Графический метод. Для нахождения значения j/, соответствующего данному значению я, яужно проделать четыре операции: 1) выбрать из таблицы вблизи от х некоторые определенны6 удобные значения ж* и у*;, соответствующие друг другу, 2) нанести эти точки на обыкновенную клетчатую бумагу? 3) вычертить наилучшим образом подходящую кривую, изо" бражающую у = /(ж), 4) найти на кривой искомое значение у. В зависимости от числа точек, масштаба и тщательности, с кот^ рой были нанесены точки и вычерчена кривая, можно получи^ низкую, среднюю или высокую степень интерполяции.
ИНТЕРПОЛЯЦИЯ 131 Метод пропорциональных частей (линейная интерполяция). При использовании этого метода предполагается, что ^еЖДУ значениями жо, 3i,#2> • • ■ величина У изменяется линейно. дначение у, соответствующее данному значению х, лежащему меЖДУ Двумя точками хк и Xk+i, получается по формуле . Ук+i - Ук ( v У = Ук + (я - хк). ^А;+1 ~ хк Погрешность линейной интерполяции \f{x)-y\ <М\х-хк\, (2.5.1) (2.5.2) где М — значение наибольшой величины модуля производной \f(x)\ на отрезке [хк,хк+1]. Метод Лагранжа. Этот метод особенно важен потому, что им можно пользоваться для интерполяции даже в том случае, когда таблица содержит беспорядочную совокупность соответствующих друг другу значений х и у , причем шаг аргумента Дя не постоянен. Интерполяционный многочлен Лагранжа имеет вид (x-xi)...(x-xn) L(x) = f(x0) (xq - Xi) .. .(xq - xn) {x-xo){x-x2)...{x-xn) +J\xl)l -77 ч 7 H +f{Xn) (xi - ж0)(а?1 - x2). ■. {xi - xn) (x - x0)(x - Xi) ... (x - zn_x) (2.5.3) (xn - x0)(xn - Xi) ... (xn - xn-i) Приведем пример использования интерполяционного многочлена Лагранжа. Пусть имеются табличные данные X J /(*) 0 1 1 2 3 3 2 5 5 т, йгда = 1(х-2)(х-3)(х-5) + гх(х-Щх-5) (_2)(-3)(-5) 2(2-3)(2-5) +
132 ЧИСЛЕННЫЕ ME тодь х(х-2)(х-5) х(х-2)(х-3) _ 3 3 _ Hj . ЁН 3(3-2)(3-5) + °5(5-2)(5-3) ~ 10 6 + 15 + h Погрешность интерполяционной формулы Лангранжа мо^ но представить следующим выражением \f(x) - L(x))\ < ^JyK* ~ *о)(х -Xl)...(x- хп)\, (2.5.4) где Mn+i — значение наибольшей величины модуля производной |/п+1(ж)| на отрезке интерполирования [а, Ь]. При практической интерполяции встает вопрос: приведет ли выбор большого количества узлов к достаточно точному построению интерполирующей функции? Таким образом, возникает задача о сходимости интерполяционного процесса. Пусть задана треугольная матрица z(0) х{1) х(1) все элементы которой принадлежат отрезку [а, Ь]. Для некоторой заданной на отрезке [а, Ь] функции f(x) строится последовательность полиномов Лагранжа Ln(x), п = 0,1, 2,..., причем для построения Ln(x) в качестве узлов интерполирования используются все элементы n-ik строки нашей матрицы. Интерполяционный процесс называется сходящимся, если lim Ln(x) = /(ж), х G [а, 6]. п—>-оо Увеличение числа узлов и соответственно степени полиноМа Ln(x) ведет в свою очередь к увеличению погрешности из-за р0' ста производных |/(п)(:г)|. Кроме того, следует учитывать, чТ° некоторые функции не имеют производных высоких степеней т.е. не обладают достаточной гладкостью.
0ТЕРПОЛЯЦИЯ 133 Порядком гладкости функции называется максимальный цоряДок производной, который существует у функции во всех дочках области определения аргументов. Например, кусочно - линейная функция, изображенная на рис. 2.5.1 имеет нулевой порядок гладкости, поскольку в точках х\ и х2 не существует производных даже 1-го порядка. Параболическая функция f(x) — ax2 + bx + c имеет бесконечный порядок гладкости, поскольку для нее определены производные любого порядка. Порядок гладкости функции, имеющей разрывы 1-го рода, т.е. скачки значений функции в каких-то точках, принимается равным -1. В вычислительной практики широко используется интерполяция функций с помощью сплайнов. Термин сплайн произошел от английского слова spline, что в переводе означает рейка, стержень — название приспособления, которое применяли чертежники для проведения гладких кривых через заданные точки. Разобьем отрезок [а, Ь] узловыми точками а = хо < xi < ... < хт = Ь на т отрезков. Сплайном называется функция Snj(x), такая, что на каждом отрезке [x^zj+i], 0 < j < т — 1 — это полином п-ой степени "nj(x) = cloj + CLijX + • • • + anjXn, Xj < x < £j-fi, n > 1. (2.5.5) Функции (2.5.5) должны совпадать со значениями интерполируемой функции f(x) в узловых точках. Кроме того, накладываются дополнительные условия сопряжения в узловых точках \х\,..., zm_i) — сплайн-функции и их производные до некоторого значения v должны быть непрерывны, т.е. 51?(^+1) = 5^+1)(^+1), j-0,l,...,m-2, / = 0,1, ...,i/. (2.5.6) Дефектом сплайна d называется разность между степенью определяемых его полиномов п и порядком гладкости интернирующей функции (2.5.5), (2.5.6). Очевидно, что d — n — v. Условия сопряжения (2.5.6) приводят к системе линейных ^Равнений относительно коэффициентов {aoj,... anj}, причем ма-
134 ЧИСЛЕННЫЕ МЕТОДА трица системы будет разреженной, т.е. иметь большое коли^ ство нулей, что упрощает процедуру решения. Большое распространение получили сплайны с дефектом d ^ 1, например линейная интерполяция на рис. 2.5.1. Интерполяция кубическими сплайнами, т.е. п = 3, широко применяется в настоящее время. Используя значение интерпо- лируемой функции f(x) в узловых точках и условия сопряженил (2.5.6) с v = 1,2, получим систему линейных уравнений трех- диагонального вида, которая достаточно эффективно решается. Получившаяся сплайн-функция имеет дефект d = 1. Отметим, что кубические сплайны являются сплайнами минимальной степени, которые в узловых точках имеют непрерывную вторую производную, а следовательно, непрерывную кривизну. Непрерывность кривизны является обычным требованием при проектировании кривых и поверхностей различных технических объектов. Для кубических сплайнов, при условии задания значений функции fj и ее производной в узловых точках Xj) j = О,.. .,m можно получить достаточно простые формулы S3j{x) = ai(t)fj + a2(*)/j+i + MOfy/j + ^(O^/j+i* X ai{t) = (1 - t2){l + 2t), a2{t) = t2(3 - 2t), a3(t) = t(l - t)\ a4(£) = —t2(l — £)," hj = xj+i — Xj) t = (x — Xj)/hj. (2.5.7) Приведенные формулы кубической сплайн-интерполяции имею? непрерывные первые производные в узловых точках и дефект d = 2. Отметим, что главное отличие интерполяции сплайнами о? интерполяции многочленами Лагранжа состоит в том, что повышение точности связано не с увеличением степени полином^ а с уменьшением расстояния между узлами. Кроме того, повЫ" шение точности не влечет за собой требования существования У f(x) производных все более высокого порядка.
0ТЕРПОЛЯЦИЯ 135 Использование сплайнов первой степени называется линейной интерполяцией, или методом пропорциональных частей/рассмотренным выше. При этом интерполяционная функция непрерывна в узловых точках, а первые производные имеют разрыв. Да рис.2.5.1 показана линейная интерполяция для функции /(х), заданной в четырех узловых точках ж0, хь а?2, яз- Xq Xj Х£ Xj X Рис.2.5.1 Программа линейной интерполяции имеет следующий вид: FUNCTION FLIN(X.Y.N.XP) DIMENSION X(N),Y(N) DO 5 I-l.H-1 IF(XP.LE.X(I+D) GOTO 10 Если это условие выполняется, то точка ХР принадлежит отрезку с границами Х(1) и Х(1+1) CONTINUE .Xl-X(I) X2=X(I+1) Y1=Y(I) Y2=Y(I+1) FLIN=Y1+(Y2-Y1)*(XP-X1)/(X2-X1) RETURN END С С Б Ю
136 ЧИСЛЕННЫЕ МЕТОДА Здесь N — число узлов интерполяции, X — массив аргумец. тов, т.е. узловых точек, Y — массив значений функции в соо^ ветствующих узловых точках, ХР — заданная точка в пределах от Х(1) до X(N), FLIN — значение интерполирующей функции а этой точке. Интерполяция используется также для функций двух й большего числа леременных, значения которых известны в фик- сированном количестве узловых точек на плоскости, пространстве и т.д. Аналогично описанному выше одномерному случаю может быть составлен интерполяционный многочлен Лагранжа, который предлагается записать внимательному читателю для функции двух переменных. Опишем наиболее часто используемую интерполяцию с помощью линейных сплайнов (линейная интерполяция) на примере функции двух переменных. Пусть на плоскости (я, у) задано какое-то число узловых точек, в которых известно значение интерполируемой функции z = f(x, у). Рассмотрим область на плоскости, составленную из совокупности непересекающихся треугольников, вершинами которых являются заданные точки (см. рис. 2.5.2). Получившиеся треугольники будем называть конечными элементами. В пределах каждого конечного элемента интерполяционная функция z = ф(х) у) геометрически представляет собой плоскость, проходящую через три точки (a^i, j/i, ^1)? {x2,y2,Z2) И (x3)y3)Z3), Т'е ах + by + с z = —1— Здесь коэффициенты а, Ь, с, d выражаются формулами а = t/i(*3 - z2) - z1(y3 - у2) + (2/3*2 - У223), b = zi(x3 - x2) - xi(z3 - z2) + {z3x2 - z2x3), (2.5.9) с = xi(y2z3 - y3z2) - yi{x2z3 - x3z2) + zx(x2y3 - x3y2), d = хг(у2 - уз) - yi(x2 - x3) + (x2y3 - x3y2), (2.5.8)
0ТЕРПОЛЯЦИЯ 137 где ^ь^игз — значения интерполируемой функции /(я, у) в узловых точках, соответстенно, (#1, yi), (х2> уг) и (жз, Уз). Величина d присутствующая в знаменателе (2.5.8) не может обращаться в нуль, поскольку узловые точки (a?i, yi), (х2, У2) и (хз, Уз) не лежат на одной прямой. Рассмотренная сплайн-функция имеет деф- фект равный 1. Отметим, что разбиение области на конечные элементы, описанное выше, может быть проведено неединственным способом и соответственно интерполирующие функции будут разными. Например, на рис.2.5.2 конечные элементы могут быть также составлены из треугольников с вершинами {(ei,j/i), (а^Уг), ^4,у4)} и {(яъУ1),(яз,Уз),(я4)У4)}. Каких-то четких правил по °птимальному разбиению области на подобласти не существует. ЧЦнако можно порекомендовать выбирать конечные элементы в В1*Де треугольников, у которых углы лежат в диапазоне от 45 ^° 90°. В этом случае точность интерполяции будет несколько аЬцце. Для составления алгоритма линейной интерполяции необхо-
138 ЧИСЛЕННЫЕ МЕТОДА димо иметь условие, определяющее принадлежность точки с за. данными координатами данному треугольнику. УЬ S(^y2) *(*#) С(Х3Уз) Рис. 2.5.3 Из рис. 2.5.3 ясно, что для точки К, принадлежащей треугольнику ABC, сумма углов LAKB + LBKC + LAKC = 360°, а для точки М, не принадлежащей треугольнику, сумма углов LAMC+ IAMB + /.ВМС < 360°. Таким образом, если точка с координатами (я, у) принадлежит треугольнику ABC, то ai = а2 = a3 = arccosai + arccosa2 + агссоваз = 2тг, (xi - x)(x2 - ж) + (yi - y)(y2 - y) (2.5.10) у/(хг - ж)2 + (yi - у)2 • yf{x2 - ж)2 + (у2 ~ У)2' (х2 - х)(х3 - ж) + (у2 - у){Уз ~ У) у/(х2 - ж)2 + (у2 - У)2 • у/(хз - я)2 + (уз - У)2' (ж! - ж)(ж3 - ж) + (yi - у)(уз - У) y/(xi - ж)2 + (yi - у)2 • ^(жз - ж)2 + (уз - у)2 На основании изложенного, программа линейной интерполяции функции двух переменных имеет следующий вид: FUNCTION FLIN2 (Х1Д2,X3,Y1>Y2,Y3,Z1,Z2,Z3,N,X,Y) DIMENSION X1(N),X2(N),X3(N),Y1(N),Y2(N),Y3(N),
0ТЕРПОЛЯЦИЯ *Z1(N),Z2(N),Z3(N) DO 5 1=1,N IF(X.EQ.XKI) .AND.Y.Eq.Yl(I)) THEN FLIN2=Z1(I) RETURN END IF IF(X.Eq.X2(I) .AND.Y.EQ.Y2(D) THEN FLIN2=Z2(I) RETURN END IF IF(X.EQ.X3(I) .AND.Y.EQ.Y3(D) THEN FLIN2=Z3(I) RETURN END IF 5 CONTINUE С Если заданная точка (X,Y) совпадает с одной из С узловых точек, то искомая функция определяется С ее значением в этой узловой точке. К=1 FIMAX=0 DO 10 1=1 N A1=SCL(X1(I),Y1(I),X2(I),Y2(I),X,Y) A2=SCL(X2(I),Y2(I),X3(I),Y3(I),X,Y) A3=SCL(X1(I),Y1(I),X3(I),Y3(I),X,Y) С Подпрограмма SCL вычисляет косинус угла между С двумя векторами FI=AC0S(A1)+AC0S(A2)+AC0S(A3) IF(FI.GT.FIMAX) THEN K=I FIMAX=FI END IF 10 CONTINUE В цикле определяется номер К конечного элемента, которому принадлежит заданная точка (X,Y) CALL PARAM(A,B,C,D,Х1(К),Х2(К),ХЗ(К),Y1(K),Y2(K),
140 ЧИСЛЕННЫЕ МЕТОД^ *Y3(K),Z1(K),Z2(K),Z3(K)) С Подпрограмма PARAM определяет коэффициенты А,В, С C,D по формулам (2.5.9) FLIN2=(A*X+B*Y+C)/D RETURN END FUNCTION SCL(XA,YA,XB,YB,X,Y) R1=SQRT((XA-X)**2+(YA-Y)**2) R2=SQRT((XB-X)**2+(YB-Y)**2) SCL=((XA-X)*(XB-X)+(YA-Y)*(YB-Y))/(R1*R2) RETURN END SUBROUTINE PARAM(A,B,C,D,X1,X2,X3, *Y1,Y2,Y3,Z1,Z2,Z3) A=Y1*(Z3-Z2)-Zl*(Y3-Y2)+Y3*Z2-Y2*Z3 B=Z1*(X3-X2)-X1*(Z3-Z2)+Z3*X2-Z2*X3 C=X1*(Y2*Z3-Y3*Z2)-Y1*(X2*Z3-X3*Z2)+ *Z1*(X2*Y3-X3*Y2) D=X1*(Y2-Y3)-Yl*(X2-X3)+X2*Y3-X3*Y2 RETURN END Здесь N — число конечных элементов области, XI, Х2, ХЗ и Yl, Y2, Y3 — массивы координат вершин треугольников (конечных элементов) по осям х и у, Zl, Z2, Z3 — массивы значений функций в узловых точках, X, Y — координаты заданной точки в области, FLIN2 — значение интерполирующей функции в этой точке. Отметим важное обстоятельство. При вычислениях на компьютере достижение строгого равенства (2.5.10) может быть неосуществимо в силу конечной точности вычислений (см. раздел 2.2). Поэтому в программе принадлежность точки с координатами х, у конечному элементу определяется из условия: сумма углов c*i + с*2 + <*з, определяемых (2.5.10), должна быть наибольшей среди всех треугольников области.
^ХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ 141 Линейная интерполяция может быть также применена к пункциям трех и большего числа переменных аналогично изложенному выше. Экстраполяция. Если требуется найти f(x) для некоторого я, лежащего вне пределов таблицы, то следует прибегнуть к экстраполяции. Методы экстраполяции и интерполяции сходны, любой метод интерполяции может быть использован для экстраполяции. Основное различие заключается в точности получаемых результатов. Если закон, выражающий зависимость от х) известен, то ни интерполяция, ни экстраполяция не представляют трудностей. Все методы, за исключением метода линейной интерполяции, могут быть использованы если не с одинаковой легкостью, то с одинаковой степенью надежности, если интервал экстраполяции не слишком велик. Если закон изменения f(x) за пределами таблицы неизвестен, то экстраполяция немногим отличается от догадки, основанной на здравом смысле. 2.6. НАХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ Задача определения оптимальных параметров научно-технических и экономических задач приводит, как правило, к нахождению экстремума (максимума или минимума) функции одного или нескольких переменных. Задача поиска максимума функции *(#i,.. ,хп) сводится к минимизации функции [—Ф(хх,...жп)], потому, не ограничивая общности, будем рассматривать задачу п°иска минимума. Функция Ф(^1,.. .хп) называется целевой функцией. Приме- Рами таких функций могут служить: стоимость Ф выпускаемой продукции предприятия, характеристики летательных аппара- °в> расход электроэнергии в диспетчерских энергосистем и т.д. Значительные проблемы при поиске минимума Ф("^) возни- а1°т, когда размерность п вектора х = (#1,. . .хп) велика, по- ому при решении конкретных задач целесообразно стремиться
142 ЧИСЛЕННЫЕ МЕТОДА к уменьшению размерности. Это обычно достигается тем, что в исследуемой математической модели стараются сохранить толь^0 те переменные, которые сильнее других влияют на изменение це. левой функции. <Pooi Следует различать абсолютный и локальный экстремумы (сМ- рис. 2.6.1). Здесь отрезок [а, Ь] — допустимая область изменения переменной х. Тогда точки end будут точками локального ми- нинимума функции Ф(х), а точка d будет точкой глобального минимума. Отметим, что далеко не во всех задачах удается найтИ
^ХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ 143 оЯки глобального экстремума, поскольку функциональная зависимость от переменных может быть весьма сложной и зачастую е удается даже определить количество локальных экстремумов. Рассмотрим сначала поиск минимума для функции от одной переменной. Будем полагать, что известны границы отрезка [CL)b]) внутри которого непрерывная функция Ф(х) имеет один экстремум — локальный минимум (см. рис. 2.6.2). Разделим отрезок [а, Ь] точками ai, b\ на три равных отрезка [a,ai]> tai>bi], [&ьЧ и вычислим значение функции в точках а\ и Ь\. Очевидно, что если Ф(ах) < Ф(&1), то в интервале (bi,6) точка минимума находится не может и поэтому для нахождения экстремума следует рассматривать отрезок [а, Ь{\. Аналогично, если Ф(й1) > Ф(Ь1), то экстремум находится на отрезке [ai,b], если Ф(а1) = Ф{Ь\)) то на отрезке [ai,bi]. Далее, получившийся отрезок вновь разделим двумя точками на три равных отрезка и т.д. При задании абсолютной точности £, алгоритм завершается при условии, что длина отрезка после к-го деления станет меньше £, т.е. ш*<е- (2<и) В этом случае за приближенное значение точки локального минимума принимается середина получившегося отрезка. Изложенный алгоритм близок к методу "половинного деления" для нахождения корней уравнений, который изложен в раз- Деле 2.7. Соответствующая программа для заданной точности Е, границ отрезка А,В может иметь следующий вид: SUBROUTINE MIN1(A,B,E,X,FM) DO WHILE(ABS(B-A).GT.E) H=(B-A)/3.0 A1=A+H Bl=B-H PA1=FUNC(A1) FB1*FUNC(B1)
144 ЧИСЛЕННЫЕ МЕТОДА IF(FA1.LT.FBI) В=В1 IF(FAl.GT.FBl) А=А1 IF(FAl.EQ.FBl) THEN А=А1 В=В1 END IF END DO X=(A+B)/2.0 FM=FUNC(X) RETURN END FUNCTION FUNC(X) FUNC=X**2 RETURN END Здесь X и FM — приближенные значения координаты и функции локального минимума. В программе присутствует также обращение к подпрограмме-функции FUNC, которая определяет значение целевой функции для любого аргумента X, принадлежащего отрезку [А, В]. Для примера взята функция Ф(х) = х2. Рассмотрим методы поиска минимума функции многих переменных. Опишем сначала метод перебора. Идея алгоритма весьма проста. Вычислим в конечном числе точек области изменения переменных D значения функции Ф(!^) и сравним их между собой. Точка it = (zi,.. .яп), которая дает минимальное значение целевой функции, будет приближенным значением, минимизирующим Ф(1^). Точность определения минимума, причем глобального, определяется частотой заполнения области D рассматриваемым конечным множеством точек. Отметим, что при большой размерности п вектора ■f, т.е. при большом количестве переменных, алгоритм перебора станса вится неэффективным из-за большого объема вычислений. ДеИ"
^ХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ 145 зрительно, пусть область D — гиперкуб D = {аг- < Х{ < Ь{, 1 < г < п], котором ищется минимум Ф("^). Разобъем область D по каждой переменной на 10 частей. Тогда потребуется вычислить ф(Т^) в 10п точках. Пусть для нахождения Ф в каждой точке требуется выполнить к арифметических операций. Тогда для реализации алгоритма требуется ~ к • 10п операций. Для примера: k = 100, п = 10 и быстродействие около 10е оп/с. В этом случае для решения задачи необходимо ~ 106 с. ж 10 суток непрерывной работы компьютера. Однако при небольших размерностях п < 5 изложенный алгоритм является весьма эффективным методом поиска минимума Ф(я), особенно в случае сложного поведения функции и наличия нескольких локальных экстремумов. Соответствующая программа поиска минимума функции двух переменных XI ,Х2 в прямоугольнике D = {А\ < Х\ < Bi, &2 < Х2 < В2} имеет следующий вид: SUBROUTINE MIN2(A1,A2,B1,B2,X1,X2,FM,N1,N2) H1=(B1-A1)/(N1-1) H2=(B2-A2)/(N2-1) X1=A1 X2=A2 FM=FUNC(X1,X2) DO 5 11=1, N1 DO 5 12=1, N2 X10=A1+H1*(I1-1) X20=A2+H2*(I2-1) FT=FUNC(X10,X20) IF(FT.LE.FM) THEN FM=FT Xl=X10 X2=X20 END IF
146 ЧИСЛЕННЫЕ МЕТОДА 5 CONTINUE RETURN END FUNCTION FUNC(X1, X2) FUNC=X1**2+X2**2 RETURN END Здесь N1, N2 — число точек разбиения по каждой оси; XI, Х2, FM — значения координат и функции, в которой достигается минимум. Здесь также присутствует обращение к подпрограмме- функции FUNC, которая определяет значение целевой функции для любых аргументов XI,Х2, принадлежащих прямоугольнику D. В приведенной программе для примера взята функция Ф = х\ + х\ Для нахождения экстремумов большое распространение получили различные методы спуска. Идея этих методов заключало) ется в том, что исходя из некоторой начальной точки х = / (о) (о)\ - -^^ ( (1) (*Ь = [х\ ,.. .Хп ') перейти в следующую точку х — (х\ ',.. .Хп ) так, чтобы Ф(И? ) < Ф(1^ ). Наиболее широко используются методы градиентного спуска и покоординатного спуска (метод Ху ка-Дживса). v(0) В градиентном методе в начальной точке х вычисляются производные по каждой переменной, и на основе этого определяется направление максимального уменьшения функции Ф( $ ) в данной точке. Затем в данном направлении осуществляется ле- реход с шагом а к новой точке х и т.д. до тех пор, пока w придем в такую точку, где подобный переход приведет к воЗ' растанию Ф(1^). Если шаг h соответствует заданной точное?** нахождения точки минимума, то процесс прекращается, в пр0' тивном случае шаг уменьшается вдвое и найденная точка мин**' мума уточняется. Этот метод удобен, если производные фу#*' ции Ф(^) можно вычислить аналитически. В методе покоординатного спуска процесс начинает0*
^ХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ 147 а#же из начальной точки х . По первой переменной х\ осуществляется переход с шагом h в точку, которой соответствует меньшее значение Ф(1?). При этом другие переменные не изменяются, а точек сравнения три — начальная точка, сдвиг по первой координате с шагом h в одну и другую сторону. Затем из полученной точки аналогично осуществляется переход с шагом h по второй переменной и т.д. до п-и переменной. В результате переходим в некоторою точку х . Затем процесс повторяется до тех пор, пока происходит изменение координат точки. Теперь если шаг h соответствует заданной точности нахождения точки минимума, то процедура прекращается, в противном случае шаг h уменьшается вдвое и алгоритм повторяется. Этот метод особенно удобен, если производные функции Ф( х) невозможно или сложно вычислить аналитически. Заметим, что оба приведенных метода спуска позволяют находить только точку локального минимума. Если известно, что точек минимума несколько, то можно рекомендовать находить точки минимума из разных начальных точек. Тогда среди получившихся точек локального минимума можно выбрать наименьшую. Однако в общем случае это не гарантирует нахождение точки глобального минимума. При выборе шага h желательно учитывать априорную, т.е. Полученную извне, информацию о характере изменения функции н^этом размере. Для некоторых целевых функций целесообразен т^кже выбор неодинаковых шагов по координатам. Программа поиска минимума функции N переменных по ме- Т°ДУ покоординатного спуска может иметь следующий вид: SUBROUTINE MIN3(X0,X1,H,N,FM,KH) DIMENSION X0(N),X1(N),H(N) DO 5 1=1,N X1(I)=X0(I) CONTINUE K=0 S FM=FUNC(XO,N)
148 ЧИСЛЕННЫЕ МЕТОДА 25 DO 10 1=1,N X1(I)=X1(I)+H(I) F1=FUNC(X1,N) IF(Fl.LT.FM) THEN FM=F1 GO TO 10 END IF X1(I)=X1(I)-2*H(I) F1=FUNC(X1,N) IF(Fl.LT.FM) THEN FM=F1 GO TO 10 END IF X1(I)=X0(I) 10 CONTINUE С Цикл покоординатного спуска из точки ХО в XI IF(RX01(X0,X1,N).EQ.0.0) THEN С При выполнении условия точка XI совпадает с ХО и С уменьшаются шаги по координатам, при условии К<КН К=К+1 IF(K.LE.KH) THEN С Если К > КН, то алгоритм завершается DO 15 1=1,N H(I)=H(I)/2«0 15 CONTINUE GO TO 25 ELSE RETURN END IF ELSE DO 30 1=1,N X0(I)=X1(I) 30 CONTINUE GO TO 35 С Запуск из новой начальной точки ХО
НАХОЖДЕНИЕ ЭКСТРЕМУМА ФУНКЦИИ 149 END IF RETURN END FUNCTION RX01(X0,X1,N) DIMENSION X0(N),X1(N) R=0.0 DO 5 1=1,N R=R+(X0(I)-X1(I))**2 CONTINUE RX01=SQRT(R) RETURN END FUNCTION FUNC(X.N) DIMENSION X(N) FUNC=0.0 DO 5 1=1,N FUNC=FUNC+X(I)**2 CONTINUE RETURN END Здесь X0.X1 — массивы координат начальной и промежу- т°нной точки, Н —массив шагов по координатам, FM — значение Функции, в которой достигается минимум, КН — параметр, порывающий сколько раз можно уменьшить шаг вдвое в процессе "волнения алгоритма (например, если КН=5, то наименьший шаг УДет Н/32). Величины XO,H,N,KH должны быть заданы и Пересы в подпрограмму при ее вызове. После выполнения подпро- Р^ммы массив ХО определит координаты точки минимума, a FM эначение функции в этой точке. Подпрограмма RX01 предна- ^Чена для определения расстояния между точками в N-мерном ^странстве, а подпрограмма FUNC определяет эначение целе- И функции для заданного массива аргументов X. В приведенной °грамме для примера взята функция Ф = х\ + • • • + х\.
150 ЧИСЛЕННЫЕ МЕТОд^ 2.7. РЕШЕНИЕ УРАВНЕНИЙ Нахождение корней уравнения — одна из древнейших мате. матических задач, которая часто встречается и сегодня в раз. личных областях науки и техники. Простейшим нелинейным уравнением является квадратное уравнение ах2 + Ьх + с = 0, (2.7.1) корни которого описываются формулой -Ъ ± у/Ь2 - 4ас *!,, = £ ' (2'7'2' Численное нахождение корней по (2.7.2) элементарно. Однако на этом примере хотелось бы обратить внимание на следующее важное обстоятельство. Вычислительный алгоритм должен быть построен так, чтобы он давал правильный результат при всех возможных исходных данных из области их определения (область определения является неотъемлимой частью алгоритма и должна быть тщательно описана). В рассматриваемом случае будем полагать, что областью определения исходных данных являются любые действительные числа а, 6, с. Тогда при а = О формула (2.7.2) теряет смысл, поскольку уравнение (2.7.1) становится линейным. Таким образом, в алгоритме должны бы?ь предусмотрены все возможные ситуации. Программа нахожДе' ния действительных корней уравнения (2.7.1) при любых а,М может иметь следующий вид: WRITEC*,*)^^,^ READ (*,*) А,В,С IF(A.NE.O.O) GOTO 2 IF(B.HE.O.O) GOTO 3 IF(C.NE.O.O) WRITE(*,4) IF(C.EQ.O.O) WRITE(*,*) 5 STOP
?0ЕНИЕ УРАВНЕНИЙ 151 3 Х""С/В HRITE(*,6) X STOP „ ' D=B**2-4.0*A*C IF(D.GE.O.O) GO TO 8 • WRITE(*,4) STOP 8 SD=SQRT(D) X1=(-B+SD)/(2.0*A) X2=(-B-SD)/(2.0*A) WRITE(*,7) XI,X2 4 FORMAT (2X,'ДЕЙСТВИТЕЛЬНЫХ КОРНЕЙ НЕТ') 5 FORMAT (2X,'КОРЕНЬ - ЛЮБОЕ ЧИСЛО') 6 FORMAT (2Х,'КОРЕНЬ УРАВНЕНИЯ Х=',Е10.3) 7 FORMAT (2Х,' КОРНИ УРАВНЕНИЯ Х1=',ЕЮ. 3, 2Х,' Х2=', * Е10.3) END Во многих научно-технических задачах коэффициенты а, 6, ^являются комплексными числами и требуется нахождение комплексных корней уравнения. В этом случае (2.7.2) остается спра- ВеДливой, но извлечение квадратного корня понимается в комплексном смысле. Полагая, что \а\ ф 0, запишем программу нахождения комплексных корней уравнения (2.7.1) COMPLEX A,B,C,D,SD,X1,X2 WRITE(*,*)'A,B,C READ(*,*) А,В,С D=B**2-4.0*A*C SD=CSqRT(D) Xl=(-B+SD)/(2.0*A) X2=(-B-SD)/(2.0*A) x WRITE(*,1) xi,X2 P0RMAT(2X,'X=',Ei0.3,lX,E10.3,'i')
152 ЧИСЛЕННЫЕ МЕТОд^ STOP END После завершения работы программы на экране появятся дВе строки с корнями уравнения. В конце каждой строки будет на. ходится символ i, показвающий мнимую часть корня. Кубическое уравнение вида х3 + ах2 + Ьх + с = О (2.7.3) имеет, в общем случае, три корня, которые описываются формулами Кардано А _|_ Г> А D хх = -а/Ъ + А + В, z2)3 = -a/3 — ±г—^—\/3. (2.7.4) Здесь A=\/-l + VQ, B = ^J-q--./Q, a\3 ab 5) причем в качестве Аи В берутся любые значения кубических корней, удовлетворяющие соотношению АВ = —р/3. Если уравнение (2.7.3) действительно, то следует брать действительные значен^ этих корней. Рассмотрим уравнение четвертой степени х4 + ах3 + bx2 + cx + d = 0, (2.7-6' которое, в общем случае, имеет четыре решения. Корни урав# ния (2.7.6), согласно методу Феррари, совпадают с корнями ДБ^ квадратных уравнений х2 + (а + А) | + (у + ^^) = О, А = ± V8y + а> - 46, (2-771
г>$ЩЕНИЕ УРАВНЕНИЙ 153 де У — любой корень кубического уравнения 8г/3 - АЪу2 + {2ас - Ы)у + d(4b - а2) - с2 = 0. французским математиком и революционером Галуа было доказано, что для алгебраических уравнений, начинал с пятой степени, не могут быть получены соответствующие конечные формулы в общем случае. Для алгебраического уравнения пятой степени с действительными коэффициентами вида х5 + ах4 + Ьх3 + сх2 + dx + f = 0 (2.7.8) можно использовать следующий численный метод. Поскольку степень уравнения нечетная, то уравнение имеет, по крайней мере, один действительный корень. Это следует из того, что при х —У +оо и при х —> —оо функция имеет разные знаки, а значит, пересекает ось абсцисс. Этот корень может быть найден с помощью метода "половинного деления" (см. ниже). Затем делением (2.7.8) на (х — xi) где х\ — найденный корень, приходим к алгебраическому уравнению четвертой степени, для нахождения корней которого используются точные формулы. Программы для нахождения корней алгебраических уравнении третьей, четвертой и пятой степени предлагается составить ^тателю. В общем случае, аналитические формулы для решения функционального уравнения f{x) = 0 (2.7.9) Вестны только для узкого класса функциональных зависимо- еи- Поэтому для нахождения корней уравнений общего вида ^Меняются, как правило, приближенные методы. При этом , е-ЧУет отметить, что нет общих методов нахождения всех ре- **йй (2.7.9), поэтому рассматриваемые ниже численные алго- ^ьг применяются для нахождения одного из решений. Пусть задана непрерывная на отрезке [а, Ь] функция /(ж), ия /(а) и f(b) имеют разные знаки. Тогда уравнение
154 ЧИСЛЕННЫЕ МЕТОд> (2.7.9) имеет на [а,Ь], по крайней мере, одно решение, котор0 будем считать единственным (рис. 2.7.1). В этом случае дл нахождения корня можно использовать метод "половинное деления" или бисекции. Разделим отрезок [а, Ь] пополам точкой сх = (а + Ь)/2 и выберем для дальнейшего деления ту половину отрезка, на концах которого f{x) имеет разные знаки. Получив. шийся отрезок вновь делим пополам точкой c<i и т.д. Алгоритм завершается, если для какого-то номера деления к оказываетсл f(ck) = 0. Тогда значение корня х = с^. Рйс 2.7.1 Если задана абсолютная точность определения корня е) т° алгоритм завершается при условии, что длина отрезка после * го деления станет меньше, т.е. (Ь — а)/2к < е. В этом случае эа приближенное значение корня х принимается значение с*;, при^ очевидно, что \х -ск\ < 2к < е. Соответствующая программа для заданной точности Е, rpatf** отрезка А, В может иметь следующий вид: FUNCTION C0R(A,B,E)
РЕШЕНИЕ УРАВНЕНИЙ 155 DO WHILE (ABS(B-A).GT.E) C=(A+B)/2.0 FC=FUNC(C) IF(FC.NE.O.O) GOTO 1 C0R=C RETURN i FA=FUNC(A) FAC=FA*FC IF(FAC.LT.O.O) B=C IF(FAC.GT.O.O) A=C END DO C0R=(A+B)/2.0 RETURN END FUNCTION FUNC(X) FUNC=X RETURN END Здесь присутствует обращение к подпрограмме-функции FUNC, которая определяет значение функции f(x) для любого ар- гУмента х, принадлежащего отрезку [а, 6]. В приведенной про- гРамме для примера взята функция f(x) = х. Изложим метод простой итерации. Запишем уравнение 12.7.9) в виде х = <р(х), (2.7.10) Построим последовательность {$(*)} по формуле *(*+1> = ¥>(*(*)), ife = 0,1,2,..., (2.7.11) Де х\°) — начальное значение, которое требуется задать. Опре- ^Им отрезок 5, который является г — окрестностью точки х(°\ *е- S = {х : \х — ж(°)| < г}. Пусть отображение <р(х) является ^Мающим в 5, т.е. для любых х\}Х2 G S имеет место \<p(xi) - <р{х2)\ < <*\*1 - *2\, (2.7-12)
156 ЧИСЛЕННЫЕ МЕТОдк где коэффициент сжатия а удовлетворяет неравенству О < ос < 1. (2.7.Ц Пусть также |^(х(°))-х(°)|<(1-а)г. (2.7.14) Доказывается, что при выполнении (2.7.12)—(2.7.14) на отрезке S существует единственное решение (2.7.10), к которому схо~ дится последовательность (2.7.11) с начальной точкой х(°\ Описанный метод называется методом простой итерации и широко используется при решении алгебраических уравнений. Можно показать, что справедлива следующая оценка погрешности после к-го шага итерации \х№ -х\< акг, (2.7.15) где х — точное решение (2.7.10). Из приведенной оценки можно найти требуемое число итераций к = \n(e/r)/ In а для достижения заданной точности е. % Проверка выполнения условия (2.7.12) может оказаться довольно затруднительной для многих задач. Поэтому часто используется более сильное условие, из которого следует (2.7.12). Пусть функция (р(х) является дифференцируемой на 5 и для любого х € S имеет место d(p(x) dx <а< 1. Тогда выполняется неравенство (2.7.12) и значит, при выполнении условия (2.7.14), итерации (2.7.11) сходятся к решение (2.7.10). Для иллюстрации рассмотрим определение корня уравнен*** х = 7г/2 sin х на отрезке \х —1.5| < 0.1. Несложно увидеть, что на этом отре^ выполняются приведенные условия с а = 0.267. Тогда перя^ две итерации (2.7.11) дают значение корня с четырьмя вернЫ^
р$ШЕНИЕ УРАВНЕНИЙ 157 знаками после запятой. Точное значение корня х = тг/2. На йс. 2.7.2 геометрически представлена сходимость итерационного процесса. Рис. 2.7.2 Соответствующая программа для заданной точности Е и начальной точности ХО может иметь следующий вид: SUBROUTINE SIMPE(XO,REZ,E,MAX,KOL) K0L=0 1 X=FUNC(X0) K0L=K0L+1 IF(KOL.EQ.MAX) THEN REZ=X RETURN END IF IF(ABS(X-XO).LE.E) THEN REZ=X RETURN ELSE X0=X GOTO 1 END IF RETURN
158 ЧИСЛЕННЫЕ МЕТОд^ END FUNCTION FUNC(X) FUNC=ASIN(1.0)*SIN(X) RETURN END Параметр MAX определяет максимальное количество итера- ций, которое может быть реализовано в процессе исполнения алгоритма, и введен для того, чтобы не было зацикливания программы при неправильном задании исходных данных. Переменная K0L определяет, какое количество итераций было фактически реализовано в алгоритме. С данной программой полезно поэкспериментировать с целью определения зависимости скорости сходимости, т.е. количества требуемых итераций для получения заданной точности, от начальной точки ХО. Теперь изложим метод Ньютона для решения уравнения вида (2.7.9) на отрезке S. Пусть f(x) — дифференцируемая функция, причем f'(x) ф О, х 6 S . В точке ж(°) произведем линеаризацию, т.е. заменим f(x) линейной функцией, проходящей через ж(°) и имеющей производную f(x^). Получим уравнение f(xW)+f(xW)(x-xW) = 0, корень которого определяется формулой (!) = *(°) - Я*(0)) /'(ж(°))' Далее, производя линеаризацию (2.7.9) в точке х^ аналогией0 получаем х^2\ затем z(3) и т.д. Таким образом, для проиэвоЛь ного к имеем формулу f'(xwy {
р$Ц1ЕНИЕ УРАВНЕНИЙ 159 аетод Ньютона также называется методом касательных, что ^ответствует геометрическому смыслу линеаризации на одном шаге (рис. 2.7.3). хю xi"} Рис. 2.7.3 Несложно видеть, что метод Ньютона является методом простой итерации для уравнения (2.7.10) со специально подобранной Функцией (р(х) = х - /'(»)' (2.7.17) Ясно, что поскольку f'(x) ф 0, то (2.7.10), (2.7.17) эквивалентны Уравнению (2.7.9). Поэтому, используя условия для сходимости Граций (2.7.11) к решению (2.7.10), получим |/(х)/"(х)| ТГ~ <а< 1. 1Л*(0))1 \п*щ < (1 - а)г. Отметим, что оценка (2.7.15) для скорости сходимости ите- Чай (2.7.16) получилась слишком грубой, поскольку в этом слу- сходимость квадратична по а на каждом шаге.
160 ЧИСЛЕННЫЕ МЕТОДА Если известна аналитическая формула для производи функции /(ж), то программа для данного метода мало чем 0^ личается от программы для метода простой итерации , котор^ приведена выше. Если такой формулы нет, то нецелесообразно использовать данный метод. 2.8. РЕШЕНИЕ СИСТЕМ ЛИНЕЙНЫХ УРАВНЕНИЙ Системы линейных уравнений используются во многих областях науки и техники и являются наиболее часто встречающимися типами математических задач. В общем виде система п уравнений с п неизвестными записывается следующим образом ацХ\ + CL12X2 + \-ainxn = bi a2\Xi + CL22X2 Н h a2nxn = b2 aniXi + an2X2 + \-annxn = bn. (2.8.1) Здесь zi,..., xn — неизвестные величины; {%■}, i, j = 1,..., я, {Ь{}, г = 1,...,тг — заданные действительные числа. Система (2.8.1) может быть записана также в матричном виде А$= Y, (2.8.2) где X = (xi,..., хп), Ъ = (Ъ\,..., Ьп) — вектора в тг-мерном пр0' странстве, А — {a,ij} — линейный оператор в этом пространстве т.е. матрица размерности п X п. Доказывается, что если определитель матрицы не равен нЯ1*0, то.система (2.8.1) имеет единственное решение. Ниже будем я0' лагать, что это условие выполняется. В пространстве n-мерных векторов Rn введем эвклиД0^ норму и скалярное произведение по формулам II ь ||= N £>?, (?,?)=][>, (2.8-3) г=1
СИСТЕМЫ ЛИНЕЙНЫХ УРАВНЕНИЙ 161 гг0гда для нормы линейного оператора А справедлива оценка II А ||< N Е4- (2-8-4) м=1 Пусть матрица А задается точно, а при задании правой части Ь в (2.8.2) возможны погрешности. В этом случае, число обусловленности (см. раздел 2.3) рассматриваемой задачи оценивается формулой К <\\ А || • || А-1 ||, где А"1 — обратная матрица. Иногда используется другая оценка для числа обусловленности т^ ^ Итах| ~ IЛ -Г гДе Атах и Ат,п — наибольшее и наименьшее по модулю собственные числа матрицы А. Если и матрица А, и правая часть b в (2.8.2) задаются с погрешностями, то формула для относительной погрешности решения имеет вид Н^.1^ к \\Х\\ -1-*||*А||/||Л|| \\Щ \\8_b_ ИИ \\?\ (2.8.5) ■\ —»■ °Десь 5Х — вектор погрешности решения при погрешности S Ъ ВеКтора Ь и погрешности SА матрицы А, К — число обусловлен- н°сти матрицы А. Отметим, что формула (2.8.5) справедлива Ри малых ошибках в задании матрицы А, а именно кШ <, (,8.6) Существуют два основных класса методов для решения си- ^ линейных уравнений — прямые и итерационные. Прямые *А'Ь. Самохин
162 ЧИСЛЕННЫЕ ME 1% методы характеризуются тем, что при абсолютной точности в числений точное решение системы может быть получено с по\* щью конечного числа арифметических операций. Итерационна методы характеризуются тем, что даже при абсолютной т0. ности вычислений за конечное число арифметических операц^ может быть получено только приближенное решение систем^ хотя возможно и очень близкое к точному. Однако при реальных вычислениях на компьютерах указанное различие теряет свой смысл, и для многих задач итерационные методы оказываются более предпочтительными, нежели прямые. Рассмотрим сначала прямые методы. Наиболее известным является метод Гаусса, поскольку другие методы являются, как правило, его модификацией. Алгоритм метода Гаусса состоит из следующей последовательности шагов. 1. Исключение неизвестной х\ из всех уравнений (2.8.1), кроме первого. Полагал ап ф О, из первого уравнения имеем xi = (а12х2 Н Ь ainxn) Н . (2.8.7) ац ац Если ац = 0, то переставим строки матрицы А так, чтобы в левом верхнем углу оказался ненулевой элемент. В первом столбце такой элемент всегда найдется, иначе det А = 0. Перенумеровав соответствующим образом элементы матрицы А ичвектора Ь- придём к системе (2.8.1) с ац ф 0. Далее, подставляя (2.8.7) в° 2-е, .. .,7г-е уравнение (2.8.1), получаем систему вида anxi + ai2x2 Н VcL\nxn = h 4^2 + ---+4ла:п = ь[1) a^)x2 + ... + al1n)xn = b{nl). (2.8.8) где элементы матрицы а\ , 2 < г, j < п и вектора b\ , 2 < г'6 определяются формулами (1) 1
С0СТЕМЫ ЛИНЕЙНЫХ УРАВНЕНИЙ 163 Ь-Х) = bi ацЬг. ап 9 Исключение неизвестной x<i из всех уравнений (2.8.8), кроме (i) первого и второго. Полагая а^2 ф 0, из второго уравнения имеем 1 6(1) х2 = —щ(4з *з + • • • + <4nZn) + -Jjy. (2.8.9) Если а^2 = 0, то выполним, как и выше, перестановку строк матрицы со второй по п-ю так, что перенумеровав элементы а-- , 2 < г, j < п, получим а^2 / 0. Очевидно, это всегда возможно, поскольку в противном случае det А = 0. Далее, подставляя (2.8.9) в 3-е,... ,п-е уравнение (2.8.8), получаем систему вида anxi Н \-ainXn = &1 а^жг + • • • • • • + cQxn = b[l) 4зжз + "- + 45жп = b£2) 423)^3 + --- + 42n)xn = bl2), (2.8.10) гДе элементы матрицы а\-\ 3 < i, j < п и вектора b\ , 3 < г < п °пределяются формулами а(2) _ fl(i) _ JL^OJi) a«'i ~at"i (1)аг2 a2J' °i — °i (i) ai2 °2 " a22 ^ee, продолжая процесс исключения, переставляя при необхо- Мости строки так, чтобы а(2) / 0 (n-2) , Q а33 7е и> • • • j an-l,n-l 7е и>
164 ЧИСЛЕННЫЕ М S?% после (n - 1)-го шага, получаем систему уравнений aii^i Н bainzn = Ь 1 а22 ^2Т "Г «271 x™ — t>2 alr'^n = 6ln-1}. (2.8.11) с верхней треугольной матрицей. Преобразование исходной системы (2.8.1) к системе (2.8.Ц) называется прямым ходом. Процедура нахождения неизвестных из (2.8.11) называется обратным ходом. Соответствующий алгоритм очевиден и состоит в последовательном нахождении переменных хП)..., х\ по формулам Хп = Ь(п-1) v/.("-2)_>-2), *n-l,n-l Xn-l — (п_2) \°n-l ап-1,пХп) xi = —{bi-ainxn ai2x2). an В силу сложности алгоритма метода Гаусса вычислительные ошибки могут приводить к значительной потере точности Vе' шения. Для уменьшения вычислительной погрешности целесообразно производить перестановку строк матрицы так, чтобы ведущий элемент на к-м шаге исключения был наибольшим я° модулю среди элементов fc-ro столбца матрицы, которые учас?' вуют в дальнейшем исключении, т.е. (*-i) акк = max k<i<n aik 1 < к < п, где aJi = ац. Кроме того, для оценки вычислительной иогре^ ности целесообразно решить систему уравнений с двойной т° ностью и сравнить полученный результат с тем, который по^У чается при использовании одинарной точности.
С0СТЕМЫ ЛИНЕЙНЫХ УРАВНЕНИЙ 165 Ниже приведена программа численного решения системы лилейных уравнений методом Гаусса с выбором ведущего элемента п0 столбцу SUBROUTINE GAUSS (АД, В, N) DIMENSION A(N,N),B(N),X(N) REAL MAX DO 5 K=1,N-1 L=K MAX=ABS(A(K,K)) DO 25 I=K+1,N IF (MAX.LT.ABS(A(I,K))) THEN L=I MAX=A(I,K) END IF 25 CONTINUE С В цикле по I выбирается ведущий элемент в К-м С столбце, если L^K, то L-e уравнение переставля- С ется на место К-го уравнения, а К-е на место L-ro IF(L.NE.K) THEN DO 30 J=K,N C=A(K,J) A(K,J)=A(L,J) A(L,J)=C 30 CONTINUE C=B(K) B(K)=B(L) B(L)=C END IF DO 40 I=K+1,N D=A(I,K)/A(K,K) A(I,K)=0.0 DO 45 J=K+1,N A(I,J)=A(I,J)-D*A(K,J) 5 CONTINUE
166 ЧИСЛЕННЫЕ МЕТОДА B(I)=B(I)-D*B(K) 40 CONTINUE 5 CONTINUE С В цикле, оканчивающимся меткой 40, неизвестная С Х(К) исключается из всех уравнении от (К+1)-го С до N-ro. При этом происходит преобразование С элементов матрицы и вектора правой части X(N)=B(N)/A(N,N) DO 55 I=N-1,1,-1 S=0.0 DO 50 J=I+1,N S=S+A(I,J)*X(J) 50 CONTINUE X(I)=(B(I)-S)/A(I,I) 55 CONTINUE С В цикле, оканчивающимся меткой 55, выполняется С процедура обратного хода для нахождения решения RETURN END Здесь А и В — матрица системы (2.8.1) и вектор ее правой части, X — вектор искомого решения, N — размерность системы уравнений. Из приведенного алгоритма следует, что количество ариф' метических операций Т, которое необходимо для получения ре' шения, оценивается формулой Т~п3. (2.8.12) Из (2.8.12) следует, что при п « 100 требуемое время решен*1 задачи на компьютере среднего класса является небольшим, н° этому в этих случаях метод Гаусса широко используется. Одн^ порядок системы п « 1000 является предельным даже для к<^ пьютеров с быстродействием около 106 оп./с.
СЦСТЕМЫ ЛИНЕЙНЫХ УРАВНЕНИЙ 167 Перейдем к рассмотрению итерационных методов. Во всех ytUX методах определяется некоторая последовательность векто- ров % о, ^1,..., х к)--ч такая, что существует предел этой по- сЛедовательности, совпадающий с решением (2.8.2). При этом вектор "Ffc+i, к = 0,1,... выражается по определенному алгоритму через вектор х д.. Кроме того, для сходимости последовательности {хк} к решению требуется, чтобы матрица А обладала определенными свойствами. Другими словами, итерационный метод не может быть применен для решения системы (2.8.1) общего вида, подобно методу Гаусса, и поэтому для использования того или иного метода необходимо проверить выполнение требуемых условий. Существует большое количество итерационных методов, имеющих разные условия сходимости. Ниже рассмотрим метод минимальных невязок, который в последнее время начал широко применяться при решении конкретных задач. Определим следующую итерационную процедуру: х k+i = х к ~ П h к, к = 0,1,..., h к — А х к — о, тк = С^*Ч (2.8.13) 1ИМ12 Доказано, что если для любого ненулевого вектора а имеет место С^,А^)^0, (2.8.14) ^о последовательность { х ^}, определяемая (2.8.13), сходится к Решению (2.8.2) при любом начальном векторе tq. Геометрически условие (2.8.14) означает, что нет такого век- ^°ра в пространстве n-мерных векторов, который матрицей А ^реводится в ортогональный.
168 ЧИСЛЕННЫЕ МЕТОДА Вектор h к в (2.8.13) называется вектором невязки и пока зывает насколько приближенное решение х к близко к точному Действительно, из (2.8.13) ясно, что если имеет место 1А-=Г < е, (2-8.15) II * II где е — заданная малая величина, например е = 10~5, то ~$к дает решение (2.8.2) с заданной точностью. Это обстоятельство выгодно отличает итерационный метод от прямого метода, поскольку в процессе выполнения алгоритма (2.8.13) можно контролировать точность и прекращать вычисления по достижению требуемой точности приближенного решения. Приведем программу численного решения системы уравнений (2.8.1) размерности N с помощью итерационного метода минимальных невязок SUBROUTINE MMN(A,X,B,N,E,H,AH,MAX,KOL,EPS) DIMENSION A(N,N),B(N),X(N) DIMENSION H(N),AH(N) K0L=0 DO 5 1=1, N X(I)=B(I) 5 CONTINUE С Задается вектор начального приближения X 20 CALL MULTI (A,X,H,N) K0L=K0L+1 DO 10 1=1, N H(I)=H(I)-B(I) 10 CONTINUE С Здесь вычисляется вектор невязки Н EPS=SQRT(SCALAR(H,H,N)/SCALAR(B,B,N)) IF(KOL.EQ.MAX)RETURN IF (EPS.GT.E) THEN
СИСТЕМЫ ЛИНЕЙНЫХ УРАВНЕНИЙ 169 CALL MULTI (A,H,AH,N) , TAU=SCALAR (H,AH,N)/SCALAR(AH,AH,N) DO 15 1=1, N X(D =X(I)-TAU*H(I) l5 CONTINUE q Здесь вычисляется следующее приближение X в q соответствии с формулами (2.8.13) GO ТО 20 END IF RETURN END SUBROUTINE MULTI (A,X,Y,N) DIMENSION A(N,N), X(N),Y(N) DO 5 1=1,N S=0.0 DO 10 J=1,N S=S+A(I,J)*X(J) 10 CONTINUE Y(I)=S 5 CONTINUE RETURN END FUNCTION SCALAR (X,Y,N) DIMENSION X(N), Y(N) SCALAR=0.0 DO 5 1=1, N SCALAR=SCALAR+X(I)*Y(I) 5 CONTINUE RETURN END Здесь E — требуемая относительная точность решения в со- ^Ветствии с формулой (2.8.15), А и В — матрица системы (2.8.1) ** Вектор ее правой части, X — вектор искомого решения, Н и АН —
170 ЧИСЛЕННЫЕ МЕТОДА вектор невязки h и вектор Ад, которые в программе являют^ рабочими массивами. Параметр МАХ определяет максимально^ количество итераций, которое может быть реализовано в про. цессе исполнения алгоритма. Эта величину введена для того чтобы ограничить время счета при медленной сходимости итераций. Типичное значение параметра ~ 100 — 200. Переменная K0L определяет, какое количество итераций было фактически реализовано в алгоритме, а переменная EPS показывает относительную точность полученного решения. Подпрограмма MULTI предназначена для процедуры умножения матрицы на вектор, подпрограмма SCALAR вычисляет скалярное произведение векторов. Из приведенного алгоритма ясно, что количество арифметических операций Т, которое необходимо для получения приближенного решения системы (2.8.1), оценивается формулой Т~тп2. (2.8.16) Здесьт — количество итераций (2.8.13), требуемое для получения решения с заданной точностью е. Если т << п , что имеет место во многих задачах, то величина (2.8.16) оказывается значительно меньше (2.8.12). Действительно, с помощью приведенного итерационного метода удается решать задачи с п > 1000 на персональных компьютерах, при условии достаточно быстрой сходимости итераций, например, га « 10 — 30 для достижения точности е « 10~5. 2.9. ЗАДАЧИ ЛИНЕЙНОЙ АЛГЕБРЫ Задача нахождения собственных чисел матрицы является о?г ной из наиболее часто используемых на практике задач линейной алгебры. Это обусловлено тем, что подобные вопросы возникаю? при анализе сложных технических систем, в волновых процесса* и т.д.
3hAA чи линейной алгебры 171 Итак, пусть дана матрица А размерностью п х тг, т.е. квадратная таблица действительных чисел вида / ап а12 ... аы \ a2i а22 а2п А= . . . • (2.9.1) \ ^nl ^п2 • • • 0"пп / Собственными числами матрицы А называются такие значения параметра Л, для которых матрица (А - XI), где / — единичная матрица, является вырожденной. Это значит, что определитель матрицы (А - XI) обращается в нуль, т.е. (ап - А) а12 ain «21 («22 - А) а2п flni 0-п2 0. •(2.9.2) \апп ~ X) Уравнение (2.9.2) называется характеристическим уравнением матрицы А. Раскрыв (2.9.2), получим алгебраическое уравнение п- й степени относительно А. Уравнение подобного вида имеет п корней, вообще говоря комплексных. Если Аь А2,..., Хп — собственные числа матрицы, то имеет Место полезное равенство Ai + А2 + • - + Хп = ап+а22-\ Ь апп. (2.9.3) гДе выражение справа от знака равенства называется следом малицы. При решении уравнения (2.9.2) возникают два вопроса: 1. Запись (2.9.2) в виде алгебраического уравнения (_1)"АП + Ьп_! X71-1 + ... + biA + bo = 0. (2.9.4) 2. Собственно решение (2.9.4). Для небольших значений $ 5 можно использовать формулу раскрытия определителя че- ^ главные миноры. Однако при больших значениях п целесообразно использовать специальные методы нахождения коэффи- *ta< ентов, например аналог метода Гаусса для решения линейных
172 ЧИСЛЕННЫЕ МЕТОд^ уравнений, так как непосредственное раскрытие определите^ приводит к ряду проблем. При п = 2,3,4 можно использова^ точные формулы для корней соответствующих алгебраических уравнений, а при п = 5 — численный метод, изложенный в р^ деле 2.7. Для алгебраических уравнений более высоких степеней не применяются общие численные методы решения, в этих случаях используются алгоритмы, учитывающие специфику конкретных уравнений. Во всех случаях для контроля точности полученных результатов целесообразно использовать соотношение (2.9.3). Во многих приложениях используются симметрические матрицы, которые характеризуются условием aij = aji] hj — 1) • • •) п- (2.9.5) Доказыватся, что все собственные числа симметрической матрицы являются действительными. Пусть Ai > А2 > ... > Ап — собственные числа. Особую роль играют наибольшее Ai и наименьшее Ап собственные числа. Это связано с тем, что их отношение определяет число обусловленности матрицы (см. раздел 2.8) а, кроме того, они имеют важное значение при анализе многих технических систем. Для наибольшего и наименьшего собственного числа справедливо следующее представление: A1 = max("^!i4jf), (2.9.6) An = min^——-1. (2.9-П Здесь max и min берется среди всех возможных векторов х , пр^ надлежащих пространству n-мерных векторов Rn, а (*,*) обозн^ чает скалярное произведение в Rn (см. (2.8.3)).
3дДА ЧИ ЛИНЕЙНОЙ АЛГЕБРЫ 173 Рассмотрим численный метод для нахождения приближениях значений Х\ и Ап. Обозначим через m = 1 п вектор из Rn) компоненты которого определяются элементами га-й строки матрицы А) т.е. Хт = (a>ml,a»m2, • • • , 0>тп) (2.9.8) Теперь в качестве приближенных величин Ai и Ап будем брать значения, определяемые (2.9.6) и (2.9.7), где max и min рассматривается только среди п векторов (2.9.8). Хотя изложенный метод является приближенным, тем не менее во многих случаях он дает неплохие результаты. Соответствующая программа может иметь следующий вид. SUBROUTINE VALUE(A,X,Y,N,V1,VN) DIMENSION A(N,N),X(N),Y(N) DO 5 1=1,N DO 10 J=1,N X(I)=A(I,J) 10 CONTINUE CALL MULTI(A,X,Y,N) PR=SCALAR(X,Y,N)/SCALAR(X,X,N) IF (I.EQ.l) THEN V1=PR VN=PR END IF IF (PR.GT.V1) V1=PR IF (PR.LT.VN) VN=PR 5 CONTINUE RETURN END Здесь A — исследуемая матрица размерности N x N; X, Y "" рабочие массивы для организации алгоритма, VI и VN — наибольшее и наименьшее собственные числа матрицы. В программе
174 ЧИСЛЕННЫЕ МЕТОДА присутствует обращение к подпрограмме MULTI, которая предн^ значена для процедуры умножения матрицы на вектор, и к под. программе SCALAR, которая вычисляет скалярное произведение векторов. Эти подпрограммы приведены в конце раздела 2.8. Описанный алгоритм можно использовать для нахождения абсолютной величины наибольшего и наименьшего собственного числа произвольной матрицы. Определим транспонированную матрицу А* для заданной матрицы А по следующему правилу: строки матрицы А* являются столбцами матрицы А, а строки матрицы А — столбцами матрицы А*) т.е. а*3 = a3i ij = 1,...,тг. (2.9.9) Теперь определим матрицу J3, являющуюся произведением матрицы А на транспонированную матрицу А*, т.е. п b%3 = ^aikajk. (2.9.10) k=i Здесь b{j — элементы матрицы В. Нетрудно видеть, что матрица В = А • А* — симметрическая матрица. Кроме того, собственные числа щ, к = 1,.. .,п матрицы В связаны с собственными числами Хк матрицы А следующими соотношениями: Vk = \h\\ * = 1,...,п (2.9.И) Отметим, что Л^ — комплексные числа. Теперь, прграмма для нахождения приближенных значений модулей наибольшего и наименьшего собственного числа для про- извольной матрицы А может иметь следующий вид: SUBROUTINE 0WN(A,B,X,Y,N,V1,VN) DIMENSION A(N,N),B(N,N),X(N),Y(N) DO 5 1=1,N DO 5 J=1,N S=0
ЗАДАЧИ МАТЕМАТИЧЕСКОЙ СТАТИСТИКИ 175 DO 10 K=1,N S=S+A(I,K)*A(J,K) l0 CONTINUE B(I,J)=S 5 CONTINUE CALL VALUE(B,X,Y,N,V1,VN) V1=SQRT(V1) VN=SQRT(VN) RETURN END Здесь A — исследуемая матрица, Б, X, Y — рабочие массивы для использования подпрограммы VALUE, составленной выше. После вызова подпрограммы VALUE из найденных значений VI и VN извлекается квадратный корень в соответствии с (2.9.11). 2.10. ЗАДАЧИ МАТЕМАТИЧЕСКОЙ СТАТИСТИКИ Математическая статистика используется для описания са- ^Ых различных объектов живой природы, технических и с°Циально-экономических систем, результатов научных измерений и т.д. Ниже рассмотрим основные характеристики, наибо- Лее широко применяемые при статистическом описании. Пусть 3аДан одномерный массив из п чисел хг, г = 1,...,тг, который бактеризует рассматриваемое явление. Например, при исследовании демографического состава населения страны это может ^ть число жителей, возраст которых г лет (235 — число жители, имеющих возраст 35 лет). Характеристиками подобных распределений являются:
176 ЧИСЛЕННЫЕ МЕТОДА Математическое ожидание (среднее значение) 1 п *=„£**■ (2-lo-i) Дисперсия (среднее квадратичное отклонение) я=[^Х>*-*)2]"- (2Л0-2) к=г Коэффициент ассиметрии (характеризует скошенность функции распределения: при А = 0 функция симметрична, при А > 0 вытянут правый, а при А < О — левый участок спада кривой распределения) 1 п А= -J2(Xk-xf, (2.10.3) Коэффициент эксцесса (характеризует степень остроты пика кривой в сравнении с нормальным распределением: если Е > 0, то кривая распределения имеет более острый пик, чем при нормальном распределении, если Е < 0 пик менее острый) Соответствующая программа для вычисления указанных статистических характеристик для заданного массива данные Х(1), 1=1,... ,N может иметь следующий вид: SUBROUTINE STAT(X,N,XA,D,A,E) DIMENSION X(N) S=0.0 DO 5 1=1,N S=S+X(I)
ЗАДА ЧИ MA ТЕМА ТИЧЕСКОИ СТА ТИСТИКИ 177 5 CONTINUE XA=S/N D=0 DO 10 1=1,N D=D+(X(I)-XA)**2 Ю CONTINUE D=SQRT(D/N) A=0 E=0 DO 15 1=1,N A=A+(X(I)-XA)**3 E=E+(X(I)-XA)**4 15 CONTINUE A=A/(N*D**1.5) E=E/(N*D**2)-3 RETURN END Здесь XA,D,A,E — математическое ожидание, дисперсия, коэффициент ассиметрии и коэффициент эксцесса соответственно. Изучаемая совокупность может по какому-либо качественному признаку разбиваться на г классов, г < п. Соответствующее этому разбиению распределение задается путем указания численностей yi, 2/2,..., уг отдельных класов, причем г п k=l k=l Подобное разбиение на классы при больших значениях п позволяет выявлять существенные свойства распределения и не усложнять картину второстепенными деталями. Например, при анализе диаметров деревьев на участке леса соответствующее разбиение может быть следующим: у\ — число деревьев с диаметром
178 ЧИСЛЕННЫЕ МЕТОДЫ от 0 до 10 см., у2 — число деревьев с диаметром от 10 до 20 см и т.д. Составленная по таким группированным данным кривая называется гистограммой (рис. 2.10.1). 1 Диаметр деревьев Рис. 2.10.1 Для математического описания наиболее часто используются следующие функции: распределение Пуассона, нормальное распределение, биномиальное распределение и др. При выборе того или иного распределения исходят из близости экспериментальной кривой рассматриваемой функции. При изучении статистических закономерностей часто требуется установить возможную взаимосвязь (корреляцию) двух последовательностей. Например, ясно, что высоты деревьев связаны с их диаметрами. Пусть ж^, Ук, к = 1,2,..., п — распределения двух величин. Коэффициент парной корреляции R ]Г хкук - пху k=i (2.10.5) 1Т,х\-п{х)\Т,у1-п{уУ к=г V k=i характеризует степень отклонения связи между хк и ук от линейной. Если |Д| близок к единице, то связь линейная, т.е. ук ^
ЗАДАЧИ МАТЕМАТИЧЕСКОЙ СТАТИСТИКИ 179 с$к + ^ причем, если R > 0, то с > 0, а если R < 0, то и с < 0. В формуле (2.10.5) af и у — математические ожидания величин Xk й уь А; = 1,..., п, определяемые формулой (2.10.1). Соответствующая программа нахождения коэффициента парной корреляции R двух последовательностей X(I), Y(I), 1»1,... ,N может иметь следующий вид: FUNCTION R(X,Y,N) DIMENSION X(N),Y(N) XA=0 YA=0 DO 5 1=1,N XA=XA+X(I) YA=YA+Y(I) 5 CONTINUE XA=XA/N YA=YA/N XY=0.0 X2=0.0 Y2=0.0 DO 10 1=1,N XY=XY+X(I)*Y(I) X2=X2+X(I)**2 Y2=Y2+Y(I)**2 Ю CONTINUE R1=(XY-N*XA*YA) R2=SQRT(X2-N*XA**2)*SQRT(Y2-N*YA**2) R=R1/R2 RETURN END
180 ЧИСЛЕННЫЕ МЕТОДЫ 2.11. ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ Интегрирование функций является составной частью мно^ гих научных и технических задач. Поскольку аналитическое интегрирование далеко не всегда возможно, используют различные методы численного интегрирования. Геометрический смысл определенного интеграла Jm dx (2.11.1) от неотрицательной функции f(x) заключается в том, что / — это площадь, ограниченная кривой у = f(x), осью абсцисс и прямыми х = а, х — Ъ (рис.2.11.1). Рис. 2.11.1 Рассматриваемые ниже методы интегрирования такЖе имеют ясный геометрический смысл, а формулы численного интегрирования носят название квадратурных формул. На отрезке интегрирования [а, Ь] определим (п + 1)-у точку х0 = а, xi = а + Л,..., Xk — а + (к - 1)Л,..., хп = 6, h= {Ь-а)/п. (2.11.2)
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ 181 Построенное множество точек, равноотстоящих друг от друга, яасто называют равномерной сеткой, а сами точки — узлами сетки. Равномерные сетки также используются при численном решении интегральных и дифференциальных уравнений. Соответствующие значения функции в узлах сетки будем обозначать 2/0, Угу-Уп, т.е. ук = f(xk). Приближенное значение интеграла по методу прямоугольников задается формулой Inp = (Уо + У\ + ''' + yn-i)h. (2.11.3) На рис. 2.11.2 площади заштрихованных участков показывают ошибку, которую дает формула (2.11.3) при вычислении интеграла. Аналитическая оценка погрешности имеет вид |/-/nP|< max Щ^Н(Ь-а). (2.11.4) хе[а,Ь] 2 Приближенное значение интеграла по методу трапеции задается формулой Impan = (Уо + 2yi + • • ■ + 2yn_i + yn)h/2. (2.11.5) На рис. 2.11.3 площади заштрихованных участков показывают ошибку, которую дает (2.11.5) при вычислении интеграла. Аналитическая оценка погрешности имеет вид |/ " 1трап\ < max Щ^к2(Ъ - а). (2.11.6) Из (2.11.3), (2.11.5), рис. 2.11.2, 2.11.3, ясно, что метод прямоугольников и метод трапеций геометрически заключаются в ^ом, что площадь криволинейной трапеции, т.е. интеграл, приниженно представляется в виде суммы площадей элементарных
182 ЧИСЛЕННЫЕ МЕТОДЫ прямоугольников или трапеции соответственно. Рис. 2.11.3 Если число отрезков разбиения п четное, то для вычисления интеграла (2.11.1) можно использовать формулу Симпсона Icuun = (2/o + 4y1 + 2y2 + 4t/3 + --- + 2y„_2+4y„-i + y„)V3- (2.П-?) Формула Симпсона геометрически заключается в том, что через три ординаты, отвечающие трем последовательным узлаМ
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ 183 сетки, проводится парабола и затем складываются получивши- еСя при этом площади элементарных криволинейных трапеций. Дналитическая оценка погрешности определяется формулой |/ - 1симп\ < max ,}^h4(b - а). (2.11.8) x£[a,b] loll Сравнивая формулы вычисления погрешностей- (2.11.4), (2.11.6), (2.11.8), видим, что при одинаковом малом шаге h наилучшую точность будет давать метод Симпсона, что геометрически совершенно ясно. Однако в (2.11.8) присутствует четвертая производная функции, поэтому для функций, не имеющих такую степень гладкости, более точным может оказаться метод трапеций. Это обстоятельство весьма важно, поскольку указанные ситуации встречаются в практических задачах. Для численного интегрирования используются также квадратурные формулы Гаусса. Рассмотрим сначала формулы Гаусса первого порядка. Определим узловые точки х^к\ к = 1,...., тг, в середине отрезков [xk-i, ж*], т.е. хМ = {хк-г+хк)/2. (2.11.9) Здесь Xk — узлы равномерной сетки, определяемые (2.11.2). Значения функции в точках ж^) будем обозначать yW, т.е. у(*) = f(x(k))m Тогда квадратурная формула Гаусса первого порядка имеет вид 'Гаусс = (У(1) + У{2) + ■■■ + У4)11- (2-11Л°) Аналитическая оценка погрешности определяется формулой I'-jffUi^^v»-)- <*■"•»> Рассмотрим квадратурные формулы Гаусса второго порядка. Определим узловые точки х[\ ж^ , к = 1,...,п, находящиеся **Утри отрезков [ж&_1, ж&], по следующим формулам: д,) = Хк-г+ хк _ о 5?735 ^
184 ЧИСЛЕННЫЕ МЕТОДА (к) Xk_l+Xk r-rj-r h /Oil , х\ } = + 0.57735 • -, (2.11.12) где хк — узлы равномерной сетки, определяемые (2.11.2). Значе- ния функции в точках х\ , х^ будем обозначать у[ , у$ , т.е. У{ = /(^i ), У2 = /(4 )• Тогда квадратурная формула Гаусса второго порядка имеет вид / (1) , (1) (п) , (п)\ Аналитическая оценка погрешности определяется формулой |'-&^ailr*,(1-+ (2Л1-14) Существуют квадратурные формулы Гаусса более высоких порядков. Однако в настоящее время они используются редко, поскольку алгоритмически являются более сложными, а кроме того могут приводить к существенным погрешностям при неточном задании значений функции в узловых точках. Сравнивая формулы трапеций и Симпсона с квадратурными формулами Гаусса первого и второго порядков, видим,что эти формулы имеют одинаковый порядок точности по h. Однако формулы Гаусса имеют меньшие коэффициенты в оценках погрешности и поэтому являются более точными. На практике формулы Гаусса первого порядка используются довольно широко. Приведем программу численного интегрирования с помощью квадратурной формулы Гаусса первого порядка при заданном числе отрезков разбиения N FUNCTION GSS(A,B,N) H=(B-A)/N GSS=0.0 X=A+H/2 DO 5 1=1,N
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ 185 F=FUNC(X) GSS=GSS+F Х=Х+Н 5 CONTINUE GSS=GSS*H RETURN END FUNCTION FUNC(X) FUNC-SIN(X) RETURN END Здесь А и В — границы отрезка интегрирования, а подпрограмма-функция FUNC определяет значение интегрируемой функции при любом аргументе X Е [А,В]. В приведенной программе для примера взята функция f(x) — sin (ж). При численном интегрировании конкретных функций обычно трудно заранее определить требуемую величину N, которая обеспечит заданную точность Е. Приведем программу, которая будет автоматически определять требуемое количество отрезков разбиения и соответственно определять приближенное значение интеграла по заданной точности. Соответствующий алгоритм обоснован тем, что сравниваются приближенные значения Интегралов при некотором значении N и при вдвое большем значении 2N. Тогда, если разница меньше Е, то алгоритм заканчивайся, а если нет, то проводится сравнение при значениях 2N и 4N й т.д. Начальное число отрезков разбиения N=2. FUNCTION GSSE(A,B,E,NMAX) N=2 G1=GSS(A,B,N) 1 N=N*2 G2=GSS(A,B,N)
186 ЧИСЛЕННЫЕ МЕТОДА IF(N.GE.NMAX) THEN GSSE=G2 RETURN END IF IF(ABS(G1-G2).LE.E) THEN GSSE=G2 RETURN ELSE G1=G2 GO TO 1 END IF RETURN END Параметр NMAX определяет максимальное количество отрезков разбиения, которое может быть реализовано в процессе исполнения алгоритма, например NMAX=1000. Эта величина введена для того, чтобы не было зацикливания программы при неправильном задании ^сходных данных. В приведенной подпрограмме GSSE присутствуют обращения к подпрограмме GSS. При стремлении шага сетки h к нулю приближенное значение интеграла, как следует из приведенных выше оценок точности, также стремится к нулю. Однако эти оценки получены при условии математически точных вычислений, что в реальности не имеет место, поскольку всегда присутствует ошибка округления (см. раздел 2.2). Рассмотрим качественную зависимость точности приближенного значения интеграла /, определяемого какой-либо из квадра' турных формул, от числа узлов сетки N. Примерный график имеет следующий вид (рис. 2.11.4). Пороговое значение N* имеет ту же природу, что и численная сходимость многих расходящихся функциональных рядов, ° чем указывалось в разделе 2.4. Для уменьшения точности Ь можно использовать два способа: первый — применение двойне
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ 187 точности при проведении вычисления; второй — использование древовидной схемы суммирования, которая уменьшает влияние ошибок округления. Рис. 2.11.4 На рис. 2.11.5 дан пример такой схемы для восьми узловых точек. Уо У1 У2 Уз У* Уз Ув У? Рис. 2.11.5 Численное интегрирование функций многих переменных имеет, помимо вышеуказанных, ряд существенных особенностей. Рассмотрим функции двух переменных, для которых эти особенности присутствуют в полной мере. Итак, пусть определен дву-
188 ЧИСЛЕННЫЕ МЕТОДЫ мерный интеграл вида = ///(.,») dxdy, (2.11.15) где S — заданная область на плоскости (х) у) (рис. 2.11.6). Рис. 2.11.6 Для численного интегрирования функций двух переменных иногда применяются квадратурные формулы, которые получаются комбинацией одномерных квадратурных формул. Однако для областей со сложной границей этот подход приводит к значительным трудностям и поэтому используется редко. Пусть область S можно представить в виде совокупности подобластей определенного вида, например прямоугольников, со сторонами hx и hy (рис. 2.11.7). Выберем узловые точки в центре прямоугольников, т.е. в точке пересечения диагоналей, и обозначим их (х^, у к)) к = 1,..., п, где п — количество подобластей. Соответствующие значения функции в узловых точках будем обозначать *ь .. .,zn, т.е. zk = /(я*,!/*)- Теперь приближенное значение интеграла (2.11.15) зададим формулой 1прям = {z\ Н h zn)hxhy. (2.11Д6)
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ 189 Отметим, что квадратурная формула (2.11.16) является прямым обобщением формулы Гаусса первого порядка (2.11.10) на дву- yk • • • U hx Рис. 2.11.7 мерный случай. Аналогично можно получить квадратурные формулы и для многомерных интегралов. При этом в качестве подобластей необходимо брать соответствующие многомерные прямоугольные параллелепипеды. Аналитическая оценка погрешности для квадратурной формулы (2.11.16) имеет вид \I-InV^\<-{h2x + h2y)S, А = max max x,y£S d2f(x,y) дх2 24' max x,yes d2f(x,y) dy2 (2.11.17) Приведенная оценка справедлива тогда, когда область S может быть точно представлена в виде совокупности прямоугольников. Однако для многих задач это не так, например, если область S — круг. В этих случаях для повышения точности чиненного интегрирования, можно использовать три способа: 1. Произвольная область 5 с любой точностью может быть Представлена в виде совокупности прямоугольников малого размера. Однако на практике для достижения заданной точности
190 ЧИСЛЕННЫЕ МЕТОДЫ количество требуемых прямоугольников может оказаться очень большим и, следовательно, приводить к значительным вычислительным затратам. Поэтому при использовании данного способа необходимо, в первую очередь, учитывать конкретный вид области S и требуемую точность интегрирования. 2. Отказаться от требования, чтобы все подобласти имели форму прямоугольников. Тогда подобласти, находящиеся вблизи границы 5, будут иметь неправильную форму, но будут точно описывать область S. Теперь в квадратурной формуле необходимо значения функций в узловых точках умножать на площадь соответствующей подобласти, которая, естественно, не будет прямоугольником вблизи границы S. Однако в этом случае точность квадратурной формулы будет пропорциональна Jh% + Щ (аналогично формуле прямоугольников (2.11.3) для од- номерного'случая) и поэтому для достижения заданной точности возможно придется существенно уменьшать размеры подобластей. 3. Использовать такое же разбиение на подобласти, как и в предыдущем способе, но узловые точки в подобластях неправильной формы помещать в их центр, который определяется формулами J J х dxdy J J у dxdy xc = ^Ц , yc = ^Ц . (2.11.18) Здесь Sh — соответствующая подобласть. Заметим, что точка (яо Ус) совпадает с центром масс однородной плоской пластины, имеющей форму Sh- Тогда соответствующая квадратурная формула будет иметь оценку точности вида (2.11.17). Приведем программу численного интегрирования с помощью формулы (2.11.16), полагал, что произвольная область S целиком находится в прямоугольнике со сторонами А и В (рис. 2.11.8)? а число точек разбиения по осям х и у равно N1 и N2 соответственно.
ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ Ш А Рис. 2.11.8 FUNCTION GSS2(A,B,N1,N2) LOGICAL SURF HX=A/N1 HY=B/N2 GSS2=0.0 DO 5 IX=1,N1 DO 5 IY=1,N2 X=(IX-0.5)*HX Y=(IY-0.5)*HY IF (SURF(X,Y,A,B)) THEN GSS2=GSS2+FUNC(X,Y) END IF 5 CONTINUE GSS2=GSS2*HX*HY RETURN END LOGICAL FUNCTION SURF(X,Y,A,B)
192 ЧИСЛЕННЫЕ МЕТОДЫ SURF=(X-A/2)**2/(A/2)**2+(Y-B/2)**2/(B/2)**2.LE.l RETURN END FUNCTION FUNC(X,Y) FUNC=X**2+Y**2 RETURN END Здесь область интегрирования 5 — элипс с центром в точке (А/2, В/2) и осями А/2 и В/2 соответственно. С помощью логической подпрограммы-функции SURF в квадратурной формуле учитываются только те прямоугольники, узловые точки которых принадлежат эллипсу. В приведенной программе для примера взята функция /(х, у) — х2 + у2- 2.12. РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ Уравнения, содержащие производные от функции, возникают при решении многих научно-технических задач, причем существует большое разнообразие классов подобных уравнений. Для решения некоторых из них могут быть использованы аналитические методы, рассматриваемые в курсах математики, однако в большинстве случаев приходится применять численные методы- Сначала рассмотрим один из простейших классов дифференциальных уравнений, на примере которого будут показаны особенности использования численных методов. Пусть задано дифференциальное уравнение первого поряди с начальным условием (задача Коши) % = F{x,y), (2.12.1)
РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ 193 УЫ - Уо, (2.12.2) где F(x,y) — заданная функция двух переменных х и у, xq) у0 — известные числа. Требуется определить функцию у = у(х) при х > xq. Уравнение (2.12.1) можно рассматривать как задание кривой через ее производную в координатной плоскости я, у) поскольку известно как вычислить производную в каждой точке этой кривой через ее координаты. В общем случае уравнению (2.12.1) удовлетворяет целое семейство кривых; начальное условие (2.12.2) позволяет выбрать из этого семейства одну определенную кривую, которая проходит через заданную точку хо, уо> Для численного решения (2.12.1), (2.12.2) заменим область непрерывного изменения аргумента х дискретным множеством точек, т.е. введем сетку. Положим, что величина х изменяется от значения х — хо до значения х = Ь. Тогда, рассматривая равномерную сетку, получаем узловые точки х0, х\).. .ж^,.. .6, находящиеся на расстоянии h друг от друга, т.е. х*+1-я* = Л, fc-0,1,..., (2.12.3) где h — шаг сетки. Соответствующие значения функции будем обозначать уь, т.е. У к = У*{хк)- Здесь у*(х) — функция, которая является приближенным решением (2.12.1), (2.12.2). Для получения численного решения, дифференциальное уравнение (2.12.1) заменяется уравнениями относительно значений функций у*(х) в узловых точках. Эти уравнения называются разностными. Простейшее разностное уравнение для (2.12.1) имеет вид УШ~Ук =F(xk,yk), к = 0,1,... (2.12.4) Уравнение (2.12.4) следует из (2.12.1), если производную -^ приближенно представить через значения функции у(х) в соседних Узлах. 7 А. Б. Самохин
194 ЧИСЛЕННЫЕ МЕТОДЫ Соотношения (2.12.4) можно записать в виде Ук+i = Vk + hF(xk)yk) Тогда, учитывая (2.12.2), с помощью формулы (2.12.5) можно последовательно определить значения j/i, у2> • • • Этот метод приближенного решения (2.12.1), (2.12.2) называется методом Эйлера. Доказывается, что если шаг сетки h стремится к нулю, то приближенное решение, определяемое (2.12.5), стремится к точному решению (2.12.1), (2.12.2), т.е. имеется факт сходимости приближенного решения к точному при h -* 0. Однако в условиях реальных вычислений на компьютере при конечном шаге целесообразно знать насколько полученное приближенное решение близко к точному. В качестве меры отклонения (нормы ошибки) часто используют величину 6у = max \у{хк) - ук\. (2.12.6) к Здесь у(х) — строгое решение (2.12.1), (2.12.2), ук — приближенное значение искомой функции в узловых точках хк, полученное путем решения разностных уравнений, например (2.12.4). Для разностных уравнений величина 5у оценивается формулой 6y~Chm. (2.12.7) Здесь С — const, зависящая от длины отрезка, на котором ищется решение, и способа дискретизации (2.12.1) , т — параметр, который называется порядком точности решения. Порядок точности метода Эйлера — минимальный, т.е. т — 1, что связано с довольно грубым способом аппроксимации дифференциального уравнения разностным. Как правило, чем выше порядок точности, тем более предпочтительным является численный метод. Можно утверждать, что любое правильно составленное раз ностное уравнение аппроксимирует исходное дифференциальное с той или иной точностью. Качество аппроксимации обычно оце- (2.12.5)
РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ 195 нивают по точности, с которой решение исходной задачи удовлетворяет разностному уравнению, т.е. по формуле max к у(хш) уЫ _ Пхк)У{хк))\ < С/Л (2Л2в8) h где С — const, т — порядок аппроксимации разностного уравнения. Сравнение (2.12.1) и (2.12.4) показывает , что метод Эйлера имеет первый порядок аппроксимации, так же как и точность решения. Однако в общем случае утверждение о равенстве порядков точности решения и аппроксимации разностного уравнения не является очевидным и требует доказательства. Метод Эйлера является одним из самых старых и широко известных методов численного решения дифференциальных уравнений. К сожалению, этот метод может приводить к недопустимо большим ошибкам, а кроме того, он часто оказывается неустойчивым — малая ошибка (происходящая при округлении или из-за неточности исходных данных) существенно увеличивается с ростом х. Поэтому в настоящее время этот метод редко используется при решении конкретных задач. Широкое распространение при численном решении (2.12.1), (2.12.2) имеет метод Рунге — Кутта, разностные уравнения которого имеют вид h, (2.12.9) +1 Яг Я2 9з 44 к — = = = = = У к + tWi + 472 + ^?з F(xk,yk)i / h hqi\ F(Xk + lyk+2) F(xk + h, yk + hq3) 0,1,... Метод Рунге — Кутта имеет четветый порядок точности решения и аппроксимации разностных уравнений. Этот метод для
196 ЧИСЛЕННЫЕ МЕТОДЫ большинства задач дает хорошие результаты, причем точность существенно возрастает с уменьшением шага h. Приведем программу численного решения (2.12.1), (2.12.2) методом Рунге —- Кутта при заданном числе узлов N OPEN(1,FILE= >RESULT.DAT') WRITE(*,*),A,B,N,YO) READ(*,*) A,B,N,Y0 CALL RUNGE(A,B,N,YO) STOP END SUBROUTINE RUNGE(A,B,N,YO) H=(B-A)/N X=A Y=Y0 DO 5 1=1,N Q1=FUNC(X,Y) Q2=FUNC(X+H/2,Y+H*Ql/2) Q3=FUNC(X+H/2,Y+H*Q2/2) Q4=FUNC(X+H,Y+H*Q3) Y=Y+(H/6)*(Q1+2*Q2+2*Q3+Q4) X=X+H WRITE(1,10) X,Y 5 CONTINUE 10 FORMAT(2X,,X=',E10.3,2X,'Y=',E10.3) RETURN END FUNCTION FUNC(X,Y) FUNC=X**2 RETURN END Здесь А и В — границы отрезка, на котором ищется решение (2.12.1), Y0 — начальное значение искомой функции при
РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ 197 х — А\ подпрограмма-функция FUNC определяет значение функции F(x,y) при любых х и у. В приведенной задаче для примера взята функция F — х2. Рассмотрим еще один важный класс задач. Пусть на отрезке [p,q] задано обыкновенное дифференциальное уравнение второго порядка Ф)0 + S{x)di + t{x)y = f{x) (2-12'10) и краевые условия на концах отрезка di^ + дгУ х=р (d^%+9^y) \х= =<Рг- (2.12.11) Здесь r(x),s(x),t(x), f(x) — заданные функции, di,d2>0i» <72»- ^ъ¥>2 — известные числа. Требуется определить функцию у = у(х) на отрезке [p,q]. Сформулированная задача является двухточечной краевой задачей, поскольку граничные условия определены на разных концах отрезка. Для численного решения (2.12.10), (2.12.11) введем на отрезке [p,q] равномерную сетку со следующим множеством точек: яо = Р, хп = q, h— (р- q)/n, Sjt+i - Xk = h, к = 0,1,. ..,n. (2.12.12) Для аппроксимации производных в дифференциальном уравнении (2.2.10) будем использовать разностные соотношения dy_\ _ Ук+i - Ук-1 dx)Xk~ 2h ' (d2y\ _ ук+1 - 2ук + ук_г Г9 19 1^ \ / хк
198 ЧИСЛЕННЫЕ МЕТОДЫ которые имеют второй порядок аппроксимации. Для аппроксимации производных в краевых условиях (2.12.11) будем использовать разностные соотношения dy\ _ yi - 2/о fdy\ _ уп - Уп-1 Л>12Ш dz)p~ h ' иЛ~ h ' (2Л2Л4) которые имеют первый порядок аппроксимации. Если в (2.12.11) значения d\ и d2 равны нулю, т.е. рассматриваются граничные условия Дирихле, то краевые условия аппроксимируются точно и не вносят ошибку в процедуру решения. Окончательно получим следующие разностные уравнения: соУо - Ь0у\ = /о, -акук-\ + СкУк - ЬкУк+i = Л, 1 < & < п - 1 -anyn_i + спуп = /п. (2.12.15) Здесь /* = /(&*)> k = l,...,n-l; fo = (pi, fn = <P2 di di со = gi + -г-, o0 = - — r{xk) s{xk) an = -j^, cn = g2 + -£. (2.12.16) Нетрудно видеть, что (2.12.15) является системой (п + 1)- го уравнения с (п + 1)-м неизвестным относительно значений искомой функции в узловых точках. В отличие от разностных уравнений Рунге — Кутта (2.12.9) в явном виде записать решение в этом случае невозможно, и его необходимо находить путем решения системы линейных уравнений. Однако использование
РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ 199 прямых методов, типа метода Гаусса (см. раздел 2.8), приводит к большим вычислительным затратам, поскольку число узловых точек 71, как правило, весьма велико, п ^> 1000. В тоже время, матрица системы уравнений имеет ленточную структуру, т.е. ненулевыми являются только элементы вблизи главной диагонали. Для таких систем разработаны специальные прямые методы, требующие значительно меньших вычислительных ресурсов. Одним из таких методов является метод прогонки, широко используемый для решения подобных систем. Будем полагать, что решение (2.12.15), (2.12.16) существует и единственно, что должно обеспечиваться правильной постановкой исходной задачи. Тогда искомое решение по методу прогонки описывается следующими формулами: Уп = /?п+Ь Ук = ак+хук+1 + Pk+i, к = п- 1,п-2,..., 0, (2.12.17) где прогоночные коэффициенты oikiftk находятся по рекурент- ным формулам ^0 Ьк с*1 = —; а*+1 = , & = 1,...,гс-1 со Ск - ак<*к Р1 = к. р I±±*!E!Lt * = !,...,„. (2.12.18) СО Ск - dkOtk Отметим, что общее число арифметических операций, требуемое для реализации (2.12.17), (2.1,2.18), приблизительно равно 8п. Поэтому даже для очень больших значений п реализация алгоритма не представляет трудностей. Однако здесь могут возникнуть проблемы, связанные с численной устойчивостью алгоритма (см. раздел 2.3). Этот вопрос является очень непростым и во многих случаях рассматривается путем численных исследований. Укажем одно простое условие численной устойчивости алгоритма — для всех к должно выполняться условие \ак\ < 1. Программа, реализующая метод прогонки, может иметь следующий вид:
200 ЧИСЛЕННЫЕ МЕТОДЫ SUBROUTINE PROGON(Y,ALTHA,BETA,N,P,Q) DIMENSION Y(1),ALTHA(1),BETA(1) H=(Q-P)/N С H - шаг сетки X=P CALL COEF(X,P,Q,H,A,B,C,F) С Подпрограмма COEF для точки X определяет С коэффициенты A,B,C,F в уравнениях (2.12.15) ALTHA(1)=B/C BETA(1)=F/C DO 5 1=1,N Х=Х+Н CALL COEF(X,P,Q,H,A,B,C,F) BETA(I+1)=(F+A*BETA(I))/(C-A*ALTHA(I)) IF(I.EQ.N) GO TO 5 ALTHA(I+1)=B/(C-A*ALTHA(D) 5 CONTINUE Y(N+1)=BETA(N+1) С В вышеприведенных операторах вычисляются С прогоночные коэффициенты по формулам (2.12.18) DO 10 I=N,1,-1 Y(I)=ALTHA(I)*Y(I+1)+BETA(I) 10 CONTINUE С В цикле, оканчивающемся меткой 10, вычисляются С значения искомой функции по формулам (2.12.17) RETURN END SUBROUTINE C0EF(X,P,Q,H,A,B,C,F) CALL GRAN(D1,G1,FI1,D2,G2,FI2) С Подпрограмма GRAN определяет коэффициенты в С краевых условиях (2.12.11) IF(X.EQ.P) THEN А=0.0 B=-D1/H C=G1+D1/H
РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ 201 F=FI1 RETURN END IF IFCX.GT.Q-H/2) THEN A=D2/H B=0.0 C=G2+D2/H F=FI2 RETURN END IF CALL FUNC(X,R,S,T,F) С Подпрограмма FUNC для точки X определяет С коэффициенты R,S,T,F в уравнении (2.12.10) A=S/(2*H)-R/(H**2) B=-R/(H**2)-S/(2*H) C=-2*R/(H**2)+T RETURN END SUBROUTINE GRAN(D1,G1,FI1,D2,G2,FI2) D1=0.0 Gl=l. FI1=0.0 D2=0.0 G2=l. FI2=0.0 RETURN END SUBROUTINE FUNC(X,R,S,T,F) R=1.0 S=0.0 T=-2.0 F=-3.0*SIN(X) RETURN END
202 ЧИСЛЕННЫЕ МЕТОДЫ Здесь Р и Q — границы отрезка, на котором ищется решение, N+1 — число узловых точек, массив Y определяет значения искомой функции в узловых точках, массивы ALPHA и BETA определяют прогоночные коэффициенты в узловых точках. В программе присутствуют обращения к подпрограммам COEF, GRAN и FUNC, которые вычисляют коэффициенты разностных уравнений согласно (2.12.15), (2.12.16). Конкретное задание исходных данных присутствует в подпрограммах GRAN и FUNC. Для примера рассмотрено дифференциальное уравнение -г-; - 2у = -3sinz ахг с нулевыми граничными условиями Дирихле У\ = 0 у х=р = 0. x=q При решении конкретных задач заранее трудно определить величину шага /г, которая обеспечивает требуемую точность решения е. Можно рекомендовать следующий прием: находятся решения разностных уравнений при шаге h и при шаге /г/2. Если в общих узлах сетки разница величин меньше заданного значения е, то решение с шагом /г/2 обеспечивает требуемую точность. Если данное условие не выполняется, то аналогично рассматриваются решения разностных уравнений с шагами /г/2 и /г/4 и т.д. до тех пор, пока не достигнем заданной точности. Начальное значение шага обычно выбирается таким, чтобы на длине h искомое решение мало менялось. 2.13. РЕШЕНИЕ ИНТЕГРАЛЬНЫХ УРАВНЕНИЙ Уравнения, содержащие интегралы от неизвестных функций, часто встречаются при решении научно-технических задач,
РЕШЕНИЕ ИНТЕГРАЛЬНЫХ УРАВНЕНИЙ 203 в частности, многие дифференциальные уравнения могут быть сведены к интегральным, решение которых численными методами оказывается проще и эффективнее. Наиболее широко используются два основных класса интегральных уравнений: интегральное уравнение Фредгольма первого рода ь JK(x,y)u(y) = f(x) (2.13.1) а и интегральное уравнение Фредгольма второго рода ь и{х) + J К(х, y)u(y)dy = f(x). (2.13.2) а Здесь и(х) — неизвестная функция, подлежащая определению, К(х,у) — заданная функция двух переменных х и у) которая называется ядром интегрального уравнения, f(x) — известная функция, называемая источником, а и b — заданные числа, определяющие пределы интегрирования. Прежде чем приступить к численному решению интегрального уравнения, необходимо убедиться, что его решение существует и единственно. Этот факт обычно следует из свойств решения рассматриваемой задачи или является следствием общих математических теорем. Ниже будем полагать, что решение уравнений существует и единственно. Сформулируем условие корректности задачи: малым возмущением правой части уравнения, т.е. функции /(ж), должны соответствовать малые (того же порядка) возмущения решения. Это условие впервые было введено Адамаром и поэтому иногда называется условием корректности по Адамару. Нетрудно видеть, что задача нахождения решения интегрального уравнения Фредгольма первого рода является некорректной. Действительно, добавим к искомой функции и(у) быстро колеблющуюся функцию, например Asmuy. Если ядро К(х,у) гладкое, например дифференцируемо по координатам, то при любой величине
204 ЧИСЛЕННЫЕ МЕТОДЫ А можно выбрать достаточно большую величину w, так что К(х, y)Asinu>y dy\ I <е, где е — любое как угодно малое (но конечное) число. Долгое время считалось, что некорректные задачи вообще не имеют реального смысла и их нельзя решать, поскольку исходные данные не могут быть заданы абсолютно точно. После появления так называемых обратных задач, которые имеют большое практическое значение, интерес к исследованию интегральных уравнений первого рода возрос. Были разработаны методы решения этих уравнений, которые позволяют получать решение с требуемой точностью. Перейдем к рассмотрению интегральных уравнений Фред- гольма второго рода. Будем полагать, что ядро К(х, у) и источник f(x) являются непрерывными функциями своих аргументов. Доказывается, что соответствующая задача является корректной. Это существенно упрощает процедуру решения. Изложим численный метод решения, основанный на замене интегрального уравнения конечной системой линейных алгебраических уравнений — метод коллокации. На отрезке [а, Ь] введем равномерную сетку с п узловыми точками Xi = a, Xk+i — Xk + h, к = 1, 2,... (n - 1), Л =-^4. (2.13.3). п — 1 Соответствующие значения приближенного решения и*(х) в узловых точках обозначим ик = и*(хк), к = 1,...п. (2.13.4) Теперь, вычисляя интеграл (2.13.2) в узловых точках с помощью любой формулы численного интегрирования (см. раздел 2.11),
РЕШЕНИЕ ИНТЕГРАЛЬНЫХ УРАВНЕНИЙ 205 получаем систему п уравнений с п неизвестными щ,..., ип п щ + У^2/акК{хихк)ик = /(х/), / = 1,...тг. (2.13.5) k=i Система (2.13.5) аппроксимирует исходное интегральное уравнение (2.13.2). Здесь ак — коэффициенты, определяемые формулой численного интегрирования. Например, по методу трапеций, см. (2.11.5), получаем h h Доказывается, что если шаг сетки h стремится к нулю, то решение, определяемое (2.13.5), сходится к решению исходного интегрального уравнения (2.13.2). Порядок точности решения (2.13.5) определяется зависимостью точности формулы численного интегрирования от шага h (см. раздел 2.11). В частности, для метода трапеций система уравнений (2.13.5), аппроксимирующая интегральное уравнение (2.13.2), имеет второй порядок точности по h. Для решения (2.13.5) применяют методы решения систем линейных уравнений (см. раздел 2.8). Как показывают численные исследования, во многих случаях использование интегральных уравнений дает более точное решение при одинаковом шаге /i, чем эквивалентных дифференциальных уравнений. Кроме того, при решении интегральных уравнений, как правило, не возникает проблем с численной устойчивостью решения. Это объясняется тем, что сама процедура интегрирования является менее чувствительной к возможным ошибкам, нежели операция дифференцирования. Для нахождения шага сетки /г, который аппроксимирует искомое решение с требуемой точностью, можно рекомендовать прием, описанный в конце раздела 2.12. Для численного решения интегральных уравнений широко используется метод Галеркина. Изложим этот метод применительно к решению уравнения (2.13.2). Определим функциональ-
206 ЧИСЛЕННЫЕ МЕТОДЫ ное пространство L2, состоящее из функций, для которых существует интеграл на отрезке [а, Ь] от их квадрата. К элементам этого пространства относятся, в частности, любые непрерывные на [а, Ь] функции. В пространстве L2 введем норму и скалярное произведение, согласно следующим формулам: ь \\f\\=(Jf(x)dx)\ а Ь (f,g) = J f(x)g(x)dx. (2.13.6) а Здесь / и д — любые функции из пространства Z,2. Пространство L2 является бесконечномерным, но имеет много общих свойств с конечномерным пространством векторов. В L2 можно ввести бесконечный базис функций <pi,¥>2>---j (fk, • • •, по которому раскладывается любой элемент д из L2 т.е. оо д{х) = ^ак<рк(х). (2.13.7) к=1 Числа afc, к = 1,2,... называются коэффициентами разложения функции д по заданному базису. Можно построить много различных базисов. Например, функции {1, х, х2,..., хк,...} образуют базис в L2. Пусть и — приближенное решение интегрального уравнения (2.13.2), которое представляется в виде разложения по п базисным функциям п й(х) = ^a^W)- (2.13.8) k=i Коэффициенты ajj.71' определяются, согласно методу Галеркина, из решения следующей системы п линейных уравнений: п У^ Кткогк = Ст, т = 1,. .., п,
РЕШЕНИЕ ИНТЕГРАЛЬНЫХ УРАВНЕНИЙ 207 ь ь Ктк = / <Pm(x)<Pk{x) dx + / / K(x,y)<pm(x)ipk(y)dxdy, а а ь Ст = I f(x)cpm{x)dx, (2.13.9) а Геометрический смысл (2.13.9) заключается в том, что функция б й{х) + [ К{х, у)й(у) dy - f(x) (2.13.10) а ортогональна в L2 n-мерному подпространству, образованному базисными функциями {<pi,..., (рп}. Другими словами, функция (2.13.10) ортогональна каждой базисной функции ^(я), к = 1,..., п. Доказывается, что приближенное решение (2.13.8), (2.13.9) при п —> оо сходится к точному решению и(х) интегрального уравнения (2.13.2). На практике выбирают такое количество базисных функций, которое аппроксимирует искомое решение с требуемой точностью, а затем решают систему линейных уравнений (см. раздел 2.8). Заранее определить это количество не всегда возможно, поэтому при решении конкретных задач можно поступать следующим образом — получить приближенное решение щ при некотором количестве базисных функций п и решение U2 при количестве базисных функций 2гг. Если относительная ошибка || щ - и2 || / || и2 || в норме />2 будет меньше заданной точности, например 10~3, то функция и2 определяет приближенное решение с необходимой точностью. Если приведенное условие не выполняется, то сравниваются решения при количестве базисных функций 2п и An и т.д. Однако необходимо учитывать важное обстоятельство. При увеличении количества базисных функций численная устойчивость
208 ЧИСЛЕННЫЕ МЕТОДЫ алгоритма может ухудшаться, особенно, если используемый базис не является ортогональным в пространстве L2. Программа, реализующая метод Галеркина при фиксированном количестве базисных функций N, может иметь следующий вид: SUBROUTINE GALERK(A,B,N,AK,C,AfcTHA,M) DIMENSION AK(N,N),C(N),ALTHA(N) CALL SIDE(C,N,M,A,B) CALL MATR(AK,N,M,A,B) CALL GAUSS(AK,ALTHA,C,N) С Происходит обращение к подпрограмме GAUSS из С раздела 2.8 RETURN END SUBROUTINE SIDE(C,N,M,A,B) DIMENSION C(N) DO 5 1=1,N C(I)=GINT1(I,A,B,M) С Подпрограмма GINT1 осуществляет численное С интегрирование в (2.13.9) для определения С компоненты правой части С(1) 5 CONTINUE RETURN END SUBROUTINE MATR(AK,N,M,A,B) DIMENSION AK(N,N) DO 5 1=1,N DO 5 J=1,N AK(I,J)=GINT2(I,J,A,B,M)+GIN3(I,J,A,B,M) С Подпрограммы GINT2 и GINT3 производят вычисления С одномерного и двумерного интегралов в (2.13.9) С для определения коэффициента матрицы системы С уравнении AK(I,J) 5 CONTINUE
РЕШЕНИЕ ИНТЕГРАЛЬНЫХ УРАВНЕНИЙ 209 RETURN END FUNCTION GINT1(I1,A,B,M) H=(B-A)/M S=0 DO 5 1=1,M X=A+(I-0.5)*H S=S+BASIS(I1,X)*FUNC(X) ;5 CONTINUE : GINT1=S*H RETURN END FUNCTION GINT2(I1,J1,A,B,M) H=(B-A)/M S=0 DO 5 1=1,M X=A+(I-0.5)*H S=S+BASIS(I1,X)*BASIS(J1,X) Б CONTINUE GINT2=S*H RETURN END FUNCTION GINT3(I1,J1,A,B,H) H=(B-A)/M S=0 DO 5 1=1,M DO 5 J=1,M X=A+(I-0.5)*H Y=A+(J-0.5)*H S=S+YADR0(X,Y)*BASIS(I1,X)*BASIS(J1,Y) 5 CONTINUE GINT2=S*H**2 RETURN END FUNCTION BASIS(I.X)
210 ЧИСЛЕННЫЕ МЕТОДЫ IF(I.EQ.l) BASIS=1.0 IF(I.GT.l) BASIS=X**(I-1) RETURN END FUNCTION YADR0(X,Y) YADR0=X*Y RETURN END FUNCTION FUNC(X) FUNC=X RETURN END Здесь А и В — границы отрезка интегрирования, АК — двумерный массив матрицы системы уравнений, С — вектор правой части. Матрица системы уравнений и вектор павой части этой системы определяются в (2.13.9). ALTHA — массив неизвестных коэффициентов а из (2.13.8). В программе происходит обращение к подпрограмме GAUSS, описанной в разделе 2.8. Эта подпрограмма решает систему линейных уравнений методом Гаусса и определяет массив коэффициентов ALTHA. Подпрограммы SIDE и MATR формируют массивы С и АК, обращаясь к подпрограммам GINT1, GINT2 и GINT3. Эти подпрограммы производят численное интегрирование в (2.13.9) по формулам Гаусса первого порядка (см. раздел 2.11) для одномерных и двумерных интегралов. Число отрезков разбиения по каждой оси равно М. Подпрограмма-функция BASIS с формальными параметрами I и X определяет значение 1-й базисной функции в точке X, подпрограмма-функция FUNC вычисляет значение функции f(x) из уравнения (2.13.2) в точке X, подпрограмма-функция YADR0 определяет значение ядра уравнения (2.13.2) в точках X и Y- В рассматриваемой программе взяты базисные функции {1, я, х2,..., £п}, а в качестве ядра и правой части взяты для примера функции К(х, у) = х • у, f(x) = х.
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ 211 В заключение отметим, что изложенные методы не могут быть использованы для численного решения интегральных уравнений Фредгольма первого рода, поскольку приводят к абсолютно неверным результатам. Для решения подобных уравнений применяются другие методы, рассмотрение которых выходит за рамки этой книги. 2.14. ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ ВЫЧИСЛИТЕЛЬНЫХ ЗАДАЧ Пусть поставлена задача, требующая численного решения. Далее найдена математическая формулировка задачи и проведена ее алгоритмизация. Остается только составить программу на языке высокого уровня, например на Фортране. Число программ, моделирующих некоторую данную задачу, практически неограниченно, даже если известен некий алгоритм решения. Как же выбрать из всех возможных вариантов тот, при котором программа будет самой лучшей? Однозначного ответа на этот вопрос нет, хотя можно указать основные требования, которыми целесообразно руководствоваться. Во-первых, необходимо учитывать соображения, связанные с эффективностью программы, т.е. временем счета и объемом требуемой памяти (раздел 2.3). Во-вторых, необходимо максимально снизить трудоемкость написания и отладки программы. Для этого существует ряд правил и рекомендаций, часть из которых изложена ниже. Однако нужно иметь ввиду, что процедура написания программ является творческим процессом, поэтому любые советы Могут быть только ориентирами в конкретной работе. Изложим ряд рекомендаций на "микроуровне" • Имена переменных целесообразно выбирать так, чтобы они соответствовали смыслу обозначаемых величин. Для этого лучше использовать не одну, а несколько букв в наименовании (в языке Фортран число символов может достигать
212 ЧИСЛЕННЫЕ МЕТОДЫ шести), например TIME (обозначение времени), РОТ (обозначение потенциала). • Имеет смысл снабжать программу комментариями внутри текста. Это облегчает использование программы даже их авторам, поскольку по прошествии некоторого времени многие детали забываются. • При вычислении индексов массивов следует проявлять особое внимание, так как в ходе вычислений машина не определяет, соответствуют ли вычисленные индексы массивов первоначально установленным размерностям. Это может приводить к ошибкам, которые трудно локализовать. • Для экономии памяти целесообразно подумать о возможности использования одного массива, в том случае, если разные массивы не используются одновременно. • Для записи сложных математических выражений имеет смысл применять промежуточные переменные, которые повышают наглядность программы и могут уменьшать количество арифметических операций при вычислениях. • При использовании вложенных циклов нужно стремиться к тому, чтобы во внутреннем цикле число выполняемых арифметических операций было минимальным. Это способствует уменьшению времени счета. Рекомендации на "макроуровне" касаются вопросов организации программы в целом. Основная проблема здесь состоит в разбиении задачи на подпрограммы. Действительно, большинство вычислительных задач являются достаточно сложными и могут состоять из многих составных частей, например суммирования рядов, вычисления интегралов, решения уравнений и т.Д- В принципе для любой вычислительной задачи можно написать единую программу без разбиения ее на подпрограммы. Однако
для сложных программ здесь есть существенное препятствие, которое поясним на следующем примере. На рис. 2.14.1 представлен качественный график зависимости времени составления и Технология программирования 213 Рис.2.14.1 Ьтладки программы Т от количества операторов программы N. [Здесь критическое число операторов N* для программистов разрой квалификации изменяется от 50 до 200. Очевидно, составление более громоздких программ требует очень значительных [временных затрат. Объяснение приведенной зависимости состоит [в том, что для человека существует некоторый порог сложности системы, начиная с которого трудно воспринимать ее в це- [лом. Поэтому сложную программу необходимо разбивать на относительно независимые подпрограммы, которые составляются 1и отлаживаются самостоятельно. Оптимальный размер подпрограммы не должен, как правило, превышать 50 операторов. Однако возникает вопрос о том, как разбивать исходную задачу На подпрограммы. Существуют два основных подхода: метод Модульного программирования и метод структурного программирования. Модульное программирование часто называют программированием "снизу-вверх". Смысл его заключается в том, что из ^отдельных модулей (подпрограмм), реализующих ту или
214 ЧИСЛЕННЫЕ МЕТОДЫ иную задачу, "собирается" общая программа решения исходной задачи (рис.2.14.2). Рис. 2.14.2 Во многих случаях метод модульного программирования дает хорошие результаты, существенно упрощая процесс программирования. Однако для сложных задач с большим количеством модулей (подпрограмм) М (например М « 30 — 50) процедура "сборки" всей программы может оказаться очень трудоемкой в силу вышеуказанного порога сложности. Поэтому для программ большой сложности целесообразно использовать метод структурного программирования, ко торый часто называют программированием "сверху-вниз*. Смысл его заключается в том, что исходная задача разбивается на некоторое количество связанных задач, как правило, не более 10 — 15, представленных в виде программных модулей, для которых четко определены входные и выходные параметры. Далее определяются имена этих подпрограмм и происходит их "сборка в общую программу, хотя сами программные модули еще фактически не написаны. Таким образом, если исходную задачу будем называть задачей 0-го уровня, то в результате такого разбиения придем к задачам 1-го уровня, которые проще исходной задачи- Далее задачи 1-го уровня разбиваются на задачи 2-го уровня и т.д. до тех пор, пока получившиеся задачи не окажутся доста
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ 215 [точно простыми для программирования (рис.2.14.3). Задача 1-го уровня Задача 2-го уровня Задана 0-го уровня Задача 1-го уровня Задача 1-го уровня Рис. 2.14.3 Рассмотрим метод структурного программирования на примере решения следующей задачи. Даны п точек на плоскости с декартовыми координатами я,-, yt, г = 1,... 7г. Найти координаты V* Рис. 2.14.4 вершин выпуклого многоугольника, для которого все точки заданного множества либо находятся внутри многоугольника, либо
216 ЧИСЛЕННЫЕ МЕТОДЫ являются его вершинами (рис 2.14.4). Очевидно, что поставленная задача имеет единственное решение. Пусть X(I) ,Y(I) ,1=1, . . ,N — массивы декартовых координат заданного множества точек, a XM(I), YM(I), 1=1, . . ,М, причем М < N, — массивы декартовых координат вершин искомого многоугольника. Для задачи нулевого уровня массивы X,Y являются входными параметрами, а массивы XM,YM — выходными параметрами. Сначала запишем основную программу, полагая для определенности число заданных точек N < 100. Исходные данные будут считываться, например из файла DAN.DAT, а результат записываться в файл RESULT.DAT. Тогда основная программа может иметь вид PARAMETER (NN=100) DIMENSION X(NN),Y(NN),XM(NN),YM(NN) OPEN (1,FILE=,DAN.DAT>) READ(1,2) N READ(1,3) (X(I),Y(I),I=1,N) CALL PR0(X,Y,XM,YM,N,M) OPEN (2,FILE='RESULT.DAT') WRITE(2,4) (XM(I),YM(I),I=1,M) 2 FORMAT(13) 3 F0RMAT(E12.5,2X,E12.5) 4 F0RMAT(2X,,X=,,E12.5,2X,,Y=,,E12.5) STOP END Задачу нулевого уровня PRO разобьем на задачи 1-го уровня следующим образом. Пусть подпрограмма PR11 среди заданного множества точек определяет координаты двух первых соседних вершин искомого многоугольника, подпрограмма PR12 при задании текущего значения М-й вершины определяет координаты соседней (М+1)-й вершины многоугольника. Процедура нахождения вершины многоугольника заканчивается, если очередная найденная вершина совпадает с первой вершиной.
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ 217 Тогда подпрограмма PRO будет иметь вид SUBROUTINE PRO(X,Y,XM,YM,N,M) DIMENSION X(1),Y(1),XM(1),YM(1) LOGICAL EX CALL PR11(X,Y,XM,YM,N) M=2 5 CALL PR12(X,Y,XM,YM,N,M) EX=(XM(1).EQ.XM(M+1)).AND.(YM(1).EQ.YM(M+1)) IF(.NOT.EX) THEN M=M+1 GO TO 5 END IF RETURN END Здесь логическая переменная EX принимает значение .TRUE., если найденная (М+1)-я вершина многоугольника совпадает с первой вершиной и .FALSE, в противном случае. Перейдем к подпрограммам первого уровня. Отметим, что выпуклый многоугольник характеризуется тем, что, если провести прямую через любые две соседние вершины, то все другие вершины, а также точки, находящиеся внутри многоугольника, будут находиться по одну сторону от этой прямой. Подпрограмму PR11 можно записать следующим образом: SUBROUTINE PR11(X,Y,XM,YM,N) DIMENSION X(1),Y(1),XM(1),YM(1) LOGICAL PR21,CUR DO 5 1=1,N CUR=PR21(X,Y,N,I) IF(CUR) GO TO 10 5 CONTINUE 10 XM(1)=X(I) YM(1)=Y(I) M=l
218 ЧИСЛЕННЫЕ МЕТОДЫ CALL PR12(X,Y,XM,YM,N,M) RETURN END Подпрограмма 2-го уровня PR21 является логической подпрограммой-функцией, которая принимает значение .TRUE., если точка с 1-ми координатами будет вершиной искомого многоугольника, и значение .FALSE, в противном случае. Подпрограмму PR12 можно записать следующим образом: SUBROUTINE PR12(X,Y,XM,YM,N,M) DIMENSION X(1),Y(1),XM(1),YM(1) LOGICAL CUR.PR22 R1=0.0 DO 5 1=1,N R2=(X(I)-XM(M))**2+(Y(I)-YM(M))**2 IF(R2.EQ.0.0) GO TO 5 CUR=PR22(X,Y,N,XM(M) ,YM(M) ,X(I) ,Y(D) IF(CUR) THEN IF(R2.GT.R1) THEN XM(M+1)=X(I) YM(M+1)=Y(I) CALL PR23(X,Y,N,R1,I) R1=R2 END IF END IF 5 CONTINUE RETURN END Подпрограмма 2-го уровня PR22 является логической подпрограммой-функцией, которая принимает значение .TRUE-, если все заданные координаты точки лежат по правую сторону или на прямой, проходящей через две данные точки и .FALSE. ^ в противном случае. В приведенном обращении к подпрограмм6 этими точками являются точки с координатами (ХМ(М) ,YM(M)) и (X(I),Y(D) соответственно.
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ 219 Подпрограмма PR23 удаляет из массивов заданных точек X, Y точку, которая лежит на прямой, соединяющей вершины многоугольника. В приведенном обращении к подпрограмме этой точкой является 1-й элемент массивов X,Y, если Rl^O. Логическая подпрограмма-функция PR21 имеет вид LOGICAL FUNCTION PR21(X,Y,N,IN) DIMENSION X(1),Y(1) LOGICAL PR22,PR31,CUR DO 5 1=1,N IF(I.EQ.IN) GO TO 5 CUR=PR22(X,Y,N,X(IN) ,Y(IN) ,X(I) ,Y(D) IF(CUR) THEN CUR=PR31(X,Y,N,IN,I) IF(CUR) GO TO 5 PR21=.TRUE. RETURN END IF 5 CONTINUE PR21=.FALSE. RETURN END Здесь логическая подпрограмма-функция PR31 принимает значение .TRUE., если на прямой, соединяющей IN-ю и 1-ю точки существует J-я точка из заданного множества такая, что IN-я точка находится между J-й и 1-й точками. В противном случае подпрограмма-функция PR31 принимает значение .FALSE. Пусть в трехмерном пространстве заданы три точки с координатами (а?о>Уо?0)> (xi, ?/i,0) и (ж,у, 0). Определим два вектора с координатами (ai,a2,0) (bi, f>2, 0), где а\ = х\ — х0, а2 = 2/1 — 2/о» ^1 = х - хо, Ь2 = У - Уо- Тогда векторное произведение этих векторов будет иметь только z-ю компоненту, причем ясно, что, если эта компонента больше нуля, то точка на плоскости с координатами (х,у) лежит по левую сторону от прямой, проходящей через точки (я0, Уо) и (zi,2/i). Здесь положительным
220 ЧИСЛЕННЫЕ МЕТОДЫ считается направление от 0-й к 1-й точке. Теперь логическую подпрограмму-функцию PR22 можно записать следующим образом: LOGICAL FUNCTION PR22(X,Y,N,X0,Y0,X1,Y1) DIMENSION X(1),Y(1) A1=X1-X0 A2=Y1-Y0 PR22=.TRUE. DO 5 1=1,N B1=X(I)-X0 B2=Y(I)-Y0 IF(A1*B2-A2*B1.GT.0.0) THEN PR22=.FALSE. RETURN END IF 5 CONTINUE RETURN END Подпрограмма PR23 удаляет 1-й элемент массивов X,Y если R^O SUBROUTINE PR23(X,Y,N,R,IN) DIMENSION X(1),Y(1) IF(R.EQ.O.O) RETURN DO 5 I=IN,N-1 X(I)=X(I+1) Y(I)=Y(I+1) 5 CONTINUE N=N-1 RETURN END При составлении логической подпрограммы-функции PR31 нужно учесть следующие обстоятельства. Если точка лежит на
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ 221 прямой, соединяющей две другие точки, и является первой в последовательности трех точек, то векторное произведение векторов, введенных выше при составлении подпрограммы PR22, равно нулю, а кроме того, скалярное произведение этих векторов отрицательно. Тогда подпрограмму PR31 можно записать LOGICAL FUNCTION PR31(X,Y,N,IN,I) DIMENSION X(1),Y(1) PR31=.FALSE. A1=X(I)-X(IN) A2=Y(I)-Y(IN) DO 5 J=1,N B1=X(J)-X(IN) B2=Y(J)-Y(IN) IF(A1*B2-A2*B1.EQ.0.0) THEN IF(A1*B1+A2*B2.LT.0.0) THEN PR31=.TRUE. RETURN END IF END IF 5 CONTINUE RETURN END Совокупность приведенных программных модулей является программой решения поставленной задачи. Читателю рекомендуем составить структурную схему решения задачи из приведенных модулей, подобно рис.2.14.3. Для большинства сложных задач метод структурного программирования дает очень хорошие результаты и приводит к значительному снижению трудозатрат при программировании. Таким способом могут быть написаны программные комплексы, состоящие из десятков тысяч операторов языка программирования. В процессе программирования задач можно также использовать стандартные программы из какой-либо библиотеки про-
222 грамм. Для этого необходимо ознакомиться с описанием этой библиотеки, где указаны наименования подпрограмм, имена формальных параметров, необходимые ограничения в использовании и т.д. Однако нужно твердо убедиться, что данная программа, предназначенная, например, для решения дифференциальных уравнений, соответствует вашей задаче. Таким образом, сложная вычислительная задача может состоять из набора подпрограмм, часть из которых написана самостоятельно, а часть взята из библиотеки стандартных программ. В заключение отметим, что в процессе реального программирования сложных задач программист-вычислитель приобретает собственный опыт и необходимые навыки, которые повышают эффективность его работы. СПИСОК ЛИТЕРАТУРЫ 1. Марчук Г.И. Методы вычислительной математики.—М.: Наука,1980. 2. Бахвалов Н.С., Жидков Н.П., Кобельков Г.М. Численные методы.—М.: Наука,1987. 3. Бонди Б. Методы оптимизации.—М.: Радио и связь,1988. 4. Боглаев Ю.П. Вычислительная математика и программирование.—М.: Высшая школа,1990. 5. Самохин А.Б., Самохина А.С. Фортран и вычислительные методы для пользователя IBM PC.—М.: Русина, 1994. 6. Колдербэнк В. Программирование на Фортране.—М.: Радио и связь,1986. 7. Горелик A.M., Ушкова В.Л. Фортран сегодня и завтра. —М.: Наука,1990. 8. Соловьев В.П. Fortran для персонального компьютера. —М.: Арист,199Ь
ОГЛАВЛЕНИЕ Предисловие 3 Часть 1. Программирование на Фортране 5 1.1. Устройство компьютера с точки зрения пользователя 5 1.2. Эволюция языка Фортран 13 1.3. Основные трансляторы Фортрана для персональных компьютеров 14 1.4. Начальные сведения о Фортране 20 1.5. Типы и структура данных 30 1.6. Разветвляющиеся и циклические процессы 43 1.7. Ввод-вывод данных 51 1.8. Организация сложных программ 64 1.9. Отладка программ 78 1.10. Список основных библиотечных функций Фортрана 82 1.11. Создание программных библиотек 86 1.12. Задачи и решения 91 Часть 2. Численные методы 108 2.1. Этапы решения задач с использованием компьютера 108 2.2. Погрешности вычислений 110 2.3. Вычислительные алгоритмы 117 2.4. Вычисление функций 122 2.5. Интерполяция 130 2.6. Нахождение экстремума функции 141 2.7. Решение уравнений 150 2.8. Решение систем линейных уравнений 160
224 ОГЛАВЛЕНИЕ 2.9. Задачи линейной алгебры 170 2.10. Задачи математической статистики 175 2.11. Численное интегрирование 180 2.12. Решение дифференциальных уравнений 192 2.13. Решение интегральных уравнений 202 2.14. Технология программирования вычислительных задач 211 Список литературы 222