2

2 つの引数を持つサブルーチン (最小化用) を作成しようとしています。

  • x任意の長さの配列
  • fその長さの配列を取り、スカラーを返す関数

モジュールの例:

module foo

contains

  subroutine solve(x, f)
    real, dimension(:), intent(inout) :: x
    interface
      real pure function f(y)
        import x
        real, dimension(size(x)), intent(in) :: y
      end function
    end interface

    print *, x
    print *, f(x)
  end subroutine

end module

そしてテストプログラム:

use foo

real, dimension(2) :: x = [1.0, 2.0]

call solve(x, g)

contains

  real pure function g(y)
    real, dimension(2), intent(in) :: y

    g = sum(y)
  end function

end

gfortran は以下で失敗します:

call solve(x, g)
              1
Error: Interface mismatch in dummy procedure 'f' at (1): Shape mismatch in dimension 1 of argument 'y'

変更すると、正常にsize(x) => 2コンパイル (および実行) されます。変更しても問題なく動作します : => 2。しかし、これらのソリューションのどちらも、私が望むものを得ることができません。

どうすればこれを達成できるかについてのアイデアはありますか?

4

4 に答える 4

2

MSBのソリューションのコメントに示されているように安全性を確保したい場合は、使用する必要が-fcheck=boundsあり、コンパイラは想定および遅延形状配列の実行時チェックを生成します。の詳細については、gfortran の man ページを参照してください-fcheck。ただし、速度は多少落ちます。

于 2013-04-11T10:08:21.817 に答える
1

解決策はありますが、説明する価値はあります...仮引数に明示的なインターフェイスがある場合(ここではそれを行います)、実引数として渡されるプロシージャの特性がそれらの特性と一致する必要があります純粋性と要素の組み込みに関するいくつかの例外を除いて、仮引数。手続きの特性には、特にその仮引数の特性が含まれます。

仮引数の特徴には、とりわけその形状が含まれます。その形状が定数式でない場合、特性には「式内のエンティティに対する [形状の] 正確な依存性」が含まれます。

仮引数のインターフェイス ブロックはf、配列が size であることを宣言しますSIZE(x)。x は、ホストに関連付けられた想定形状変数です。そのサイズは実行時に変化する可能性があるためSIZE(x)、定数ではありません。したがって、その式とその中の実体は、仮引数の特性になります。

モジュール プロシージャgは、配列が size であることを宣言します2。それは明らかに定数です。

f の仮引数のサイズの非定数式の値に関係なく、それらの配列サイズの特性 (ある種の式と定数) が一致しないため、エラーが発生します。

定数 2に置き換えるSIZE(x)と、明らかに特性が一致します。仮定された形状xを定数サイズ 2 に変更するとSIZE(x)、値 2 の定数式になります。これは定数式であるため、関連するのはその値だけです。したがって、2 つの引数の特性は一致します。fの仮引数と の仮引数の両方を変更するg(:)、特性が一致します。

于 2013-04-10T20:46:04.020 に答える
0

これは、割り当て可能な配列を渡す方法を示すデモです。

いくつかのヒント:

  • モジュールを使用して、煩雑なインターフェースを回避します。
  • 配列を実際の関数に渡すときに、追加の行列サイズ情報を追加します。たとえばf(y, sizeinfo)、実際の関数内で入力行列のサイズを正しく宣言できるようにします。割り当て可能な配列は subroutine に渡すことができるsolveため、 subroutine で size(mat) を使用してサイズを取得できますsolve

したがって、修正版は次のようになります。

module foo

contains

  subroutine solve(x, f)
    real, dimension(:), intent(inout) :: x
    real,external::f
        integer::sizeinfo

    print *,'x=', x
    sizeinfo = size(x)
    print *, 'f(x)=',f(x,sizeinfo)
  end subroutine

    real function g(y,sizeinfo)
    integer::sizeinfo
    real, dimension(sizeinfo) :: y

    g = sum(y)
  end function
end module

メインプログラムは次のとおりです。

program main
use foo

real, dimension(2) :: x = (/1.0, 2.0/)

call solve(x, g)

end program

結果は次のとおりです。

x=   1.000000       2.000000    
f(x)=   3.000000 
于 2017-02-21T01:23:41.610 に答える