Fortran ソース MEX ファイルの作成
この例では、MATLAB® 行列を使用して MATLAB で Fortran サブルーチン timestwo
を呼び出す MEX ファイルの作成方法を説明します。ソース ファイル全体は、ここで参照できます。この例では、MATLAB エディターを使用してソース コードを作成し、MATLAB mex
コマンドを使用して MEX 関数を作成します。
Fortran サブルーチン timestwo
次のコードは、サブルーチン timestwo
を定義しています。このサブルーチンは、n
次元の配列 x_input
を 2
で乗算し、配列 y_output
に結果を返します。
subroutine timestwo(y_output, x_input) real*8 x_input, y_output y_output = 2.0 * x_input return end
ソース ファイルの作成
MATLAB エディターを開いてファイルを作成し、次の情報を含む MEX ファイルをドキュメント化します。
C====================================================================== C timestwo.f C Computational function that takes a scalar and doubles it. C This is a MEX file for MATLAB. C======================================================================
MATLAB API 関数の宣言を含む Fortran ヘッダー ファイル fintrf.h
を追加します。
#include "fintrf.h"
たとえば c:\work
などの MATLAB パス上にファイルを保存し、timestwo.F
という名前を付けます。MEX ファイルの名前は timestwo
です。
ゲートウェイ ルーチンの作成
MATLAB は、Fortran サブルーチンのエントリ ポイントとして、ゲートウェイ ルーチン mexfunction
を使用します。以下に示す mexFunction
のコードを追加します。
C Gateway routine subroutine mexFunction(nlhs, plhs, nrhs, prhs) C Declarations C Statements return end
次のステートメントをサブルーチン mexfunction
に追加して、すべての変数を宣言するようにします。
implicit none
64 ビット配列は、明示的な型宣言が必要です。
mexfunction
の引数の宣言
mxArray
変数を宣言するには、MATLAB 型の mwPointer
を使用します。Declarations
ステートメントの後に次のコードを追加します。
C mexFunction arguments: mwPointer plhs(*), prhs(*) integer nlhs, nrhs
関数およびローカル変数の宣言
この MEX ファイルで使用される MATLAB API 関数のシンボリック名と型を宣言します。
C Function declarations: mwPointer mxGetDoubles mwPointer mxCreateDoubleMatrix integer mxIsNumeric mwPointer mxGetM, mxGetN
関数の型を決定する場合は、MATLAB API 関数のリファレンス ドキュメンテーションを参照してください。たとえば、
mxGetDoubles
のドキュメンテーションなどが参考になります。mexfunction
引数のローカル変数を宣言します。C Pointers to input/output mxArrays: mwPointer x_ptr, y_ptr
行列変数を宣言します。
C Array information: mwPointer mrows, ncols mwSize size
MEX ファイルの入出力引数の確認
nrhs
および nlhs
引数を使用して、MEX ファイルの入出力引数の数を確認します。以下のステートメントを mexfunction
のコード ブロックに追加します。
C Check for proper number of arguments. if(nrhs .ne. 1) then call mexErrMsgIdAndTxt ('MATLAB:timestwo:nInput', + 'One input required.') elseif(nlhs .gt. 1) then call mexErrMsgIdAndTxt ('MATLAB:timestwo:nOutput', + 'Too many output arguments.') endif
prhs
引数を使用して入力引数の型を確認します。
C Check that the input is a number. if(mxIsNumeric(prhs(1)) .eq. 0) then call mexErrMsgIdAndTxt ('MATLAB:timestwo:NonNumeric', + 'Input must be a number.') endif
計算ルーチンの作成
timestwo
のコードを追加します。このサブルーチンは計算ルーチンです。計算ルーチンとは、MATLAB で使用する機能を実行するソース コードのことです。
C Computational routine subroutine timestwo(y_output, x_input) real*8 x_input, y_output y_output = 2.0 * x_input return end
計算ルーチンはオプションです。このコードは mexfunction
Function ブロックの中に置くこともできます。
計算ルーチンの変数の宣言
次の変数宣言を mexFunction
に入れます。
C Arguments for computational routine: real*8 x_input, y_output
入力配列の読み取り
入力行列データをポイントするには、関数 mxGetDoubles
を使用します。
x_ptr = mxGetDoubles(prhs(1))
Fortran 配列 x_input
を作成するには、関数 mxCopyPtrToReal8
を使用します。
C Get the size of the input array. mrows = mxGetM(prhs(1)) ncols = mxGetN(prhs(1)) size = mrows*ncols C Create Fortran array from the input argument. call mxCopyPtrToReal8(x_ptr,x_input,size)
出力データの準備
出力引数 plhs(1)
を作成するには、関数 mxCreateDoubleMatrix
を使用します。
C Create matrix for the return argument. plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
関数 mxGetDoubles
を使用して、y_ptr
引数を plhs(1)
に割り当てます。
y_ptr = mxGetDoubles(plhs(1))
計算の実行
引数を timestwo
に渡します。
C Call the computational subroutine. call timestwo(y_output, x_input)
結果の出力引数へのコピー
C Load the data into y_ptr, which is the output to MATLAB. call mxCopyReal8ToPtr(y_output,y_ptr,size)
ソース ファイル全体の表示
フォルダーにある matlabroot
/extern/examples/refbooktimestwo.F
とソース ファイルを比較します。エディターでファイルを開きます。
バイナリ MEX ファイルのビルド
MATLAB コマンド プロンプトで、バイナリ MEX ファイルをビルドします。
mex -R2018a timestwo.F
MEX ファイルのテスト
x = 99; y = timestwo(x)
y = 198
参考
mexfunction
| mwPointer
| mwSize
| mxIsNumeric
| mxGetM
| mxGetN
| mxCreateDoubleMatrix
| mxGetDoubles