#fortran #fortran90 #gfortran
#fortran #fortran90 #gfortran
Вопрос:
program main
implicit none
double precision x0, a, b
x0 = -3
call findzero(x0)
contains
function f(x)
implicit none
double precision x,f
f = SIN(x) - exp(-x)
end function
function fprime(x)
implicit none
double precision fprime, x
fprime = COS(x) exp(-x)
end function
subroutine findbracket(x0,a,b)
implicit none
double precision x0, a, b
double precision fa, fb
double precision dx
dx = 0.001d0
a = x0
b = x0
do
fa = f(a)
fb = f(b)
!print*,"bracket[", a, b, "]"
a = a - dx
if (fa*fb < 0) then
exit
end if
b = b dx
if (fa*fb < 0) then
exit
end if
dx = dx*2
end do
end subroutine
subroutine findzero(x0)
implicit none
double precision x0, a, b
double precision p, tol
while (x0 <11) do
x0 = -3
print*, "what is x0", x0
call findbracket(x0,a,b)
call newtonbisection (p,a,b,tol)
print*, "this is x0, x", x0, p
x0 = x0 1
end do
end subroutine
Используя эту подпрограмму, я пытаюсь решить для нулей
f(x) = sinx - e^-x
с x0 = -3, -2, ..., 10
помощью .
У меня есть рабочие подпрограммы findbracket
и newtonbisection
. Используя findbracket
, я намереваюсь получить [a,b] и используя эти a и b, я хочу найти p для каждого x0.
Когда я компилирую, мой код попадает в бесконечный цикл, я попробовал это с комментированием
call newtonbisection (p,a,b,tol)
итак, я предполагаю, что проблема в findbracket
с. Но если я просто использую подпрограмму для поиска [a,b]
x0 = -3
, она работает, но не тогда, когда я их объединяю.
Почему у меня бесконечный цикл?
Комментарии:
1. Похоже, вы не заканчиваете
subroutine findbracket
, это опечатка?2. Это тип. Я только что отредактировал. Извините за это.
3. можете ли вы объяснить, как вы ожидаете, что последний цикл выполнения завершится?
4. Извините за еще одну ужасную опечатку.. Я пробовал много разных способов решения проблемы и немного запутался. Я попытался
while (x0 <11) do
, чтобы x0 = 10 могло быть последней итерацией, но у меня все еще была та же проблема.5. И вы все еще не последовали совету, данному в комментарии к одной из более ранних версий этого вопроса, использовать отступы для отражения структуры вашего кода.
Ответ №1:
Давайте сузим этот цикл:
do while (x0 < 11)
x0 = -3
call findbracket(x0, a, b)
x0 = x0 1
end do
Это цикл, который выполняется до тех пор, пока x0
он меньше одиннадцати. Внутри цикла вы явно устанавливаете x0
значение минус 3, затем вызываете подпрограмму, которая использует x0
, наконец, increment x0
Я не видел ни одного места внутри findbracket
подпрограммы, где значение x0
было бы изменено, поэтому оно все равно будет -3
в конце вызова. Затем он увеличивается на единицу, так что теперь -2
он все еще меньше 11
, поэтому цикл начинается снова. Первое, что он делает, это сбрасывает x0
значение -3
, и весь текст снова начинается с той же точки.
Таким образом, условие x0 < 11
всегда будет истинным, поскольку на каждой итерации x0
будет сброшено на -3
. Цикл никогда не завершится. Ваша программа зависает.
Вам нужно переместить x0 = -3
до перед циклом, вот так:
x0 = -3
do while (x0 < 11)
call findbracket(x0, a, b)
x0 = x0 1
end do
Таким образом, x0
значение не будет сбрасываться -3
на каждой итерации цикла и в конечном итоге станет больше, чем 11
так, чтобы цикл заканчивался.
Ответ №2:
«Бесконечный» цикл for достигается следующим образом:
do
** Some executable statements
if (conditional_statement) exit
end do
Вкратце, набор операторов выполняется повторно до тех пор, пока не будет удовлетворен условный оператор, то есть,
conditional_statement .eqv. .true.
Когда это происходит, управление программой переходит к следующему исполняемому оператору сразу после do
построения.
Комментарии:
1. К вашему сведению, бесконечные циклы предпочтительнее
do while
флагов оптимизации помощи.2. Я попытался сделать x0 =-3,
if (x0 == 10) then exit
но он все равно попадает в бесконечный цикл.. Извините, что пишу все коды в одной строке3. Это просто говорит вам, что
x0
никогда не увеличивается на10
. Следовательно, виновата одна из ваших нижних подпрограмм.