Changeset 25857
- Timestamp:
- Oct 15, 2009, 3:12:27 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/pap/psModules/src/imcombine/pmSubtractionEquation.c
r25841 r25857 19 19 #define USE_VARIANCE // Include variance in equation? 20 20 21 //#define OLD_FUNCTIONS // Use old functions22 21 23 22 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 25 24 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 26 25 27 #ifndef OLD_FUNCTIONS28 26 // Calculate the least-squares matrix and vector 29 27 static bool calculateMatrixVector(psImage *matrix, // Least-squares matrix, updated … … 401 399 } 402 400 403 #ifdef OLD_FUNCTIONS404 // Calculate a single element of the least-squares matrix, with the polynomial expansions in one direction405 static inline bool calculateMatrixElement1(psImage *matrix, // Matrix to calculate406 int i, int j, // Coordinates of element407 const psKernel *image1, // First image in multiplication408 const psKernel *image2, // Second image in multiplication409 const psKernel *variance, // Variance image410 const psImage *polyValues, // Spatial polynomial values411 int numKernels, // Number of kernel basis functions412 int footprint, // (Half-)Size of stamp413 int spatialOrder, // Maximum order of spatial variation414 bool symmetric // Is the matrix symmetric?415 )416 {417 double sum = calculateSumProduct(image1, image2, variance, footprint); // Sum of the image products418 if (!isfinite(sum)) {419 return false;420 }421 422 // Generate the pseudo-convolutions from the spatial polynomial terms423 for (int iyOrder = 0, iIndex = i; iyOrder <= spatialOrder; iyOrder++) {424 for (int ixOrder = 0; ixOrder <= spatialOrder - iyOrder; ixOrder++, iIndex += numKernels) {425 double convPoly = sum * polyValues->data.F64[iyOrder][ixOrder];426 427 assert(iIndex < matrix->numRows && j < matrix->numCols);428 429 matrix->data.F64[iIndex][j] = convPoly;430 if (symmetric) {431 432 assert(iIndex < matrix->numCols && j < matrix->numRows);433 434 matrix->data.F64[j][iIndex] = convPoly;435 }436 }437 }438 return true;439 }440 441 // Calculate a single element of the least-squares matrix, with the polynomial expansions in both directions442 static inline bool calculateMatrixElement2(psImage *matrix, // Matrix to calculate443 int i, int j, // Coordinates of element444 const psKernel *image1, // First image in multiplication445 const psKernel *image2, // Second image in multiplication446 const psKernel *variance, // Variance image447 const psImage *polyValues, // Spatial polynomial values448 int numKernels, // Number of kernel basis functions449 int footprint, // (Half-)Size of stamp450 int spatialOrder, // Maximum order of spatial variation451 bool symmetric // Is the matrix symmetric?452 )453 {454 double sum = calculateSumProduct(image1, image2, variance, footprint); // Sum of the image products455 if (!isfinite(sum)) {456 return false;457 }458 459 // Generate the pseudo-convolutions from the spatial polynomial terms460 for (int iyOrder = 0, iIndex = i; iyOrder <= spatialOrder; iyOrder++) {461 for (int ixOrder = 0; ixOrder <= spatialOrder - iyOrder; ixOrder++, iIndex += numKernels) {462 double iPoly = polyValues->data.F64[iyOrder][ixOrder]; // Value of polynomial463 for (int jyOrder = 0, jIndex = j; jyOrder <= spatialOrder; jyOrder++) {464 for (int jxOrder = 0; jxOrder <= spatialOrder - jyOrder; jxOrder++, jIndex += numKernels) {465 double convPoly = sum * iPoly * polyValues->data.F64[jyOrder][jxOrder];466 467 assert(iIndex < matrix->numRows && jIndex < matrix->numCols);468 469 matrix->data.F64[iIndex][jIndex] = convPoly;470 if (symmetric) {471 472 assert(iIndex < matrix->numCols && jIndex < matrix->numRows);473 474 matrix->data.F64[jIndex][iIndex] = convPoly;475 }476 }477 }478 }479 }480 return true;481 }482 483 // Calculate the square part of the matrix derived from multiplying convolutions484 static bool calculateMatrixSquare(psImage *matrix, // Matrix to calculate485 const psArray *convolutions1, // Convolutions for element 1486 const psArray *convolutions2, // Convolutions for element 2487 const psKernel *variance, // Variance image488 const psImage *polyValues, // Polynomial values489 int numKernels, // Number of kernel basis functions490 int spatialOrder, // Order of spatial variation491 int footprint // Half-size of stamp492 )493 {494 bool symmetric = (convolutions1 == convolutions2 ? true : false); // Is matrix symmetric?495 496 for (int i = 0; i < numKernels; i++) {497 psKernel *iConv = convolutions1->data[i]; // Convolution for i-th element498 499 for (int j = (symmetric ? i : 0); j < numKernels; j++) {500 psKernel *jConv = convolutions2->data[j]; // Convolution for j-th element501 502 if (!calculateMatrixElement2(matrix, i, j, iConv, jConv, variance, polyValues, numKernels,503 footprint, spatialOrder, symmetric)) {504 psTrace("psModules.imcombine", 2, "Bad sumCC at %d, %d", i, j);505 return false;506 }507 }508 }509 510 return true;511 }512 513 // Calculate least-squares matrix and vector514 static bool calculateMatrix(psImage *matrix, // Matrix to calculate515 const pmSubtractionKernels *kernels, // Kernel components516 const psArray *convolutions, // Convolutions of source with kernels517 const psKernel *input, // Input stamp, or NULL518 const psKernel *variance, // Variance stamp519 const psImage *polyValues, // Spatial polynomial values520 int footprint, // (Half-)Size of stamp521 bool normAndBG // Calculate normalisation and background terms?522 )523 {524 int numKernels = kernels->num; // Number of kernel components525 int spatialOrder = kernels->spatialOrder; // Maximum order of spatial variation526 int numSpatial = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of spatial variation terms527 int bgOrder = kernels->bgOrder; // Maximum order of background fit528 int numBackground = normAndBG ? PM_SUBTRACTION_POLYTERMS(bgOrder) : 0; // Number of background terms529 int numTerms = numKernels * numSpatial + (normAndBG ? 1 + numBackground : 0); // Total number of terms530 assert(matrix);531 assert(matrix->numCols == matrix->numRows);532 assert(matrix->numCols == numTerms);533 assert(convolutions && convolutions->n == numKernels);534 assert(polyValues);535 assert(!normAndBG || input); // If we want the normalisation and BG, then we need the input image536 537 // Square part of the matrix (convolution-convolution products)538 if (!calculateMatrixSquare(matrix, convolutions, convolutions, variance, polyValues, numKernels,539 spatialOrder, footprint)) {540 return false;541 }542 543 // XXX To support higher-order background model than simply constant, the below code needs to be updated.544 if (normAndBG) {545 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation546 int bgIndex = PM_SUBTRACTION_INDEX_BG(kernels); // Index in matrix for background547 548 for (int i = 0; i < numKernels; i++) {549 psKernel *conv = convolutions->data[i]; // Convolution for i-th element550 551 // Normalisation-convolution terms552 if (!calculateMatrixElement1(matrix, i, normIndex, conv, input, variance, polyValues, numKernels,553 footprint, spatialOrder, true)) {554 psTrace("psModules.imcombine", 2, "Bad sumIC at %d", i);555 return false;556 }557 558 // Background-convolution terms559 double sumC = 0.0; // Sum of the convolution560 for (int y = - footprint; y <= footprint; y++) {561 for (int x = - footprint; x <= footprint; x++) {562 double value = conv->kernel[y][x];563 #ifdef USE_VARIANCE564 value /= variance->kernel[y][x];565 #endif566 sumC += value;567 }568 }569 if (!isfinite(sumC)) {570 psTrace("psModules.imcombine", 2, "Bad sumC at %d", i);571 return false;572 }573 574 for (int yOrder = 0, index = i; yOrder <= spatialOrder; yOrder++) {575 for (int xOrder = 0; xOrder <= spatialOrder - yOrder; xOrder++, index += numKernels) {576 double value = sumC * polyValues->data.F64[yOrder][xOrder];577 matrix->data.F64[index][bgIndex] = value;578 matrix->data.F64[bgIndex][index] = value;579 }580 }581 }582 583 // Background only, normalisation only, and background-normalisation terms584 double sum1 = 0.0; // Sum of the weighting585 double sumI = 0.0; // Sum of the input586 double sumII = 0.0; // Sum of the input squared587 for (int y = - footprint; y <= footprint; y++) {588 for (int x = - footprint; x <= footprint; x++) {589 double invNoise2 = 1.0;590 #ifdef USE_VARIANCE591 invNoise2 /= variance->kernel[y][x];592 #endif593 double value = input->kernel[y][x] * invNoise2;594 sumI += value;595 sumII += value * input->kernel[y][x];596 sum1 += invNoise2;597 }598 }599 if (!isfinite(sumI)) {600 psTrace("psModules.imcombine", 2, "Bad sumI detected");601 return false;602 }603 if (!isfinite(sumII)) {604 psTrace("psModules.imcombine", 2, "Bad sumII detected");605 return false;606 }607 if (!isfinite(sum1)) {608 psTrace("psModules.imcombine", 2, "Bad sum1 detected");609 return false;610 }611 matrix->data.F64[normIndex][normIndex] = sumII;612 matrix->data.F64[bgIndex][bgIndex] = sum1;613 matrix->data.F64[normIndex][bgIndex] = sumI;614 matrix->data.F64[bgIndex][normIndex] = sumI;615 }616 617 return true;618 }619 620 621 // Calculate least-squares matrix and vector622 static bool calculateVector(psVector *vector, // Vector to calculate, or NULL623 const pmSubtractionKernels *kernels, // Kernel components624 const psArray *convolutions, // Convolutions of source with kernels625 const psKernel *input, // Input stamp, or NULL if !normAndBG626 const psKernel *target, // Target stamp627 const psKernel *variance, // Variance stamp628 const psImage *polyValues, // Spatial polynomial values629 int footprint, // (Half-)Size of stamp630 bool normAndBG // Calculate normalisation and background terms?631 )632 {633 int numKernels = kernels->num; // Number of kernel components634 int spatialOrder = kernels->spatialOrder; // Maximum order of spatial variation635 int numSpatial = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of spatial variation terms636 int bgOrder = kernels->bgOrder; // Maximum order of background fit637 int numBackground = normAndBG ? PM_SUBTRACTION_POLYTERMS(bgOrder) : 0; // Number of background terms638 int numTerms = numKernels * numSpatial + (normAndBG ? 1 + numBackground : 0); // Total number of terms639 assert(vector && vector->n == numTerms);640 assert(convolutions && convolutions->n == numKernels);641 assert(target);642 assert(polyValues);643 assert(!normAndBG || input); // If we want the normalisation and BG, then we need the input image644 645 // Convolution terms646 for (int i = 0; i < numKernels; i++) {647 psKernel *conv = convolutions->data[i]; // Convolution for i-th element648 double sumTC = 0.0; // Sum of the target and convolution649 for (int y = - footprint; y <= footprint; y++) {650 for (int x = - footprint; x <= footprint; x++) {651 double value = target->kernel[y][x] * conv->kernel[y][x];652 #ifdef USE_VARIANCE653 value /= variance->kernel[y][x];654 #endif655 sumTC += value;656 }657 }658 if (!isfinite(sumTC)) {659 psTrace("psModules.imcombine", 2, "Bad sumTC at %d", i);660 return false;661 }662 for (int yOrder = 0, index = i; yOrder <= spatialOrder; yOrder++) {663 for (int xOrder = 0; xOrder <= spatialOrder - yOrder; xOrder++, index += numKernels) {664 vector->data.F64[index] = sumTC * polyValues->data.F64[yOrder][xOrder];665 }666 }667 }668 669 if (normAndBG) {670 // Background terms671 double sumT = 0.0; // Sum of the target672 double sumIT = 0.0; // Sum of the input-target product673 for (int y = - footprint; y <= footprint; y++) {674 for (int x = - footprint; x <= footprint; x++) {675 double value = target->kernel[y][x];676 #ifdef USE_VARIANCE677 value /= variance->kernel[y][x];678 #endif679 sumIT += value * input->kernel[y][x];680 sumT += value;681 }682 }683 if (!isfinite(sumT)) {684 psTrace("psModules.imcombine", 2, "Bad sumI detected");685 return false;686 }687 if (!isfinite(sumIT)) {688 psTrace("psModules.imcombine", 2, "Bad sumIT detected");689 return false;690 }691 692 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation term693 vector->data.F64[normIndex] = sumIT;694 int bgIndex = PM_SUBTRACTION_INDEX_BG(kernels); // Index for background term695 vector->data.F64[bgIndex] = sumT;696 }697 698 return true;699 }700 701 702 703 // Calculate the cross-matrix, composed of convolutions of each image704 // Note that the cross-matrix is NOT square705 static bool calculateMatrixCross(psImage *matrix, // Matrix to calculate706 const pmSubtractionKernels *kernels, // Kernel components707 const psArray *convolutions1, // Convolutions of image 1708 const psArray *convolutions2, // Convolutions of image 2709 const psKernel *image1, // Image 1 stamp710 const psKernel *variance, // Variance stamp711 const psImage *polyValues, // Spatial polynomial values712 int footprint // (Half-)Size of stamp713 )714 {715 assert(matrix);716 int numKernels = kernels->num; // Number of kernel components717 int spatialOrder = kernels->spatialOrder; // Maximum order of spatial variation718 int numSpatial = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of spatial polynomial terms719 int numBackground = PM_SUBTRACTION_POLYTERMS(kernels->bgOrder); // Number of background terms720 int numCols = numKernels * numSpatial + 1 + numBackground; // Number of columns721 int numRows = numKernels * numSpatial; // Number of rows722 assert(matrix->numCols == numCols && matrix->numRows == numRows);723 assert(convolutions1 && convolutions1->n == numKernels);724 assert(convolutions2 && convolutions2->n == numKernels);725 726 int normIndex, bgIndex; // Indices in matrix for normalisation and background terms727 PM_SUBTRACTION_INDICES(normIndex, bgIndex, kernels);728 729 if (!calculateMatrixSquare(matrix, convolutions1, convolutions2, variance, polyValues, numKernels,730 spatialOrder, footprint)) {731 return false;732 }733 734 for (int i = 0; i < numKernels; i++) {735 // Normalisation736 psKernel *conv = convolutions2->data[i]; // Convolution737 if (!calculateMatrixElement1(matrix, i, normIndex, conv, image1, variance, polyValues, numKernels,738 footprint, spatialOrder, false)) {739 psTrace("psModules.imcombine", 2, "Bad sumIC at %d", i);740 return false;741 }742 743 // Background744 double sumC = 0.0; // Sum of the weighting745 for (int y = - footprint; y <= footprint; y++) {746 for (int x = - footprint; x <= footprint; x++) {747 double value = conv->kernel[y][x];748 #ifdef USE_VARIANCE749 value /= variance->kernel[y][x];750 #endif751 sumC += value;752 }753 }754 if (!isfinite(sumC)) {755 psTrace("psModules.imcombine", 2, "Bad sumC detected at %d", i);756 return false;757 }758 for (int yOrder = 0, index = i; yOrder <= spatialOrder; yOrder++) {759 for (int xOrder = 0; xOrder <= spatialOrder - yOrder; xOrder++, index += numKernels) {760 matrix->data.F64[index][bgIndex] = sumC * polyValues->data.F64[yOrder][xOrder];761 }762 }763 }764 765 return true;766 }767 #endif768 769 401 // Add in penalty term to least-squares vector 770 402 static bool calculatePenalty(psVector *vector, // Vector to which to add in penalty term … … 941 573 switch (kernels->mode) { 942 574 case PM_SUBTRACTION_MODE_1: 943 #ifdef OLD_FUNCTIONS944 status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,945 stamp->variance, polyValues, footprint, true);946 status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,947 stamp->image2, stamp->variance, polyValues, footprint, true);948 #else949 575 status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image2, stamp->image1, 950 576 stamp->variance, stamp->convolutions1, kernels, polyValues, 951 577 footprint); 952 #endif953 578 break; 954 579 case PM_SUBTRACTION_MODE_2: 955 #ifdef OLD_FUNCTIONS956 status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions2, stamp->image2,957 stamp->variance, polyValues, footprint, true);958 status &= calculateVector(stamp->vector1, kernels, stamp->convolutions2, stamp->image2,959 stamp->image1, stamp->variance, polyValues, footprint, true);960 #else961 580 status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image1, stamp->image2, 962 581 stamp->variance, stamp->convolutions2, kernels, polyValues, 963 582 footprint); 964 #endif965 583 break; 966 584 case PM_SUBTRACTION_MODE_DUAL: … … 975 593 psVectorInit(stamp->vector2, NAN); 976 594 #endif 977 #ifdef OLD_FUNCTIONS978 status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,979 stamp->variance, polyValues, footprint, true);980 status &= calculateMatrix(stamp->matrix2, kernels, stamp->convolutions2, NULL,981 stamp->variance, polyValues, footprint, false);982 status &= calculateMatrixCross(stamp->matrixX, kernels, stamp->convolutions1,983 stamp->convolutions2, stamp->image1, stamp->variance, polyValues,984 footprint);985 status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,986 stamp->image2, stamp->variance, polyValues, footprint, true);987 status &= calculateVector(stamp->vector2, kernels, stamp->convolutions2, NULL,988 stamp->image2, stamp->variance, polyValues, footprint, false);989 #else990 595 status = calculateDualMatrixVector(stamp->matrix1, stamp->vector1, stamp->matrix2, stamp->vector2, 991 596 stamp->matrixX, stamp->image1, stamp->image2, stamp->variance, 992 597 stamp->convolutions1, stamp->convolutions2, kernels, polyValues, 993 598 footprint); 994 #endif995 599 break; 996 600 default: … … 1291 895 1292 896 // Pure matrix operations 1293 1294 897 // A * a = Ct * b + d 1295 898 // C * a = B * b + e 1296 899 // 1297 // a = (Ct * Bi * C - A)i (Ct * Bi * e - d) 1298 // b = Bi * (C * a - e) 1299 psVector *a = psVectorRecycle(kernels->solution1, numParams, PS_TYPE_F64); 1300 psVector *b = psVectorRecycle(kernels->solution2, numParams2, PS_TYPE_F64); 1301 #ifdef TESTING 1302 psVectorInit(a, NAN); 1303 psVectorInit(b, NAN); 1304 #endif 1305 psImage *A = sumMatrix1; 1306 psImage *B = sumMatrix2; 1307 psImage *C = sumMatrixX; 1308 psVector *d = sumVector1; 1309 psVector *e = sumVector2; 1310 1311 assert(a->n == numParams); 1312 assert(b->n == numParams2); 1313 assert(A->numRows == numParams && A->numCols == numParams); 1314 assert(B->numRows == numParams2 && B->numCols == numParams2); 1315 assert(C->numRows == numParams2 && C->numCols == numParams); 1316 assert(d->n == numParams); 1317 assert(e->n == numParams2); 1318 1319 psImage *Bi = psMatrixInvert(NULL, B, NULL); 1320 assert(Bi->numRows == numParams2 && Bi->numCols == numParams2); 1321 psImage *Ct = psMatrixTranspose(NULL, C); 1322 assert(Ct->numRows == numParams && Ct->numCols == numParams2); 1323 1324 psImage *BiC = psMatrixMultiply(NULL, Bi, C); 1325 assert(BiC->numRows == numParams2 && BiC->numCols == numParams); 1326 psImage *CtBi = psMatrixMultiply(NULL, Ct, Bi); 1327 assert(CtBi->numRows == numParams && CtBi->numCols == numParams2); 1328 1329 psImage *CtBiC = psMatrixMultiply(NULL, Ct, BiC); 1330 assert(CtBiC->numRows == numParams && CtBiC->numCols == numParams); 1331 1332 psImage *F = (psImage*)psBinaryOp(NULL, CtBiC, "-", A); 1333 assert(F->numRows == numParams && F->numCols == numParams); 1334 float det = 0.0; 1335 psImage *Fi = psMatrixInvert(NULL, F, &det); 1336 assert(Fi->numRows == numParams && Fi->numCols == numParams); 1337 psTrace("psModules.imcombine", 4, "Determinant of F: %f\n", det); 1338 1339 psVector *g = psVectorAlloc(numParams, PS_TYPE_F64); 1340 #ifdef TESTING 1341 psVectorInit(g, NAN); 1342 #endif 1343 assert(CtBi->numRows == numParams && CtBi->numCols == numParams2); 1344 assert(e->n == numParams2); 1345 assert(d->n == numParams); 900 // Set F = ( A -Ct ; C -B ) 901 // Set g = ( a ; b ) 902 // Set h = ( d ; e ) 903 // So that we combine the above two equations: Fg = h 904 905 int num = numParams + numParams2; // Number of params for new set 906 psImage *F = psImageAlloc(num, num, PS_TYPE_F64); 907 psVector *h = psVectorAlloc(num, PS_TYPE_F64); 908 1346 909 for (int i = 0; i < numParams; i++) { 1347 double value = 0.0; 910 h->data.F64[i] = sumVector1->data.F64[i]; 911 for (int j = 0; j < numParams; j++) { 912 F->data.F64[i][j] = sumMatrix1->data.F64[i][j]; 913 } 1348 914 for (int j = 0; j < numParams2; j++) { 1349 value += CtBi->data.F64[i][j] * e->data.F64[j]; 1350 } 1351 g->data.F64[i] = value - d->data.F64[i]; 1352 } 1353 1354 assert(Fi->numRows == numParams && Fi->numCols == numParams); 1355 assert(g->n == numParams); 1356 for (int i = 0; i < numParams; i++) { 1357 double value = 0.0; 915 F->data.F64[i][numParams + j] = - sumMatrixX->data.F64[j][i]; 916 } 917 } 918 for (int i = 0; i < numParams2; i++) { 919 h->data.F64[numParams + i] = sumVector2->data.F64[i]; 1358 920 for (int j = 0; j < numParams; j++) { 1359 value += Fi->data.F64[i][j] * g->data.F64[j]; 1360 } 1361 a->data.F64[i] = value; 1362 } 1363 1364 psVector *h = psVectorAlloc(numParams2, PS_TYPE_F64); 1365 #ifdef TESTING 1366 psVectorInit(h, NAN); 1367 #endif 1368 assert(C->numRows == numParams2 && C->numCols == numParams); 1369 assert(a->n == numParams); 1370 assert(e->n == numParams2); 1371 for (int i = 0; i < numParams2; i++) { 1372 double value = 0.0; 1373 for (int j = 0; j < numParams; j++) { 1374 value += C->data.F64[i][j] * a->data.F64[j]; 1375 } 1376 h->data.F64[i] = value - e->data.F64[i]; 1377 } 1378 1379 assert(Bi->numRows == numParams2 && Bi->numCols == numParams2); 1380 assert(h->n == numParams2); 1381 for (int i = 0; i < numParams2; i++) { 1382 double value = 0.0; 921 F->data.F64[numParams + i][j] = sumMatrixX->data.F64[i][j]; 922 } 1383 923 for (int j = 0; j < numParams2; j++) { 1384 value += Bi->data.F64[i][j] * h->data.F64[j]; 1385 } 1386 b->data.F64[i] = value; 1387 } 1388 1389 1390 #if 1 1391 for (int i = 0; i < numParams; i++) { 1392 double aVal1 = 0.0, bVal1 = 0.0; 1393 for (int j = 0; j < numParams2; j++) { 1394 aVal1 += A->data.F64[i][j] * a->data.F64[j]; 1395 bVal1 += Ct->data.F64[i][j] * b->data.F64[j]; 1396 } 1397 bVal1 += d->data.F64[i]; 1398 for (int j = numParams2; j < numParams; j++) { 1399 aVal1 += A->data.F64[i][j] * a->data.F64[j]; 1400 } 1401 printf("%d: %lf\n", i, aVal1 - bVal1); 1402 } 1403 1404 for (int i = 0; i < numParams2; i++) { 1405 double aVal2 = 0.0, bVal2 = 0.0; 1406 for (int j = 0; j < numParams2; j++) { 1407 aVal2 += C->data.F64[i][j] * a->data.F64[j]; 1408 bVal2 += B->data.F64[i][j] * b->data.F64[j]; 1409 } 1410 bVal2 += e->data.F64[i]; 1411 for (int j = numParams2; j < numParams; j++) { 1412 aVal2 += C->data.F64[i][j] * a->data.F64[j]; 1413 } 1414 printf("%d: %lf\n", i, aVal2 - bVal2); 1415 } 1416 #endif 924 F->data.F64[numParams + i][numParams + j] = - sumMatrix2->data.F64[i][j]; 925 } 926 } 927 psFree(sumMatrix1); 928 psFree(sumMatrix2); 929 psFree(sumMatrixX); 930 psFree(sumVector1); 931 psFree(sumVector2); 1417 932 1418 933 #ifdef TESTING 1419 934 { 1420 psFits *fits = psFitsOpen("sumMatrix 1.fits", "w");1421 psFitsWriteImage(fits, NULL, sumMatrix1, 0, NULL);935 psFits *fits = psFitsOpen("sumMatrix.fits", "w"); 936 psFitsWriteImage(fits, NULL, F, 0, NULL); 1422 937 psFitsClose(fits); 1423 938 } 1424 939 { 1425 psFits *fits = psFitsOpen("sumMatrix2.fits", "w"); 1426 psFitsWriteImage(fits, NULL, sumMatrix2, 0, NULL); 940 psImage *image = psImageAlloc(1, num, PS_TYPE_F64); 941 psFits *fits = psFitsOpen("sumVector.fits", "w"); 942 for (int i = 0; i < num; i++) { 943 image->data.F64[0][i] = h->data.F64[i]; 944 } 945 psFitsWriteImage(fits, NULL, image, 0, NULL); 946 psFree(image); 1427 947 psFitsClose(fits); 1428 948 } 1429 { 1430 psFits *fits = psFitsOpen("sumMatrixX.fits", "w"); 1431 psFitsWriteImage(fits, NULL, sumMatrixX, 0, NULL); 1432 psFitsClose(fits); 1433 } 1434 { 1435 psFits *fits = psFitsOpen("sumFinverse.fits", "w"); 1436 psFitsWriteImage(fits, NULL, Fi, 0, NULL); 1437 psFitsClose(fits); 1438 } 1439 #endif 1440 1441 kernels->solution1 = a; 1442 kernels->solution2 = b; 1443 1444 // XXXXX Free temporary matrices and vectors 949 #endif 950 951 psVector *permutation = NULL; // Permutation vector, required for LU decomposition 952 psImage *luMatrix = psMatrixLUDecomposition(NULL, &permutation, F); 953 if (!luMatrix) { 954 psError(PS_ERR_UNKNOWN, true, "LU Decomposition of least-squares matrix failed.\n"); 955 psFree(F); 956 psFree(h); 957 psFree(luMatrix); 958 psFree(permutation); 959 return NULL; 960 } 961 psFree(F); 962 963 psVector *g = psMatrixLUSolution(NULL, luMatrix, h, permutation); // Solution! 964 if (!g) { 965 psError(PS_ERR_UNKNOWN, true, "LU Decomposition of least-squares matrix failed.\n"); 966 psFree(h); 967 psFree(luMatrix); 968 psFree(permutation); 969 return NULL; 970 } 971 psFree(permutation); 972 psFree(luMatrix); 973 psFree(h); 974 975 if (!kernels->solution1) { 976 kernels->solution1 = psVectorAlloc(numParams, PS_TYPE_F64); 977 } 978 if (!kernels->solution2) { 979 kernels->solution2 = psVectorAlloc(numParams2, PS_TYPE_F64); 980 } 981 982 for (int i = 0; i < numParams; i++) { 983 kernels->solution1->data.F64[i] = g->data.F64[i]; 984 } 985 for (int i = 0; i < numParams2; i++) { 986 kernels->solution2->data.F64[i] = g->data.F64[numParams + i]; 987 } 988 psFree(g); 1445 989 1446 990 }
Note:
See TracChangeset
for help on using the changeset viewer.
