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

Книга Фортран Павловец 2008

.pdf
Скачиваний:
127
Добавлен:
31.05.2015
Размер:
1.55 Mб
Скачать

43. Вывод графиков

На основании каких-либо произведённых расчётов бывает очень полезно эти результаты представить еще и графически. Это позволит оценить правильность расчёта или быстро определить, к примеру, экстремальные точки.

Программ вывода графиков может быть великое множество, так как их можно организовать по-разному, начиная от расположения графика (вертикально, горизонтально) и заканчивая масштабированием графика (с помощью одной программы можно построить график, например, для значений 1…10 и для значений 1000…100000).

К сожалению, простейшая программа на языке ФОРТРАН позволяет рисовать график только отдельными символами и график получается точечным с большими промежутками между точками. При очень высоких требованиях к выводимым графикам необходимо обращаться к Fortran Power Station для Windows или к другим языкам программирования, например ПАСКАЛЬ или к языкам, которые разрабатывают приложения под WINDOWS – это

DELPHI, С++ и др.

Вывод простейших графиков рассмотрим на примере задачи.

Задача:

Написать подпрограмму, которая выводит в виде графика одномерный массив Х размерностью N.

Основные положения подпрограммы:

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

2.Каждый элемент массива отпечатаем в виде числа и отобразим текстовым символом «*» на экране дисплея в той же строке, что и число. Месторасположение символа «*» будет зависеть от величины текущего значения элемента массива и будет занимать на экране крайнее правое положение при максимальном значении и крайнее левое положение при минимальном.

3.Учитывая, что ширина вывода на экран составляет 80 позиций, и что одну позицию при выводе мы вынуждены пропустить, что для вывода самого числа по спецификации G10.4 используем 10 позиций, определяем, что для вывода символа «*» остается 69 позиций.

4.Чтобы символ «*» попадал в поле с 1 по 69 позицию, выведем формулу номера позиции символа «*» в зависимости от текущего значения элемента массива.

N= xтек xmin 68 + 1

xmax xmin

5.Печатая число и символ «*» столько раз, сколько имеется элементов массива, получим

его график.

В подпрограмме надо найти максимальное и минимальное значение массива, организовать цикл n-ное количество раз. В этом цикле в соответствии со значением Xтек определить номер позиции, в которую надо поместить символ «*». Символ «*» нужно поместить в текстовый массив из 69 позиций, который состоит из пробелов и одного символа «*». Причём номер позиции, в которой размещается символ «*», зависит от Xтек. Для удобства анализа графика отпечатаем ось в виде символа «|».

101

СПрограмма №32 SUBROUTINE GRAF(X,N)

Вподпрограмму передаётся массив Х размерностью N, значения которого используются для построения графика.

DIMENSION X(N)

CHARACTER*1 S(69),PROB,ZW,OS DATA PROB,ZW,OS/’ ’,’*’,’|’/

Втекстовую переменные помещаем: PROB – пробел, ZW – символ « * », OS

– символ “ |”.

XMA=X(1)

XMI=X(1) DO 2 I=2,N

XMA=AMAX1(X(I),XMA) Находим максимум и минимум

2XMI=AMIN1(X(I),XMI)

A=XMA–XMI DO 5 I=1,N DO 6 J=1,69

6S(J)=PROB

Заполняем текстовый массив пробелами. Можно просто записать S(J)=’ ’ NZW=(X(I)-XMI)/A*68.+1. Определяем номер позиции, в которую будем выводить символ «*»

NOS= –XMI/A*68.+1. Определяем номер позиции оси графика

S(NOS)=OS

S(NZW)=ZW

Элементы массива S, номера которых рассчитаны, заменяются символами

«*» и «|».

WRITE (6,7) X(I),S

7FORMAT (1X,G10.4,69A1)

5CONTINUE RETURN END

Недостатки программы вывода графиков:

Внутри цикла происходит N-ное количество раз определение номера позиции оси, что является нерациональным. Этот оператор нужно вынести до начала цикла. На каждом цикле рабочий массив заполняется пробелами. Можно это сделать однократно до начала цикла, а после печати в элемент массива, где была «*», записывать пробел. При выводе графика, где все значения положительны либо все отрицательны, образуется сбойная ситуация в строке 15. Чтобы ее избежать, необходимо включить число 0 в аргументы функций AMAX1(X(I),XMA,0.), AMIN1(X(I),XMI,0.). В программе желательно было бы осуществить вывод координатной сетки. Возможно написание одной подпрограммы для вывода одного, двух, трех графиков в одних координатах. Вам предоставляется возможность самостоятельно усовершенствовать подпрограмму и проявить свои способности.

Задача:

Использовать подпрограмму GRAF для вывода графика тока для цепи:

102

R

U L

i = u/z u =Umsin wt * e-t ,

F = 50

w = 2*π * F t =0...π

R = 2000 Ом, L = 50 мГн Um = 220в

z = X L2 + R2

Получить 40 точек и вывести I = f(t).

СПрограмма №33 DIMENSION TOK(2000)

WRITE (6,*)’Введите значения Um,R,F,L’ READ (5,*) Um,R,F,AL XL=2.*3.14*F*АL*1.Е-3 Z=SQRT(XL**2+R*R)

T=0.

DT=3.14/40. DO 9 I=1,40

TOK(I)=Um*SIN(2.*3.14*F*T)*EXP(-T)/Z

9T=T+DT

CALL GRAF(TOK,40)

Идёт обращение к программе GRAF, куда засылается массив данных ТОК размерностью 40 элементов, в этой программе строится график на основании значений элементов массива ТОК.

STOP END

На экране дисплея появится график:

103

.0000

 

*

*

 

-94.60

*

|

 

-154.8

 

|

 

-172.6

*

 

|

 

-150.2

*

 

|

 

-98.29

*

*

|

 

-32.54

 

|

*

30.75

 

 

|

78.15

 

 

|

*

101.6

 

 

|

*

99.56

 

 

|

*

76.11

 

 

|

*

39.48

 

 

|

*

-.4268

 

*

*

 

-34.44

 

|

 

-56.01

 

*

|

 

-62.25

 

*

|

 

-54.01

 

*

|

 

-35.21

 

*

|

 

-11.47

 

*

|

*

11.32

 

 

|

28.33

 

 

|

*

36.70

 

 

|

*

35.86

 

 

|

*

27.33

 

 

|

*

14.08

 

 

|

*

-.3055

 

*

*

 

-12.54

 

|

 

-20.26

 

*

|

 

-22.45

 

*

|

 

-19.43

 

*

|

 

-12.61

 

*

|

 

-4.042

 

 

*|

 

4.164

 

 

|*

*

10.27

 

 

|

13.25

 

 

|

*

12.92

 

 

|

*

9.813

 

 

|

*

5.023

 

 

| *

 

-.1648

 

 

*

 

44. Эквивалентирование текстовых переменных

С помощью оператора EQUIVALENCE можно приводить в соответствие два объекта данных текстового типа.

Если в списке оператора EQUIVALENCE описать две переменные, например А и В, то при выполнении программы в оперативной памяти ЭВМ переменной В будет соответствовать блок памяти переменной А. То есть, если переменной А присвоить какое-либо значение, то изза того, что обе переменные занимают в памяти ЭВМ один и тот же блок, значение переменной В будет соответствовать значению переменной А и наоборот.

104

Пример:

CHARACTER*12 A,B*3

EQUIVALENCE(A(1:3),B)

В примере первые 3 символа текстовой переменной А будут соответствовать переменной

В.

Задача:

В файле DEKANAT хранятся записи, а в каждой записи записаны: Фамилия и инициалы, и 4 оценки по экзаменам.

Написать подпрограмму, которая по запросу выдаёт сообщения об успеваемости студента, фамилия которого вводится с клавиатуры.

СПрограмма №34 CHARACTER*12 FAM1,FAM2 OPEN (3,FILE=’DEKANAT’)

WRITE (6,*)’Введите искомую фамилию’

READ (5,’(A12)’) FAM1

Происходит считывание искомой фамилии студента. Запись

READ(5,’(A12)’)FAM1 можно заменить на следующие две строки:

READ (5,7) FAM1

7FORMAT (A12) или 7 FORMAT(A) , что абсолютно аналогично предыдущему.

4READ (3,8,END=1) FAM2,K1,K2,K3,K4

Вэтой строке из файла DEKANAT происходит считывание

Ф.И.О.(переменная FAM2) и оценок за экзамены (переменные K1,K2,K3,K4) при помощи оператора FORMAT с меткой 8. При возникновении ситуации «конец файла» управление передаётся на метку 1.

8FORMAT(A12,4I5)

IF(FAM1.EQ.FAM2) WRITE(6,9) FAM2,K1,K2,K3,K4

9FORMAT(1X,A12,4I5)

В этой строке происходит сравнивание исходной фамилии (введенной с клавиатуры после запроса) и очередной считанной фамилии из файла DEKANAT. Если фамилии совпадают, то выводим на экран: Ф.И.О. и 4 оценки. Затем происходит переход на новую строку файла и считывание очередной фамилии и проверка её по условию.

GOTO 4

1STOP END

Недостатком программы является то, что фамилия в файле и фамилия, введённая с клавиатуры, должны совпадать полностью. Если будет различие хоть в одном символе (другая буква или лишний символ пробел), то программа не выведет никакого результата (так как не выполнится условие оператора IF). Еще необходимо бы доработать программу, чтобы выводимый текст выводился с поясняющей информацией (Ф.И.О.: …, Оценка №1: …, Оценка №2: … и т.д.).

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

105

Задача:

В отдел кадров предприятия из КГБ пришла телеграмма: “Сотрудник вашего предприятия Михаил, 1962 года рождения, замешан в связях с вражеской разведкой. Используя вашу базу данных, представьте все сведения о всех сотрудниках по имени Михаил 1962 года

рождения”.

 

 

 

 

База данных предприятия содержится в файле KADRY в виде записей:

 

Ф.И.О.

год рождения

домашний адрес

табельный №

телефон

40 поз.

5 позиций

15 поз.

5 поз.

7 поз.

СПрограмма №35

CHARACTER*40 FIO,DOM*15,TEL*7,IMJA*6/’Михаил’/ В операторе character можно не только описывать длину текстовых переменных, но и задавать значение 'Михаил' так же, как и в операторе DАТА.

OPEN (4,FILE=’WYWOD’)

WRITE (4,*)’Сведения по вашему запросу’

OPEN (3,FILE=’KADRY’,STATUS=’OLD’)

4READ (3,7,END=10) FIO, NGOD, DOM, NTAB, TEL

Считываем запись: Ф.И.О., год рождения, домашний адрес, номер по табелю, телефон.

7FORMAT (A40,I5,A15,I5,A7) IF (NGOD.NE.1962) GOTO 4

Здесь в условии применён элемент обратной логики: если считанный из файла год не равен 1962, тогда производится переход на метку 4 и считывается следующая запись. В область, расположенную ниже, попадаем только тогда, когда считанный год рождения равен 1962.

NI=INDEX(FIO,’ ’)

Чтобы найти имя Михаил, выделяем номер индекса, в котором находится символ «пробел» после фамилии. Этот индекс присваивается переменной

NI.

IF (FIO(NI+1:NI+6).EQ.’Михаил’) WRITE (4,9) FIO, NGOD, *DOM,NTAB,TEL

С помощью этой записи вылавливаем шпиона: если в текстовой переменной FIO, начиная с индекса NI+1 по индекс NI+6, встречается ’Михаил’, то в файл WYWOD выводим Ф.И.О., год рождения, домашний адрес, номер по табелю, номер телефона. NI+1:NI+6 – текстовая подцепочка.

9 FORMAT (1X,A40,I5,A15,I5,A7) GOTO 4

10WRITE(4,*)’Конец просмотра базы данных’

CLOSE (UNIT=3) CLOSE (UNIT=4) STOP

END

Если производить поиск не по имени, а по отчеству, то номер индекса найдем: NI2=INDEX(FIO(NI+1:),’ ’), то есть поиск по второму пробелу.

текстовая подцепочка от N+1 позиции и до конца переменной FIO

Например, если записано :

106

Иванов Иван Иванович то NI=7, a NI2=12.

45. Создание библиотек

Причины создания библиотек стандартных программ были рассмотрены ранее. В этой главе мы рассмотрим процесс создания этих библиотек.

Существуют три стандартные библиотеки языка ФОРТРАН:

Llibfora.lib, Llibfore.lib, Llibfor7.lib.

В этих библиотеках содержатся файлы в виде:

имя.obj

Библиотеки создаются командой lib в диалоговом режиме под DOS. Набираем на клавиатуре lib и нажимаем на «ввод».

При этом появятся 2 или 3 сообщения. Далее: подчеркнутый текст – сообщения компьютера, а следующий за ним неподчеркнутый текст – ответ пользователя.

Library name: Libmain

задаётся имя создаваемой библиотеки (например, Libmain). Можно задать полный путь. Можно задать имя существующей библиотеки. При этом можно будет её дополнить своей программой, удалить любую программу из библиотеки или заменить старую программу новой.

Library does not exist. Create? (y/n) y

библиотека не существует, создать? (да/нет) Отвечаем: да, создать.

В эту, пустую библиотеку внесем (добавим) два файла matr.obj и integ.obj.

Operations: +matr+integ

Существуют 3 вида операций: + добавить в библиотеку:

– удалить из библиотеки;

–+ заменить (удалить и вставить. Но лучше эту операцию не использовать) Примечание: при занесении программы в библиотеку необходимо проследить, чтобы на

этапе компиляции создался файл с расширением obj. Если это не произошло, попробуйте произвести компиляцию при помощи команды FL (см.раздел "Командные файлы").

List file: spisok.txt

в файл с именем spisok.txt выведем список всех программ из библиотеки Libmain.

Output library: Libmain

исходящая библиотека. Если указать Libmain, то сохранится прежняя библиотека, дополненная файлами matr.obj и integ.obj. Если создать новое имя файла исходящей библиотеки, то создастся библиотека с введенным именем, которая будет полной копией Libmain, но дополненной новыми файлами.

46. Решение дифференциальных уравнений

Дифференциальные уравнения представляют собой функцию вида: y'=f(x,y)

Решить дифференциальное уравнение – это значит найти очередную точку кривой, которая описывается этим уравнением.

107

Y

Yk+1

Y0

dx X

yk +1 = yk + Дy – каждое новое значение будет равно: предыдущее (yk) + добавка Дy .

x = x + dx

Задача:

Решить дифференциальное уравнение:

dy

= 2sinx +

3cos y

dx

x0

= 0;

y0

= 1.73

на отрезке от х=0 до х=1.5 с шагом 0.1 по методу Рунге-Кутта 4 порядка:

 

1

 

 

 

 

 

 

yk +1 = yk +

 

 

(K1+ 2K 2 + 2K3 + K 4)

6

где K1 = f (x, yk x;

 

 

 

 

K 2 = f (x +

Дx

, yk +

K1

x;

 

 

 

 

 

2

 

 

 

 

2

 

 

K3 = f (x +

 

Дx

, yk +

 

K 2

x;

2

 

2

 

 

 

 

 

K 4 = f (x + Дx, yk + K3)Дx .

Решение:

Необходимо в программе задать цикл, при котором будут вычисляться значения коэффициентов K1,K2,K3,K4 и значения y.

СПрограмма №36

WRITE (6,*)’ Введите ИД: Xo,Yo,DX,Xкон’

READ (5,*) X0,Y0,DX,XK

Y=Y0

CЗадаём цикл

DO 1 X=X0,XK-DX,DX AK1=FUN(X,Y)*DX

Коэффициенты К1, К2, К3, К4 заменены на AK1, AK2, AK3,AK4 потому, что первый символ (буква K) относит переменную к целому типу (I, J, K, L, M, N), а она должна быть вещественного типа. Fun – подпрограмма функция, описывающая наше уравнение.

AK2=FUN(X+DX/2.,Y+AK1/2.)*DX

AK3=FUN(X+DX/2.,Y+AK2/2.)*DX

108

AK4=FUN(X+DX,Y+AK3)*DX Y=Y+(AK1+2.*AK2+2.*AK3+AK4)/6.

XN=X+DX Чтобы напечатать X, соответствующее новому значению Y

1WRITE (6,*) ’При X=’,XN,’ Новое значение Y=’,Y PAUSE

STOP END

FUNCTION FUN(X,Y) FUN=2.*SIN(X)+SQRT(3.)*COS(Y) RETURN

END

Хизменяется в цикле от ХО до ХК с шагом DX. Для того, чтобы напечатать новое значение Y с соответствующим ему значением Х, определяем новое ХN=Х+DX.

Недостатки программы:

Данные вводятся, но тут же не распечатываются, не создаётся массив данных для построения графика. Можно было бы посчитать общее количество полученных значений.

Попробуйте свои силы в устранении этих недостатков.

Задача:

Решите дифференциальное уравнение:

dy

= 2sin x + 3 cos y

dx

 

x0

= 0, y0 =1.73, xk =1.5, dx = 0.001

Для решения дифференциального уравнения использовать стандартную программу из библиотеки стандартных программ RK2.

RK2(FUN,H,X1,Y1,K,N,VEC), где

FUN – имя внешней подпрограммы-функции, в которой описано решаемое дифференциальное уравнение. Обязательно описать при помощи оператора EXTERNAL;

Н – шаг интегрирования;

Х1, Y1 – начальные значения Xo, Yo;

K – количество шагов между двумя сохраняемыми значениями; N – количество значений;

VEC – результирующий вектор-столбец, длиной N.

При помощи параметра K вычисления можно производить для всех значений, а сохранять только одно из 3, 4, … Т.е. можно будет построить график, например из 10 точек, но при расчётах будет использовано 200 точек. Точность расчетов сохраняется, а график выводится приближённо.

СПрограмма №37

СПодпрограмма-функция вычисления дифференциального уравнения

FUNCTION FUN(X,Y) FUN=2.*SIN(X)+SQRT(3.)*COS(Y) RETURN

END

109

C

Головная программа

 

DIMENSION VEC(1000)

 

EXTERNAL FUN

 

Поскольку имя подпрограммы-функции FUN используется в списке

 

фактических параметров при обращении к RK2, то ее необходимо описать

 

в EXTERNAL

 

WRITE (6,*)’Введите значения Xo, Yo, Xк, dx’

 

READ (5,*) X0,Y0,XK,DX

 

K=10

 

При K=10 будем сохранять каждое десятое значение.

 

N=((XK–X0)/DX+1.)/K

 

Вычисление общего количества сохраняемых точек, где (XK–X0)/DX+1.) –

 

количество всех точек при расчёте.

 

CALL RK2(FUN,DX,X0,Y0,K,N,VEC)

 

После возврата из подпрограммы RK2 мы имеем заполненный массив VEC в

 

количестве N элементов.

 

WRITE (6,*) (VEC(I), I=1,N) Грубый вывод на экран массива с

 

результатами расчета

CПостроение графика и вывод результатов расчёта на экран

CALL GRAF(VEC,N) XT=X0

DO 8 I=1,N

WRITE (6,*) XT,VEC(I)

8XT=XT+K*DX В этом цикле выводится таблица со значениями аргумента и функции

PAUSE STOP END

47. Работа с комплексными данными

В ФОРТРАНЕ имеется специально выделенный тип переменных, который называется

комплексными переменными.

Все данные комплексного типа должны быть описаны в программе специальным оператором описания COMPLEX.

Пример описания:

COMPLEX A,B,DOK(10),C(4,5)

Правило:

В операторе COMPLEX должны быть описаны все переменные, которым может быть присвоено выражение комплексного типа (в том числе и промежуточные данные).

Константы комплексного типа представляют собой два вещественных числа, заключенных в скобки и разделённых запятой.

Примеры:

(-1.67,1.Е–2)= –1.67+j0.01 (0.,–2.)=0–j2= –j2

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

110