2016-08-04 7 views
1

Fortranで拡張アレイをエミュレートする既存の方法はありますか? C++のベクトルと似ています。私はインターネット上でこのテーマについて何も見つけていないとき、非常に驚​​いていました。値を追加するときにFortranアレイが自動的に増加する

動機付けの例として、いくつかの反復関係を計算し、私が得るすべての中間の数値を保存したいとします。私の停止基準は隣接する結果の違いですので、私はこれに割り当てるメモリ量を事前に知ることができません。

+0

関連するまたは重複する可能性がありますか? http://stackoverflow.com/questions/8384406/how-to-increase-array-size-on-the-fly-in-fortran – solalito

+0

上記の記事の回答を引用するには、次のようにします。 FortranでN個の要素からN + 1個に配列を拡張するには、新しい配列を作成し、既存の要素をすべてコピーすることが必要です。より適切なデータ構造はリンクリストになる可能性があります。 – solalito

+0

[tag:fortran90]とタグ付けしました。あなたは本当に過去25年間の言語の変更を無視する必要がありますか?例えば、非常に単純な 'a = [a、5]'はF90ではありません。 (または効率的です。) – francescalus

答えて

5

私はこれまでこのサイトのどこかに表示されていると確信していますが、私はそれを見つけることができません。 francescalusによってコメントとして

まず、Fortran 2003の中で、あなたは簡単な

a = [a, item] 

によって一つの要素を追加することができます。これは配列を頻繁に再割り当てする可能性が高く、遅くなります。

配列数は、要素数nよりやや大きめになるようにすることができます。要素数nが配列size(a)のサイズを超えると、新しい要素をいくつかの要素(ここでは2x)で割り当ててそこの古い要素をコピーできます。残念ながら、Fortranにはrealloc()はありません。

module growing_array 
    implicit none 

    real, allocatable :: a(:) 

    integer :: n 

contains 

    subroutine add_item(item) 
    real, allocatable :: tmp(:) 
    real, intent(in) :: item 

    if (n == size(a)) then 
     !this statement is F2003, it can be avoided, but I don't see why in 2016 
     call move_alloc(a, tmp) 

     allocate(a(n*2)) 
     a(1:n) = tmp 
    end if 

    n = n + 1 

    a(n) = item 
    end subroutine 
end module 

私は最初の割り当てを省いただけで十分です。

タイプバインドされたプロシージャを使用して派生型に入れることができ、データ構造として使用できますが、これは純粋なFortran 2003であり、90を望みました。したがって、Fortran 90には欠陥がある割り当て可能な配列のための多くの方法であり、必然的に時代遅れであり、本質的に死んでいる。

+1

ありがとう、私はfortranが既に実装しているので、私はホイールを再発明しないようにしたいと思っていましたが、 fortranはあなたの人生を楽にしたくありません。 – DartLenin

+1

FWIW参照されるC++ベクトル型は、一度にブロックを割り当てて同様のことを行います。アルゴリズムが何であるかを調べる価値があるかもしれません。 – agentp

+0

@HighPerformanceMark残念ながら、それは私の決断ではありません。もっと公正な比較をしよう。 C++には、多くのタスクでFortranを性能を上回らないようにする標準ライブラリのさまざまな関数とデータ構造があります。Fortranは同じ標準ライブラリを持つことができましたが、誰もまだそれを書いていませんでした。なぜなら、Fortranはあなたの人生を楽にしたくないと言ったからです:) – DartLenin

関連する問題