Home » excel » excel – VBA: Summing a matrix

excel – VBA: Summing a matrix

Posted by: admin March 9, 2020 Leave a comment

Questions:

Why doesn’t this function work?

Type =funtest(2.1) in Excel and it’ll give me #VALUE!.

Public Function funtest(a As Double) As Double

Dim z, j, i As Integer
Dim matrix(3, 3, 3) As Double

For z = 0 To 3 Step 1
For j = 0 To 3 Step 1
For i = 0 To 3 Step 1

matrix(z, j, i) = a

Next i, j, z

funtest = Application.WorksheetFunction.Sum(matrix)

End Function
How to&Answers:

WorksheetFunction.Sum will work with either a range or a 2 dimentional array. It errors because you are passing it a 3 dimensional array.

So, this works

Public Function funtest(a As Double) As Double
    Dim z As Long, j As Long, i As Long
    Dim matrix() As Double

    ReDim matrix(0 To 3, 0 To 4)
    For j = LBound(matrix, 1) To UBound(matrix, 1)
    For i = LBound(matrix, 2) To UBound(matrix, 2)
        matrix(j, i) = a
    Next i, j

    funtest = Application.WorksheetFunction.Sum(matrix)
End Function

Note I have modified your declarations slighly, see note at end of answer.

To sum higher dimensional arrays you will need to do some looping.

One option (which may or may not suit your overal requirements) is to declare your array slightly differently, as a so called Jagged Array.

Public Function funtest2(a As Double) As Double
    Dim z As Long, j As Long, i As Long
    Dim matrix() As Variant
    Dim InnerMatrix(0 To 4, 0 To 4) As Double

    ' Dimension Jagged Array
    ReDim matrix(0 To 4)
    For i = LBound(matrix, 1) To UBound(matrix, 1)
        matrix(i) = InnerMatrix
    Next

    'Load Data into matrix
    For z = LBound(matrix) To UBound(matrix)
    For j = LBound(matrix(z), 1) To UBound(matrix(z), 1)
    For i = LBound(matrix(z), 2) To UBound(matrix(z), 2)
        matrix(z)(j, i) = a
    Next i, j, z

    ' Sum matrix
    For z = LBound(matrix) To UBound(matrix)
        funtest2 = funtest2 + Application.WorksheetFunction.Sum(matrix(z))
    Next
End Function

This is an array of 2 dimensional arrays. The Sum is then applied to each of the inner arrays in turn. This way, at least you are only looping one dimension and not all three.

Note on Dim and Integer
You must specify all As Type‘s, otherwise variables default to Variant
In your code z and j will be Variants

Also, using Integer rather than Long is actually counter productive on a 32 bit OS: Long‘s will be slightly faster.

Answer:

I’m going to take you literally when you say “I’m trying to solve the simple case of a (3,3,3) matrix with each element equal to some double, a”. This will do that:

Public Function funtest(a As Double) As Double
   funtest = 4*4*4*a
End Function

Answer:

First, when you get #VALUE! this means there is an error, it can mean using a matrix that is not valid.

To answer your question, your code does not work because your syntax is not correct. The following function creates a matrix from values.

Function FQ_matrix_create(StartValue As Double, Interval As Double,
nrow As Long, ncol As Long) As Double()
Dim M() As Double
' Creates matrix with sequential element values with given row and
' column sizes. Fills matrix row-wise with numbers.
' - set Interval = 0 for constant element values
' - error input arguments nrow and ncol are not positive integers

To SUM the Values use:

Function FQ_matrix_element_sum(M() As Double, SumOption As
MatrixDirection) As Double()
' Returns the sum of elements of matrix M, either row or column wise
' - Rowwise sum returns a horizontal 1xNcol matrix
' - Columnwise sum returns a vertical 1 xNrow matrix
' - Element sum (all elements) returns a 1x1 matrix
' - error if M is not a matrix
' - error if SumOption is not 1 (nRowWiseSum) or 2 (nColWiseSum) or
3 (nElementSum)

To help you understand Matrix in Excel VBA, here is a good resource: http://finaquant.com/download/matrixvectorvba

Specifically, take a look at the PDF Download on the site.