Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 130
  • Last Modified:

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
 ROTATION_ARR = Array(ii, jj, RAD_VAL)
'------------------------------------------------------------------------------------------------
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
0
Michael Hamacher
Asked:
Michael Hamacher
  • 2
  • 2
1 Solution
 
Michael HamacherAuthor 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
 
BitsqueezerCommented:
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)

Open in new window


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))

Open in new window


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
 
Michael HamacherAuthor Commented:
Vielen Dank!
0
 
BitsqueezerCommented:
Gern geschehen...:-)
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now