Dear Statalist members,
I'm using Stata 19MP on Windows and am looking for efficient routines to accelerate the computation of eigenvectors and eigenvalues for a symmetric matrix with all diagonal entries equal to 1. According to help mf_eigensystemselect##intro,
Contrary to expectations, eigensystemselect() appears to be significantly slower than eigensystem(). I am wondering whether I may have used eigensystemselect() incorrectly.
As shown in the following examples, eigensystemselect() is approximately twice as slow as eigensystem() for a 1000-by-1000 symmetric matrix, regardless of whether one or two processors are used, whether eigensystemselectr() or eigensystemselecti() is called, and whether eigenvalues are supplied to eigensystemselect() or not.
I also ran this example by Stata 17SE on the same machine, and the results were mixed. On one hand, eigensystemselect() is indeed faster than eigensystem(); on the other hand, eigensystemselect() runs faster on Stata 17SE than Stata 19MP. Additionally, it seems that eigensystem() was improved by Stata 19, whereas eigensystemselect() has gotten worse compared to Stata 17SE, which makes me even more uncertain whether I am using eigensystemselect() correctly.
Lastly, besides eigensystem() and eigensystemselect(), are there any faster methods to compute eigenvalues that are larger than sqrt(epsilon(1)) and their corresponding eigenvectors for a symmetric matrix with all diagonal entries equal to 1?
Thank you very much!
I'm using Stata 19MP on Windows and am looking for efficient routines to accelerate the computation of eigenvectors and eigenvalues for a symmetric matrix with all diagonal entries equal to 1. According to help mf_eigensystemselect##intro,
These routines [i.e., eigensystemselect()] compute subsets of the available eigenvectors. This computation can be much faster than computing all the eigenvectors [by eigensystem()].
As shown in the following examples, eigensystemselect() is approximately twice as slow as eigensystem() for a 1000-by-1000 symmetric matrix, regardless of whether one or two processors are used, whether eigensystemselectr() or eigensystemselecti() is called, and whether eigenvalues are supplied to eigensystemselect() or not.
Code:
clear all mata: rseed(1) n =1000 M =runiform(n,1,-5,5) M =makesymmetric(exp(-(rowsum(M:^2) :-2*M*M' :+rowsum(M:^2)'))) e =sqrt(epsilon(1)) end set processors 2 mata: timer_clear() timer_on(1); symeigensystem(M, V0=., L0=.) i =selectindex(L0:>=e); L1 =L0[ i] V1 =V0[,i] timer_off(1) timer_on(2); symeigensystemselectr(M, (e,.) , V2=., L2=. ); timer_off(2) timer_on(3); symeigensystemselecti(M, minmax(i), V3=., L3=. ); timer_off(3) timer_on(4); symeigensystemselectr(M, (e,.) , V4=., L4=L0); timer_off(4) //eigenvalues are supplied timer_on(5); symeigensystemselecti(M, minmax(i), V5=., L5=L0); timer_off(5) //eigenvalues are supplied timer() end --------------------------------------------------------------------------- timer report 1. .155 / 1 = .155 2. .423 / 1 = .423 3. .419 / 1 = .419 4. .421 / 1 = .421 5. .418 / 1 = .418 --------------------------------------------------------------------------- set processors 1 mata: timer_clear() timer_on(1); symeigensystem(M, V0=., L0=.) i =selectindex(L0:>=e); L1 =L0[ i] V1 =V0[,i] timer_off(1) timer_on(2); symeigensystemselectr(M, (e,.) , V2=., L2=. ); timer_off(2) timer_on(3); symeigensystemselecti(M, minmax(i), V3=., L3=. ); timer_off(3) timer_on(4); symeigensystemselectr(M, (e,.) , V4=., L4=L0); timer_off(4) //eigenvalues are supplied timer_on(5); symeigensystemselecti(M, minmax(i), V5=., L5=L0); timer_off(5) //eigenvalues are supplied timer() end --------------------------------------------------------------------------- timer report 1. .196 / 1 = .196 2. .415 / 1 = .415 3. .409 / 1 = .409 4. .418 / 1 = .418 5. .409 / 1 = .409 ---------------------------------------------------------------------------
I also ran this example by Stata 17SE on the same machine, and the results were mixed. On one hand, eigensystemselect() is indeed faster than eigensystem(); on the other hand, eigensystemselect() runs faster on Stata 17SE than Stata 19MP. Additionally, it seems that eigensystem() was improved by Stata 19, whereas eigensystemselect() has gotten worse compared to Stata 17SE, which makes me even more uncertain whether I am using eigensystemselect() correctly.
Code:
clear all mata: rseed(1) n =1000 M =runiform(n,1,-5,5) M =makesymmetric(exp(-(rowsum(M:^2) :-2*M*M' :+rowsum(M:^2)'))) e =sqrt(epsilon(1)) end mata: timer_clear() timer_on(1); symeigensystem(M, V0=., L0=.) i =selectindex(L0:>=e); L1 =L0[ i] V1 =V0[,i] timer_off(1) timer_on(2); symeigensystemselectr(M, (e,.) , V2=., L2=. ); timer_off(2) timer_on(3); symeigensystemselecti(M, minmax(i), V3=., L3=. ); timer_off(3) timer_on(4); symeigensystemselectr(M, (e,.) , V4=., L4=L0); timer_off(4) //eigenvalues are supplied timer_on(5); symeigensystemselecti(M, minmax(i), V5=., L5=L0); timer_off(5) //eigenvalues are supplied timer() end --------------------------------------------------------------------------- timer report 1. .338 / 1 = .338 2. .305 / 1 = .305 3. .302 / 1 = .302 4. .307 / 1 = .307 5. .304 / 1 = .304 ---------------------------------------------------------------------------
Lastly, besides eigensystem() and eigensystemselect(), are there any faster methods to compute eigenvalues that are larger than sqrt(epsilon(1)) and their corresponding eigenvectors for a symmetric matrix with all diagonal entries equal to 1?
Thank you very much!

Comment