C言語で書いてMATLABで実行する
まずはサンプルコードMATLABとC言語の間のデータの受け渡しを理解しよう
#include <stdio.h> #include <math.h> #include "mex.h" int n,x,y,z,a,x_size,y_size,z_size; int *prdims0, *pldims0, *pldims1; double *S, *S_new, *zahyo; make_a(){ a=4; } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ a=0; //右の第一引数から次元数を取得し,それをprdims0に代入 prdims0 = (int*)mxGetDimensions(prhs[0]); //配列の要素にはそれぞれの次元数が入っているので,それを代入 x_size=prdims0[0]; y_size=prdims0[1]; z_size=prdims0[2]; //prhs[0]の(先頭)アドレスを取得して,Sに代入 //実質は代次元配列は一次元配列として取得しているので //ここではSに配列の先頭アドレスの代入 S = mxGetPr(prhs[0]); //mxGetScalarは値を取得する. //この場合第二引数を取得 n=(int)mxGetScalar(prhs[1]); printf("%d\n",n); //同じくzahyoに第三引数の先頭アドレスを代入することで,配列を代入 //値が三つあるので,それぞれを表示している処理 zahyo = mxGetPr(prhs[2]); printf("%lf, %lf, %lf\n", zahyo[0], zahyo[1], zahyo[2]); //返り値の行列の次元数を宣言 pldims0 = (int*)mxCalloc(3, sizeof(int)); //それぞれの次元の大きさを設定 //mxCreateNumericArray用にpldims0を用意しなくてはいけないのでやっている pldims0[0] = x_size; pldims0[1] = y_size; pldims0[2] = z_size; //上で準備したpldims0行列を使ってディメンションを指定> //3次元でそれぞれの次元の大きさがいくつであるという指定 //第三引数は多分あまり意味が無い.doubleを使っているわけではないから... //第四引数は虚数がないということを明示している plhs[0] = mxCreateNumericArray(3, pldims0, mxDOUBLE_CLASS, mxREAL); //まずS_newに先頭アドレスを指定.初期化 S_new = mxGetPr(plhs[0]); //行列の全ての要素にnをかけている for(z=0;z<z_size;z++){ for(y=0;y<y_size;y++){ for(x=0;x<x_size;x++){ S_new[x + (x_size)*y + (x_size*y_size)*z] = n * S[x + (x_size) *y + (x_size*y_size)*z]; } } } //make_a()関数を呼んでいる. make_a(); //第二引数にあった行列の部分に別の値を代入するための処理 //注意点は-1をしている点 S_new[ ((int)zahyo[0]-1) + (x_size)*((int)zahyo[1]-1) + (x_size*y_size)*((int)zahyo[2]-1)]=a; return; }
とりあえず,上記のコードをsample.cとして保存し,何も考えずに同じディレクトリで
以下を実行しよう.
%mex sample.c %S=ones(2,3,4) %n=5 %zahyo=[1 1 2] %[S_new]=sample(S,n,zahyo)
ちなみに返り値が2つ以上ある場合は
%[S_new, x]=sample(S,n,zahyo)
とすると,Cのソースコードでそのように指定していれば出来ます.