summaryrefslogtreecommitdiff
path: root/libm/double/eigens.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/double/eigens.c')
-rw-r--r--libm/double/eigens.c181
1 files changed, 0 insertions, 181 deletions
diff --git a/libm/double/eigens.c b/libm/double/eigens.c
deleted file mode 100644
index 4035e76a1..000000000
--- a/libm/double/eigens.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* eigens.c
- *
- * Eigenvalues and eigenvectors of a real symmetric matrix
- *
- *
- *
- * SYNOPSIS:
- *
- * int n;
- * double A[n*(n+1)/2], EV[n*n], E[n];
- * void eigens( A, EV, E, n );
- *
- *
- *
- * DESCRIPTION:
- *
- * The algorithm is due to J. vonNeumann.
- *
- * A[] is a symmetric matrix stored in lower triangular form.
- * That is, A[ row, column ] = A[ (row*row+row)/2 + column ]
- * or equivalently with row and column interchanged. The
- * indices row and column run from 0 through n-1.
- *
- * EV[] is the output matrix of eigenvectors stored columnwise.
- * That is, the elements of each eigenvector appear in sequential
- * memory order. The jth element of the ith eigenvector is
- * EV[ n*i+j ] = EV[i][j].
- *
- * E[] is the output matrix of eigenvalues. The ith element
- * of E corresponds to the ith eigenvector (the ith row of EV).
- *
- * On output, the matrix A will have been diagonalized and its
- * orginal contents are destroyed.
- *
- * ACCURACY:
- *
- * The error is controlled by an internal parameter called RANGE
- * which is set to 1e-10. After diagonalization, the
- * off-diagonal elements of A will have been reduced by
- * this factor.
- *
- * ERROR MESSAGES:
- *
- * None.
- *
- */
-
-#include <math.h>
-#ifdef ANSIPROT
-extern double sqrt ( double );
-extern double fabs ( double );
-#else
-double sqrt(), fabs();
-#endif
-
-void eigens( A, RR, E, N )
-double A[], RR[], E[];
-int N;
-{
-int IND, L, LL, LM, M, MM, MQ, I, J, IA, LQ;
-int IQ, IM, IL, NLI, NMI;
-double ANORM, ANORMX, AIA, THR, ALM, ALL, AMM, X, Y;
-double SINX, SINX2, COSX, COSX2, SINCS, AIL, AIM;
-double RLI, RMI;
-static double RANGE = 1.0e-10; /*3.0517578e-5;*/
-
-
-/* Initialize identity matrix in RR[] */
-for( J=0; J<N*N; J++ )
- RR[J] = 0.0;
-MM = 0;
-for( J=0; J<N; J++ )
- {
- RR[MM + J] = 1.0;
- MM += N;
- }
-
-ANORM=0.0;
-for( I=0; I<N; I++ )
- {
- for( J=0; J<N; J++ )
- {
- if( I != J )
- {
- IA = I + (J*J+J)/2;
- AIA = A[IA];
- ANORM += AIA * AIA;
- }
- }
- }
-if( ANORM <= 0.0 )
- goto done;
-ANORM = sqrt( ANORM + ANORM );
-ANORMX = ANORM * RANGE / N;
-THR = ANORM;
-
-while( THR > ANORMX )
-{
-THR=THR/N;
-
-do
-{ /* while IND != 0 */
-IND = 0;
-
-for( L=0; L<N-1; L++ )
- {
-
-for( M=L+1; M<N; M++ )
- {
- MQ=(M*M+M)/2;
- LM=L+MQ;
- ALM=A[LM];
- if( fabs(ALM) < THR )
- continue;
-
- IND=1;
- LQ=(L*L+L)/2;
- LL=L+LQ;
- MM=M+MQ;
- ALL=A[LL];
- AMM=A[MM];
- X=(ALL-AMM)/2.0;
- Y=-ALM/sqrt(ALM*ALM+X*X);
- if(X < 0.0)
- Y=-Y;
- SINX = Y / sqrt( 2.0 * (1.0 + sqrt( 1.0-Y*Y)) );
- SINX2=SINX*SINX;
- COSX=sqrt(1.0-SINX2);
- COSX2=COSX*COSX;
- SINCS=SINX*COSX;
-
-/* ROTATE L AND M COLUMNS */
-for( I=0; I<N; I++ )
- {
- IQ=(I*I+I)/2;
- if( (I != M) && (I != L) )
- {
- if(I > M)
- IM=M+IQ;
- else
- IM=I+MQ;
- if(I >= L)
- IL=L+IQ;
- else
- IL=I+LQ;
- AIL=A[IL];
- AIM=A[IM];
- X=AIL*COSX-AIM*SINX;
- A[IM]=AIL*SINX+AIM*COSX;
- A[IL]=X;
- }
- NLI = N*L + I;
- NMI = N*M + I;
- RLI = RR[ NLI ];
- RMI = RR[ NMI ];
- RR[NLI]=RLI*COSX-RMI*SINX;
- RR[NMI]=RLI*SINX+RMI*COSX;
- }
-
- X=2.0*ALM*SINCS;
- A[LL]=ALL*COSX2+AMM*SINX2-X;
- A[MM]=ALL*SINX2+AMM*COSX2+X;
- A[LM]=(ALL-AMM)*SINCS+ALM*(COSX2-SINX2);
- } /* for M=L+1 to N-1 */
- } /* for L=0 to N-2 */
-
- }
-while( IND != 0 );
-
-} /* while THR > ANORMX */
-
-done: ;
-
-/* Extract eigenvalues from the reduced matrix */
-L=0;
-for( J=1; J<=N; J++ )
- {
- L=L+J;
- E[J-1]=A[L-1];
- }
-}