Циклы на плоских матрицах Фортрана

У меня есть немного кода, который выглядит следующим образом:

DO I=0,500
    arg1((I*54+1):(I*54+54)) = premultz*sinphi(I+1)
ENDDO

Короче говоря, у меня есть массив premultz измерения 54. У меня есть массив sinphi измерения 501. Я хочу взять первое значение sinphi, умноженное на все записи premultz, и сохранить его в первых 54 записях arg1, затем второе значение sinphi умножает все записи на Premultz и сохраняет его во втором 54 записях в arg1 и так далее.

Это сплюснутые матрицы. Я сгладил их в интересах скорости, так как одной из основных целей этого проекта является очень быстрый код.

У меня такой вопрос: есть ли более эффективный способ кодирования такого рода расчетов в Fortran90? Я знаю, что в Фортране есть много изящных операций с массивами, которые я не полностью осознаю.

Заранее спасибо.

1 ответ

Решение

Это выражение, если я правильно понял, должно создать arg1 в одном заявлении

arg1 = reshape(spread(premultz,dim=2,ncopies=501)*&
              &spread(sinphi,dim=1,ncopies=54),[1,54*501])

Я здесь запрограммировал размеры, которые могут соответствовать или не соответствовать вашим целям. Внутреннее выражение генерирует внешний продукт premultz а также sinphi, который затем преобразуется в вектор. Вы можете обнаружить, что вам нужно изменить транспонирование внешнего продукта, я не очень тщательно все проверял.

Однако, основываясь на моем опыте такого умного использования встроенных в Fortran массивов, я сомневаюсь, что это или большинство других разумных применений встроенных массивов в Fortran превзойдут реализацию простого цикла, которую вы уже использовали. Для многих из этих операций компилятор собирается создавать копии массивов, а копирование данных является относительно дорогим. Конечно, это утверждение, которое вы можете проверить.

Я оставлю вам решать, является ли однострочник более понятным, чем циклы. Иногда выразительность синтаксиса массива достигается за приемлемую цену производительности, иногда - нет.

Другие вопросы по тегам