patternModerate
Enter the Matrix
Viewed 0 times
matrixenterthe
Problem
I've semi-often been frustrated at the lack of a proper Matrix data structure in VBA. A multi-dimensional array is obviously the right way to handle it, but there is so much missing... for example, you can't natively check to see if an array has been dimensioned, you can't resize the array while preserving values except on the last dimension, there is no convenient VBA syntax for loading immediate values into the array, etc.
So I created a Matrix class that supports:
The parser was made based on this tutorial on hand coding a recursive descent parser.
The Elementary Row Operations are destructive, because doing otherwise would degrade the performance too much.
The Matrix operations are non-destructive, in that they create a new Matrix with the results and return it. This allows method chaining, such as
I posted an earlier version of the class as an answer to a question here, but have since made some improvements. The test code there is still valid.
I'm particularly intersted to know whether I should split the parser off into a separate class to be used independently, or maybe be called by the Matrix class itself. I've tried to clean up the code naming conventions - PascalCase for the sub/functions and camelCase for the variable names and removing H
So I created a Matrix class that supports:
- Matrix operations -
Add,Subtract,Multiply,ScalarMultiply,Augment,Transpose
- Elementary Row Operations
SwapRows,ScaleRow,AddScalarMultipleRow
- A Parser for loading the Matrix from a String -
LoadMatrixString
- Utility functions -
ToString,Clone
- An implementation of Gaussian Elimination -
RowReduce
The parser was made based on this tutorial on hand coding a recursive descent parser.
The Elementary Row Operations are destructive, because doing otherwise would degrade the performance too much.
The Matrix operations are non-destructive, in that they create a new Matrix with the results and return it. This allows method chaining, such as
Set D = A.Multiply(B).Add(C).ScalarMultiply(5), and the intuitive behavior such that C = A x B and A and B themselves are not modified in the process. I'm tempted to make these methods destructive to improve performance (an object is created for every intermediate matrix operation), but I'm not sure how intuitive it would be that the result of A.Multiply(B) would be A.I posted an earlier version of the class as an answer to a question here, but have since made some improvements. The test code there is still valid.
I'm particularly intersted to know whether I should split the parser off into a separate class to be used independently, or maybe be called by the Matrix class itself. I've tried to clean up the code naming conventions - PascalCase for the sub/functions and camelCase for the variable names and removing H
Solution
This is by no means a full review, but I did notice something. The way you raise errors could use a little work if you're striving for maintainable code.
So, first off, I like that you're correctly adding
The benefits are two fold.
Something like this:
Err.Raise vbObjectError + 1, "Matrix.Add", "Could not Add matrices: the Rows and Columns must be the same. The left matrix is (" & Me.Rows & ", " & Me.Cols & ") and the right matrix is (" & m.Rows & ", " & m.Cols & ")."So, first off, I like that you're correctly adding
vbObjectError to the error number. What I don't like is if I want to add a new error, I have to manually look at the whole file to see if I'm reusing one. This is a great use of an Enum. Public Enum MatrixError
AdditionError = vbObjectError + 1
SomeOtherError
' ...
End EnumThe benefits are two fold.
- It becomes easier to add and use the error number.
- The error numbers get exposed to the client code, so if an error gets raised, I can check the
Err.Numberand handle it appropriately.
Something like this:
ErrHandler:
If Err.Number = AdditionError Then
' do something to handle the matrix error
Else
' throw it upstream
Err.Raise Err.Number
End If
End SubCode Snippets
Err.Raise vbObjectError + 1, "Matrix.Add", "Could not Add matrices: the Rows and Columns must be the same. The left matrix is (" & Me.Rows & ", " & Me.Cols & ") and the right matrix is (" & m.Rows & ", " & m.Cols & ")."Public Enum MatrixError
AdditionError = vbObjectError + 1
SomeOtherError
' ...
End EnumErrHandler:
If Err.Number = AdditionError Then
' do something to handle the matrix error
Else
' throw it upstream
Err.Raise Err.Number
End If
End SubContext
StackExchange Code Review Q#67870, answer score: 13
Revisions (0)
No revisions yet.