1

次のようなコードが少しあります。

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

つまり、次元 54 の配列 premultz があります。次元 501 の配列 sinphi があります。sinphi の最初の値に premultz のすべてのエントリを掛けて、arg1 の最初の 54 エントリに格納し、次にsinphi の 2 番目の値は、premultz のすべてのエントリを掛けて、arg1 の second54 エントリに格納します。

これらは平坦化された行列です。このプロジェクトの主な目標の 1 つは非常に高速なコードであるため、速度のためにそれらを平坦化しました。

私の質問はこれです: Fortran90 でこの種の計算をコーディングするより効率的な方法はありますか? Fortran には、私が十分に認識していない気の利いた配列操作がたくさんあることを知っています。

前もって感謝します。

4

1 に答える 1

0

この表現は、私が物事を正しければarg1、1 つのステートメントで作成する必要があります。

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

ここに寸法を配線しましたが、目的に合う場合と合わない場合があります。内部式は と の外積を生成premultzsinphi、それをベクトルに再形成します。外積の転置を再形成する必要があるかもしれませんが、私は物事を注意深くチェックしていません。

しかし、Fortran の配列組み込み関数のこの種の巧妙な使用に関する私の経験に基づいて、これ、または Fortran の配列組み込み関数の他のほとんどの巧妙な使用法が、既に持っている単純なループ実装よりも優れているとは思えません。これらの操作の多くで、コンパイラは配列のコピーを生成しようとしますが、データのコピーには比較的コストがかかります。もちろん、これはテストしたいアサーションです。

ワンライナーがループよりも理解しやすいかどうかを判断するのはあなたに任せます。配列構文の表現力は、許容できるパフォーマンスのコストを伴う場合もありますが、そうでない場合もあります。

于 2013-01-21T15:49:19.147 に答える