Проходящий подмассив 2-мерного массива в FORTRAN-77 - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть двумерный массив

real triangle(0:2, 0:1)

, где "треугольник" - это массив векторов (1-мерные массивы), также у меня есть подпрограмма

subroutine vecSub(lhs, rhs, result)
real lhs(0:1), rhs(0:1), result(0:1)
    result(0) = lhs(0) - rhs(0)
    result(1) = lhs(1) - rhs(1)
    return
end

, есть ли способ передать один из векторов из переменной "треугольник" в эту подпрограмму? Fortran-90 может сделать это: triangle(0, :), который дает первый массив треугольника, но мне разрешено использовать только FORTRAN-77, так что это не подойдет, какие-либо предложения?

Ответы [ 2 ]

3 голосов
/ 16 февраля 2020

@ Хавьер Мартин написал "не с текущей компоновкой вашего массива", но упустил возможность предложить альтернативу.

Если вместо этого вы объявили переменную следующим образом:

real triangle(0:1, 0:2)

в обратном порядке границ, затем вы можете передать triangle(0,0), triangle(0,1) или triangle(0,2) подпрограмме и получить именно то поведение, которое вам нужно, благодаря функции Fortran, называемой «ассоциация последовательности» , Когда вы передаете один элемент массива фиктивному аргументу, который является массивом, вы неявно передаете этот и последующие элементы в порядке элементов массива. Это единственное допустимое нарушение нормальных правил соответствия форм Фортрана, которое было частью FORTRAN 77.

1 голос
/ 16 февраля 2020

Нет , не с текущей компоновкой вашего массива, по двум причинам:

  • Fortran использует порядок элементов массива, в котором непрерывное крайнее левое измерение. То есть в массиве размером (n,m,l) расстояние между элементами (шаг 1008 *) составляет (1,n,m), измеренное в единицах элементов массива (т. Е. Не в байтах).
  • F77 не включает в себя массивы предполагаемой формы a(:), которые обычно реализуются путем передачи небольшой структуры дескриптора, которая передает детали, такие как шаг или количество элементов. Вместо этого вы можете использовать только массивы предположительной длины a(*), которые обычно являются указателями на первый элемент, вроде C массивов. Вы должны передать длину в качестве отдельного аргумента, а элементы массива должны быть смежными

По этой причине вы можете"передать подмассив «к подпрограмме F77, если этот подмассив является, например, столбцом матрицы: элементы в нем являются смежными.

Возможное решение (которое реализуют многие современные компиляторы Фортрана) заключается в том, что при попытке передать не Непрерывный подмассив функции, которая, как известно, не принимает их, создает копию массива и даже записывает ее обратно в память, если это необходимо. Это было бы эквивалентно:

! Actual array
integer m(3,5)
integer dummy(5)
dummy = m(2,:)
call myF77sub(dummy, 5)
m(2,:) = dummy

Однако, как говорят другие, вы должны стараться не вызывать функции F77 напрямую, а либо адаптировать их или, по крайней мере, обернуть их в более поздние интерфейсы Fortran. Затем вы можете иметь код, подобный приведенному выше, в оболочке и вызывать эту оболочку «как обычно» из современных подпрограмм Фортрана. Тогда вы можете в конечном итоге переписать реальную реализацию на современном Фортране, не затрагивая клиентский код.

...