Changeset 26347
- Timestamp:
- Dec 6, 2009, 8:41:50 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionEquation.c
r26345 r26347 973 973 } 974 974 975 # define SVD_ANALYSIS 1 975 976 // re-do this section with SVD: 976 // psMatrixSVD (); 977 if (SVD_ANALYSIS) { 978 // We have sumVector and sumMatrix. we are trying to solve the equation: sumMatrix * x = sumVector. 979 // we can use any standard matrix inversion to solve this. However, the basis 980 // functions in general have substantial correlation, so that the solution may be 981 // somewhat poorly determiend or unstable. If not numerically ill-conditioned, the 982 // system of equations may be statistically ill-conditioned. Noise in the image 983 // will drive insignificant but correlated terms in the solution. To avoid these 984 // problems, we can use SVD to identify numerically unconstrained values and to 985 // avoid statistically badly determined value. 986 987 // A = sumMatrix, B = sumVector 988 // SVD: A = U w V^T -> A^{-1} = V (1/w) U^T 989 // x = V (1/w) (U^T B) 990 // \sigma_x = sqrt(diag(A^{-1})) 991 // solve for x and A^{-1} to get x & dx 992 // identify the elements of (1/w) that are nan (1/0.0) -> set to 0.0 993 // identify the elements of x that are insignificant (x / dx < 1.0? < 0.5?) -> set to 0.0 994 995 // I get confused by the index values between the image vs matrix usage: In terms 996 // of the elements of an image A(x,y) = A->data.F32[y][x] = A_x,y, a matrix 997 // multiplication is: A_k,j * B_i,k = C_i,j 998 999 psImage *U = NULL; 1000 psImage *V = NULL; 1001 psVector *w = NULL; 1002 if (!psMatrixSVD (&U, &w, &V, sumMatrix)) { 1003 psError(PS_ERR_UNKNOWN, false, "failed to perform SVD on sumMatrix\n"); 1004 return NULL; 1005 } 1006 1007 // calculate A_inverse and x_svd 1008 // A'_i,j = \sum_k (V_k,j * w_k * Ut_i,k) 1009 // but U^T_i,j = U_j,i, so: 1010 // A'_i,j = \sum_k (V_k,j * w_k * U_k,i) 1011 1012 // v1_j = \sum_k (UT_k,j * B_k) 1013 // v1_j = w_j * \sum_k (U_j,k * B_k) 1014 // x_i = \sum_j V_j,i * w_j * \sum_k (U_j,k * B_k) 1015 1016 // A'_i,j = \sum_k (V_k,j * w_k * U_k,i) 1017 1018 psImage *Ainv = psImageAlloc(A->numCols, A->numRows, PS_TYPE_F32); 1019 psVector *Xsvd = psVectorAlloc(A->numCols, PS_TYPE_F32); 1020 for (int iy = 0; iy < A->numRows; iy++) { 1021 double vsum = 0.0; 1022 for (int ix = 0; ix < A->numCols; ix++) { 1023 double msum = 0.0; 1024 double vsum1 = 0.0; 1025 for (int k = 0; k < A->numCols; k++) { 1026 if (fabs(w->data.F32[k]) < FLT_EPSILON) continue; 1027 msum += V->data.F32[iy][k] * U->data.F32[ix][k] / w->data.F32[k]; 1028 vsum1 += U->data.F32[k][iy] * B->data.F32[k]; 1029 } 1030 Ainv->data.F32[iy][ix] = sum; 1031 if (fabs(w->data.F32[ix]) < FLT_EPSILON) continue; 1032 vsum += V->data.F32[iy][ix] * vsum1 / w->data.F32[ix]; 1033 } 1034 Xsvd->data.F32[iy] = vsum; 1035 } 1036 1037 // compare Xsvd[k] to dXsvd and zero out w entries that are not significant 1038 # define COEFF_SIG 1.0 1039 for (int k = 0; k < A->numRows; k++) { 1040 float dXsvd = sqrt(Ainv->data.F32[k][k]); 1041 if (fabs(Xsvd->data.F32[k] / dXsvd) < COEFF_SIG) { 1042 w->data.F32[k] = 0.0; 1043 } 1044 } 1045 1046 // 1047 1048 1049 } 977 1050 978 1051 psVector *permutation = NULL; // Permutation vector, required for LU decomposition
Note:
See TracChangeset
for help on using the changeset viewer.
