[原创] vb.net编写的 矩阵计算程序
vb.net吧
全部回复
仅看楼主
level 8
rzfc 楼主
由于工作需要,用到一些简单的矩阵计算,查到 一些vc的代码,又自己补充了矩阵求逆的功能,基本上自用没什么问题了。
通过编写,了解了运算符重载,函数重载。
功能比较 单薄,有兴趣这可以扩大。其中矩阵求逆的过程,因为本身遇到的问题阶数不大,所以直接按照定义编写了代码,这样效率可能不算高,但是计算结果肯定无误,也许对病态矩阵也有好的结果。
希望吧友批评指正。
附:源代码
矩阵计算程序
在vs2008中新建 项目:类库项目,项目名称:ClassLibMat
包括一个矩阵类:clsMatrix及一些属性参数。
函数有:
运算符重载的 四则运算
矩阵转置
方矩阵的行列式(按照数学定义计算)
方阵的逆矩阵(按照数学定义计算)
特征值(待加入)
Public Class clsMatrix
PublicShared nCols AsInteger ''矩阵宽度
PublicShared nRows AsInteger ''矩阵高度
PublicConst MAX_COLS AsInteger = 50 '最大行列数
PublicConst MAX_ROWS AsInteger = 50 '最大行列数
PublicMAT(MAX_ROWS, MAX_COLS) As Double
'运算符重载,加法
PublicShared Operator+(ByVal s1 AsclsMatrix, ByVal s2 AsclsMatrix) As clsMatrix
Dimi As Integer
Dimj As Integer
Dims3 As NewclsMatrix
If((s1.nRows = s2.nRows) And (s1.nCols =s2.nCols)) Then
Fori = 0 To s1.nRows - 1
s3.MAT(i, j) =s1.MAT(i, j) + s2.MAT(i, j)
Nexti
s3.nRows = s1.nRows
s3.nCols = s1.nCols
EndIf
Return s3
EndOperator
'设置行数,列数
PublicSub setRowCol(ByValtrows As Integer,ByVal tcols As Integer)
nRows = trows
nCols = tcols
EndSub
'以某数值填充矩阵
PublicSub Fill(ByVala As Double)
Dimi As Integer
Dimj As Integer
Fori = 0 To nRows - 1
Forj = 0 To nCols - 1
MAT(i, j) = a
Next
Next
EndSub
'乘法
PublicShared Operator*(ByVal s1 AsclsMatrix, ByVal s2 AsclsMatrix) As clsMatrix
Dimi As Integer
Dimj As Integer
Dimsum As Double
Dimk As Integer
If((s1.nCols = s2.nRows)) Then
Dims3 As NewclsMatrix
Fori = 0 To s1.nRows - 1
For j = 0 To s1.nCols- 1
sum = 0.0
Fork = 0 To s1.nCols - 1
sum = sum +s1.MAT(i, k) * s2.MAT(k, j)
Next k
s3.MAT(i, j) =sum
Next
Nexti
s3.nRows = s1.nRows
s3.nCols = s2.nCols
Returns3
Else
ReturnNothing
EndIf
EndOperator
'PublicShared Operator =(ByVal s1 As clsMatrix, ByVal s2 As clsMatrix) As clsMatrix
' Dim i As Integer
' Dim j As Integer
' Dim sum As Double
' Dim k As Integer
' If ((s1.nRows = s2.nRows) And (s1.nCols =s2.nCols)) Then
' For i = 0 To s1.nRows - 1
' For j = 0 To s1.nCols - 1
' Next
' Next i
' s3.nRows = s2.nRows
' s3.nCols = s1.nCols
' Return s3
' End If
'EndOperator
'
'矩阵转置
PublicFunction T() AsclsMatrix
Dimm As NewclsMatrix
Dimi As Integer
Dimj As Integer
For i = 0 To nRows - 1
Forj = 0 To nCols - 1
m.MAT(j, i) = Me.MAT(i, j)
Next
Next
m.nRows = Me.nCols
m.nCols = Me.nRows
Returnm
EndFunction
'//'通用行列式计算方法,按照数学定义计算
PublicFunction MdetermDirect() As Double
Dimi As Integer
DimtempD As Double
Dimresult As Double
IfnRows <> nCols Then '行列不等返回nothing
ReturnNothing
EndIf
IfnRows = 1 Then
result = MAT(0, 0)
Returnresult
ElseIfnRows = 2 Then
result = MAT(0, 0) *MAT(1, 1) - MAT(0, 1) * MAT(1, 0)
Returnresult
ElseIfnRows = 3 Then
result = MAT(0, 0) *MAT(1, 1) * MAT(2, 2) + MAT(0, 1) * MAT(1, 2) * MAT(2, 0) + MAT(1, 0) * MAT(2,1) * MAT(0, 2) - MAT(0, 2) * MAT(1, 1) * MAT(2, 0) - MAT(0, 1) * MAT(1, 0) *MAT(2, 2) - MAT(0, 0) * MAT(2, 1) * MAT(1, 2)
Returnresult
ElseIfnRows > 3 And nRows < 51 Then '最大计算到50阶
DimRX As NewclsMatrix
result = 0.0
Fori = 0 To nRows - 1
RX = Residual(0,i) '余子式
tempD =RX.MdetermDirect
result = result + CDbl(Math.Pow(-1.0, i)) * MAT(0, i) * tempD
Next
Returnresult
Else'
'//MsgBox("超出最大计算矩阵范围!最多计算16阶矩阵。")
Return-1.0
EndIf
EndFunction
'关于curRow,curCol的余子式
PublicFunction Residual(ByValcurRow As Integer,ByVal curCol AsInteger) AsclsMatrix
Dimi As Integer
Dimj As Integer
IfnRows <> nCols Then
ReturnNothing
EndIf
DimRX As NewclsMatrix
'StaticiniMat As Object
'iniMat= MAT
For i = 0 To nRows - 1
Forj = 0 To nCols - 1
RX.MAT(i, j) =MAT(i, j)
Next
Next
'RX.MAT = MAT
Fori = curRow To nRows - 1
Forj = 0 To nCols - 1
RX.MAT(i, j) =RX.MAT(i + 1, j)
Next
Next
Fori = 0 To nRows - 1
Forj = curCol To nCols - 1
RX.MAT(i, j) =RX.MAT(i, j + 1)
Next
Next
'MAT= iniMat
Debug.Print(MAT(0, 0))
RX.nRows = nRows - 1
RX.nCols = nCols - 1
ReturnRX
EndFunction
'直接计算逆矩阵,按照数学定义计算
PublicFunction InvDirect() AsclsMatrix
DimdetermX As Double
determX = MdetermDirect()
IfMath.Abs(determX) < 0.000000000000001 Then
MsgBox("病态矩阵!")
ReturnNothing
ExitFunction
EndIf
Dimi As Integer
Dimj As Integer
DimRX As NewclsMatrix
DiminvMat As New clsMatrix
DimtempD As Double
Dimc As Double
Fori = 0 To nRows - 1
Forj = 0 To nCols - 1
RX = Me.Residual(i, j)
tempD =RX.MdetermDirect()
If (i + j) Mod 2 = 0 Then
c = 1.0
Else
c = -1.0
End If
invMat.MAT(j, i) =tempD * c / determX
Debug.Print(Me.MAT(0, 0))
Debug.Print(RX.MAT(0, 0))
Next
Next
invMat.nCols = nCols
invMat.nRows = nRows
ReturninvMat
EndFunction
'构造
PublicSub New()
Dimi As Integer
Dimj As Integer
Fori = 0 To MAX_ROWS - 1
Forj = 0 To MAX_COLS - 1
MAT(i, j) = 0
Nextj
Nexti
Me.nRows= MAX_ROWS
Me.nCols= MAX_COLS
EndSub
ProtectedOverrides SubFinalize()
MyBase.Finalize()
EndSub
End Class
编译之后,release目录下生成classMatLib.dll文件。
应用
新建windows 窗体程序,form1窗体中加入按钮
Imports ClassLibMat ‘词句为vs2008中引用classMatLib.dll的方法,不同于vb6
Public Class Form1
DimA As ClassLibMat.clsMatrix ‘直接定义矩阵变量A
‘按钮事件
PrivateSub Button1_Click(ByValsender As System.Object, ByVal e AsSystem.EventArgs) Handles Button1.Click
a = NewclsMatrix ‘矩阵a初始化
a.nCols = 4 ‘列数
a.nRows = 4 ‘行数
a.MAT(0, 0) = 1 ‘矩阵赋值
a.MAT(0, 1) = 2
a.MAT(1, 0) = 3
a.MAT(1, 1) = 34
DimB As clsMatrix = a.T ‘定义b矩阵=A 的转置
B=B+ A
EndSub
End Class
2017年01月22日 08点01分 1
level 7
为什么你要用代数余子式计算逆阵?而不用高斯法?
2017年01月23日 04点01分 2
level 7
是基于运算速度么?还是算法实现
2017年01月23日 04点01分 3
速度上 应该比不上 那些算法,不过对于小矩阵,不明显,自己算够用了。 有一个想法:用定义算,对病态矩阵 可能 不敏感。不过没验证过。
2017年01月23日 04点01分
level 13
其实这些算法已经有Nuget包实现。
_
2017年01月25日 04点01分 6
谢谢,回头找来看看
2017年01月25日 05点01分
回复 rzfc : 我之前参加数学建模比赛用的是MathNet _
2017年01月25日 05点01分
@Nukepayload2 查了一下,很不错。
2017年01月25日 05点01分
level 9
然后求方程组啊,然后先matlab做的真好。
2017年01月30日 17点01分 18
1