2.3 MatrixVB 的矩阵操作
矩阵是表示一组数据关系的组合,在MatrixVB中包含了许多矩阵分析函数,为了在VB中直接应用MatrixVB这些高效的计算方法,一般将VB中的数组当成矩阵进行处理,需要说明的是与matricVB矩阵元素相关的运算在VB中对应的数据类型一般为double类型。
2.3.1 在VB中生成MatrixVB矩阵
可以像在MATLAB命令窗口中那样,直接在VB中定义MATLAB矩阵变量;也可以使用VB的VARIANT通用型变量表示矩阵,其定义的方法如下:
Dim x As Variant
一般在VB中产生MatrixVB的方法主要有以下几种:
1.通过函数mabs转化为MatrixVB的矩阵
将VB中定义的数组通过函数mabs转化为MatrixVB的矩阵,格式为:
MATRIXVB_MATRIX=mabs(VB_ARRAY)
MATRIXVB_MATRIX为MatrixVB的矩阵名称,如同在MATLAB窗口中那样,不需要事先定义,VB_ARRAY是VB程序中定义的数组,也可以是单独的VB常量与变量。
修改图7-8中command按钮的Click事件的处理过程代码为:
Private Sub Command1_Click()
Dim A(1to 3,1to 3) As double
Dim i,j As integer
for i=1 To 3
for j=1 To 3
A(i,j)=CDbl(i+j)
Next
Next
B=mabs(A)
A. show
End Sub
该段代码首先定义了一个二维VB数组A,然后将其赋值,通过mabs函数转化为MatrixVB矩阵B并将其显示出来。
运行程序并单击该按钮,运行的结果如图7-11所示。
图7-11 通过函数mabs产生的MatrixVB矩阵
2.通过MatrixVB函数生成矩阵
可以使用MatrixVB中的特殊函数(如zeros()、ones()、magic()等)直接生成矩阵。如在VB程序代码中直接嵌入语句:
A=zeros(3,4)
A.show
结果将产生一个3行4列元素都为0的矩阵并将其显示出来。
在应用程序中我们也可以先定义变量,然后再赋值产生矩阵。产生矩阵VB支持的两种类型为Matrix与Variant的如下语句,都将产生一个3×4的0矩阵。
Dim mat As Matrix
Dim x As Variant
Set mat=zeros(3,4) '赋值为3×4的0矩阵
Set x=zeros(3,4) '赋值为3×4的0矩阵
3.通过函数 CreateMatrix
通过函数CreateMatrix创建的矩阵可以在创建过程中直接赋值,格式为:
CreateMatrix(p1 , p2 ,…, pn ,)
p1 , p2 ,…, pn 为矩阵的值。
函数Reshape用来设置由函数CreateMatrix所创建的函数的维数,格式为:
Reshap(X,rows,cols)
X为由CreateMatrix创建的矩阵,rows为指定的行数,cols为指定的列数,
如下例所示:
A=CreateMatrix(1,2,3,4,5,6,7,8,9)
Reshap(A,3,3)
A.Show
创建一个矩阵,并将其指定为3行3列,结果如图7-12所示。
图7-12 由CreateMatrix 产生的MatrixVB矩阵
2.3.2 对矩阵元素进行操作
1.矩阵元素的存取及与VB的数据转换
(1) 通过圆括号方式访问MatrixVB矩阵,但是这种方式只能对矩阵元素进行写操作,其格式如同访问VB的数组元素一样,例如:A是一个二维矩阵则下列代码:
A(i,j)=2.0
可以将矩阵的第i行第j列赋值为1。
(2) MatrixVB矩阵属性rN、iN可以以读写的形式访问矩阵X中的每个元素的实部和虚部,其中N表示矩阵的维数,例如,对于一维MatrixVB矩阵A
A.r1(i)=12'写操作
a=A.r1(i+1) '读操作
将矩阵A的第i个元素赋值为12,将第i+1个元素赋值给VB中的变量a。
再如,对于二维矩阵B
B.r2(i,j)=12
a=B.r2(i,j)
将矩阵B的第i行j列元素赋值为12,将矩阵B的第i行第j列元素赋值给VB中的变量a,要通过iN的方式来访问。
(3) X.simple可以将MatrixVB矩阵X转换为VB中的数据类型。在X为只有一个元素的矩阵情况下,若X为一个实数则将值转换为VB中的Double类型,如:
Dim S As Double
A=CreateMatrix(1.0)
S=A.simple
若X为一个字符的单元素矩阵,则X.simple返回一个VB中的字符串类型;若X为由多个元素的一维或者多维矩阵,则该表达式将返回一个矩阵,但不能自动转换为VB中相应的一维或者多维数组。
2.矩阵的显示
属性show具有打开Matrix viwer窗口显示矩阵内容的功能,格式为:
X.Show
3.获得矩阵的行、列、维数
利用函数rows()、cols()、dims()、dimension(n)返回矩阵的行数、列数、维数及第n维数的个数属性,与这些属性相关的VB中的数据类型一般为integer类型,如,对于二维矩阵A,下面的代码将得到矩阵的函数与列数,并将其赋值给VB中的变量。
a=A.rows()' 获得矩阵的行数
b=A.cols()' 获得矩阵的列数
c=dims()' 获得矩阵的维数
d=dimension(1) ' 第一维的个数
例如,在VB程序中产生一个MatrixVB矩阵并修改其元素的值,获得其属性并输出,修改图7-8中command按钮的Click事件的处理过程。代码为:
Private Sub Command1_Click()
'定义变量用于接收MatrixVB中矩阵元素的值或属性值
Dim xr As double
Dim xi As double
Dim i As integer
Dim row As integer
Dim col As integer
Dim dims As integer
A=zeros(3) '产生一个3行3列的零矩阵
'给矩阵赋值
for i=1 To 3
for j=1 To 3
A(i,j)=CDbl(i+j)
Next
Next
A.show'显示矩阵
xr=A.r2(2,2) '获得矩阵2行2列的值
row=A.rows()'获得行数
col=A.col()'获得列数
dims=A.dims()'获得维数
'输出属性
Print "行数为:";
Print row;
Print "列数为:";
Print col;
Print "维数为:";
Print col;
End Sub
运行程序并单击command1按钮,结果如图7-13和7-14所示。
图7-13 显示矩阵
图7-14 显示矩阵元素的值及属性
2.3.3 矩阵的保存与载入
使用vbsave命令将矩阵写入磁盘文件中,并将数据文件中保存的文件读到程序中。语法格式分别为:
vbsave filename variable
vbload(filename)
例如以下代码将产生的魔方矩阵A保存到文件magic.txt中,并读到B中
A=magic(3)
vbsave "magic.txt" A
B=vbload("magic.txt")
也可以使用MatrixVB提供的与C语言语法格式相似的函数来对特定格式的文件进行读写,把矩阵所有的元素都输出为一列,数据文件只能用Dos方式打开,如:
Dim fid As Variant
Dim A As Variant
Dim B As Variant
A = magic(4)
fid = fopen("one.txt", "w")
Call fprintf(fid, "%g/n", A)
Call fscanf(fid, "%g/n", B)
fclose (fid)
2.3.4 应用举例
我们下面考虑将第5章中的计算器用MatrixVB来实现,并增加矩阵的行列式运算,LU分解。
(1) 建立一个工程,工程名为Project1,工程类型为Standard EXE,如图7-15所示。
图7-15 新建VB工程
(2) 按照7.2节步骤创建工程并设置环境。
(3) 在主窗口上添加若干控件,如图7-16所示。
图7-16 应用主界面
各控件的类型、名称、标题及作用如表7-1所示:
表7-1 主窗口控件
控 件 类 型 | 控 件 名 称 | 标 题 | 作 用 |
Label | Label1 | Label1 | 显示正在输入的行、列 |
TextBox | Text1 | 接受输入数据 | |
ComboBox | Comb1 | 选择运算 | 选择运算类型 |
CommandButton | Command1 | 计算 | 执行运算命令 |
CommandButton | Command2 | 下一个 | 切换下一条数据输入 |
CommandButton | Command3 | 关闭 | 关闭主窗口 |
CommandButton | Command4 | 重置 | 清除主窗口中的打印内容 |
(4) 声明模块级的变量。
'定义保存原始数据的矩阵及表示当前行列的变量
Dim mat As Variant
Dim i As Integer
Dim j As Integer
(5) 为主窗口Form的Load事件编写代码。
Private Sub Form_Load()
Set mat = zeros(4, 4) '产生一个4×4的零矩阵
'向组合框增加计算选项字符串
Combo1.AddItem "转置"
Combo1.AddItem "逆矩阵"
Combo1.AddItem "特征值"
Combo1.AddItem "LU分解"
Combo1.AddItem "SVD分解"
Combo1.AddItem "行列式"
i = 1
j = 1
End Sub
(6) 为Command2的Click事件处理过程编写代码。
Private Sub Command2_Click()
Dim row As Integer
Dim col As Integer
Dim temp As Double
Label1.Caption = "当前行,列为" & CStr(i) & ", " & CStr(j)
mat(i, j) = CDbl(Text1.Text) '接收文本框中输入的数据到mat中
temp = CDbl(Text1.Text)
Print temp; '将当前输入的数据输出
'设置输出的行,列值,当行数大于4时输出结束
If j Mod 4 = 0 Then
i = i + 1
j = 1
Else
j = j + 1
End If
Text1.Text = "0"
If i = 4 Then
i = 1
j = 1
Text1.Text = ""
MsgBox "输入已经结束"
Command2.Enabled = False
Exit Sub
End If
End Sub
(7) 为Command1的Click事件编写代码。
'判断计算类型然后对mat矩阵进行相应的操作并将结果输出
Private Sub Command1_Click()
If Combo1.Text = "转置" Then
A = transpose(mat)
A.Show
ElseIf Combo1.Text = "逆矩阵" Then
B = inv(mat)
B.Show
ElseIf Combo1.Text = "特征值" Then
C = eig(mat)
v = C(1) 'C(1)为特征值向量,C(2)为主对角线为特征值的方阵
v.Show
ElseIf Combo1.Text = "LU分解" Then
D = lu(mat)
l = D(1) 'D(1)为下三角矩阵,D(2)为上三角矩阵,D(3)为交换矩阵
l.Show
ElseIf Combo1.Text = "SVD分解" Then
E = svd(mat) 'E[2]为对角线为奇异值的矩阵,E[1],E[3]为正交矩阵
v = E(1)
v.Show
ElseIf Combo1.Text = "行列式" Then
F = det(mat)
Print F.Simple '将行列式的值输出到窗口上
End If
End Sub
(8) 为Command 4的Click事件处理过程编写代码。
i = 1
j = 1
Form1.Cls
If Command2.Enabled = False Then
Command2.Enabled = True
End If
此外读者可以尝试进行编程求矩阵的范数,秩等运算。
说明:
(1) 与通过ActiveX自动化服务器方式相比,采用MatrixVB使得代码简练,它不需要在不同的环境中交换数据,也不必启动MATLAB的环境即可得到运算的结果。
(2) 有些矩阵运算函数可以返回若干个矩阵,如LU分解等,一般可以通过X(n)方式来区分。
(3) 有些针对一个二维矩阵的运算返回的是一个一维向量或单独的值,如矩阵的特征值或行列式值、范数等。
3.4 MatrixVB的运算符
VB不支持运算符的重载,例如“+”只能用于标量的加法运算,但在MatrixVB组件包中提供了一组函数用于扩展VB本身的运算符的适用范围,这些函数不仅能对MatrixVB矩阵进行算术运算,而且可以对VB支持的数据类型进行相同的运算,或者进行二者的混合运算。因此这些函数相当于扩展了VB运算符的范围。可以像使用MatrixVB组件包中其他函数一样对这些函数进行调用。我们可以将MatrixVB运算符函数分为算术运算符函数、关系运算符函数和逻辑运算符函数等。
值得注意的是,虽然MatrixVB的这一组函数可以用于VB的某些数据类型的变量或常量,但VB的运算符却不能用于MatrixVB矩阵。
3.4.1 算术运算符
矩阵的算术运算符及与VB对应的运算符如表7-2所示。
表 7-2 MatrixVB的算术运算符函数及与VB相关运算符的对应关系
Visual Basic | MatrixVB | MatrixVB运算函数说明 |
a^b | power(a,b) | a的b次方 |
a*b | times(a,b) | a乘b |
a/b | rdivide(a,b) | a右除b |
a/b | ldivide(a,b) | a左除b |
a Mod b | mmod(a,b) | a对b求余 |
a+b | plus(a,b) | a加b |
a-b | minus(a,b) | a减b |
-a | uminus(a) | 取a的每一个元素的相反数 |
说明:
(1) a和b可以都为VB所支持的整型,浮点型变量或者常量,运算的结果为MatrixVB标量矩阵,此时与VB的运算符所起的作用是一样的,如:
Dim x As Double
Dim y As integer
x=4.0
y = 2
C = power(x, y)
C.Show
运算的结果为16,如图7-17所示。
图7-17 4.0的2次方
(2) a与b都为MatrixVB矩阵,此时二者的维数、大小均要一致,所做的运算为二个矩阵对应元素的运算,如:
A = CreateMatrix(1, 2, 3, 4, 5, 6, 7, 8, 9)
B = CreateMatrix(2, 2, 2, 3, 3, 3, 4, 4, 4)
A = reshape(A, 3, 3)
B = reshape(B, 3, 3)
C = power(A, B)
C.Show
结果将产生一个矩阵C,其中任一元素C(i,j)的值为A矩阵对应元素A(j,i)的B(j,i)次方,计算结果如图7-18所示。
图7-18 矩阵A的B次方
(3) a与b中一个为MatrixVB矩阵,一个为VB中的数据类型(整型,浮点型)的标量,所做的运算为该标量对矩阵每个元素的算术运算,如:
A = CreateMatrix(1, 2, 3, 4, 5, 6, 7, 8, 9)
A = reshape(A, 3, 3)
B = power(A, 2)
B.Show
结果产生一个每一个元素为矩阵A对应元素值2次方的矩阵,如图7-19所示。
图7-19 矩阵的2次方
3.4.2 关系运算符
矩阵的关系运算符及与VB对应的运算符如表7-3所示。
表7-3 MatrixVB的关系运算符函数及与VB相关运算符的对应关系
Visual Basic | MatrixVB | MatrixVB运算函数说明 |
a<b | lt(a,b) | a若小于b则结果为真否则为假 |
a<=b | le((a,b) | a若小于等于b则结果为真否则为假 |
a>b | gt(a,b) | a若大于b则结果为真否则为假 |
a>=b | ge(a,b) | a若大于等于b则结果为真否则为假 |
a=b | eq(a,b) | a若等于b则结果为真否则为假 |
a<>b | ne(a,b) | a若不等于b则结果为真否则为假 |
说明:
a 和b可以都为VB所支持的整型、浮点型变量或者常量,此时与VB的运算符所起的作用是一样的,如:
(1) 如果a,b都为VB所支持的类型,运算的结果为MatrixVB标量矩阵,其中的值为0或1,如:
Dim x As integer
Dim y As integer
x=1
y=2
C = ge(x, y)
C.show
结果如图7-20所示。
图7-20 VB类型的比较运算
(2) a与b都为MatrixVB矩阵,此时二者的维数,大小均要一致,所做的运算为两个矩阵对应元素的运算,运算结果为由1,0构成的矩阵,如:
A = CreateMatrix(1, 2, 3, 4, 5, 6, 7, 8, 9)
B = CreateMatrix(2, 2, 2, 3, 3, 3, 4, 4, 4)
A = reshape(A, 3, 3)
B = reshape(B, 3, 3)
C = ge(A, B)
C.Show
结果如图7-21所示。
图7-21 矩阵的比较运算
(3) a与b中一个为matricVB矩阵,一个为VB中的数据类型(整型,浮点型)的标量,所做的运算为该标量对矩阵每个元素的逻辑运算,如:
A = CreateMatrix(1, 2, 3, 4, 5, 6, 7, 8, 9)
A = reshape(A, 3, 3)
B = ge(A, 5)
B.Show
运算结果如图7-22所示。
图7-22 矩阵与标量的比较运算
3.4.3 逻辑运算符
矩阵的逻辑运算符及与VB对应的运算符如表7-4所示。
表7-4 MatrixVB的逻辑运算符函数及与VB相关运算符的对应关系
Visual Basic | MatrixVB | MatrixVB运算函数说明 |
a And b | mand(a,b) | a与b做与运算 |
a Eqv b | mnot(mxor(a),b | 当a与b同时为真或假时结果为真,否则为假 |
a Imp b | mor(mnot(a),b) | a为真b为假时结果为假,否则为真 |
not a | mnot(a) | a做非运算 |
a Or b | mor(a,b) | a与b做或运算 |
a Xor b | mxor(a,b) | a与b做异或运算 |
有关矩阵逻辑运算符的数据类型说明与关系运算符相同,所得到的结果值为由0,1构成的矩阵或标量。
3.4.4 一些常用的运算函数
在前几节中我们介绍了矩阵的操作及与VB运算符有对应关系的运算符函数,其中包含了一些矩阵进行运算的函数。除此之外,MatrixVB还提供了大量运算函数,本节我们将介绍几个常用的运算符函数,如表7-5所示。
表7-5 MatrixVB的一些其他运算符函数
函 数 名 | 函 数 说 明 |
Colon(a,b,c) | 产生一个从a到c步长为b的序列 |
Primes(n) | 产生小于n的素数序列 |
Rand(n) | 产生一个个数为n的随机序列 |
Logspace(a,b,n) | 产生一个个数为n的对数序列 |
vbfilter(a,b,c) | FIR滤波函数,a,b为滤波器系数矩阵,c为一个数据向量 |
fft(a) | 快速傅立叶变换,a为一个输入序列 |
Roots(a) | 用来求多项式的根,a为输入的矩阵 |
Mldivide(a,b) | 解线性方程组,a为系数矩阵,b为方程组等号右边的向量 |
Strcat(a,b) | 连接两个矩阵 |
例:给定一个线性方程组:
代码为:
A = CreateMatrix(2, 11, 7, 3, -4, 5, 1, 8, -8)
B = CreateMatrix(2, 6, 9)
A = reshape(A, 3, 3)
B = reshape(B, 3, 1)
C = mldivide(A, B)
D=strcat(A,B)
E=vertcat(C,D)
D.Show
运行的结果如图7-23所示。
图7-23 求方程组的解
最后一列为方程组的解向量。
此外还有很多运算函数请参考帮助文档refguide.pdf,这里不一一介绍了。
MatrixVB组件包提供了一整套用于二维或三维作图的函数、颜色处理函数、图像处理函数、图像句柄处理函数及用户界面对话框等工具。mattrixVB同时支持在figuer窗口及VB窗口中绘制图形与图像处理。
本节将介绍如何使用这些函数和工具来为VB程序创建和处理图形。
3.5.1 在figure窗口中绘制图形
在MatrixVB组件包中包含了用于生成圆饼图、直方图、频率图、等高线图、极坐标图和散点图等函数,可以基本满足图形绘制应用需求,同时也提供了能读取多种格式图像的处理函数。
借助这些函数及数学运算函数、颜色处理函数,可以方便地作出各种图形。下面以一个具体的二次曲线的例子来说明MatrixVB组件包在该领域的应用方法。假设该曲线的方程为:
(1) 参照7.2节建立VB工程,引入MatrixVB,在程序主窗口中添加一个按钮控件,如图7-24所示。
图7-24 图形绘制程序主窗口
(2) 为按钮的click事件的处理过程编写代码:
Private Sub Command1_Click()
a = colon(1, 1, 10) '产生一个序列
y = times(2,power(a, 2))
y = plus(y, 3)
figure (1) '生成绘制图形的窗口
plot (y) '绘制曲线
End Sub
运行程序点击按钮得到的结果如图7-25所示。
图7-25 二次方程曲线
说明:
(1) figure命令用来生成空白的图形绘制窗口,当在一段代码中有多个绘制图形时,参数用来标识不同的窗口,利用gcf命令可以设置当前窗口。如下列代码:
a = colon(1, 1, 10)
y = times(2, power(a, 2))
y = plus(y, 3)
figure (1) '生成绘制图形的窗口
plot (y)
figure (2)
plot (randn(10))
所绘制的两个图形分别在窗口figure1与figure2上。
(2) 每一个figure窗口都有一个系统默认的菜单,该命令菜单主要包括File 、Edi、Control等,可以将所绘制的图形保存成常用的图形图像格式,控制图形显示、设置和修改图形的属性,对图形窗口进行设置和控制等。
3.5.2 在VB窗口或控件中绘制图形
MatrixVB也支持直接在VB窗口或控件中绘图,此时需要用到MatrixVB函数vbaxes来为窗口添加一个axes对象,代码为:
ax=vbaxes(FormHandle)
ax为一个axes对象,FormHandle为窗口或者控件的句柄。下面我们在VB的窗口中绘制出7.5.1中的图形。步骤如下:
(1) 修改上例中的主窗口,增加一个PictureBox控件,名称为Picture1。如图7-26所示。
图7-26 程序主窗口
(2) 在command1按扭的click事件处理过程中添加如下代码:
ax = vbaxes(Picture1.hWnd)
a = colon(1, 1, 10)
y = times(2, power(a, 2))
y = plus(y, 3)
plot (y)
运行程序,点击按扭运行的结果如图7-27所示。
图7-27 在PictureBox控件中绘图
3.6 线 性 规 划
MatrixVB也支持线性问题的求解,下面以求解线性规划问题为例,介绍MatrixVB的线性求解应用。问题如下:
求 -x+3y-2z 的最小值,其中 x, y, z均为非负数。问题的约束条件可以表示为:
该问题的求解过程在VB中可以由以下代码段实现:
c = zeros(3,1)
c(1) = -1
c(2) = 3
c(3) = -2
a =CreateMatrix(1,3,0,2,0,5,0,4,6)
a = reshape(a,3,3)
b = zeros(3,1)
b(1) = 3
b(2) = 7
b(3) = 2
lb = zeros(3,1)
x = lp(c,a,b,lb)
x.show
上述代码中有绝大部分代码是用于整理相应的输入条件,关键的语句是对函数lp(c,a,b,lb)的调用,其运行结果由MatrixVB提供的矩阵浏览器显示。结果为:
[17/9 0 1/3]