Циклы на плоских матрицах Фортрана
У меня есть немного кода, который выглядит следующим образом:
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 превзойдут реализацию простого цикла, которую вы уже использовали. Для многих из этих операций компилятор собирается создавать копии массивов, а копирование данных является относительно дорогим. Конечно, это утверждение, которое вы можете проверить.
Я оставлю вам решать, является ли однострочник более понятным, чем циклы. Иногда выразительность синтаксиса массива достигается за приемлемую цену производительности, иногда - нет.