#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). Вы, конечно, знаете об откатах.