Как вывести 2 или более массивов в функцию фортрана?

Я пишу программу, которая вычисляет LU-разложение матрицы с частичным поворотом, и я хотел бы, чтобы функция выводила несколько (2 или 3) матриц без запуска программы несколько раз для вывода каждой по отдельности, что является пустой тратой времени. раз с тех пор, как он дает мне все, что я хочу, за один раз. Есть ли способ сделать это? Например, вот моя функция, использующая алгоритм Дулиттла для квадратной матрицы, которая не требует поворота. Я хочу, чтобы мой вывод был матрицей l и u одновременно, но я не знаю, как это сделать.

function lu_d(aa) result(l)

real, dimension (:,:) :: aa !input matrix
real, dimension (size(aa,1), size(aa,2)) :: a !keeping input variable intact
real, dimension (size(a,1), size(a,2)) :: l , u !lower and upper matrices
integer :: i,j,k !index
real :: s !auxiliar variable

a=aa

do j=1 , size(a,2)
  u(1,j)=a(1,j)
end do

l(1,1)=1

do j=2, size(a,2)
  l(1,j)=0
end do

do i=2, size(a,1)

  l(i,1)=a(i,1)/u(1,1)
  u(i,1)=0

  do j=2, i-1

    s=0
    u(i,j)=0

    do k=1, j-1
      s=s+l(i,k)*u(k,j)
    end do

    l(i,j)=(a(i,j)-s)/u(j,j)

  end do

  l(i,i)=1

  do j=i, size(a,2)

    s=0
    l(i,j)=0

    do k=1, i-1
      s=s+l(i,k)*u(k,j)
    end do

    u(i,j)=a(i,j)-s

  end do

end do

end function

person António Carneiro    schedule 12.09.2016    source источник
comment
Всегда используйте тег fortran. Добавьте конкретную версию, где необходимо отличить. Только очень небольшое количество людей подписано на fortran95.   -  person Vladimir F    schedule 12.09.2016
comment
Конечно, есть способ делать такие вещи, но вы должны приложить некоторые усилия. Как выглядит ваш код? Какие проблемы вы нашли?   -  person Vladimir F    schedule 12.09.2016
comment
Я ищу некоторую информацию в Интернете, но я ничего не нашел об этом. Я отредактирую пост и добавлю свой код! Момент.   -  person António Carneiro    schedule 12.09.2016
comment
О, под выводом вы подразумеваете возврат как результат функции? Я не вижу никакого массива m в вашем коде, поэтому я все еще не уверен, что именно вы хотите, но я думаю, что будет проще с подпрограммой вместо функции.   -  person Vladimir F    schedule 12.09.2016
comment
сорри, матрица u, исправил. Итак, нельзя ли иметь 2 результата для одной функции? Что-то вроде вектора матриц.   -  person António Carneiro    schedule 12.09.2016


Ответы (1)


Вы можете переключиться с использования функции на использование подпрограммы. Таким образом, вы можете вывести значения для нескольких массивов в списке аргументов. Дополнительно используйте определение INTENT при объявлении переменных в подпрограмме, например:

REAL,INTENT(IN)::a объявляет a и не позволяет изменять его значения внутри подпрограммы/функции

REAL,INTENT(OUT)::b объявляет b и игнорирует любые значения, поступающие в подпрограмму/функцию

REAL,INTENT(INOUT)::c это так по умолчанию, если ничего не писать.

Я предполагаю, что вам нужно, чтобы вывод был l и u (а не m), и в этом случае структура будет выглядеть примерно так, как показано ниже. Обратите внимание, что l и m должны быть либо объявлены в основной программе, а их размер определен относительно aa (как в первом случае, показанном ниже), либо объявлен с размером allocatable в основной программе, переданным подпрограмме без выделения и выделения внутри подпрограммы (второй пример). Последнее может потребовать, чтобы вы поместили подпрограмму в модуль, чтобы интерфейсы обрабатывались должным образом.

Первый пример:

SUBROUTINE lu_d(aa,l,m)
implicit none
real,intent(in):: a(:,:)
real,intent(out):: l(:,:), m(:,:)
integer:: i,j,k
real:: s

<operations>

RETURN
END SUBROUTINE lud_d

Второй пример:

SUBROUTINE lu_d(aa,l,m)
implicit none
real,intent(in):: a(:,:)
real,allocatable,intent(out):: l(:,:), m(:,:)
integer:: i,j,k,size_a1,size_a2
real:: s

size_a1=size(aa,1)
size_a2=size(aa,2)
allocate( l(size_a1,size_a2), m(size_a1,size_a2))

<operations>

RETURN
END SUBROUTINE lud_d
person ptev    schedule 12.09.2016
comment
Удивительно, но я этого не делаю... Но может ли функция возвращать структуру? Если это так, то она могла бы вернуть структуру с двумя массивами, но подпрограмма кажется проще... Вероятно, поэтому я делаю это таким образом. - person Holmz; 12.09.2016
comment
Это справедливое замечание, технически вы также можете вывести матрицу, которая содержит l и m с функциональным подходом, но тогда вам придется потом их разделить. Объявление результата функции, например. A(size(aa,1),size(aa,2),2), а затем наличие A(:,:,1)=l; A(:,:,2)=m должно сделать это, но вы можете видеть неудобство. - person ptev; 12.09.2016
comment
@Holmz Вы можете сделать это, но без анонимных структур и без синтаксического сахара для легкой распаковки, что очень неудобно в Фортране. - person Vladimir F; 12.09.2016
comment
@ptev обратите внимание, что ВОЗВРАТ лишний и может привести к тому, что везде необходимо иметь ВОЗВРАТ и СТОП. Я бы определенно не использовал RETURN здесь. - person Vladimir F; 12.09.2016
comment
Отмечено - мне не нужно проводить какие-то исследования о правильном использовании, так как я унаследовал ряд кодов, в которых он есть. - person ptev; 12.09.2016