Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Статистика и анализ геологических данных

..pdf
Скачиваний:
20
Добавлен:
15.11.2022
Размер:
21.12 Mб
Скачать

Арифметические выражения в качестве индексов. В арифме­ тических предложениях индексы можно представить целыми пе­ ременными, как, например, переменные I, J в выражении ALPHA (I, J), или целыми константами, как, например, в выра­ жении BETA (2,3). В качестве индексов употребляются также некоторые арифметические выражения целого типа.

Приведем несколько примеров:

Обозначение на ФОРТРАНе

Математическое обозначение

ALPHA

(1 + 2)

* 1+2

ALPHA ( 1 - 3 )

« 1 -3

ALPHA

(2 * I)

«21

ALPHA

( 3 * 1 + 4 )

a 3 l+ 4

ALPHA

( 3 * 1 - 1 )

« 3 1 -1

Индекс вычисляется всякий раз, когда переменная исполь­ зуется в программе. Он не может становиться нулем или отрица­ тельным числом. Индексы такого вида будут особенно полезны при использовании матриц больших порядков в факторном и тренд-анализах. В большинстве вычислительных машин выра­ жения такого вида можно использовать в качестве индексов.

Размерности массивов. Переменные с индексами нередко представляют собой элементы массивов довольно большого по­ рядка, которые вводятся в вычислительную машину.

В некоторых процедурах, которые будут рассматриваться в следующих главах, эти массивы достигают значительных объ­ емов. Необходимо сообщить машине заранее, до компиляции программы, какой объем памяти потребуется для хранения этих массивов, представленных переменными с индексами. Это дела­ ется с помощью предложения DIMENSION, которое дает имя каждой индексированной переменной и определяет максималь­ ный размер массива по каждому индексу. В нашем примере тре­ буемое предложение DIMENSION можно записать в виде

DIMENSION ALPHA (20)

Это значит, что для хранения переменной ALPHA нужно предоставить двадцать ячеек памяти. Описываемый массив не обязательно должен быть требуемого размера; описание может превышать число ячеек, требуемое в действительности, но не мо­ жет быть меньше. Если описываются и не используются исклю­ чительно большие массивы, то часть ресурсов машины расходу­ ется впустую и расход ресурсов памяти может оказаться нерен­ табельным. Предложение DIMENSION должно характеризовать каждую индексированную переменную в программе. Переменные разделяются запятыми, как, например, в предложении

DIMENSION ALPHA (20), BETA (3, 20), NUMB (10).

Заметим, что предложение DIMENSION не может содержать переменных индексов. Последние должны быть явно заданы, так как они используются для определения размера массивов, пред­ назначенных для записи индексированных переменных. Предло­ жения DIMENSION рассматриваются в книгах Голда [5], Мак­ Крэкена [7], а также Мэррилла и Смита [8].

Циклы DO. Предложение DO позволяет повторять требуемое число раз некоторую часть программы, причем каждое новое по­ вторение (цикл) осуществляется при новом, полученном после автоматического приращения значении целой переменной (так называемой управляющей переменной). Циклы DO, использую­ щие индексированные переменные, являются чрезвычайно эф­ фективным средством языка ФОРТРАН. Повторяющийся уча­ сток программы называется циклом DO, так как часть про­ граммы, находящаяся под предложением DO, повторяется в цикле до тех пор, пока не будут выполнены условия окончания цикла.

Типичный цикл DO может выглядеть, например, следующим образом:

DO 10 1 = 1 , 20

10 □ SUMA = SU M A +A (I).

Это предложение означает: «выполнить все операции до предложения 10 включительно, затем возвратиться к предложе­ нию DO и повторить все сначала до тех пор, пока последова­ тельность не будет повторена 20 раз». В заключение этой после­ довательности операций переменная SUMA будет содержать сумму первого значения, второго и т. д., до двадцатого значения переменной А. Предложение 10 может быть либо следующим предложением в этой последовательности, как в данном при­ мере, либо располагаться довольно далеко от оператора DO. Все операции, записанные между предложениями DO и концом цикла DO, выполняются последовательно. Предложения между оператором DO и концом цикла DO считаются расположенными внутри цикла DO. Любые правильно записанные операторы ФОРТРАНа можно включить в цикл с одним лишь исключением: внутренний цикл DO не может иметь область, которая распро­ страняется за пределы области объемлющего его цикла DO. Хотя управление от цикла DO может быть передано на любое предложение типа GO ТО или IF, его нельзя, однако, передать обратно в область цикла.

Мы можем написать программу на ФОРТРАНе и найти сред­ нее значение множества измерений, используя цикл. DO. Предпо­ ложим, что мы располагаем пятью измерениями площадей неф­ теносных бассейнов в северо-восточной части штата Оклахома. Мы хотим найти среднее значение площади, занимаемой бассей­ ном. Это можно сделать, сложив все измерения и разделив их

на пять. Основная часть программы такова:

SUMA = 0.0

DO 101 = 1,5

SUMА = SUMА + AREA (1) 10 □CONTINUE

AMEAN= SUM A/5

Предположим, что наши данные находятся в массиве, назван­ ном AREA, и пять результатов измерений в акрах следующие:

AREA (1) = 39.

AREA (2) = 13.

AREA (3) = 27.

AREA (4) = 87.

AREA (5) = 62.

Проследим последовательно операции программы. Во-пер­ вых, полагаем переменную SUMA равной нулю. Затем вводим цикл DO и значение индекса I приравниваем к единице (1 = 1). Величина, хранящаяся в таблице в позиции AREA(l) прибавля­ ется к SUMA (39.+0. = 39.). Эта сумма записывается на место предыдущего значения SUMA, поэтому SUMA теперь равно 39. Конец области цикла DO приходится на предложение с номе­ ром 10, после чего управление возвращается оператору DO.

Теперь, присваивая I значение, равное 2 (1 = 2), выберем величину, хранящуюся в массиве в положении AREA(2), кото­ рая равна 13, и прибавим к текущему значению SUMA (13.+ + 39. = 52.), что дает новое значение SUMA. Цикл DO состоит, таким образом, из пяти однотипных операций:

для

I =

1

39. + 0 . = 3 9 .

 

 

SUMA =

для

I =

2

13. + 3 9 . = 52.

 

 

SUMA =

для

1 = 3

27. + 5 2 . = 7 9 .

 

 

SUMA =

для

1 = 4

 

 

 

SUMA =

87. + 7 9 . = 166.

для

I =

5

62. + 166. = 2 2 8 .

 

 

SUMA =

После того как оператор DO сработает указанное число раз, управление передается следующему оператору деления суммы SUMA на пять ’(228./5.= 45.6), в результате чего получается тре­ буемая величина AMEAN.

Размещение одних циклов DO внутри других циклов DO на­ зывается гнездованием. Вообще говоря, внутри одного цикла мо­

 

DO....38

1

 

жет гнездоваться

любое

число

цик­

 

 

лов, но, как указано на фиг. 2.5, гра­

 

DO.... 15

 

 

ницы области внутреннего цикла не

 

■ 3

 

могут выходить за пределы области

гнездование

DO....8

5

 

внешнего цикла.

Следовательно, цикл

DO....15

 

жением цикла DO логически должно

 

 

 

DO не может оканчиваться предложе­

 

 

8

 

ниями GO ТО,

IF,

RETURN,

STOP,

 

 

 

END или DO. Если последним предло­

Правильное

 

10

 

быть одно

из

этих

предложений, то

 

 

 

 

15

 

необходимо

воспользоваться

фиктив­

 

D0....36

25

 

ным предложением

CONTINUE. Оно

 

 

 

просто передает

управление

следую­

 

 

36

5J

щему оператору.

приведенные

ниже,

 

 

5

Предложения,

 

 

38

§

используют два вложенных один в дру­

 

 

 

§•

гой цикла DO с целью выполнения

|

 

 

сложения каждой строки

массива, на­

 

00....10

 

I

званного В (I,

J),

и

хранения

этих

 

1

сумм в массиве, названном А(1). Зна­

 

D0....12

I

чения А(1)

печатаются по мере их вы­

гнездование

 

 

 

числения:

A

(I) =

A

(I)+ B

(I.

J)

 

 

 

 

 

 

DO

11 1 = 1 ,

N

 

 

 

 

00....15

8

 

 

DO

10 J = l,

М

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Неправильное

DO....38

10

 

10 □ CONTINUE

 

 

 

 

 

12

 

11 □

WRITE (6,

100) A

 

 

 

15

 

Однако внешне эквивалентный пре­

 

 

 

дыдущему ряд предложений

 

 

 

 

25

 

 

DO

10 1 = 1 ,

N

 

 

 

 

DO....42

36

 

 

DO

И

J = 1. М

 

 

 

 

 

 

 

А

(1)=

А

(1)+В

(1.

J)

 

 

 

38

 

 

 

 

 

 

10 □

WRITE (6,

100)

А (I)

 

 

 

42

 

11 □ CONTINUE

 

 

 

 

 

Фиг. 2.5. Правильное и не-

является

незаконным,

так

как

вто-

правильное

гнездование

рои цикл DO выходит

за область пер-

циклов ЕЮ.

 

 

ВОГО.

 

 

 

 

 

 

 

 

 

 

Отметим, что внутри цикла DO нельзя производить никакие операции, которые приводили бы к изменению индекса в самом цикле. Иначе говоря, если мы используем предложение

DO 10 1 = 1 , 20,

то использовать переменную I никаким образом нельзя, если это приводит к ее изменению внутри цикла DO. Можно сослаться на I, как в предложении IF, и положить другую переменную рав­ ной I, изменив затем вторую переменную, но значение самого I менять нельзя.

Для придания индексу последовательных приращений, отлич­ ных от единицы, используется другая форма предложения DO. Например, предложение

DO 10 1 = 1, 19, 2

означает, что «цикл состоит из последовательности предложе­ ний, начиная с данного и кончая предложением 10, причем к пе­ ременной I в каждом цикле добавляется 2 до тех пор, пока I не превысит 19». Ясно, что будут выполнены 10 циклов. Чтобы рас­ сеять недоумение читателя по поводу того, зачем может понадо­ биться давать приращения, равные 2, вместо того, чтобы давать приращения, равные 1 в цикле от 1 до 9, рассмотрим следующий

пРимеР:

DO 10 1=1, 19, 2

 

 

10 □ SUMY = SUMY-f-A (1).

 

Выбирая каждое второе значение в

массиве А(1)

и находя

А (1 )+ А (3 )+ А (5 )+ . . .+А (19),

получим

SUMY. Эта

процедура

оказывается

очень полезной в

тех случаях, когда

различные

типы данных хранятся в разных местах массива.

Циклы DO, которые мы рассматривали, содержат как управ­ ляющие переменные целые положительные константы. В каче­ стве управляющих переменных допускается использование также переменных целого типа при условии, что они положительны и не являются нижними индексами. Конечно, в области цикла DO значение переменной не может быть никаким образом изме­

нено. Например,

JQ 1 =

1 J

 

10 □ READ (5,

1000) ALPHA (I)

Здесь J может быть числом наблюдений в некоторой после­ довательности данных, вводимых в вычислительную машину в область массива ALPHA. Последовательность операторов

DO 10 1 = 1 , М N = M + 1

J = N - 1

10 □ BETA (I) = ALPHA (J)

предписывает хранение содержимого массива ALPHA (J) в мас­ сиве ВЕТА(1) в обратном порядке. Более подробное описание

циклов DO содержится в книгах Голда

[5], Мак-Крэкена [7],

а также Мэррилла и Смита [8].

требуется многократно

Функции и подпрограммы. Иногда

выполнить ряд одинаковых вычислений в различных частях про­ граммы. Бывает и так, что в нескольких программах требуется

выполнить одинаковые вычисления. В связи с этим

было бы

очень удобно один

раз написать соответствующую

программу

и затем ссылаться

на нее по мере необходимости.

Например,

многие процедуры, которые будут рассмотрены ниже, требует решения систем уравнений. Соответствующую программу мы на­ пишем в гл. 4. Предложения этой программы можно было бы включить в качестве составных частей в соответствующие про­ цедуры, однако мы предпочитаем использовать ее независимо, вызывая в случае необходимости. Это можно сделать с помощью подпрограмм, два типа которых, называемые FUNCTION и SUBROUTINE, мы рассмотрим.

Функции, определяемые пользователем. В ФОРТРАНе опре­ делены некоторые арифметические функции, такие, как ALOG и SQRT. Кроме того, ФОРТРАН также дает возможность поль­ зователю определять свои собственные функции. Например, предположим, что нам необходимо многократно извлекать куби­ ческие корни из чисел. Мы можем написать подпрограмму FUNCTION, которая будет использоваться таким же образом, как функция SQRT, имеющаяся в компиляторе ФОРТРАНа. Мы будем называть эту функцию CUBE.

FUNCTION CUBE (X)

C U B E = X ** 0.33333

RETURN

END

Первое предложение определяет подпрограмму как функцию с именем CUBE. Совокупность переменных, указанных в скоб­ ках, следующих за именем, представляет собой список парамет­ ров. В этом примере указан только один параметр, хотя в слу­ чае необходимости их можно указать несколько. Здесь X — на­ звание фиктивной переменной. Это не обязательно та же переменная, которая используется в основной программе, упот­ ребляющей подпрограмму CUBE. Необходимо отметить, что фик­ тивные переменные в списке параметров не должны иметь ин­ дексов. Однако они могут служить именами массивов. Необхо­ димо также отметить, что значения фиктивных переменных нельзя менять внутри функции. Например, X не может стоять слева от знака равенства в функции CUBE. Функция CUBE со­

держит только одно арифметическое предложение для вычисле­ ния значения CUBE, тогда как другие функции могут содер­ жать целый ряд предложений. Любая допустимая комбинация предложений ФОРТРАНа может быть использована в операторе FUNCTION. Предложение RETURN означает, что вычисления внутри подпрограммы закончены, и осуществляет передачу вы­ численного значения функции во внешнюю программу. Послед­ нее предложение в подпрограмме должно быть END.

Мы можем использовать функцию CUBE в нашей программе вычисления эквивалентного сферического радиуса эллипсоидаль­ ного зерна. Заменим предложение

R = ((AAXIS *BAXIS * CAXIS)/8.0) * * 0,33333

на предложение

R = CUBE ((AAXIS * ВAXIS * CAXIS)/8.0)

Заметим, что в качестве фиктивной переменной X в списке параметров функции CUBE в скобках стоит целое предложение.

Правила использования оператора FUNCTION сравнительно просты. Функция должна быть названа в соответствии с теми соглашениями, которые были приняты для переменных (не бо­ лее шести символов, никаких специальных символов), и может начинаться с любой буквы от I до N, если требуемое операто­ ром возврата значение является целым. Заметим, что с помощью функции может быть возвращено только одно значение. Вообще говоря, каждой функции можно поставить в соответствие ма­ тематическое обозначение. В рассмотренном уже примере экви­ валентные обозначения следующие:

Запись на ФОРТРАНе

Математический символ

 

з _

CUBE (X )

/ X .

Функция должна содержать предложение RETURN и кон­ чаться предложением END. Одним из преимуществ оператора FUNCTION является то, что его можно скомпилировать и про­ верить на машине без использования сопровождающей про­ граммы, а только с помощью небольшой проверочной программы

А = CUBE (27.0)

WRITE (6.10) А CALL EXIT

10 □ FORMAT (F 10.4) END

Этой короткой программы достаточно для контроля функции FUNCTION CUBE, в данном случае для проверки того, что она дает требуемое значение 3.0. Проверка больших программ по частям делает отладку более простой (см. Голд [5], Мак-Крэ- кен [7], Мэррилл и Смит [8]).

Подпрограммы. Другой тип подпрограмм, который мы рас­ смотрим,— SUBROUTINE. В отличие от оператора FUNCTION подпрограмма не может использоваться как математический оператор. Напротив, список параметров, содержащих перемен­ ные, передается подпрограмме SUBROUTINE, которая возвра­ щает во внешнюю программу результаты вычислений. Подпро­ граммы можно вызвать оператором CALL, определяющим на­ звание подпрограммы и переменных, которые должны быть внесены в список параметров. Предположим, что мы имеем дан­ ные, представляющие координаты X, Y точек на карте, и хотим повернуть систему координат на угол 0. Допустим также, что предусмотрено неоднократное выполнение вращения, и мы хо­ тим написать программу выполнения этой операции. Для каж­ дой точки требуется указать две координаты, поэтому оператор FUNCTION не подходит в этом случае. Однако подпрограмма SUBROUTINE ROTATE, приведенная ниже, осуществляет тре­ буемое вращение и возвращает две новые координаты. Список параметров определяет как передачу, так и возврат фиктивных переменных.

SUBROUTINE ROTATE (OLDX, OLDY, THETA, XNEW, YNEW) RADIAN= THETA * 0.01745329

XNEW = OLDX* COS (RADIAN) - OLDY * SIN (RADIAN) YNEW = OLDX * SIN (RADIAN)-f-OLDY * COS (RADIAN) RETURN

END

Эту подпрограмму можно вызвать с помощью предложения основной программы, такого, как

CALL ROTATE (XCOORD, YCOORD, DEG, X, Y).

Конечно, значения переменных XCOORD, YCOORD и DEG должны быть предварительно определены в программе. В под­ программе OLDX, OLDY и THETA автоматически приравнива­ ются этим переменным, и в результате выполнения вычислений определяются значения переменных XNEW и YNEW. При воз­ врате к основной программе значения XNEW и YNEW автома­ тически присваиваются переменным X и Y. С этого места все пе­ ременные, перечисленные в предложении CALL, пригодны для дальнейшего использования в программе. Необходимо отметить,

что подпрограмма является отдельной программой, не являю­ щейся составной частью основной программы и ее можно ис­ пользовать независимо от других подпрограмм. В основной про­ грамме переменная может быть названа OLDX или THETA, при­ чем как в основной программе, так и в подпрограмме SUBROUTINE ROTATE переменные с такими же именами от­ носятся к различным объектам, что гарантирует от недоразу­ мений.

На название подпрограмм не налагается никаких ограниче­ ний, кроме запрещения употреблять специальные символы. Так как название подпрограммы не является переменной, то согла­ шения, определяющие название программы, не подчиняются правилам образования наименований для вещественных или це­ лых переменных. Конечно, переменные в списке параметров дол­ жны иметь обоснованные названия. Ни одна из фиктивных пере­ менных в списке параметров не может быть снабжена нижним индексом, хотя массивы индексированных переменных могут входить в список параметров, как мы увидим в следующем при­

мере.

Более подробная информация о подпрограммах содер­

жится

в

книгах Голда {5], Мак-Крэкена [7] и Мэррилла

и Смита

[8].

Как подпрограммы, так и функции могут использовать дру­ гие функции и вызывать другие подпрограммы с одним лишь ограничением, запрещающим двум подпрограммам вызывать одна другую. В остальных отношениях подпрограммы являются совершенно независимыми и могут быть компилированы и отла­ жены отдельно от других подпрограмм или основной программы. Большинство процедур, запрограммированных в этой книге, опи­ сано в форме подпрограмм. Это позволяет объединить их произ­ вольным образом с помощью короткой и простой основной программы, содержащей операторы вызова подпрограмм. В сле­ дующих главах приведено несколько примеров основных программ, которые можно использовать с некоторыми из этих подпрограмм. Однако пользователь может составить свою собственную основную программу и видоизменять подпро­ граммы таким образом, чтобы они отвечали его конкретным целям.

Часто требуется решить достаточно общую проблему — отыскать в массиве данных наибольшее и наименьшее значение или целый ряд данных. Это можно сделать различными спосо­ бами, включая использование систем функций некоторых ком­ пиляторов. Однако мы хотим написать подпрограмму решения этой задачи с целью иллюстрации одновременного использова­ ния массива и индексированных переменных. В данном случае нельзя использовать подпрограмму FUNCTION, так как мы хотим получить на выходе три переменные: минимальное и

максимальное значения, а также квадратный корень каждого из исходных значений.

Заметим, что размер массива данных в подпрограмме описы­ вается с помощью предложения DIMENSION. Для всех пере­ менных с нижними индексами, используемых в подпрограмме, должны быть указаны размерности, даже если они не содер­ жатся в списке параметров, а являются'лишь внутренними пере­ менными. Это должно быть сделано по двум причинам. Предпо­ ложим, что MEAN(I) — индексирования целая переменная. Ком­ пилятор не может отличить ее от функции с названием MEAN

ис аргументом I. Однако предложение DIMENSION указывает компилятору, что MEAN является индексированной переменной

ихарактеризует порядок соответствующего ей массива. Вторая причина, по которой для всех индексированных переменных дол­ жны быть указаны размерности, объясняется способом хранения массивов в вычислительной машине. Предложение CALL пере­ дает только адрес первого элемента массива; для того чтобы разместить элементы массива в правильном порядке, компиля­ тору надо указать, сколька строк и столбцов содержится в мас­ сиве.

Однако в отличие от предложений DIMENSION в основной программе предложения DIMENSION внутри подпрограммы мо­ гут содержать индексированные переменные. Например, список параметров в подпрограмме может быть следующим:

SUBROUTINE ALPHA (A, N, М, X),

причем за ним следует предложение

DIMENSION A (N, М).

В этом случае размер массива А будет определяться значе­ ниями, передаваемыми через список параметров подпрограммы, за которым следует предложение DIMENSION. Конечно, раз­ мерности этого массива в подпрограмме не должны превышать размерностей соответствующего массива в основной программе, т. е. N и М не могут быть больше, чем размерности мас­ сива А, указанные в предложении DIMENSION основной про­ граммы.

Список параметров подпрограммы SUBROUTINE RANGE содержит наименование исследуемого массива, его длину, макси­ мальное и минимальное значения, а также квадратный корень из исходных значений массива. Конечно, названия переменных

в списке параметров являются фиктивными и могут не совпадать

сназваниями в списке параметров оператора CALL. Однако фактические наименования в предложении CALL должны стоять