org.biojava.nbio.survival.cox.stats.Cholesky2 Maven / Gradle / Ivy
The newest version!
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.nbio.survival.cox.stats;
/**
*
* @author Scooter Willis
*/
public class Cholesky2 {
/* $Id: cholesky2.c 11357 2009-09-04 15:22:46Z therneau $
**
** subroutine to do Cholesky decompostion on a matrix: C = FDF'
** where F is lower triangular with 1's on the diagonal, and D is diagonal
**
** arguments are:
** n the size of the matrix to be factored
** **matrix a ragged array containing an n by n submatrix to be factored
** toler the threshold value for detecting "singularity"
**
** The factorization is returned in the lower triangle, D occupies the
** diagonal and the upper triangle is left undisturbed.
** The lower triangle need not be filled in at the start.
**
** Return value: the rank of the matrix (non-negative definite), or -rank
** it not SPD or NND
**
** If a column is deemed to be redundant, then that diagonal is set to zero.
**
** Terry Therneau
*/
/**
*
* @param matrix
* @param n
* @param toler
* @return
*/
public static int process(double[][] matrix, int n, double toler) {
double temp;
int i, j, k;
double eps, pivot;
int rank;
int nonneg;
nonneg = 1;
eps = 0;
for (i = 0; i < n; i++) {
if (matrix[i][i] > eps) {
eps = matrix[i][i];
}
for (j = (i + 1); j < n; j++) {
matrix[j][i] = matrix[i][j];
}
}
eps *= toler;
rank = 0;
for (i = 0; i < n; i++) {
pivot = matrix[i][i];
if (pivot < eps) {
matrix[i][i] = 0;
if (pivot < -8 * eps) {
nonneg = -1;
}
} else {
rank++;
for (j = (i + 1); j < n; j++) {
temp = matrix[j][i] / pivot;
matrix[j][i] = temp;
matrix[j][j] -= temp * temp * pivot;
for (k = (j + 1); k < n; k++) {
matrix[k][j] -= temp * matrix[k][i];
}
}
}
}
return (rank * nonneg);
}
}