Sunteți pe pagina 1din 15

Option Explicit

Private Sub cmdEnd_Click()


End
End Sub
Private Sub cmdGaussian_Click()
'***************************************************************************
'This subroutine calls GaussianElimination(3) to solve Ax = b.
'***************************************************************************
Call GaussianElimination(3)
End Sub
'===========================================================================
Private Sub cmdInverse_Click()
'***************************************************************************
'This subroutine calls GaussianElimination(1) to obtain A^(-1).
'***************************************************************************
Call GaussianElimination(1)
End Sub
'===========================================================================
Private Sub cmdDeterminant_Click()
'***************************************************************************
'This calls GaussianElimination(2) to obtain det(A).
'***************************************************************************
Call GaussianElimination(2)
End Sub
'===========================================================================
Private Sub GaussianElimination(index As Integer)
'*****************************************************************************
' This subroutine calculates the matrix X with values X = [x1 x2.. xnB]
' where the xi's are the right-hand side vectors of the matrix equations
' A*x1 = b1; A*x2 = b2; ...; A*xnB = bnB.
' The subroutine uses Gaussian elimination, and can be used to calculate
' a matrix inverse too.
' The particular operation performed by the subroutine depends on the value
' of the parameter "index", as follows:
' index = 1 --> inverse
' index = 2 --> determinant
' index = 3 --> linear system solution
'*****************************************************************************
'
'Declaration of variables
Dim matrixA As String, matrixB As String
Dim A(1 To 10, 1 To 20) As Double
Dim B(1 To 10, 1 To 10) As Double
Dim x(1 To 10, 1 To 10) As Double
Dim xR(1 To 10, 1 To 10) As Double
Dim aMax(1 To 10), S(1 To 10)
Dim detA As Double, factor As Double
Dim Order(1 To 10) As Integer, Otemp As Integer
Dim Sum As Double, epsilon As Double
Dim nA As Integer, mA As Integer
Dim nB As Integer, mB As Integer
Dim i As Integer, j As Integer, k As Integer
Dim nExchanges As Integer
Dim scaleFlag As Boolean
'

picOutput.Cls
epsilon = 0.00001
factor = 20#
'
'Read matrix A for input as a string
matrixA = txtMatrixA
'
'Extract the matrix rows and individual elements using subroutine ExtractMatrix
'Then print the matrix in the output field to confirm matrix entry
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
'Making sure matrix A is a square matrix
If nA <> mA Then
picOutput.Print "Matrix A must be a square matrix to calculate";
If index = 1 Then
picOutput.Print " the inverse matrix."
ElseIf index = 2 Then
picOutput.Print " the determinant."
Else
picOutput.Print " x from A*x = B."
End If
Exit Sub
End If
'
'Read Matrix B if needed, otherwise load identity matrix
If index = 1 Or index = 2 Then
If index = 1 Then
nB = nA: mB = mA
Else
nB = nA: mB = 1
End If
For i = 1 To nA
For j = 1 To mB
If i = j Then
B(i, j) = 1#
Else
B(i, j) = 0#
End If
Next j
Next i
Else
matrixB = txtMatrixB
Call ExtractMatrix(matrixB, B, nB, mB)
Call PrintMatrixB(B, nB, mB)
End If
' Check that matrices are compatible
If nA <> nB Then
picOutput.Cls
picOutput.Print "Matrices A and B must have the same number of"
picOutput.Print "rows in order to solve for the linear system Ax=B."
Exit Sub
End If
'Create the Order vector and load default values of aMax(i)
For i = 1 To nA
Order(i) = i
aMax(i) = 1#
Next i

'Augmenting Matrix A
For i = 1 To nA
For j = 1 To mB
A(i, j + nA) = B(i, j)
Next j
Next i
'Scaling
For i = 1 To nA
S(i) = 0#
For j = 1 To nA
S(i) = S(i) + Abs(A(i, j))
Next j
Next i
scaleFlag = False
For i = 1 To (nA - 1)
For j = (i + 1) To (nA + mB)
If S(i) > factor * S(j) Or S(j) > factor * S(i) Then
scaleFlag = True
End If
Next j
Next i
If scaleFlag Then
For i = 1 To nA
aMax(i) = 0.0000000001
For j = 1 To (nA + mB)
If (A(i, j) > aMax(i)) Then
aMax(i) = A(i, j)
End If
Next j
Next i
For i = 1 To nA
For j = 1 To (nA + mB)
A(i, j) = A(i, j) / aMax(i)
Next j
Next i
End If
'Elimination procedure applied to rows 2 to n to fill with
'zeros lower triangular part of matrix
nExchanges = 0
For k = 1 To (nA - 1)
'Pivoting implemented in the next If statement
For i = (k + 1) To nA
If Abs(A(Order(i), k)) > Abs(A(Order(k), k)) Then
nExchanges = nExchanges + 1
Otemp = Order(i)
Order(i) = Order(k)
Order(k) = Otemp
End If
Next i
For i = (k + 1) To nA
For j = (k + 1) To (nA + mB)
A(Order(i), j) = A(Order(i), j) - A(Order(i), k) * A(Order(k), j

) / A(Order(k), k)
Next j
Next i
Next k
'Calculate and print determinant
detA = 1#
For i = 1 To nA
detA = detA * A(Order(i), i) * aMax(i)
Next i
detA = (-1) ^ nExchanges * detA
If index = 2 Then
picOutput.Cls
picOutput.Print
picOutput.Print "Determinant of matrix A = ", detA
Exit Sub
End If
'If the determinant is small, then the matrix is singular
If Abs(detA) < epsilon Then
picOutput.Print "Matrix is singular."
If index = 3 Then
picOutput.Print " No solution is possible."
ElseIf index = 1 Then
picOutput.Print " Inverse does not exist."
End If
Exit Sub
End If
'Calculating solutions
For j = 1 To mB
x(Order(nA), j) = A(Order(nA), j + nA) / A(Order(nA), nA)
For i = (nA - 1) To 1 Step -1
Sum = 0#
For k = (i + 1) To nA
Sum = Sum + A(Order(i), k) * x(Order(k), j)
Next k
x(Order(i), j) = (A(Order(i), j + nA) - Sum) / A(Order(i), i)
Next i
Next j
'Print result in output field
picOutput.Cls
picOutput.Print
If index = 1 Or index = 3 Then
If index = 1 Then
picOutput.Print "Inverse of Matrix A:"
ElseIf index = 3 Then
picOutput.Print "Solution to the linear system: A*x = B. ------> x
:"
End If
For i = 1 To nA
For j = 1 To mB
picOutput.Print x(Order(i), j),
Next j
picOutput.Print
Next i
End If

End Sub
'===========================================================================
Private Sub cmdInfo_Click()
'***************************************************************************
'This subroutine puts together a message showing the way to enter the matrix
'elements into the input field, and shows that message using a message box
'***************************************************************************
Dim myMessage As String
myMessage = "Enter a matrix by using brackets to separate each row."
myMessage = myMessage & " Elements within a row are separated by blank space
s only."
myMessage = myMessage & " You can enter the entire matrix in a single line:
"
myMessage = myMessage & " [[a11 a12 ... a1m] [a21 a22 ... a2m] ... [an1 an2
... anm]] <return>"
myMessage = myMessage & " or using one line per row:
"
myMessage = myMessage & " [[a11 a12 ... a1m] <return>"
myMessage = myMessage & " [a21 a22 ... a2m] <return>"
myMessage = myMessage & "
. .
. "
myMessage = myMessage & "
[an1 an2 ... anm]] <return>"
MsgBox myMessage
End Sub
'===========================================================================
Private Sub cmdClearOutputField_Click()
'***************************************************************************
'This subroutine simple clears the output field
'***************************************************************************
picOutput.Cls
picMatrixA.Cls
picMatrixB.Cls
End Sub
'===========================================================================
Private Sub cmdFrobenius_Click()
'***************************************************************************
'This subroutine reads a Double matrix, A, and calculates its Frobenius norm,
'which is the square root of the sum of squares of all the matrix elements.
'***************************************************************************
'Declaration of variables
Dim matrixA As String
Dim A(1 To 10, 1 To 10) As Double
Dim norm As Double
Dim nA As Integer, mA As Integer
Dim i As Integer, j As Integer
'
'Read matrix input as a string
matrixA = txtMatrixA
'
'Extract the matrix rows and individual elements using subroutine ExtractMatrix
'Then print the matrix in the output field to confirm matrix entry
Call ExtractMatrix(matrixA, A, nA, mA)

Call PrintMatrixA(A, nA, mA)


'The following lines calculate the Frobenius norm
norm = 0#
For i = 1 To nA
For j = 1 To mA
norm = norm + A(i, j) ^ 2
Next j
Next i
norm = Sqr(norm)
'
'Print results of calculation in the output field
picOutput.Cls
picOutput.Print
picOutput.Print "Frobenius norm of matrix A = "; norm
End Sub
'===========================================================================
Private Sub cmdMultiplyScalar_Click()
'***************************************************************************
'This subroutine calculates the multiplication of Matrix A with a scalar c
'***************************************************************************
'
'Declaration of variables
Dim matrixA As String
Dim A(1 To 10, 1 To 10) As Double
Dim cA(1 To 10, 1 To 10) As Double
Dim C As Double
Dim nA As Integer, mA As Integer
Dim i As Integer, j As Integer
'
'Read matrix as a string
matrixA = txtMatrixA
'
'Extract rows and elements from matrix A using subroutine ExtractMatrix
'Then print the input matrix in the appropriate field
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
'
'Request value of the scalar, c, through an Input Box
C = InputBox("Enter scalar value = ")
'
'Multiply all elements of the matrix by c
For i = 1 To nA
For j = 1 To mA
cA(i, j) = C * A(i, j)
Next j
Next i
'
'Print result in output field
picOutput.Cls
picOutput.Print
picOutput.Print "Matrix A multiplied by a constant c = "; C
Call PrintMatrix(cA, nA, mA)
End Sub
'===========================================================================

Private Sub PrintMatrixA(Matrix() As Double, n As Integer, m As Integer)


'***************************************************************************
'This subroutine prints matrix A
'***************************************************************************
Dim i As Integer, j As Integer
picMatrixA.Cls
For i = 1 To n
For j = 1 To m
picMatrixA.Print Matrix(i, j); " ";
Next j
picMatrixA.Print
Next i
End Sub
'===========================================================================
Private Sub PrintMatrixB(Matrix() As Double, n As Integer, m As Integer)
'***************************************************************************
'This subroutine prints matrix B, if available
'***************************************************************************
Dim i As Integer, j As Integer
picMatrixB.Cls
For i = 1 To n
For j = 1 To m
picMatrixB.Print Matrix(i, j); " ";
Next j
picMatrixB.Print
Next i
End Sub
'===========================================================================
Private Sub cmdTrace_Click()
'***************************************************************************
'This subroutine reads a Double square matrix, A, and calculates its trace,
'which is the sum of the elements in the main diagonal.
'***************************************************************************
'Declaration of variables
Dim matrixA As String
Dim A(1 To 10, 1 To 10) As Double
Dim trace As Double
Dim nA As Integer, mA As Integer
Dim i As Integer, j As Integer
'
'Read matrix as a string
matrixA = txtMatrixA
'
'Extract rows and elements from matrix A using subroutine ExtractMatrix
'Then print the input matrix in the appropriate field
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
'
'Check if the matrix is square, if not send warning and exit subroutine
If mA <> nA Then
picOutput.Cls

picOutput.Print "Trace can only be calculated for square matrices."


Exit Sub
End If
'
'Calculation of the trace
trace = 0#
For i = 1 To nA
trace = trace + A(i, i)
Next i
'
'Print result in output field
picOutput.Cls
picOutput.Print
picOutput.Print "Trace of matrix A = "; trace
End Sub
'===========================================================================
Private Sub cmdTranspose_Click()
'***************************************************************************
'This subroutine reads a Double square matrix, A, and calculates its trace,
'which is the sum of the elements in the main diagonal.
'***************************************************************************
'Declaration of variables
Dim matrixA As String
Dim A(1 To 10, 1 To 10) As Double
Dim AT(1 To 10, 1 To 10) As Double
Dim trace As Double
Dim nA As Integer, mA As Integer
Dim i As Integer, j As Integer
'
'Read matrix as a string
matrixA = txtMatrixA
'
'Extract rows and elements from matrix A using subroutine ExtractMatrix
'Then print the input matrix in the appropriate field
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
'
'Produce transpose
For i = 1 To nA
For j = 1 To mA
AT(j, i) = A(i, j)
Next j
Next i
'
'Print results in output field
picOutput.Cls
Call PrintMatrix(AT, mA, nA)
End Sub
'===========================================================================
Private Sub cmdAddAB_Click()
Dim index As Boolean
index = True
Call AddOrSubtract(index)
End Sub
'===========================================================================

Private Sub cmdSubtractAB_Click()


Dim index As Boolean
index = False
Call AddOrSubtract(index)
End Sub
'***************************************************************************
Private Sub AddOrSubtract(index As Boolean)
'*****************************************************************************
' This subroutine adds two matrices A and B
' If index = True, then perform addition.
' If index = False, then perform subtraction.
'*****************************************************************************
'
'Declaration of variables
Dim matrixA As String, matrixB As String
Dim A(1 To 10, 1 To 10) As Double
Dim B(1 To 10, 1 To 10) As Double
Dim C(1 To 10, 1 To 10) As Double
Dim nA As Integer, mA As Integer
Dim nB As Integer, mB As Integer
Dim i As Integer, j As Integer
'
'Read matrices A and B for input as a string
matrixA = txtMatrixA
matrixB = txtMatrixB
'
'Extract the matrix rows and individual elements using subroutine ExtractMatrix
'Then print the matrix in the output field to confirm matrix entry
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
Call ExtractMatrix(matrixB, B, nB, mB)
Call PrintMatrixB(B, nB, mB)
'
' Check that matrices are compatible
If nA <> nB Or mA <> mB Then
picOutput.Cls
picOutput.Print "Matrices A and B are not compatible for addition"
picOutput.Print "or subtraction."
Exit Sub
End If
'Calculate sum/subtraction of matrices
For i = 1 To nA
For j = 1 To mA
If index Then
C(i, j) = A(i, j) + B(i, j)
Else
C(i, j) = A(i, j) - B(i, j)
End If
Next j
Next i
'
'Print result in output field
picOutput.Cls
picOutput.Print
If index Then
picOutput.Print "Matrix C = A + B:"

Else
picOutput.Print "Matrix C = A - B:"
End If
Call PrintMatrix(C, nA, mA)
End Sub
'===========================================================================
Private Sub cmdMultiplyAB_Click()
Dim index As Boolean
index = True
Call MultiplyTwoMatrices(index)
End Sub
'===========================================================================
Private Sub cmdMultiplyBA_Click()
Dim index As Boolean
index = False
Call MultiplyTwoMatrices(index)
End Sub
'===========================================================================
Private Sub MultiplyTwoMatrices(index As Boolean)
'*****************************************************************************
' This subroutine adds two matrices A and B
' If index = True, then calculate A * B.
' If index = False, then calculate B * A.
'*****************************************************************************
'
'Declaration of variables
Dim matrixA As String, matrixB As String
Dim A(1 To 10, 1 To 10) As Double
Dim B(1 To 10, 1 To 10) As Double
Dim C(1 To 10, 1 To 10) As Double
Dim nA As Integer, mA As Integer
Dim nB As Integer, mB As Integer
Dim i As Integer, j As Integer, k As Integer
'
'Read matrices A and B for input as a string
matrixA = txtMatrixA
matrixB = txtMatrixB
'
'Extract the matrix rows and individual elements using subroutine ExtractMatrix
'Then print the matrix in the output field to confirm matrix entry
Call ExtractMatrix(matrixA, A, nA, mA)
Call PrintMatrixA(A, nA, mA)
Call ExtractMatrix(matrixB, B, nB, mB)
Call PrintMatrixB(B, nB, mB)
'
' Check that matrices are compatible
If index Then
If mA <> nB Then
picOutput.Cls
picOutput.Print "Matrices A and B are not compatible for"
picOutput.Print "multiplication A*B."
Exit Sub
End If
Else
If mB <> nA Then
picOutput.Cls

picOutput.Print "Matrices A and B are not compatible for"


picOutput.Print "multiplication B*A."
Exit Sub
End If
End If
'Calculate multiplication of matrices
If index Then
For i = 1 To nA
For j = 1 To mB
C(i, j) = 0#
For k = 1 To mA
C(i, j) = C(i, j)
Next k
Next j
Next i
Else
For i = 1 To nB
For j = 1 To mA
C(i, j) = 0#
For k = 1 To mB
C(i, j) = C(i, j)
Next k
Next j
Next i
End If
'
'Print result in output field
picOutput.Cls
picOutput.Print
If index Then
picOutput.Print "Matrix C = A
Call PrintMatrix(C, nA, mB)
Else
picOutput.Print "Matrix C = B
Call PrintMatrix(C, nB, mA)
End If

+ A(i, k) * B(k, j)

+ B(i, k) * A(k, j)

* B:"
* A:"

End Sub
'===========================================================================
Private Sub ExtractMatrix(MatrixString As String, m() As Double, _
nRows As Integer, nColumns As Integer)
'***************************************************************************
'
'This subroutine reads a matrix when entered in the form:
'
' [[a11 a12 ... a1m] [a21 a22 ... a2m] ... [an1 an2 ... anm]].
'
'The subroutine takes the input from a text box called "txtInput",
'which should haveits "multi-line" property modified to "True".
'
'The subroutine locates the position of brackets,
'determines if the brackets are paired or if the expression is empty,
'and separates the elements of the matrix into a set of real numbers.
'
'The subroutine can be called from any other subroutine, by using:
'
'
Call ReadMatrix(M(),nRows,nColumns)
'
'It will return the matrix, M(i,j) As Double, the number of rows, nRows As

'Integer, and the number of columns, nColumns As Integer.


'
'Any output produced by this subroutine (mainly error messages) is
'printed to a picture box called "picOutput".
'
'This subroutine works together with subroutines DecomposeRow and
'GetValueAndTrim. Make sure you have the three of them in your project.
'
'To provide information to the user, you can create an INFO button and
'include the subroutine cmdInfo_Click()
'*************************************************************************
'
'Variable declarations
Dim MatrixStringLength As Integer
Dim OpeningBracketCount As Integer
Dim ClosingBracketCount As Integer
Dim IndexOfOpeningBracket(1 To 12) As Integer
Dim IndexOfClosingBracket(1 To 12) As Integer
Dim MatrixRow(1 To 10) As String
Dim k As Integer, j As Integer, i As Integer
Dim nCols(1 To 10) As Integer
Dim startChar As Integer, endChar As Integer, lengthChar As Integer
Dim minNCols As Integer, maxNCols As Integer
Dim CheckStatement As Boolean
Dim RowValues(1 To 10) As Variant
'Checks if the matrix string is empty
If MatrixString = "" Then
picOutput.Cls
picOutput.Print "Matrix is empty."
Exit Sub
End If
'Determines the number and locations of opening and closing brackets
MatrixStringLength = Len(MatrixString)
OpeningBracketCount = 0
ClosingBracketCount = 0
For k = 1 To MatrixStringLength
If Mid(MatrixString, k, 1) = "[" Then
OpeningBracketCount = OpeningBracketCount + 1
IndexOfOpeningBracket(OpeningBracketCount) = k
ElseIf Mid(MatrixString, k, 1) = "]" Then
ClosingBracketCount = ClosingBracketCount + 1
IndexOfClosingBracket(ClosingBracketCount) = k
End If
Next k
'Checks if the number of brackets is not balanced
CheckStatement = OpeningBracketCount = 0 Or ClosingBracketCount = 0
CheckStatement = CheckStatement Or OpeningBracketCount <> ClosingBracketCoun
t
If CheckStatement Then
picOutput.Cls
picOutput.Print "Opening or closing brackets missing."
Exit Sub
Else
nRows = OpeningBracketCount - 1
End If

'Separate the Matrix String into Row Strings


For k = 1 To nRows
startChar = IndexOfOpeningBracket(k + 1) + 1
endChar = IndexOfClosingBracket(k) - 1
lengthChar = endChar - startChar + 1
MatrixRow(k) = Trim(Mid(MatrixString, startChar, lengthChar))
Next k
'Decompose each row into elements by using the subroutine "DecomposeRow"
For i = 1 To nRows
Call DecomposeRow(MatrixRow(i), RowValues(), nCols(i))
For j = 1 To nCols(i)
m(i, j) = RowValues(j)
Next j
Next i
'Check if the number of columns is the same for each row
maxNCols = 0
minNCols = 1000
For i = 1 To nRows
If nCols(i) > maxNCols Then
maxNCols = nCols(i)
End If
If nCols(i) < minNCols Then
minNCols = nCols(i)
End If
Next i
If maxNCols <> minNCols Then
picOutput.Cls
picOutput.Print "The number of columns is not consistent."
picOutput.Print "Check your input to ensure that all rows"
picOutput.Print "have the same number of columns."
picOutput.Print
Exit Sub
Else
nColumns = maxNCols
End If
End Sub
'===========================================================================
Private Sub DecomposeRow(myRow As String, myRowValues() As Variant, _
numberOfElements As Integer)
'*****************************************************************************'
' This subroutine takes a string, "myRow", representing a row from a matrix
' and recovers all the values listed in the row. The values must be separated
' by blank spaces.
'******************************************************************************
Dim checkFlag As Boolean
Dim i As Integer
checkFlag = True
numberOfElements = 0
Do While checkFlag = True

numberOfElements = numberOfElements + 1
Call GetValueAndTrim(myRow, myRowValues(numberOfElements), checkFlag)
Loop
numberOfElements = numberOfElements - 1
End Sub
'===========================================================================
Private Sub GetValueAndTrim(myString As String, myValue As Variant, _
myFlag As Boolean)
'*************************************************************************
'This subroutine takes the string "myString" made of a series of numbers
'separated by spaces and assigns the value of the first number to the
'variant variable "myValue". Then, the subroutine trims the first number
'off the original string and replaces the trimmed string into "myString."
'If a value is recovered then the boolean flag variable "myFlag" is set as
'True. If the input string "myString" is empty, then the boolean flag
'variable "myFlag" is set to false.
'**************************************************************************
Dim
Dim
Dim
Dim
Dim
Dim

myStringLength As Integer
myValueStringLength As Integer
charactersToTheRight As Integer
i As Integer, j As Integer
startChar As Integer, endChar As Integer
leftOverChars As Integer

myString = Trim(myString)
If myString <> "" Then
myFlag = True
myStringLength = Len(myString)
If myStringLength = 1 Then
myValue = Val(myString)
myString = ""
Else
For i = 1 To myStringLength
If Mid(myString, i, 1) <> " " Then
startChar = i
Exit For
End If
Next i
endChar = myStringLength
For j = startChar To myStringLength
If Mid(myString, j, 1) = " " Then
endChar = j - 1
Exit For
End If
Next j
myValueStringLength = endChar - startChar + 1
myValue = Val(Mid(myString, startChar, myValueStringLength))
leftOverChars = myStringLength - myValueStringLength
myString = Right(myString, leftOverChars)
End If
Else
myFlag = False
End If

End Sub
'===========================================================================
Private Sub PrintMatrix(Matrix() As Double, n As Integer, m As Integer)
'*************************************************************************
' This subroutine prints a Matrix
'**************************************************************************
Dim i As Integer, j As Integer
picOutput.Print "Matrix has "; n; " rows and "; m; " columns:"
picOutput.Print
For i = 1 To n
For j = 1 To m
picOutput.Print Matrix(i, j),
Next j
picOutput.Print
Next i
End Sub
'===========================================================================
Private Sub Form_Load()
End Sub

S-ar putea să vă placă și