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