Форум программистов, компьютерный форум, киберфорум
Fortran
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33

Задача с условиями и интегралами на Fortran

28.02.2024, 18:05. Показов 4899. Ответов 54

Студворк — интернет-сервис помощи студентам
Добрый вечер!
Дали задание, запрограммировать задачу на Фортране и не могу понять где у меня ошибки и как их исправить
Изначально даны файлы A(1 2 3 2 1), B(1 2 3 2 1), T(2 2 2 2 2), и пределы от a до b (-2 -1 0 1 2)
T = 2
M = 3
Y = 5
Итог, нужно вывести все R





Мой код:
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
program F
    real :: A(1:5), A1(1:5), B(1:5), B1(1:5), T(1:5), T1(1:5),H(1:5),D(1:5),V(1:5),X(1:5),CC(1:5),CC1(1:5),T,G,M,L,Y,O1,K1,K2,F1,R,C,a,b,S,S1,e
    integer :: i,n
    open(1, file = 'A.txt')
    open(2, file = 'B.txt')
    open(3, file = 'T.txt')
    open(4, file = 'predeli.txt')
    T = 2
    M = 3
    Y = 5
    L = (Y**2)/9,81
    e = 2,718
    
    !Изначальные условия
do i = 1,5
     
        read (1,*) A
        read (2,*) B
        read (3,*) T
        read (4,*) X
    
        if (A(i).gt.0 .and. B(i).gt.0) go to 111
        else
            A1(i) = 0
            B1(i) = 0
            T1(i) = 0
        endif
        111 continue    
        if ((A(i)/B(i)).le.T(i)) then
            A1(i) = A(i)
            B1(i) = B(i)
            T1(i) = T(i)
        else
            T1(i) = T(i)
            B1(i) = B(i)
            A1(i) = B1(i) * T1(i)
        endif
        
        !V
        n=size(X)
        S=0.0
        do i=1, n-1
        S1=S
        S=S+0.5*(X(i+1)-X(i))*(A1(i+1)+A1(i))
        V(i)=S1
        end do
        V(n)=S
        
        !H
        n=size(X)
        CC(i) = (1/12.) * (B1(i))**3
        S=0.0
        do i=1, n-1
        S1=S
        S=S+0.5*(X(i+1)-X(i))*(CC(i+1)+CC(i))
        H(i)=S1
        end do
        H(n)=S * (1/V(n))
        
        !D
        n=size(X)
        CC1(i) = ((-T1(i))/2.) * A1(i)
        S=0.0
        do i=1, n-1
        S1=S
        S=S+0.5*(X(i+1)-X(i))*(CC1(i+1)+CC1(i))
        D(i)=S1
        end do
        D(n)=S * (1/V(n)) + T
        
        !G и O1
        G = D(n) + H(n) + M
        O1 = G - T
        
        !K1
        do i = X
        K1(i) = ((sin(L *(B1(i)/2.)))/(L*B1(i))/2.) * (((1+L*T1(i)) * e ** (-L*T1(i) - 1)) / ((L**2) * T1(i)))
        end do
        
        !K2
        do i = X
        K2(i) = (-((e ** (-L*T1(i) - 1)) / ((L**2) * T1(i))))* (cos(L*(B1(i)/2.)) - ((sin(L*(B1(i)/2.)))/(L*(B1(i)/2.))))
        end do
        
        !F1
        do i = X
        F1(i) = -((1 - (e**(-L*T1(i))))/(L*T1(i))) * ((sin(L*(B1(i)/2.)))/((L*B1(i))/2.))
        end do
        
        !C
        do i = X
        if (A1(i) .eq. 0 .and. B1(i) .eq. 0) then
        C(i) = 0
        else
            C(i) = A1(i) * (K1(i) + K2(i) + F1(i) * O1)
        endif
        end do
        
        !R
        do i = X
        n=size(X)
        S=0.0
        do i=1, n-1
        S1=S
        S=S+0.5*(X(i+1)-X(i))*(C(i+1)+C(i))
        R(i)=S1
        end do
        R(n)=abs(S / (V(n) * M))
        end do
        print *, R
end do
end program F
Буду благодарен за помощь
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.02.2024, 18:05
Ответы с готовыми решениями:

Есть задача на чтение из файла и обработку двумерного массива в Fortran, написал на C++, надо написать на fortran
#include <iostream> #include <fstream> #include <string> /* Составить программу для реализации предложенного вариантом...

задача с интегралами
Помогите пожалуйста с задачей. Численное интегрирование с использованием формулы трапеций. Реализовать заданный алгоритм для...

Задача на массивы Fortran
Помогите пожалуйста, я не понимаю просто, а примеров на этот тип задач (подробных или просто для меня понятных) не нашёл

54
 Аватар для Krasme
7960 / 5121 / 2162
Регистрация: 02.02.2014
Сообщений: 13,495
06.03.2024, 21:24
Лучший ответ Сообщение было отмечено Catstail как решение

Решение

Студворк — интернет-сервис помощи студентам
Fortran
1
do k = 1,50
т.е. 50 раз пытаетесь прочитать по 5 раз один и тот же файл, не закрывая его?

топорное решение - на строке 52 поставить close(1) и по остальным файлам.


грамотное решение:
перед do k=1,50 прочитать все файлы и записать данные в массивы один раз! потом просто использовать заполненные массивы.
1
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
06.03.2024, 21:43  [ТС]
Krasme,
Cпасибо огромное!
Скорее всего на следующих днях появятся вопросы по этому коду тут, завтра спрошу у руководителя про один подвох
0
 Аватар для Krasme
7960 / 5121 / 2162
Регистрация: 02.02.2014
Сообщений: 13,495
06.03.2024, 22:00
поправочка..
не 52 строка, а 56.. короче, после замыкания цикла do i = 1,5
0
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
06.03.2024, 22:01  [ТС]
Krasme, Я решил поступить грамотно
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
06.03.2024, 23:33
FrenchRedPaw, грамотно было бы переписать этот "шедевр" с нуля.

Вот, например, процедура VV, а точнее, ее 3-й параметр (снаружи OOO, внутри IY). Он исправно вычисляется при каждом вызове процедуры, но никогда и нигде не используется. Внутри процедуры его упоминания легко убрать, снаружи даже это не потребуется - просто удалить массив вместе с соответствующей частью вызовов и все.

И вот такого тут добрая половина. Оставшаяся половина все же что-то делает, но при сколько-нибудь обдуманной записи кода сокращается еще раза в два как минимум.
0
Модератор
 Аватар для Curry
5168 / 3530 / 536
Регистрация: 01.06.2013
Сообщений: 7,678
Записей в блоге: 9
07.03.2024, 02:33
Цитата Сообщение от Pphantom Посмотреть сообщение
никогда и нигде не используется
Я незнаком с современными компиляторами фортрана, но компиляторы для других языков, как правило, выдают предупреждения если переменная не используется. Наверно и тут такое должно быть. Распространённая же ошибка возникающая, например, когда имена перепутали.
0
WH
1589 / 817 / 192
Регистрация: 10.09.2013
Сообщений: 3,293
Записей в блоге: 3
07.03.2024, 04:34
Цитата Сообщение от Curry Посмотреть сообщение
Наверно и тут такое должно быть.
Есть конечно. Если переменная не объявлена, при наличии implicit none, компилятор выдает ошибку с отказом от компиляции и указанием на необъявленные переменные. Напротив, если есть объявленные, но не используемые в коде переменные, то компиляция происходит, но компилятор выдает информационное сообщение о наличии таких переменных с их указанием.
1
Модератор
 Аватар для Curry
5168 / 3530 / 536
Регистрация: 01.06.2013
Сообщений: 7,678
Записей в блоге: 9
07.03.2024, 08:25
Цитата Сообщение от WH Посмотреть сообщение
если есть объявленные, но не используемые в коде переменные, то компиляция происходит, но компилятор выдает информационное сообщение о наличии таких переменных с их указанием.
А, ну тогда FrenchRedPaw-у я советую смотреть предупреждения выдаваемые компилятором, чаще всего они указывают на ошибки программиста. В идеале их вообще не должно быть в отлаженной программе.
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
07.03.2024, 09:57
Цитата Сообщение от Curry Посмотреть сообщение
Я незнаком с современными компиляторами фортрана, но компиляторы для других языков, как правило, выдают предупреждения
Эти, естественно, тоже, но тут неиспользуемость результатов не настолько очевидна.
0
Модератор
 Аватар для Curry
5168 / 3530 / 536
Регистрация: 01.06.2013
Сообщений: 7,678
Записей в блоге: 9
07.03.2024, 10:55
Цитата Сообщение от Pphantom Посмотреть сообщение
тут неиспользуемость результатов не настолько очевидна
Почему?
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
07.03.2024, 13:27
Цитата Сообщение от Curry Посмотреть сообщение
Почему?
ТС вместо полноценного модуля с процедурой или внутренней процедуры (благо и тот, и другой инструменты в Фортране есть) написал фактически две раздельных единицы компиляции, просто засунутых в один файл с исходником. Как следствие, установление связей между процедурой и вызывающей ее программой происходит уже на стадии линковки, а линкер подобные нюансы отслеживать уже не умеет.

При этом с точки зрения основной программы третий аргумент процедуры является INOUT, т.е. на стадии компиляции программы неизвестно, будет ли значение, вернувшееся в результате первого вызова, использоваться во втором, а с точки зрения процедуры - она просто заполняет и возвращает какой-то массив и ничего не знает о его последующем использовании (или неиспользовании).
1
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
13.03.2024, 22:23  [ТС]
По итогу код после каждого повторного запуска выдает разные значения и не все близки к правде
Как можно разобраться хотя бы с первым пунктом?
Может я неправильно по итогу написал код тех условий, которые были даны на картинке...

Pphantom, вроде бы исправил то, что подметили.

Файлы txt которые использую, прикрепил:
A.txt
B.txt
T.txt
predeli.txt
Y.txt

Сам код выглядит так:

Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
program F
 Implicit none
 
 integer :: i, k
 real :: TT, M, A1(21), B1(21), T1(21), HH(21),DD(21), K1(21), K2(21), F1(21),C(21), L(50)
 real :: R(50),O1, H, V, D, HHH, RR, G, DDD, A(21), B(21), T(21), X(21),Y(50)
 open(1, file = 'A.txt')
 open(2, file = 'B.txt')
 open(3, file = 'T.txt')
 open(4, file = 'predeli.txt')
 open(5, file = 'Y.txt')
 
 
 
 TT = 5.90
 M = 3.43
 
 do i = 1, 21
  read(1, *) A(i)
  read(2, *) B(i)
  read(3, *) T(i)
  read(4, *) X(i)
  
  if (A(i) > 0 .and. B(i) > 0) then 
    if ((A(i)/B(i)) <= T(i)) then
     A1(i) = A(i)
     B1(i) = B(i)
     T1(i) = A(i)/B(i)
    else
     B1(i) = B(i)
     T1(i) = T(i)
     A1(i) = B1(i) * T1(i)
    endif
  else
   A1(i) = 0
   B1(i) = 0
   T1(i) = 0
   endif
 
    !Для нахождения V
   call VV(X, A1,V)
   
   !Для нахождения H
   HH(i) = (1.0/12.0)* B1(i)**3
   call VV(X, HH,HHH)
   
   
   !Для нахождения D
   DD(i) = ((-T1(i))/2.0) * A1(i)
   call VV(X,DD,DDD)
   
   
   
 
  
   !Найденные H, D, G
   H = HHH * (1.0/V)
   D = (DDD * (1.0/V)) + TT
   G = D + H - M 
 
 end do
 
   !Решение для 3 картинки
   O1 = G - TT 
  
  do k = 1,50
  read (5,*) Y(k)
  L = ((Y(k)**2.0) / 9.81)
 
    do i = 1,5
    !K1
    K1(i) = ((sin(L(k) *(B1(i)/2.)))/(L(k)*B1(i))/2.) * (((1+L(k)*T1(i)) * exp(-L(k)*T1(i) - 1)) / ((L(k)**2) * T1(i)))
    
    !K2
    K2(i) = (-((exp(-L(k)*T1(i) - 1)) / ((L(k)**2) * T1(i))))* (cos(L(k)*(B1(i)/2.)) - ((sin(L(k)*(B1(i)/2.)))/(L(k)*(B1(i)/2.))))
   
    !F1
    F1(i) = -((1 - (exp(-L(k)*T1(i))))/(L(k)*T1(i))) * ((sin(L(k)*(B1(i)/2.)))/((L(k)*B1(i))/2.))
   
    !C
    if (A1(i) .eq. 0 .and. B1(i) .eq. 0) then
    C(i) = 0
    else
    C(i) = A1(i) * (K1(i) + K2(i) + F1(i) * O1)
   endif
   
   !R
   call VVV (X, C, RR)
   end do
   
  !Ответ 
  R(k) = abs(RR/(V*M))
 
  print *, Y(k),R(k)
 
  
  end do
  
 
 
  
  
 
 
end program F
 
! Для расчета Интегралов
subroutine VV(X, Y, O)
real, intent(in):: X(1:21), Y(1:21)
real :: IY(1:21), S, S1
real O
integer:: i, n
  n=size(X)
  S=0.0
  do i=1, n-1
    S1=S
    S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
    IY(i)=S1
  end do
  IY(n)=S
  O = IY(n)
  return
end subroutine VV
 
! Для расчета Интегралов R
subroutine VVV(X, Y, O)
real, intent(in):: X(1:21), Y(1:21)
real :: IY(1:50), S, S1
real O
integer:: i, n
  n=size(X)
  S=0.0
  do i=1, n-1
    S1=S
    S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
    IY(i)=S1
  end do
  IY(n)=S
  O = IY(n)
  return
end subroutine VVV
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
13.03.2024, 23:13
Цитата Сообщение от FrenchRedPaw Посмотреть сообщение
вроде бы исправил то, что подметили.
Я в общем-то подметил, что этот хтонический ужас надо переписать полностью. Вместо этого вы зачем-то соорудили еще одну процедуру, идентичную первой, а большую часть предыдущего кода сохранили без изменений.

Серьезно, при таком качестве кода нет смысла искать частные ошибки. Если вы будете и дальше писать в таком стиле, то пока одну поправите - десяток новых внесете. Надо сначала научиться программировать на чем-нибудь, а потом научиться программировать на Фортране, причем, судя по всему, и тому, и другому учиться придется с нуля.

Какие "разные" результаты оно у вас выдает - непонятно, поскольку типовой проблемой является, например, чтение 50 чисел из Y.txt, в котором их содержится 49.
0
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
13.03.2024, 23:34  [ТС]
Pphantom, вторая процедура была сделана уже для 50 значений функций
Вот вы говорите что это хаотический ужас, но для себя, по сравнению с другими программами я вижу только момент, что после open добавляется close, и то что ввод значений типа "real" записать более компактно, а так же, вместо .eq. использовать знак =. Условия с картинки у меня подписаны в коде, что и где считается (кроме первой)
Не посчитайте это за грубость, просто я говорю со своей стороны необразованного человека и что мне может броситься в глаза.

Добавлено через 12 минут
В 70 строке ошибка (там должно быть i = 1, 21)
Добавил close
Добавил в файл Y.txt в начале значение 0.00000
20 запусков программы дали одинаковые результаты, уже хорошо
Надо будет посидеть подумать, почему дает ответ не тот, который нужен
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
14.03.2024, 00:10
Лучший ответ Сообщение было отмечено Catstail как решение

Решение

Цитата Сообщение от FrenchRedPaw Посмотреть сообщение
вторая процедура была сделана уже для 50 значений функций
А разница-то в чем?

Любая из этих двух процедур переделывается в такую:
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
subroutine VV(X, Y, O)
real, intent(in):: X(1:), Y(1:)
real :: IY(1:size(X)), S, S1
real O
integer:: i, n
  n=size(X)
  S=0.0
  do i=1, n-1
    S1=S
    S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
    IY(i)=S1
  end do
  IY(n)=S
  O = IY(n)
  return
end subroutine VV
после чего оказывается универсальной и подходящей для массивов любого размера.

Затем код можно внимательно просмотреть и вычистить лишнее. Впрочем, если бы вы сразу писали комментарии - что и зачем в какой строке делаете, проблемы были бы замечены сразу.

Итак, после чистки получаем следующее:
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
subroutine VV(X, Y, O)
real, intent(in):: X(1:), Y(1:)
real :: S
real O
integer:: i, n
  n=size(X)
  S=0.0
  do i=1, n-1
    S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
  end do
  O = S
  return
end subroutine VV
Далее уже можно задуматься над вопросом, зачем это - процедура, если она возвращает одно число? После этого (а также приведения стиля описаний к единой форме) код превратится в такой:
Fortran
1
2
3
4
5
6
7
8
9
10
function integrate(X, Y) result(S)
real, dimension(1:), intent(in):: X, Y
real :: S
integer :: i, n
  n=size(X)
  S=0.0
  do i=1, n-1
    S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
  end do
end function integrate
Заметьте, мы уже сделали из 32 строк кода 10, даже не поинтересовавшись тем, что, собственно, эти 32 строки пытались делать (а переделка процедуры в функцию сэкономит еще несколько строк в основной программе).

А теперь можно вспомнить, что это вообще-то Фортран, а не Паскаль/Си/что-то-еще-универсальное-и-не-предназначенное-для-вычислительной-математики, и преобразовать функцию к виду, имеющему смысл уже для Фортрана:
Fortran
1
2
3
4
5
6
7
function integrate(X, Y) result(S)
real, dimension(1:), intent(in):: X, Y
real :: S
integer :: n
  n=size(X)
  S=dot_product(X(2:n)-X(1:n-1),(Y(2:n)+Y(1:n-1))/2)
end function integrate
В принципе, можно еще ужаться (сэкономив на определении и вычислении n, а также на отдельной S), хотя, пожалуй, это уже будет читаться хуже предыдущего варианта:
Fortran
1
2
3
4
real function integrate(X, Y)
  real, dimension(1:), intent(in):: X, Y
  integrate=dot_product(X(2:)-X(1:size(X)-1),(Y(2:)+Y(1:size(Y)-1))/2)
end function integrate
Все. Итого из 32 строк получилось 4. В легко читаемом варианте, из которого сразу можно понять, что это формула средних прямоугольников - 7.

И вот если нечто подобное проделать и с основной программой, то произойдет примерно то же самое - она тоже сильно сократится, куча ее деталей пропадет из-за полной ненадобности, а остальное станет читаемым.
1
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
14.03.2024, 00:17  [ТС]
Pphantom
Простите за столь позднее беспокойство и спасибо за ответ
Посмотрю уже на следующий день, все внимательно прочитав и проанализировав (постараюсь вникнуть по крайней мере)
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
16.03.2024, 15:49
Ну и как процесс вникания?

А то при переписывании основной программы действительно вылавливаются ошибки: например, вызовы процедуры интегрирования в 41, 45 и 50-й строках, когда еще данные до конца не прочитаны.
0
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
27.03.2024, 00:31  [ТС]
Pphantom, Добрый вечер
Простите за столь позднее беспокойство, только приехал из больницы
Пробежал глазами, условие в начале сделал проще, а так вроде больше нечего сокращать, так же заставил функцию работать

Сам код:
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
program F
 Implicit none
 
 integer :: i, k
 real :: TT = 5.90, M = 1.07, O1, H, V, D, HHH, RR, G, DDD
 real :: R(25), A(21), B(21), T(21), X(21),Y(25), A1(21), B1(21), T1(21), HH(21),DD(21), K1(21), K2(21), F1(21),C(21), L(25)
 
 
 
 open(1, file = 'A.txt')
 open(2, file = 'B.txt')
 open(3, file = 'T.txt')
 open(4, file = 'predeli.txt')
 open(5, file = 'Y.txt')
 
 do i = 1, 21
  read(1, *) A(i)
  read(2, *) B(i)
  read(3, *) T(i)
  read(4, *) X(i)
  
  A1(i) = 0
  B1(i) = 0
  T1(i) = 0
  
  if (A(i) > 0 .and. B(i) > 0) then 
    if ((A(i)/B(i)) <= T(i)) then
     A1(i) = A(i)
     B1(i) = B(i)
     T1(i) = A(i)/B(i)
    else
     B1(i) = B(i)
     T1(i) = T(i)
     A1(i) = B1(i) * T1(i)
    endif
  endif
 
    !Для нахождения V
   V = integrate(X, A1)
   
   !Для нахождения H
   HH(i) = (1.0/12.0)* B1(i)**3
   HHH = integrate(X, HH)
    
   !Для нахождения D
   DD(i) = ((-T1(i))/2.0) * A1(i)
   DDD = integrate(X,DD)
   
   !Найденные H, D, G
   H = HHH * (1.0/V)
   D = (DDD * (1.0/V)) + TT
   G = D + H - M 
 
 end do
 
   !Решение для 3 картинки
   O1 = G - TT 
  
  do k = 1,25
  read (5,*) Y(k)
  
  L = ((Y(k)**2.0) / 9.81)
 
    do i = 1,21
    !K1
    K1(i) = ((sin(L(k) *(B1(i)/2.)))/(L(k)*B1(i))/2.) * (((1+L(k)*T1(i)) * exp(-L(k)*T1(i) - 1)) / ((L(k)**2) * T1(i)))
    
    !K2
    K2(i) = (-((exp(-L(k)*T1(i) - 1)) / ((L(k)**2) * T1(i))))* (cos(L(k)*(B1(i)/2.)) - ((sin(L(k)*(B1(i)/2.)))/(L(k)*(B1(i)/2.))))
   
    !F1
    F1(i) = -((1 - (exp(-L(k)*T1(i))))/(L(k)*T1(i))) * ((sin(L(k)*(B1(i)/2.)))/((L(k)*B1(i))/2.))
   
    !C
    if (A1(i) .eq. 0 .and. B1(i) .eq. 0) then
    C(i) = 0
    else
    C(i) = A1(i) * (K1(i) + K2(i) + F1(i) * O1)
   endif
   
   !R
   RR = integrate(X, C)
   
   end do
   
  !Ответ 
   R(k) = abs(RR/(V*M))
 
   print *, Y(k), R(k)
  
  end do
    
  close (1)
  close (2)
  close (3)
  close (4)
  close (5)
    
  contains
  function integrate(X,Y) result(S)
  real, dimension(1:), intent(in):: X,Y
  real :: S
  integer:: n
  n=size(X)
  S= dot_product(X(2:n)-X(1:n-1),(Y(1:n-1))/2)  
  end function integrate  
 
end program F
0
 Аватар для Pphantom
2470 / 1616 / 742
Регистрация: 17.03.2022
Сообщений: 5,275
27.03.2024, 12:10
Лучший ответ Сообщение было отмечено Pphantom как решение

Решение

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

В итоге лишней оказывается куча массивов, каких-то промежуточных переменных без содержательных названий, а заодно - еще и множество скобочек (а то просто LISP какой-то получался).

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

Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
program F
    Implicit none
 
    integer :: i, k
    real,parameter :: TT = 5.90, M = 1.07
 
    real :: O1, V
    real,dimension(21) :: A, B, T, X, K1, K2, F1, C
    real,dimension(25) :: Y, L
 
    open(1, file = 'A.txt')
    read(1,*) A
    close(1)
 
    open(2, file = 'B.txt')
    read(2, *) B
    close(2)
 
    open(3, file = 'T.txt')
    read(3, *) T
    close(3)
 
    open(4, file = 'predeli.txt')
    read(4, *) X
    close(4)
 
    where(A>0 .and. B>0)
        where(A/B <= T)
            T=A/B
        elsewhere
            A=B*T
        end where
    end where
 
    !Для нахождения V
    V = integrate(X, A)
 
    !Найденные H, D, G
    !Решение для 3 картинки
    O1 = integrate(X,-T/2.0*A)/V + TT + integrate(X, B**3/12.0)/V - M - TT
 
    open(5, file = 'Y.txt')
    read (5,*) Y
    close(5)
 
    L = Y**2.0/9.81
 
  do k = 1,25
 
    !K1
        K1 = sin(L(k)*B/2.0)/L(k)/B*2.0 * (1+L(k)*T) * exp(-L(k)*T - 1) / (L(k)**2 * T)
 
    !K2
        K2 = -exp(-L(k)*T - 1) / (L(k)**2 * T) * (cos(L(k)*B/2.0) - sin(L(k)*B/2.0))/L(k)/B*2.0
 
    !F1
        F1 = -(1 - exp(-L(k)*T))/L(k)/T * sin(L(k)*B/2.0)/L(k)/B*2.0
 
    !C
    C=0
    where(B/=0) C = A * (K1 + K2 + F1 * O1)
 
    !Ответ
 
   print *, Y(k), abs(integrate(X, C)/V/M)
 
  end do
 
contains
 
  function integrate(X,Y) result(S)
      real, dimension(1:), intent(in):: X,Y
    real :: S
    integer:: n
    n=size(X)
        S= dot_product(X(2:n)-X(1:n-1),(Y(1:n-1))/2)
  end function integrate
 
end program F
В принципе можно дальше, но и так уже становится видно происходящее. Теперь, например, можно заметить, что в выражении для O1 константа TT сначала прибавляется, а потом вычитается, зачем это надо - непонятно. Во второй части совершенно точно можно упростить вычислительные формулы для K1, K2 и т.п.
0
2 / 2 / 0
Регистрация: 21.02.2024
Сообщений: 33
27.03.2024, 21:14  [ТС]
Pphantom, Да я думаю уже достаточно неплохо сокращено
У меня теперь вопрос, а правильно ли сформулированы те условия, которые даны мною на трех картинках?
Где у (x) - 21 значения, а у (y) - 25
Если да, то надо будет спросить у преподавателя какими входными данными лучше воспользоваться (вдруг не те использую) для проверки
Благодарю за ответ
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.03.2024, 21:14

Задача в Fortran || Разветвление
Помогите написать код для данной задачи: &quot; Даны три действительных числа a, b, c. Найти наибольшее из чисел 10a+2b+c и 2abc/3, и вывести...

[Fortran-95] Silverfrost, задача ЭМП с внутренним источником
Здравствуйте,необходима помощь с программой.Имеется программа.Ток в трубке.Электро магнитное поле равномерно по всем точкам. program...

Задача на циклы с условиями
Необходимо составить программу, определяющую оценку скорости воздушного транспорта по следующей сетке: Воздушный транспорт (класс...

Задача с несколькими условиями
Дана задача с несколькими условиями, например: С клавиатуры вводится натуральное число: а) Вывести на экран: верно ли, что сумма его...

Чтение одного и того же файла несколькими потоками на Fortran. Вызов процедур Fortran из C++, используя OpenMP
С помощью &quot;OpenMP&quot; на C++ я создаю несколько потоков, каждый их которых вызывает некие одинаковые процедуры на Фортране, которые работают с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru