IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25833


Ignore:
Timestamp:
Oct 13, 2009, 7:54:28 PM (17 years ago)
Author:
Paul Price
Message:

Attempting to fix dual convolution. Starting off by consolidating and making code plain to do forwards convolution. Adding some small optimisations: it's slightly quicker to generate the solvedKernel using the pre-computed full image kernel, but for convolving stamps, faster to use the separate x and y kernels.

Location:
branches/pap/psModules/src/imcombine
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/pap/psModules/src/imcombine/pmSubtraction.c

    r25279 r25833  
    135135          case PM_SUBTRACTION_KERNEL_ISIS: {
    136136              psArray *preCalc = kernels->preCalc->data[i]; // Precalculated values
     137#if 0
    137138              psVector *xKernel = preCalc->data[0]; // Kernel in x
    138139              psVector *yKernel = preCalc->data[1]; // Kernel in y
    139140              // Iterating over the kernel
    140141              for (int y = 0, v = -size; v <= size; y++, v++) {
     142                  float yValue = value * yKernel->data.F32[y];
    141143                  for (int x = 0, u = -size; u <= size; x++, u++) {
    142                       kernel->kernel[v][u] +=  value * xKernel->data.F32[x] * yKernel->data.F32[y];
     144                      kernel->kernel[v][u] +=  yValue * xKernel->data.F32[x];
    143145                  }
    144146              }
     
    147149                  kernel->kernel[0][0] -= value;
    148150              }
     151#else
     152              psKernel *k = preCalc->data[2]; // Kernel image
     153              for (int v = -size; v <= size; v++) {
     154                  for (int u = -size; u <= size; u++) {
     155                      kernel->kernel[v][u] +=  value * k->kernel[v][u];
     156                  }
     157              }
     158#endif
    149159              break;
    150160          }
     
    597607      case PM_SUBTRACTION_KERNEL_ISIS: {
    598608          psArray *preCalc = kernels->preCalc->data[index]; // Precalculated values
     609#if 1
    599610          psVector *xKernel = preCalc->data[0]; // Kernel in x
    600611          psVector *yKernel = preCalc->data[1]; // Kernel in y
     
    640651          }
    641652          return convolved;
     653#else
     654          return p_pmSubtractionConvolveStampPrecalc(image, preCalc->data[2]);
     655#endif
     656
    642657      }
    643658      case PM_SUBTRACTION_KERNEL_RINGS: {
  • branches/pap/psModules/src/imcombine/pmSubtractionEquation.c

    r24844 r25833  
    1515#include "pmSubtractionVisual.h"
    1616
    17 // #define TESTING                         // TESTING output for debugging; may not work with threads!
     17//#define TESTING                         // TESTING output for debugging; may not work with threads!
    1818
    1919#define USE_VARIANCE                    // Include variance in equation?
     
    2222// Private (file-static) functions
    2323//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     24
     25#if 1
     26// Calculate the least-squares matrix and vector
     27static bool calculateMatrixVector(psImage *matrix, // Least-squares matrix, updated
     28                                  psVector *vector, // Least-squares vector, updated
     29                                  const psKernel *input, // Input image (target)
     30                                  const psKernel *reference, // Reference image (convolution source)
     31                                  const psKernel *variance,  // Variance image
     32                                  const psArray *convolutions,         // Convolutions for each kernel
     33                                  const pmSubtractionKernels *kernels, // Kernels
     34                                  const psImage *polyValues, // Spatial polynomial values
     35                                  int footprint // (Half-)Size of stamp
     36                                  )
     37{
     38    // (I - R * sum_i a_i k_i - g) (R * k_j) = 0
     39    // I C_j = sum_i C_i C_j
     40
     41    // Background: C_i = 1.0
     42    // Normalisation: C_i = R
     43
     44    int numKernels = kernels->num;                      // Number of kernels
     45    int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation
     46    int bgIndex = PM_SUBTRACTION_INDEX_BG(kernels); // Index in matrix for background
     47    int spatialOrder = kernels->spatialOrder;       // Order of spatial variation
     48    int numPoly = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of polynomial terms
     49    double poly[numPoly];                                 // Polynomial terms
     50    double poly2[numPoly][numPoly];                       // Polynomial-polynomial values
     51
     52    // Evaluate polynomial-polynomial terms
     53    for (int iyOrder = 0, iIndex = 0; iyOrder <= spatialOrder; iyOrder++) {
     54        for (int ixOrder = 0; ixOrder <= spatialOrder - iyOrder; ixOrder++, iIndex++) {
     55            double iPoly = polyValues->data.F64[iyOrder][ixOrder]; // Value of polynomial
     56            poly[iIndex] = iPoly;
     57            for (int jyOrder = 0, jIndex = 0; jyOrder <= spatialOrder; jyOrder++) {
     58                for (int jxOrder = 0; jxOrder <= spatialOrder - jyOrder; jxOrder++, jIndex++) {
     59                    double jPoly = polyValues->data.F64[jyOrder][jxOrder];
     60                    poly2[iIndex][jIndex] = iPoly * jPoly;
     61                }
     62            }
     63        }
     64    }
     65
     66
     67    for (int i = 0; i < numKernels; i++) {
     68        psKernel *iConv = convolutions->data[i]; // Convolution for index i
     69        for (int j = i; j < numKernels; j++) {
     70            psKernel *jConv = convolutions->data[j]; // Convolution for index j
     71
     72            double sumCC = 0.0;         // Sum of convolution products
     73            for (int y = - footprint; y <= footprint; y++) {
     74                for (int x = - footprint; x <= footprint; x++) {
     75                    double cc = iConv->kernel[y][x] * jConv->kernel[y][x];
     76#ifdef USE_VARIANCE
     77                    cc /= variance->kernel[y][x];
     78#endif
     79                    sumCC += cc;
     80                }
     81            }
     82
     83            // Spatial variation
     84            for (int iTerm = 0, iIndex = i; iTerm < numPoly; iTerm++, iIndex += numKernels) {
     85                for (int jTerm = 0, jIndex = j; jTerm < numPoly; jTerm++, jIndex += numKernels) {
     86                    double value = sumCC * poly2[iTerm][jTerm];
     87                    matrix->data.F64[iIndex][jIndex] = value;
     88                    matrix->data.F64[jIndex][iIndex] = value;
     89                }
     90            }
     91        }
     92
     93        double sumRC = 0.0;             // Sum of the reference-convolution products
     94        double sumIC = 0.0;             // Sum of the input-convolution products
     95        double sumC = 0.0;              // Sum of the convolution
     96        for (int y = - footprint; y <= footprint; y++) {
     97            for (int x = - footprint; x <= footprint; x++) {
     98                float conv = iConv->kernel[y][x];
     99                float in = input->kernel[y][x];
     100                float ref = reference->kernel[y][x];
     101                double ic = in * conv;
     102                double rc = ref * conv;
     103                double c = conv;
     104#ifdef USE_VARIANCE
     105                float varVal = 1.0 / variance->kernel[y][x];
     106                ic *= varVal;
     107                rc *= varVal;
     108                c *= varVal;
     109#endif
     110                sumIC += ic;
     111                sumRC += rc;
     112                sumC += c;
     113            }
     114        }
     115        // Spatial variation
     116        for (int iTerm = 0, iIndex = i; iTerm < numPoly; iTerm++, iIndex += numKernels) {
     117            double normTerm = sumRC * poly[iTerm];
     118            double bgTerm = sumC * poly[iTerm];
     119            matrix->data.F64[iIndex][normIndex] = normTerm;
     120            matrix->data.F64[normIndex][iIndex] = normTerm;
     121            matrix->data.F64[iIndex][bgIndex] = bgTerm;
     122            matrix->data.F64[bgIndex][iIndex] = bgTerm;
     123            vector->data.F64[iIndex] = sumIC * poly[iTerm];
     124        }
     125    }
     126
     127    double sumRR = 0.0;                 // Sum of the reference product
     128    double sumIR = 0.0;                 // Sum of the input-reference product
     129    double sum1 = 0.0;                  // Sum of the background
     130    double sumR = 0.0;                  // Sum of the reference
     131    double sumI = 0.0;                  // Sum of the input
     132    for (int y = - footprint; y <= footprint; y++) {
     133        for (int x = - footprint; x <= footprint; x++) {
     134            double in = input->kernel[y][x];
     135            double ref = reference->kernel[y][x];
     136            double ir = in * ref;
     137            double rr = PS_SQR(ref);
     138#ifdef USE_VARIANCE
     139            float varVal = 1.0 / variance->kernel[y][x];
     140            rr *= varVal;
     141            ir *= varVal;
     142            in *= varVal;
     143            ref *= varVal;
     144#endif
     145            sumRR += rr;
     146            sumIR += ir;
     147            sumR += ref;
     148            sumI += in;
     149            sum1 += 1.0;
     150        }
     151    }
     152    matrix->data.F64[normIndex][normIndex] = sumRR;
     153    matrix->data.F64[bgIndex][bgIndex] = sum1;
     154    matrix->data.F64[normIndex][bgIndex] = matrix->data.F64[bgIndex][normIndex] = sumR;
     155    vector->data.F64[normIndex] = sumIR;
     156    vector->data.F64[bgIndex] = sumI;
     157
     158    return true;
     159}
     160
     161#if 0
     162// Calculate the least-squares matrix and vector for dual convolution
     163static bool calculateDualMatrixVector(psImage *matrix1, // Least-squares matrix, updated
     164                                      psVector *vector1, // Least-squares vector, updated
     165                                      psImage *matrix2,  // Least-squares matrix, updated
     166                                      psVector *vector2, // Least-squares vector, updated
     167                                      psImage *matrixX,  // Cross-matrix
     168                                      const psKernel *input, // Input image (target)
     169                                      const psKernel *reference, // Reference image (convolution source)
     170                                      const psKernel *variance,  // Variance image
     171                                      const psArray *convolutions,         // Convolutions for each kernel
     172                                      const pmSubtractionKernels *kernels, // Kernels
     173                                      const psImage *polyValues, // Spatial polynomial values
     174                                      int footprint // (Half-)Size of stamp
     175                                      )
     176{
     177    // (I - R * sum_i a_i k_i - g) (R * k_j) = 0
     178    // I C_j = sum_i C_i C_j
     179
     180    // Background: C_i = 1.0
     181    // Normalisation: C_i = R
     182
     183    int numKernels = kernels->num;                      // Number of kernels
     184    int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation
     185    int bgIndex = PM_SUBTRACTION_INDEX_BG(kernels); // Index in matrix for background
     186    int spatialOrder = kernels->spatialOrder;       // Order of spatial variation
     187    int numPoly = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of polynomial terms
     188    double poly[numPoly];                                 // Polynomial terms
     189    double poly2[numPoly][numPoly];                       // Polynomial-polynomial values
     190
     191    // Evaluate polynomial-polynomial terms
     192    for (int iyOrder = 0, iIndex = 0; iyOrder <= spatialOrder; iyOrder++) {
     193        for (int ixOrder = 0; ixOrder <= spatialOrder - iyOrder; ixOrder++, iIndex++) {
     194            double iPoly = polyValues->data.F64[iyOrder][ixOrder]; // Value of polynomial
     195            poly[iIndex] = iPoly;
     196            for (int jyOrder = 0, jIndex = 0; jyOrder <= spatialOrder; jyOrder++) {
     197                for (int jxOrder = 0; jxOrder <= spatialOrder - jyOrder; jxOrder++, jIndex++) {
     198                    double jPoly = polyValues->data.F64[jyOrder][jxOrder];
     199                    poly2[iIndex][jIndex] = iPoly * jPoly;
     200                }
     201            }
     202        }
     203    }
     204
     205
     206    for (int i = 0; i < numKernels; i++) {
     207        psKernel *iConv = convolutions->data[i]; // Convolution for index i
     208        for (int j = i; j < numKernels; j++) {
     209            psKernel *jConv = convolutions->data[j]; // Convolution for index j
     210
     211            double sumCC = 0.0;         // Sum of convolution products
     212            for (int y = - footprint; y <= footprint; y++) {
     213                for (int x = - footprint; x <= footprint; x++) {
     214                    double cc = iConv->kernel[y][x] * jConv->kernel[y][x];
     215#ifdef USE_VARIANCE
     216                    cc /= variance->kernel[y][x];
     217#endif
     218                    sumCC += cc;
     219                }
     220            }
     221
     222            // Spatial variation
     223            for (int iTerm = 0, iIndex = i; iTerm < numPoly; iTerm++, iIndex += numKernels) {
     224                for (int jTerm = 0, jIndex = j; jTerm < numPoly; jTerm++, jIndex += numKernels) {
     225                    double value = sumCC * poly2[iTerm][jTerm];
     226                    matrix->data.F64[iIndex][jIndex] = value;
     227                    matrix->data.F64[jIndex][iIndex] = value;
     228                }
     229            }
     230        }
     231
     232        double sumRC = 0.0;             // Sum of the reference-convolution products
     233        double sumIC = 0.0;             // Sum of the input-convolution products
     234        double sumC = 0.0;              // Sum of the convolution
     235        for (int y = - footprint; y <= footprint; y++) {
     236            for (int x = - footprint; x <= footprint; x++) {
     237                float conv = iConv->kernel[y][x];
     238                float in = input->kernel[y][x];
     239                float ref = reference->kernel[y][x];
     240                double ic = in * conv;
     241                double rc = ref * conv;
     242                double c = conv;
     243#ifdef USE_VARIANCE
     244                float varVal = 1.0 / variance->kernel[y][x];
     245                ic *= varVal;
     246                rc *= varVal;
     247                c *= varVal;
     248#endif
     249                sumIC += ic;
     250                sumRC += rc;
     251                sumC += c;
     252            }
     253        }
     254        // Spatial variation
     255        for (int iTerm = 0, iIndex = i; iTerm < numPoly; iTerm++, iIndex += numKernels) {
     256            double normTerm = sumRC * poly[iTerm];
     257            double bgTerm = sumC * poly[iTerm];
     258            matrix->data.F64[iIndex][normIndex] = normTerm;
     259            matrix->data.F64[normIndex][iIndex] = normTerm;
     260            matrix->data.F64[iIndex][bgIndex] = bgTerm;
     261            matrix->data.F64[bgIndex][iIndex] = bgTerm;
     262            vector->data.F64[iIndex] = sumIC * poly[iTerm];
     263        }
     264    }
     265
     266    double sumRR = 0.0;                 // Sum of the reference product
     267    double sumIR = 0.0;                 // Sum of the input-reference product
     268    double sum1 = 0.0;                  // Sum of the background
     269    double sumR = 0.0;                  // Sum of the reference
     270    double sumI = 0.0;                  // Sum of the input
     271    for (int y = - footprint; y <= footprint; y++) {
     272        for (int x = - footprint; x <= footprint; x++) {
     273            double in = input->kernel[y][x];
     274            double ref = reference->kernel[y][x];
     275            double ir = in * ref;
     276            double rr = PS_SQR(ref);
     277#ifdef USE_VARIANCE
     278            float varVal = 1.0 / variance->kernel[y][x];
     279            rr *= varVal;
     280            ir *= varVal;
     281            in *= varVal;
     282            ref *= varVal;
     283#endif
     284            sumRR += rr;
     285            sumIR += ir;
     286            sumR += ref;
     287            sumI += in;
     288            sum1 += 1.0;
     289        }
     290    }
     291    matrix->data.F64[normIndex][normIndex] = sumRR;
     292    matrix->data.F64[bgIndex][bgIndex] = sum1;
     293    matrix->data.F64[normIndex][bgIndex] = matrix->data.F64[bgIndex][normIndex] = sumR;
     294    vector->data.F64[normIndex] = sumIR;
     295    vector->data.F64[bgIndex] = sumI;
     296
     297    return true;
     298}
     299#endif
     300#endif
     301
    24302
    25303// Calculate the sum over a stamp product
     
    582860    switch (kernels->mode) {
    583861      case PM_SUBTRACTION_MODE_1:
     862#if 0
    584863        status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,
    585864                                 stamp->variance, polyValues, footprint, true);
    586865        status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,
    587866                                  stamp->image2, stamp->variance, polyValues, footprint, true);
     867#else
     868        status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image2, stamp->image1,
     869                                       stamp->variance, stamp->convolutions1, kernels, polyValues,
     870                                       footprint);
     871#endif
    588872        break;
    589873      case PM_SUBTRACTION_MODE_2:
     874#if 0
    590875        status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions2, stamp->image2,
    591876                                 stamp->variance, polyValues, footprint, true);
    592877        status &= calculateVector(stamp->vector1, kernels, stamp->convolutions2, stamp->image2,
    593878                                  stamp->image1, stamp->variance, polyValues, footprint, true);
     879#else
     880        status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image1, stamp->image2,
     881                                       stamp->variance, stamp->convolutions2, kernels, polyValues,
     882                                       footprint);
     883#endif
    594884        break;
    595885      case PM_SUBTRACTION_MODE_DUAL:
     
    629919
    630920#ifdef TESTING
    631     if (psTraceGetLevel("psModules.imcombine.equation") >= 10) {
     921    {
    632922        psString matrixName = NULL;
    633923        psStringAppend(&matrixName, "matrix1_%d.fits", index);
  • branches/pap/psModules/src/imcombine/pmSubtractionKernels.c

    r25120 r25833  
    140140        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
    141141            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    142                 psArray *preCalc = psArrayAlloc(2); // Array to hold precalculated values
     142                psArray *preCalc = psArrayAlloc(3); // Array to hold precalculated values
    143143                psVector *xKernel = preCalc->data[0] = subtractionKernelISIS(sigma, uOrder, size); // x Kernel
    144144                psVector *yKernel = preCalc->data[1] = subtractionKernelISIS(sigma, vOrder, size); // y Kernel
     145                psKernel *kernel = preCalc->data[2] = psKernelAlloc(-size, size, -size, size);      // Kernel
    145146
    146147                // Calculate moments
     
    149150                    for (int u = -size, x = 0; u <= size; u++, x++) {
    150151                        double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel
     152                        kernel->kernel[v][u] = value;
    151153                        moment += value * (PS_SQR(u) + PS_SQR(v));
    152154                    }
     
    164166                    psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
    165167                    psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
     168                    psBinaryOp(kernel->image, kernel->image, "*", psScalarAlloc(PS_SQR(sum), PS_TYPE_F32));
     169                    kernel->kernel[0][0] -= 1.0;
    166170                    moment *= PS_SQR(sum);
    167171                }
Note: See TracChangeset for help on using the changeset viewer.