こちらのリンクを参照して、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のローカル画面で確認できるといいんだけど、、、。
まだまだやりたいことを全て達成するには時間がかかりそうだ、、、。
コメント