Фортран транспонирования матрицы не работает на не 2D массивах - PullRequest
2 голосов
/ 16 декабря 2011

Скажем, у меня есть 3D-массив, A(1:3,1:4,1:5), и я хочу иметь дело только с его частью, например ::

real :: A(1:3,1:4,1:5), B(1:5,1:2)
real, allocatable :: C(:,:)

allocate(C(size(A,1),size(B,2)))
C = matmul(A(1:3,1,1:5),B)

Фортран, кажется, хорошо с этим. Однако, если мне нужно разобраться с транспонированием, то функция transpose в Фортране запутается, например ::10000*

real :: A(1:3,1:4,1:5), B(1:3,1:2)
real, allocatable :: C(:,:)

allocate(C(size(A,3),size(B,2)))
C = matmul(transpose(A(1:3,1,1:5)),B)

Как я могу поменять размеры в массиве с Фортраном? Например, у меня есть А (3,4,5); есть ли функция / команда, которая принимает это и дает мне A (5,4,3) или A (4,3,5) или какое-либо расположение, которое я мог бы пожелать? Конечно, без копирования A в фиктивный массив с размерами в требуемом порядке. Я ищу простой элегантный способ в одну строку.

Спасибо.

Ответы [ 2 ]

8 голосов
/ 16 декабря 2011

У вас нет проблем с TRANSPOSE. Он отлично работает для предоставленного вами примера кода. Проблема в том, что ваши массивы не совместимы для умножения матриц. От Фортрана 2008 Стандартный проект:

Случай (i): если MATRIX A имеет форму [n, m], а MATRIX B имеет форму [m, k], результат имеет форму [n, k].

В вашем случае:

C = matmul(transpose(A(1:3,1,1:5)),B)

Здесь transpose(A(1:3,1,1:5)) - матрица 5x3, а B - 2x5. Таким образом, эти две матрицы несовместимы для MATMUL. Мне интересно, как вы не поняли это, так как компиляторы выдают четкое сообщение об ошибке:

Гфортран 4.1.2:

In file matrix.f90:13

C = matmul(transpose(A(:,1,:)),B)
          1
Error: different shape on dimension 2 for argument 'matrix_a' and dimension 1 for argument 'matrix_b' at (1) for intrinsic matmul

ifort 12.0.2.137:

matrix.f90(13): error #6241: The shapes of the arguments are inconsistent or nonconformable.   [MATMUL]
C = matmul(transpose(A(:,1,:)),B)
----^
compilation aborted for matrix.f90 (code 1)

pgf90 10.6-0 компилируется, но выдает ошибку времени выполнения:

0: MATMUL: nonconforming array shapes

Для изменения формы массивов в Фортране вы можете использовать встроенную функцию RESHAPE. От Фортрана 2008 Стандартный проект:

13.7.140 РЕШАЙП (ИСТОЧНИК, ФОРМА [, ПОДУШКА, ЗАКАЗ])

1 Описание. Построить массив произвольной формы.

2 класс. Трансформационный функция.

3 Аргументы. ИСТОЧНИК должен быть массивом любого типа. Если PAD отсутствует или имеет нулевой размер, размер ИСТОЧНИКА должен быть больше чем или равный ПРОДУКТ (ФОРМА). Размер результата является произведением значений элементы ФОРМЫ. SHAPE должен быть целочисленным массивом ранга один. РАЗМЕР (x), где x - фактический аргумент, соответствующий SHAPE, должно быть константным выражением, значение которого положительно и меньше 16. Оно не должно иметь элемент, значение которого отрицательно. PAD (необязательно) должен быть массивом того же типа и параметров типа, что и SOURCE. ЗАКАЗАТЬ (необязательно) должен иметь тип integer, должен иметь ту же форму, что и SHAPE, и его значение должно быть перестановкой (1, 2, ..., n), где n - размер ФОРМЫ. Если отсутствует, это как если бы он присутствовал со значением (1, 2,. , , н).

4 Характеристики результата. Результатом является массив формы ФОРМА (то есть ФОРМА (РЕШАТЬ (ИСТОЧНИК, ФОРМА, ЗАГРУЗКА, ЗАКАЗ)) равна в форму) с теми же параметрами типа и типа, что и SOURCE.

5 Результат Значение. Элементы результата, взятые в порядке перестановки индексов ЗАКАЗАТЬ (1). , , , ORDER (n), это SOURCE в обычном массиве порядок элементов, за которым следуют, если необходимо, PAD в элементе массива порядок, сопровождаемый при необходимости дополнительными копиями PAD в массиве порядок элементов.

2 голосов
/ 16 декабря 2011

A (1: 3,1,1: 5) - это массив второго ранга размером 3 x 5. Указывая конкретное значение (1) для второго индекса массива третьего ранга "A", а недиапазон вы уменьшили размерность.транспонирование A (1: 3,1,1: 5) должно быть массивом второго ранга размером 5 x 3.

Если вы хотите произвольно изменить размеры массива, используйте "изменить "внутреннюю функцию.Разместит ли он элементы там, где вы хотите, это другой вопрос.Пример использования: A = reshape (A, [5,4,3]).

...