public static PrimitiveMatrix toCorrelations ( Access2D < ? > covariances , boolean clean ) { int size = Math . toIntExact ( Math . min ( covariances . countRows ( ) , covariances . countColumns ( ) ) ) ; MatrixStore < Double > covarianceMtrx = MatrixStore . PRIMITIVE . makeWrapper ( covariances ) . get ( ) ; if ( clean ) { Eigenvalue < Double > evd = Eigenvalue . PRIMITIVE . make ( covarianceMtrx , true ) ; evd . decompose ( covarianceMtrx ) ; MatrixStore < Double > mtrxV = evd . getV ( ) ; PhysicalStore < Double > mtrxD = evd . getD ( ) . copy ( ) ; double largest = evd . getEigenvalues ( ) . get ( 0 ) . norm ( ) ; double limit = largest * size * PrimitiveMath . RELATIVELY_SMALL ; for ( int ij = 0 ; ij < size ; ij ++ ) { if ( mtrxD . doubleValue ( ij , ij ) < limit ) { mtrxD . set ( ij , ij , limit ) ; } } covarianceMtrx = mtrxV . multiply ( mtrxD ) . multiply ( mtrxV . transpose ( ) ) ; } PrimitiveMatrix . DenseReceiver retVal = PrimitiveMatrix . FACTORY . makeDense ( size , size ) ; double [ ] volatilities = new double [ size ] ; for ( int ij = 0 ; ij < size ; ij ++ ) { volatilities [ ij ] = PrimitiveMath . SQRT . invoke ( covarianceMtrx . doubleValue ( ij , ij ) ) ; } for ( int j = 0 ; j < size ; j ++ ) { double colVol = volatilities [ j ] ; retVal . set ( j , j , PrimitiveMath . ONE ) ; for ( int i = j + 1 ; i < size ; i ++ ) { double rowVol = volatilities [ i ] ; if ( ( rowVol <= PrimitiveMath . ZERO ) || ( colVol <= PrimitiveMath . ZERO ) ) { retVal . set ( i , j , PrimitiveMath . ZERO ) ; retVal . set ( j , i , PrimitiveMath . ZERO ) ; } else { double covariance = covarianceMtrx . doubleValue ( i , j ) ; double correlation = covariance / ( rowVol * colVol ) ; retVal . set ( i , j , correlation ) ; retVal . set ( j , i , correlation ) ; } } } return retVal . get ( ) ; }
Will extract the correlation coefficients from the input covariance matrix . If cleaning is enabled small and negative eigenvalues of the covariance matrix will be replaced with a new minimal value .