I have to shrink values in the variance-covariance matrix towards the variance (diagonal values in matrix) by a shrinkage factor (lambda), so: lambda*shrinkagematrix+(1-lambda)*variancecovariancematrix, where:
Variance covariance matrix is:
Function VarCovar(rng As Range) As Variant
Dim i As Integer
Dim j As Integer
Dim numcols As Integer
numcols = rng.Columns.Count
numrows = rng.Rows.Count
Dim matrix() As Double
ReDim matrix(numcols - 1, numcols - 1)
For i = 1 To numcols
For j = 1 To numcols
matrix(i - 1, j - 1) = Application.WorksheetFunction.Covar(rng.Columns(i), rng.Columns(j)) * numrows / (numrows - 1)
Next j
Next i
VarCovar = matrix
, this gives me a matrix that looks for example like this:
0.40 -0.10 0.11
-0.10 0.17 -0.03
0.11 -0.03 0.19
Then I have trouble creating the Shrinkage matrix which should look like:
0.40 0.00 0.00
0.00 0.17 0.00
0.00 0.00 0.19
i.e returning ONLY diagonal values (= variances of the variables) and zero in all other cells.
So in some kind of way, making it return a matrix containing only the values for when row=column number, i.e. (1,1), (2,2) and (3,3) values.
Anyone that can help with this?
You need only one loop that counts from i = 1 to 3
to fill Matrix(1, 1)
, Matrix(2, 2)
and Matrix(3, 3)
using Matrix(i, i)
Function VarCovar(InputMatix As Range) As Variant
Dim MatrixColumns As Long
MatrixColumns = InputMatix.Columns.Count
Dim MatrixRows As Long
MatrixRows = InputMatix.Rows.Count
Dim Matrix() As Double
ReDim Matrix(1 To MatrixColumns, 1 To MatrixColumns)
Dim i As Long
For i = 1 To MatrixColumns
Matrix(i, i) = Application.WorksheetFunction.Covar(InputMatix.Columns(i), InputMatix.Columns(i)) * MatrixRows / (MatrixRows - 1)
Next i
VarCovar = Matrix
End Function
Note that I changed the Matrix
dimenstions Matrix(1 To MatrixDimension, 1 To MatrixDimension)
to start with 1
and not 0
so you can easily use it to write it to cells:
Sub test()
Range("A5:C7").Value = VarCovar(Range("A1:C3"))
End Sub