Как преобразовать код массива 1D matlab в код Fortran и получить значения

#matlab #fortran

#matlab — математическая лаборатория #фортран #matlab #fortran

Вопрос:

Я хочу преобразовать этот код Matlab в код Fortran. Я привел здесь коды как для Matlab, так и для Fortran. Параметры также приведены здесь.

Код Matlab

 L_10 = 1.0e-10;
e = 0.4;
n = 100000;
R = 3.1e 5;
K0_10 = 1.0e-10;
Ci  = 1.0e-15;
zv  = 1.2;
Dv  = 1
Rho = 2.0e-4
dt  = 0.01

for i=1:n
     L_10(i 1) = L_10(i)   dt*(e*K0_10- R*L_10(i)*Ci- zv*Dv*L_10(i)*Rho);
end 
  

Я написал следующий код на Fortran, но он не работает

 real, dimension (:), allocatable:: L_10
real, parameter :: e = 0.4
integer, parameter :: n  = 100000
real, parameter :: R  = 3.1e 5
real, parameter :: K0_10 = 1.0e-10
real, parameter :: Ci = 1.0e-15
real, parameter :: zv = 1.2
real, parameter :: Dv = 1.0
real, parameter :: Rho  = 2.0e-4
real, parameter :: dt = 0.01
integer:: i

do i=1:n
   L_10(i 1) = L_10(i)   dt*(e*K0_10- R*L_10(i)*Ci- zv*Dv*L_10(i)*Rho);
end 
  

Как инициализировать значение массива в коде Fortran? Как итерация будет работать в Fortran? Это отлично работает в Matlab.

Комментарии:

1. На самом деле меня больше беспокоит генерация массива в Fortran do loop. Но вы правильно заметили синтаксическую ошибку и там.

Ответ №1:

Эта программа на Fortran выдает тот же результат, что и в Matlab. Итерация массива отличается в цикле do в Fortran, как показано ниже. Итерация сохраняется в Fortran без индексации, но в Matlab она выполняется с индексированием, как показано в коде Matlab.

 program oneDimention 
    implicit none

    integer, parameter :: n  = 10
    real, dimension (n):: L_10
    real, parameter :: e = 0.4
    real, parameter :: R  = 3.1e 5
    real, parameter :: K0_10 = 1.0e-10
    real, parameter :: Ci = 1.0e-15
    real, parameter :: zv = 1.2
    real, parameter :: Dv = 1.0
    real, parameter :: Rho  = 2.0e-4
    real, parameter :: dt = 0.01
    integer:: i

    L_10 = 1.0e-10

    do i=1,n
           L_10 = L_10(i)   dt*(e*K0_10- R*L_10(i)*Ci- zv*Dv*L_10(i)*Rho);
    print*,L_10(i)
    end do

end program oneDimention
  

Комментарии:

1. L_10=... и L_10(i)=... — это очень разные вещи.

2. Да. Вы правы в этом. Это проблема работы с разными платформами. Новым пользователям вроде меня сложно разобраться в синтаксисе в начале.

Ответ №2:

Я сразу вижу две проблемы с Fortran. Вы решили сделать L_10 выделяемым, но код не выделяет его. Вы могли бы либо сделать его статическим, изменив его объявление на

 real, dimension (n 1) :: L_10
  

Если вы выберете этот подход, вам придется перемещать объявление до окончания самого объявления n , компилятор не будет работать с объявлениями forward. Альтернативой было бы оставить объявление как есть, но вставить инструкцию

 allocate(L_10(n 1))
  

после объявлений, но до того, как вы попытаетесь впервые использовать массив. Просмотрите свою документацию для allocate инструкции и узнайте, как получить отчет о коде состояния на случай, если что-то пойдет не так.

Затем вы можете установить значение всех элементов таким же образом, как вы делаете в Matlab,

 L_10 = 1.0e-10
  

У вас неправильный синтаксис для do инструкции, он должен начинаться со строки

 do i = 1, n
  

через запятую, где Matlab использует двоеточие.

В Fortran могут быть другие проблемы, которых я не заметил, но ваш компилятор поможет вам в этом.

Комментарии:

1. … например, отсутствует end do . И некоторые сказали бы, что добавление implicit none является важным аспектом преобразования языка.

2. Нужно оставить компилятору несколько ошибок для поиска! И да, implicit none .

3. Я оставил ошибку для поиска компилятором, но, вероятно, важно указать правильный размер массива (пользователю легко не заметить, а Fortran в этом отношении несколько менее снисходителен, чем Matlab). Вы, конечно, знаете об откатах.