00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "SoUtils/EigenSystems.h"
00021
00022
00023
00024
00025
00026 #include "gsl/gsl_matrix.h"
00027 #include "gsl/gsl_eigen.h"
00028
00029
00030
00038
00039
00040
00056
00057 StatusCode SoUtils::eigensystem
00058 ( const Gaudi::SymMatrix3x3& matrix ,
00059 Gaudi::Vector3& eigenvalues ,
00060 std::vector<Gaudi::Vector3> & eigenvectors )
00061 {
00062
00063
00064 const size_t num = 3 ;
00065
00066 eigenvalues = Gaudi::Vector3 (0,0,0);
00067 eigenvectors = std::vector<Gaudi::Vector3>( num , Gaudi::Vector3( 0, 0 , 0 ) ) ;
00068 if( 0 == num ) { return StatusCode::SUCCESS ; }
00069
00070
00071 gsl_matrix* mtrx = gsl_matrix_alloc( num , num ) ;
00072 gsl_matrix* evec = gsl_matrix_alloc( num , num ) ;
00073 if ( 0 == mtrx )
00074 { GSL_ERROR_VAL("SoCaloUtils::eigenvalues: the matrix(1) is not allocated",
00075 1000 , StatusCode( 1000 ) ) ; }
00076 if ( 0 == evec )
00077 { GSL_ERROR_VAL("SoCaloUtils::eigenvalues: the matrix(2) is not allocated",
00078 1000 , StatusCode( 1000 ) ) ; }
00079
00080
00081 gsl_eigen_symmv_workspace* wspace = gsl_eigen_symmv_alloc( num ) ;
00082 if ( 0 == wspace )
00083 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: workspace is not allocated",
00084 1001 , StatusCode ( 1001 ) ) ; }
00085
00086
00087 gsl_vector* eval = gsl_vector_alloc ( num ) ;
00088 gsl_vector* vcol = gsl_vector_alloc ( num ) ;
00089 if ( 0 == eval )
00090 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: vector(1) is not allocated",
00091 1002 , StatusCode ( 1002 ) ) ; }
00092 if ( 0 == vcol )
00093 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: vector(2) is not allocated",
00094 1002 , StatusCode ( 1002 ) ) ; }
00095
00096
00097 { for( size_t i = 0 ; i < num ; ++i )
00098 { for( size_t j = 0 ; j < num ; ++j )
00099 { gsl_matrix_set ( mtrx , i , j , matrix( i + 1 , j + 1 ) ) ; } } }
00100
00101 int ierror = gsl_eigen_symmv ( mtrx , eval , evec , wspace ) ;
00102 if ( ierror )
00103 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: values are not computed",
00104 1010 + ierror , StatusCode ( 1010 + ierror ) ) ; }
00105
00106
00107 { for( size_t i = 0 ; i < num ; ++i )
00108 { eigenvalues( i + 1 ) = gsl_vector_get( eval , i ) ; } }
00109
00110
00111 {
00112 for( size_t i = 0 ; i < num ; ++i )
00113 {
00114 ierror = gsl_matrix_get_col( vcol , evec , i ) ;
00115 if ( ierror )
00116 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: invalid matrix operation",
00117 1100 + ierror , StatusCode ( 1100 + ierror ) ) ; }
00118
00119 for( size_t j = 0 ; j < num ; ++j )
00120 { eigenvectors[i]( j + 1 ) = gsl_vector_get( vcol , j ) ; }
00121 }
00122 }
00123
00124
00125 if ( 0 != mtrx ) { gsl_matrix_free ( mtrx ) ; }
00126 if ( 0 != evec ) { gsl_matrix_free ( evec ) ; }
00127 if ( 0 != wspace ) { gsl_eigen_symmv_free ( wspace ) ; }
00128 if ( 0 != eval ) { gsl_vector_free ( eval ) ; }
00129 if ( 0 != vcol ) { gsl_vector_free ( vcol ) ; }
00130
00131 return StatusCode::SUCCESS ;
00132
00133 };
00134
00135
00149
00150 StatusCode SoUtils::eigenvalues
00151 ( const Gaudi::SymMatrix3x3& matrix ,
00152 Gaudi::Vector3& eigenvalues )
00153 {
00154
00155
00156 const size_t num = 3 ;
00157
00158 eigenvalues = Gaudi::Vector3( 0, 0 , 0 );
00159 if ( 0 == num ) { return StatusCode::SUCCESS ; }
00160
00161
00162 gsl_matrix* mtrx = gsl_matrix_alloc( num , num ) ;
00163 if ( 0 == mtrx )
00164 { GSL_ERROR_VAL("SoCaloUtils::eigenvalues: the matrix is not allocated",
00165 1000 , StatusCode( 1000 ) ) ; }
00166
00167
00168 gsl_eigen_symm_workspace* wspace = gsl_eigen_symm_alloc( num ) ;
00169 if ( 0 == wspace )
00170 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: workspace is not allocated",
00171 1001 , StatusCode ( 1001 ) ) ; }
00172
00173
00174 gsl_vector* eval = gsl_vector_alloc ( num ) ;
00175 if ( 0 == eval )
00176 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: vector is not allocated",
00177 1002 , StatusCode ( 1002 ) ) ; }
00178
00179
00180 { for( size_t i = 0 ; i < num ; ++i )
00181 { for( size_t j = 0 ; j < num ; ++j )
00182 { gsl_matrix_set ( mtrx , i , j , matrix( i + 1 , j + 1 ) ) ; } } }
00183
00184
00185 int ierror = gsl_eigen_symm( mtrx , eval , wspace ) ;
00186 if ( ierror )
00187 { GSL_ERROR_VAL("SoCaloUtil::eigenvalues: values are not computed",
00188 1010 + ierror , StatusCode ( 1010 + ierror ) ) ; }
00189
00190
00191 { for( size_t i = 0 ; i < num ; ++i )
00192 { eigenvalues( i + 1 ) = gsl_vector_get( eval , i ) ; } }
00193
00194
00195 if ( 0 != mtrx ) { gsl_matrix_free ( mtrx ) ; }
00196 if ( 0 != wspace ) { gsl_eigen_symm_free ( wspace ) ; }
00197 if ( 0 != eval ) { gsl_vector_free ( eval ) ; }
00198
00199 return StatusCode::SUCCESS ;
00200 };
00201
00202
00203
00204