| 1 | /* file: Choesky decomposition */
|
|---|
| 2 |
|
|---|
| 3 | /* Take the cholesky decomposition in the manner described in FA Graybill
|
|---|
| 4 | (1976).
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | #include <math.h>
|
|---|
| 8 | #include <stdio.h>
|
|---|
| 9 | #include <stdlib.h>
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 | int cholesky(double **orig, int n, double **aug, int mcol,double **chol, double **cholaug, int ofs)
|
|---|
| 13 | /*
|
|---|
| 14 | Do the augmented cholesky decomposition as described in FA Graybill
|
|---|
| 15 | (1976) Theory and Application of the Linear Model. The original matrix
|
|---|
| 16 | must be symmetric positive definite. The augmentation matrix, or
|
|---|
| 17 | series of column vectors, are multiplied by C^-t, where C is the
|
|---|
| 18 | upper triangular cholesky matrix, ie C^t * C = M and M is the original
|
|---|
| 19 | matrix. Returns with a value of 0 if M is a non-positive definite
|
|---|
| 20 | matrix. Returns with a value of 1 with succesful completion.
|
|---|
| 21 |
|
|---|
| 22 | Arguments:
|
|---|
| 23 |
|
|---|
| 24 | orig (input) double n x n array. The matrix to take the Cholesky
|
|---|
| 25 | decomposition of.
|
|---|
| 26 | n (input) integer. Number of rows and columns in orig.
|
|---|
| 27 | aug (input) double n x mcol array. The matrix for the augmented
|
|---|
| 28 | part of the decomposition.
|
|---|
| 29 | mcol (input) integer. Number of columns in aug.
|
|---|
| 30 | chol (output) double n x n array. Holds the upper triangular matrix
|
|---|
| 31 | C on output. The lower triangular portion remains unchanged.
|
|---|
| 32 | This maybe the same as orig, in which case the upper triangular
|
|---|
| 33 | portion of orig is overwritten.
|
|---|
| 34 | cholaug (output) double n x mcol array. Holds the product C^-t * aug.
|
|---|
| 35 | May be the same as aug, in which case aug is over written.
|
|---|
| 36 | ofs (input) integer. The index of the first element in the matrices.
|
|---|
| 37 | Normally this is 0, but commonly is 1 (but may be any integer).
|
|---|
| 38 | */
|
|---|
| 39 | {
|
|---|
| 40 | int i, j, k, l;
|
|---|
| 41 | int retval = 1;
|
|---|
| 42 |
|
|---|
| 43 | for (i=ofs; i<n+ofs; i++) {
|
|---|
| 44 | chol[i][i] = orig[i][i];
|
|---|
| 45 | for (k=ofs; k<i; k++)
|
|---|
| 46 | chol[i][i] -= chol[k][i]*chol[k][i];
|
|---|
| 47 | if (chol[i][i] <= 0) {
|
|---|
| 48 | fprintf(stderr,"\nERROR: non-positive definite matrix!\n");
|
|---|
| 49 | printf("\nproblem from %d %f\n",i,chol[i][i]);
|
|---|
| 50 | retval = 0;
|
|---|
| 51 | return retval;
|
|---|
| 52 | }
|
|---|
| 53 | chol[i][i] = sqrt(chol[i][i]);
|
|---|
| 54 |
|
|---|
| 55 | /*This portion multiplies the extra matrix by C^-t */
|
|---|
| 56 | for (l=ofs; l<mcol+ofs; l++) {
|
|---|
| 57 | cholaug[i][l] = aug[i][l];
|
|---|
| 58 | for (k=ofs; k<i; k++) {
|
|---|
| 59 | cholaug[i][l] -= cholaug[k][l]*chol[k][i];
|
|---|
| 60 | }
|
|---|
| 61 | cholaug[i][l] /= chol[i][i];
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | for (j=i+1; j<n+ofs; j++) {
|
|---|
| 65 | chol[i][j] = orig[i][j];
|
|---|
| 66 | for (k=ofs; k<i; k++)
|
|---|
| 67 | chol[i][j] -= chol[k][i]*chol[k][j];
|
|---|
| 68 | chol[i][j] /= chol[i][i];
|
|---|
| 69 | }
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | return retval;
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|