Фортран серьезный (40) Ошибка ... Помощь? - PullRequest
2 голосов
/ 09 июня 2010

Я могу скомпилировать, но когда я запускаю, я получаю эту ошибку "forrtl: Серьезный (40): рекурсивная операция ввода-вывода, модуль -1, файл неизвестен", если я установил n = 29 или больше ... Может кто-нибудь помочь с где я мог пойти не так? Спасибо.

 PROGRAM  SOLUTION
IMPLICIT NONE

! Variable Declaration

INTEGER  :: i
REAL  :: dt
DOUBLE PRECISION  :: st(0:9)
DOUBLE PRECISION  :: stmean(0:9)
DOUBLE PRECISION  :: first_argument
DOUBLE PRECISION  :: second_argument
DOUBLE PRECISION  :: lci, uci, mean
REAL  :: exp1, n
REAL  :: r, segma

! Get inputs

WRITE(*,*) 'Please enter number of trials: '
READ(*,*) n

WRITE(*,*)
dt=1.0
segma=0.2
r=0.1

! For n Trials

st(0)=35.0
stmean(0)=35.0
mean = stmean(0)

PRINT *, 'For ', n ,' Trials'
PRINT *,'          1     ',st(0)

! Calculate results

DO i=0, n-2
    first_argument = r-(1/2*(segma*segma))*dt
    exp1 = -(1/2)*(i*i)
    second_argument = segma*sqrt(dt)*((1/sqrt(2*3.1416))*exp(exp1))
    st(i+1) = st(i) * exp(first_argument+second_argument)

    IF(st(i+1)<=20) THEN
       stmean(i+1) = 0.0
       st(i+1) = st(i)
       else
       stmean(i+1) = st(i+1)
    ENDIF

    PRINT *,i+2,'     ',stmean(i+1)
    mean = mean+stmean(i+1)
END DO

! Output results

uci = mean+(1.96*(segma/sqrt(n)))
lci = mean-(1.96*(segma/sqrt(n)))
PRINT *,'95% Confidence Interval for ', n, ' trials is between ', lci, ' and ', uci
PRINT *,''

КОНЕЧНОЕ ПРОГРАММНОЕ РЕШЕНИЕ

Ответы [ 2 ]

1 голос
/ 09 июня 2010

Признаюсь, я не потратил время, чтобы попытаться понять, что делает программа, но на основе "быстрой" компиляции видны несколько ошибок:
- во-первых, я не смог воспроизвести вашу ошибку - вполне ожидаемо, потому что я не вижу, где вы назначаете какие-либо единицы измерения файлам. Не могли бы вы дважды проверить, действительно ли это ошибка, которую вы получаете, и указать, какой компилятор?
- массивы, если n больше 10, выходят за пределы
- что этот второй WRITE только что abov "dt" пытается выписать?
- зачем вам двойная точность?
- также, если вы используете «n» в качестве индекса в цикле, было бы разумно объявить его целым числом вместо реального
- вы используете «n» в качестве индекса, но также в квадратном корне ... конвертируйте его в реальное значение перед использованием в квадратном корне с помощью функции FLOAT (n)

Помимо этого (и, может быть, нескольких других вещей, которые ускользнули из моей головы), я не вижу в этом ничего плохого. Для n <= 10 он выдает результаты. Хотя я повторяю, я не потратил время на их анализ, поэтому они могут быть неверными, но это их выдает. </p>


  program solution; implicit none

  !variable declaration
  integer :: i, n
  real :: dt, first_argument, second_argument, lci, uci, mean, exp1, r, segma
  real, dimension(0:99) :: st, stmean

  WRITE(*,'("Please enter number of trials: ",\)'); read(*,*)n
  dt=1.0; segma=0.2; r=0.1

  st(0)=35.0; stmean(0)=35.0; mean=stmean(0)

  write(*,'("For ",i2.2," trials")')n
  write(*,'("           1   ",f14.5)')st(0)

  DO i=0, n-2
      first_argument = r-(1/2*(segma*segma))*dt
      exp1 = -(1/2)*(i*i)
      second_argument = segma*sqrt(dt)*((1/sqrt(2*3.1416))*exp(exp1))
      st(i+1) = st(i) * exp(first_argument+second_argument)

      IF(st(i+1)<=20) THEN
         stmean(i+1) = 0.0
         st(i+1) = st(i)
         else
         stmean(i+1) = st(i+1)
      ENDIF

      PRINT *,i+2,'     ',stmean(i+1)
      mean = mean+stmean(i+1)
  END DO

  uci = mean+(1.96*(segma/sqrt(float(n))))
  lci = mean-(1.96*(segma/sqrt(float(n))))
  PRINT *,'95% Confidence Interval for ', n, ' trials is between ', lci, ' and ', uci
  END PROGRAM SOLUTION
0 голосов
/ 09 июня 2010

Как идентифицировал @Idigas, проблема заключалась в том, что массивы индексировались за их пределами. При разработке программ на Фортране полезно: 1) всегда включать все параметры отладки компилятора, особенно проверку границ, и 2) помещать ваши подпрограммы и функции в модули и «использовать» их - это позволит компилятору проверять согласованность фактических и фиктивных аргументов. Эти два шага поймают очень большую долю ошибок.

Элегантный способ справиться с проблемой размера массива в современном Фортране - объявить массивы как allocatable и затем установить их размер во время выполнения после получения пользовательского ввода, а не угадывать максимальное Размер при написании программы. Если у вас есть причина установить размер во время компиляции, и пользовательский ввод может привести к его превышению, будет разумно проверить этот ввод.

Эскиз частей выделяемого решения:

real, dimension (:), allocatable :: st, stmean

read (*, *) n

allocate (st (0:n))
allocate (stmean (0:n))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...