CESolution

visual studio 2008でVBA用の行列演算のdllを作成する

こちらのリンクを参照して、VBAからEigenライブラリを使った行列計算をしてみる。

Eigen/Coreだけインクルードし、以下のように、1で初期化した[1,2]行列Aと[2,1]行列Bを作成する。


MatrixXd A=MatrixXd::Ones(1,2);
MatrixXd B=MatrixXd::Ones(2,1);

上述のリンクのままなにも頭を使わずに、まず足し算の出力だけは簡単にできた。

次は、行列計算をさせたいので、VBA側からは配列を渡したい。

関数の変数が1つのみの時は、C++側、VBA側とも以下のような記述で、VBA側の入力配列の全ての和を出力させることができた。


double __stdcall Add(double x[])

VBAのDeclare部分


Private Declare Function Add Lib "ExcelLink.dll" (ByRef x As Double) As Double

VBAの出力部分

 For i = 0 To 5
 x(i) = i + x(i)
 Next

Debug.Print (Add(x(0)))

ところが、同じ要領で以下のように設定すると、計算出力に0が返ってきてしまう。


double __stdcall Add(double x[], double y[])


Private Declare Function Add Lib "ExcelLink.dll" (ByRef x As Double, ByRef y As Double) As Double

色々思考錯誤したものの全くうまくいかず、あきらめかけていたところ、こちらのリンクを参照にして、なんとか解決できた。

最終的な設定は以下の通り。


double __stdcall Mult(double* x, double* y)

・

・

A(0,0)=x[0];
A(0,1)=x[1];
B(0,0)=y[0];
B(1,0)=y[1];

z=A*B;
Map<MatrixXd>(&z2[0],1,1)=z;
z3=z2[0];

return z3;


Private Declare Function Mult Lib "ExcelLink.dll"(ByRef x As Double, ByRef y As Double) As Double

x(0) = 3
x(1) = 5
y(0) = 4
y(1) = 5

Debug.Print (Mult(x(0), y(0)))

上記の設定で、[1,2]行列と[2,1]行列の積を計算し、結果の37を出力させることができた。

ただ、このように出力値がスカラー値の場合は、上記の設定で問題ないが、例えば[2,2]行列同士の積のように、出力値が行列になる場合、関数で出力値が1つだけだと表現できない。

出力も配列にするにはどうすればいいんだろう?

また、デバッグする時に、計算途中の値がVBAのローカル画面で確認できるといいんだけど、、、。

まだまだやりたいことを全て達成するには時間がかかりそうだ、、、。