传递矩阵数据

MATLAB擅长矩阵计算,使用GetFullMatrix和PutFullMatrix函数可以在MATLAB和VB之间传递矩阵数据。[大谦MATLAB,dqmatlab点com]

1.GetFullMatrix函数

该函数从服务器获取矩阵,其调用格式为:

如果MATLAB作为客户程序:

[xreal ximag]=h.GetFullMatrix('varname', 'workspace', zreal, zimag)

[xreal ximag]=GetFullMatrix(h, 'varname', 'workspace', zreal, zimag)

[xreal ximag]=invoke(h,'GetFullMatrix', 'varname', 'workspace', zreal, zimag)

如果VBA作为客户程序:

void GetFullMatrix([in] BSTR varname, [in] BSTR workspace,

[in, out] SAFEARRAY(double)* xreal,

[in, out] SAFEARRAY(double)* ximag);

GetFullMatrix函数从句柄h表示的服务器程序的工作空间workspace中获取保存在变量varname中的矩阵,并将实部保存在xreal中,将虚部保存在ximag中。workspace参数的值可以取base或global。zreal和zimag(xreal和ximag)参数为大小相同的矩阵。

注意:如果试图将GetFullMatrix函数的输出显示到客户窗口,必须指定xreal和/或ximag输出变量。使用第一种语法格式时,服务器函数名,例如GetFullMatrix是有大小写区分的。对于MATLAB客户程序,上面3种语法格式在操作效果上没有区别。对于VB脚本客户程序,使用GetWorkspaceData和PutWorkspaceData函数与MATLAB工作空间传递数值数据。这些函数使用variant数据类型取代safearray数据类型,因为VB脚本语言不支持safearray数据类型。

2.PutFullMatrix函数

该函数将矩阵保存到服务器程序中,调用格式为:

如果MATLAB作为客户程序:

h.PutFullMatrix('varname', 'workspace', xreal, ximag)

PutFullMatrix(h, 'varname', 'workspace', xreal, ximag)

invoke(h, 'PutFullMatrix', 'varname', 'workspace', xreal, ximag)

如果VBA作为客户程序:

void PutFullMatrix([in] BSTR name, [in] BSTR workspace,

[in] SAFEARRAY(double) xreal, [in] SAFEARRAY(double) ximag);

PutFullMatrix函数将句柄h表示的服务器的指定工作空间中的矩阵保存到变量varname中。将矩阵的实部和虚部输入到xreal和ximag输入参数中。workspace参数可以是base或global。

注意:xreal和ximag参数中指定的矩阵不能是标量、空矩阵或具有2维以上。

下面的例子将一个5×5的实数矩阵赋给服务器基本工作空间中的变量M,然后用GetFullMatrix函数将它读回。

MATLAB作为客户程序时,使用下面的命令行:

code.matlab
>> h=actxserver('matlab.application');
>> h.PutFullMatrix('M', 'base', rand(5), zeros(5));
>> MReal=h.GetFullMatrix('M', 'base', zeros(5), zeros(5))
MReal =
    0.9501    0.7621    0.6154    0.4057    0.0579
    0.2311    0.4565    0.7919    0.9355    0.3529
    0.6068    0.0185    0.9218    0.9169    0.8132
    0.4860    0.8214    0.7382    0.4103    0.0099
    0.8913    0.4447    0.1763    0.8936    0.1389

VBA作为客户程序时,使用类似下面的语句行:

code.excel vba
Dim MatLab As Object
Dim Result As text-blue-400">String
Dim XReal(3, 3) As Double
Dim XImag(3, 3) As Double
Dim RealValue As Double
Dim i, j As Integer
Set Matlab=text-blue-400">CreateObject("matlab.text-blue-400">application")
Result=MatLab.Execute("M=rand(4);")
Call MatLab.GetFullMatrix("M", "base", XReal, XImag)
For i=0 to 3    '输出第1行
  Debug.Print Xreal(0,i)
Next

下面的实例首先建立与MATLAB的自动化连接,然后传入一个3×3的矩阵,求该矩阵的逆以后将逆矩阵返回到VBA。

创建新工程vba-matlab2,标准窗体名称为frmVBAOLEMat,在窗体上拖放1个框架控件,其中放9个文本框,在框架控件右侧放置2个标签和2个命令按钮,如图2-5所示。

Document Image

图2-5 程序的设计界面

窗体和各控件的设置如表2-2所示。

表2-2 窗体和控件的设置

对象类型 名 称 属性设置
Form frmVBAOLEMat Caption="在VBA与MATLAB之间传递矩阵数据"
Frame Frame1 Caption="原矩阵"
TextBox数组 txtEle(0) Text="1"
TextBox数组 txtEle(1) Text="3"
TextBox数组 txtEle(2) Text="9"
TextBox数组 txtEle(3) Text="4"
TextBox数组 txtEle(4) Text="2"
TextBox数组 txtEle(5) Text="5"
TextBox数组 txtEle(6) Text="7"
TextBox数组 txtEle(7) Text="2"
TextBox数组 txtEle(8) Text="0"
Label Label1 Text="逆矩阵"
Label Label2 Text=""
CommandButton cmdCompute Caption="求原矩阵的逆矩阵"
CommandButton cmdExit Caption="关闭"

在代码窗口键入下面的代码:

code.excel vba
Private Sub cmdCompute_Click()
  Dim objMATLAB As Object
  Dim dblInReal(1 To 3, 1 To 3) As Double
  Dim dblInImag(1 To 3, 1 To 3) As Double
  Dim dblOutReal(1 To 3, 1 To 3) As Double
  Dim dblOutImag(1 To 3, 1 To 3) As Double
  Dim i As Integer
  Dim j As Integer

  dblInReal(1, 1)=text-blue-400">Val(txtEle(0).Text)
  dblInReal(1, 2)=text-blue-400">Val(txtEle(1).Text)
  dblInReal(1, 3)=text-blue-400">Val(txtEle(2).Text)
  dblInReal(2, 1)=text-blue-400">Val(txtEle(3).Text)
  dblInReal(2, 2)=text-blue-400">Val(txtEle(4).Text)
  dblInReal(2, 3)=text-blue-400">Val(txtEle(5).Text)
  dblInReal(3, 1)=text-blue-400">Val(txtEle(6).Text)
  dblInReal(3, 2)=text-blue-400">Val(txtEle(7).Text)
  dblInReal(3, 3)=text-blue-400">Val(txtEle(8).Text)

  For i=1 To 3
    For j=1 To 3
      dblInImag(i, j)=0
    Next
  Next

  Set MatLab=text-blue-400">CreateObject("matlab.text-blue-400">application")
  Call MatLab.PutFullMatrix("InM", "base", dblInReal, dblInImag)
  Call MatLab.Execute("OutM=inv(InM);")
  Call MatLab.GetFullMatrix("OutM", "base", dblOutReal, dblOutImag)

  Dim strOutM As text-blue-400">String
  lblOut.Caption=""
  For i=1 To 3
    For j=1 To 3
      strOutM=strOutM & dblOutReal(i, j) & text-blue-400">Chr(9)
    Next
    lblOut.Caption=lblOut.Caption & strOutM & text-blue-400">Chr(13) & text-blue-400">Chr(10)
    strOutM=""
  Next

  Set MatLab=Nothing
End Sub
Private Sub cmdExit_Click()
  Unload frmVBOLEMat
End Sub

运行程序,单击“求原矩阵的逆矩阵”命令按钮,在右侧显示原矩阵的逆矩阵,如图2-6所示。

Document Image

图2-6 程序运行效果