# EigenvectorEigenValues - Debug

The code in module 2 of attached sheet contains a function PORT_FACTOR_EIGEN_VALUES_VECTORS_JACOBI_FUNC, which essentially is supposed to return the eigenvectors and eigenvalues of a matrix (based on the so-called Jacobi method, for what its worth).

However, it seems that the code gets stuck & throws up an error message...

The issue seems to be in the following code segment: ROTATION_ARR(3), which gives a ‘type mismatch’ error
(NB: By default (variable ‘output’ = 0), the code jumps straight to the 2nd pass (1983)).

Understand that its not necessarily an easy one, but any help would be greatly appreciated

Cheers

A_ROTATION_LINE: 'Returns vector containing the row and column vectors and
'the angle of rotation for the P matrix
'------------------------------------------------------------------------------------------------
ReDim TEMP_MATRIX(1 To NSIZE, 1 To NSIZE)
MAX_VAL = -1
ii = -1
jj = -1
For i = 1 To NSIZE
For j = i + 1 To NSIZE
TEMP_MATRIX(i, j) = Abs(DATA_MATRIX(i, j))
If TEMP_MATRIX(i, j) > MAX_VAL Then
MAX_VAL = TEMP_MATRIX(i, j)
ii = i
jj = j
End If
Next j
Next i
If DATA_MATRIX(ii, ii) = DATA_MATRIX(jj, jj) Then
RAD_VAL = 0.25 * PI_VAL * Sgn(DATA_MATRIX(ii, jj))
Else
RAD_VAL = 0.5 * Atn(2 * DATA_MATRIX(ii, jj) / (DATA_MATRIX(ii, ii) - DATA_MATRIX(jj, jj)))
End If
'------------------------------------------------------------------------------------------------
Return
'------------------------------------------------------------------------------------------------

'------------------------------------------------------------------------------------------------
R_ROTATION_LINE:
'Returns the rotation PTHIS_MATRIX matrix
'------------------------------------------------------------------------------------------------
ReDim PTHIS_MATRIX(1 To NSIZE, 1 To NSIZE)
For i = 1 To NSIZE: PTHIS_MATRIX(i, i) = 1: Next i 'Identity Matrix
PTHIS_MATRIX(ROTATION_ARR(1), ROTATION_ARR(1)) = Cos(ROTATION_ARR(3))
PTHIS_MATRIX(ROTATION_ARR(2), ROTATION_ARR(1)) = Sin(ROTATION_ARR(3))
PTHIS_MATRIX(ROTATION_ARR(1), ROTATION_ARR(2)) = -Sin(ROTATION_ARR(3))
PTHIS_MATRIX(ROTATION_ARR(2), ROTATION_ARR(2)) = Cos(ROTATION_ARR(3))
'------------------------------------------------------------------------------------------------
Return
'-----------------------------------------
EigenVektorValues.xlsm
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Author Commented:
Hello;

thank you for your comment, well appreciated. I can assure you that none of my questions is a 'homework' question, or related to an academic setting. Rather, two of them center around methods intended for historical data analysis (PCA, Eigendecomposition), whereas the others around Least-squares, an application for generating hedging for a financial risk portfolio
0
Commented:
Hi,

it's not necessary to understand all the theory behind the function itself (I do not understand that, a lot to theroretically for me, I'm a programmer, no math specialist).

Simply looking at your code as programmer offers a lot of issues. First, the problem itself comes from a "subscript out of range" error which is thrown in the mentioned row. The "type mismatch" error is a follow-up error which comes from the fact that your function returns the error code number in case of an error in the function and a number variable is no array, that's why the calling "test" sub throws an error on this line:

``````For iSubA = 1 To UBound(arrSubA, 1)
``````

because the returned Variant/Long value is no array and "UBound" expects the name of an array variable.

So the original error is "subscript out of range" which comes from the line:

``````PTHIS_MATRIX(ROTATION_ARR(1), ROTATION_ARR(1)) = Cos(ROTATION_ARR(3))
``````

simply because "ROTATION_ARR" consists of the elements 0 to 2, there is no 3 and that's the reason of the error.

That's the reason and I'm sure you can solve that now, but as mentioned above, there are lots of other problems with your code:

Please add an "Option Explicit" at the beginning of each module (always do that anytime in any module in the future, let VBA do that for you by opening the Options menu ("Tools/Options") and check the "require variable declaration" checkmark in the "Editor" tab.
Now start "Debug" - "Compile" and do that regularly before executing any code. If that works without a problem it's the first step in writing better code because it makes the code a little bit faster (as it is compiled after that procedure) and it also checks your code for any basic errors. In your case you'll see that it will throw a lot of errors, two are a lot not declared variables and the sub "test" is available in more than one module so trying to call that without the module name means the first found is executed. You should always avoid to have the same name twice, especially in one module as this can also lead to a complete VBA crash.
You used "Gosub/Return" in your function. Please forget about that command as this is only available for compatibility reason to older BASIC dialects. Whenever you need a subprocedure, use a sub or function with parameters for that purpose.
Please use a readable indentation. That avoids errors in structures as you can find errors in constructs simply by looking at the code structure. Here is a free tool which do the work for you with one click, available as VBA add-in: Smart Indenter
Variant variables are easy to use as they can contain any type of variable and they can even change their type at any time. But be extremly careful especially because of this feature as you always have to check what's in the variable (especially that was the reason for your error as you expect an array as returned by your function but you also return the Err.Number in case of an error). It's better to use variants only if there is really no other way, also because they use at least 16 byte of memory each. It's better to declare the variables of the right type then you can always be sure about the contents. That's also true for any return value of a function, always explicitly declare a function's return type to be sure what you get in the calling procedure.
I recommend to use the add-in MZ-Tools (also free) which allows you for example to easily insert an error handling. An error handling should always end with a "Resume" command. If you want to let the calling procedure handle your errors, don't return the error number as the function's return value, simply leave out the error handling and add an error handler to the calling procedure. On this way you would have seen the "subscript out of range" error in the calling procedure (or with a correct error handling in the function itself).
A last recommendation: It seems as you are a German like me, here is a link to a German tool which basically checks your code for errors and offers recommendations for better code (not all meaningful, but it helps): Team Moeller VBA Inspector (also free). It can also be run in English language if you want. It forces to compile the code before it is able to run the check.

Cheers,

Christian
0

Experts Exchange Solution brought to you by