1

こんにちは、こちらで説明されているように、f2py を使用して、dgesvd.f ファイルをコンパイルし、それを llapack にリンクすることで、lapack ルーチン dgesvd をラップしています。

docstring によると、dgesvd モジュールには署名があります。

dgesvd - Function signature:
  dgesvd(jobu,jobvt,m,n,a,s,u,vt,work,lwork,info,[lda,ldu,ldvt])
Required arguments:
  jobu : input string(len=1)
  jobvt : input string(len=1)
  m : input int
  n : input int
  a : input rank-2 array('d') with bounds (lda,*)
  s : input rank-1 array('d') with bounds (*)
  u : input rank-2 array('d') with bounds (ldu,*)
  vt : input rank-2 array('d') with bounds (ldvt,*)
  work : input rank-1 array('d') with bounds (*)
  lwork : input int
  info : input int
Optional arguments:
  lda := shape(a,0) input int
  ldu := shape(u,0) input int
  ldvt := shape(vt,0) input int

次に、次の ocde を使用してモジュールを呼び出します。

mat = rand(20,30)
out_u,out_s,out_vh = zeros((20,20)), zeros((20,)), zeros((30,30))
rows, cols = shape(mat)
workspace = zeros((rows*cols))
out_info = 0

dgesvd(jobu='S', 
    jobvt='S',
    m=rows,
    n=cols,
    a=mat,
    s=out_s,
    u=out_u,
    vt=out_vh,
    work=workspace,
    lwork=rows*cols,
    info=out_info)

に格納されている正しい特異値が得られますout_sが、行列out_uout_vhはまだゼロで埋められているだけです。左/右の特異ベクトルを取得するには、何か別のことをする必要がありますか?

コードはエラーなしで実行されます。つまり、out_info0 です。

(jobu と jobvt の引数 'S' は、最初の min(m,n) 特異ベクトルのみを計算するようにルーチンに指示します。これを 'A' に変更しても、違いはありません)

どんなアイデアでも大歓迎です!ありがとうミーシャ

4

1 に答える 1

5

f2pyFortran コードの Python ラッパーを作成しますが、作成される Python 関数は、Fortran コードとまったく同じように呼び出されることを意図していません。Fortran では、出力変数を引数としてサブルーチンに渡すのが一般的です。これは「pythonic」ではありません。さらに、Python は Fortran と同じようにサブルーチンをサポートしていません。このため、f2pyFortran サブルーチンを Python 関数に変換するため、すべての出力変数が関数によって返され、呼び出しシグネチャには含まれません。したがって、次のように関数を呼び出す必要があります。

out_s, out_u, out_vh, info = dgesvd(jobu='S', 
                                    jobvt='S',
                                    m=rows,
                                    n=cols,
                                    a=mat,
                                    work=workspace,
                                    lwork=rows*cols)

INTENTただし、LAPACK ルーチンは FORTRAN77 で記述されているため、入出力変数の宣言 はありません。f2py宣言を使用して、INTENTどの変数が入力として使用され、どの変数が出力として返されるかを判断します。あなたが投稿した関数シグネチャに基づいて、f2pyすべての変数が入力であると想定していますが、これはあなたが望むものではありません。このため、 を呼び出す独自の Fortran 90 ラッパー ルーチンを作成して、宣言を自分でdgesvd追加してヒントを与えることをお勧めします。私は個人的にラッパーを使用して、渡す作業配列を割り当て、Python から渡す必要がないようにします。入力/出力署名を正確に決定する方法については、ここで説明されていますINTENTf2pydgesvdf2py(それには 3 つの方法がありますが、私は 3 番目の方法を好みます)。

于 2012-05-27T20:24:31.927 に答える