IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 20, 2004, 3:04:45 PM (22 years ago)
Author:
gusciora
Message:

...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/dataManip/psMinimize.c

    r738 r750  
    1313#include "psFunctions.h"
    1414#include "psSort.h"
    15 
    1615#include "float.h"
    1716#include <math.h>
    18 
     17// GUS: rewrite so there is no maximum order for the polynomials.
     18#define MAX_POLY_ORDER 10
     19#define MAX_POLYNOMIAL_TERMS  (((MAX_POLY_ORDER+1) * (MAX_POLY_ORDER + 2)) / 2)
     20int MyInfoLevel = 0;
    1921/******************************************************************************
    2022    This routine must minimize an arbitrary function.
     
    4345}
    4446
     47/** @brief This procedure calculates various combinations of powers of x and y
     48 *   and stores them in the data structure sums[][].  After it completes:
     49 *          sums[i][j] == x^i * y^j
     50 */
     51void buildSums(double x,
     52               double y,
     53               /*@out@*/double sums[MAX_POLY_ORDER+1][MAX_POLY_ORDER+1],
     54               int polyOrder)
     55{
     56    int         i = 0;          // loop index variable
     57    int         j = 0;          // loop index variable
     58    double       xSum = 0.0;    // The running sum of X terms
     59    double       ySum = 0.0;    // The running sum of Y terms
     60
     61    xSum = 1.0;
     62    ySum = 1.0;
     63    for(i=0;i<=polyOrder;i++) {
     64        ySum = xSum;
     65        for(j=0;j<=polyOrder;j++) {
     66            sums[i][j] = ySum;
     67            ySum*= y;
     68        }
     69        xSum*= x;
     70    }
     71}
     72
     73/** @brief The coefficients of the matrix in equation (7) from the ADD will
     74 * be very large if the x and y values are in the 0-511 range (ie: the sum y^7
     75 * for all 0<y<512).  In order to avoid potential numerical instability, we
     76 * added ability to scale those x,y values arbitrarily.  The following code
     77 * creates a 1-D matrix imageScalingFactors[] which holds the scaled down
     78 * values of x,y: the i-th element of imageScalingFactors[] contains the scaled
     79 * down value for x=i, or y=i.
     80 *
     81 *     Input:
     82 *     <ul>
     83 *         <li>height
     84 *         <li>width
     85 *     </ul>
     86 *
     87 *     Output:
     88 *     <ul>
     89 *         <li>imageScalingFactors
     90 *     </ul>
     91 *
     92 * @return error status (PsError) indicating error information, or NULL on
     93 * success.
     94 */
     95void buildImageScalingFactors(int height,
     96                              int width,
     97                              float **imageScalingFactors)
     98{
     99    int maxDim = 0;             // The largest dimension of the image.
     100    int i = 0;                  // loop index variable.
     101
     102    // Calculate the maximum dimensional extent of the image.
     103    if (height > width) {
     104        maxDim = height;
     105    } else {
     106        maxDim = width;
     107    }
     108
     109
     110    // Allocate memory for the output array.
     111    *imageScalingFactors = (float *) psAlloc((maxDim+10) * sizeof(float));
     112
     113    // This code is somewhat arbitrary.  For an image with a height/width
     114    // of 512x512, the scaling factors will be between 0.0-1.0.
     115    for (i=0;i<maxDim;i++) {
     116        (*imageScalingFactors)[i] = (((float) i) / ((float) maxDim)) - 0.5;
     117        //        (*imageScalingFactors)[i] = ((float) i);
     118    }
     119}
     120
     121
     122/** @brief buildPolyTerms(): this routine computes a 3-D array polyTerms[] that
     123 *         holds terms for the polynomial that is used to model the sky
     124 *         background.  We use this array primarily for convenience in many
     125 *         computations involving that sky model polynomials. It is defined as:
     126 *
     127 *             polyTerms[poly][i][0] = the power to which X is raised in the
     128 *         i-th term of in an poly-order sky
     129 *         background polynomial</P>.
     130 *             polyTerms[poly][i][1] = the power to which Y is raised in the
     131 *         i-th term of in an poly-order sky
     132 *         background polynomial</P>.
     133 *
     134 *    NOTE: the C_0 term defined in the ADD begins at i=2 in our data
     135 *        structures (ie. the x/y powers of the i-th term in the sky model
     136 *        polynomial are actually stored at polyTerms[][i+2][].  There are two
     137 *        reasons for this.  First, there is a term prior to C_0 in equation
     138 *        (7) of the ADD.  Second, our linear algebra codes assume data is
     139 *        stored offset from index 1.
     140 *
     141 *     Input:
     142 *     <ul>
     143 *         <li>polyTerms[][][]
     144 *     </ul>
     145 *
     146 *     Output:
     147 *     <ul>
     148 *         <li>polyTerms[][][]
     149 *     </ul>
     150 *
     151 * @return error status (PsError) indicating error information, or NULL on
     152 * success.
     153 */
     154void buildPolyTerms(/*@out@*/ int polyTerms[MAX_POLY_ORDER+1][(MAX_POLYNOMIAL_TERMS+2)][2])
     155{
     156    int polyOrder=0;                    // loop index variable.
     157    int i=0;                            // loop index variable.
     158    int term = 0;                       // loop index variable.
     159    int num=0;                          // loop index variable.
     160
     161    for(polyOrder=0;polyOrder<=MAX_POLY_ORDER;polyOrder++) {
     162        // The following 4 terms should not be used in any of the subsequent
     163        // computation.  We initialize them to zero in order to produce stable
     164        // results for debugging purposes should they mistakenly be used.
     165        polyTerms[polyOrder][0][0] = 0;
     166        polyTerms[polyOrder][0][1] = 0;
     167        polyTerms[polyOrder][1][0] = 0;
     168        polyTerms[polyOrder][1][1] = 0;
     169
     170        // This code segment loops through each term i in the polynomial and
     171        // calculates the power to which x/y are raised in that i-th term.
     172        i=2;
     173        for (term=0;term<=polyOrder;term++) {
     174            for (num=0;num<=term;num++) {
     175                polyTerms[polyOrder][i][0] = term-num;
     176                polyTerms[polyOrder][i][1] = num;
     177                if (MyInfoLevel > 2) {
     178                    printf("%d-th order Sky polynomial term %d is x^%d y^%d\n",
     179                           polyOrder, i,
     180                           polyTerms[polyOrder][i][0], polyTerms[polyOrder][i][1]);
     181                }
     182                i++;
     183            }
     184        }
     185    }
     186}
     187
     188
     189/** @brief This routine checks if all polyOrder-th terms in the polyOrder-th
     190 * order sky background polynomial defined by the coefficients in the array B[]
     191 * are consistent with zero.  If true, then *flag is set to 1.  Otherwise,
     192 * *flag is set to 0.  The matrix inversion code in the middle of this
     193 * procedure draws from Numerical Recipes in C page 48.
     194 *
     195 *     Input:
     196 *     <ul>
     197 *         <li> A       This is the LUD decomposition of the original matrix A.
     198 *         <li> N       The size of the matrix (plus 1, actually, since offset 1).
     199 *         <li> indx    misc Numerical Recipes data structure.
     200 *         <li> B       The coefficients of the sky polynomial.
     201 *         <li> polyOrder The degree of the sky polynomial.
     202 *     </ul>
     203 *     Output:
     204 *     <ul>
     205 *         <li> *flag   Set this to 1 if we must recalculate the coefficients.
     206 *     </ul>
     207 *
     208 * @return error status (PsError) indicating error information, or NULL on
     209 * success.
     210 */
     211void polyOrderCheck(float **A,
     212                    int N,
     213                    int *indx,
     214                    float *B,
     215                    int polyOrder,
     216                    int *flag)
     217{
     218    float     **y = NULL;  // This 2-D matrix will hold A^-1
     219    float      *col = NULL;             // misc NumerRecipes data structure
     220    float      *error=NULL;             // will hold the sqrt() of the
     221    // diagonal of y[][].
     222    int         i=0;                    // loop-index variable
     223    int         j=0;                    // loop-index variable
     224    int         numPolyTerms = 0;       // The number of terms in the
     225    // polynomial.
     226    int         lastTerm = 0;           // The index location of the first
     227    // n-th order term in array B[].
     228    int         firstTerm = 0;          // Index location of last such term.
     229
     230    // Allocate the necessary data structures for this procedure...
     231    error = (float *) psAlloc((N + 1) * sizeof(float));
     232    col = (float *) psAlloc((N + 1) * sizeof(float));
     233    y = (float **) psAlloc((N + 1) * sizeof(float *));
     234    for(i=1;i<=N;i++) {
     235        y[i] = (float *) psAlloc((N + 1) * sizeof(float));
     236    }
     237
     238    // Invert the matrix A and put the result in y[][].  This code is taken
     239    // from Numerical Recipes in C page 48.
     240    for(j=1;j<=N;j++) {
     241        for(i=1;i<=N;i++) {
     242            col[i] = 0.0;
     243        }
     244        col[j] = 1.0;
     245        // GUS: substitue the LUD rotine
     246        //        lubksb(A, N, indx, col);
     247        for(i=1;i<=N;i++) {
     248            y[i][j] = col[i];
     249        }
     250    }
     251
     252    // Determine where the first n-th order (in this comment, n equals
     253    // polyOrder) polynomial term is stored in the matrix B[], and also were
     254    // the last n-order term is stored.  Then we loop over all the n-order
     255    // terms and check if they are consistent with zero.
     256
     257    numPolyTerms = (((polyOrder+1) * (polyOrder + 2)) / 2);
     258    lastTerm = numPolyTerms + 1;
     259    firstTerm = lastTerm - polyOrder;
     260    *flag = 1;
     261    for (i=firstTerm; i<=lastTerm; i++) {
     262        error[i] = sqrtf(y[i][i]);
     263        if (!((B[i]  <= (2.0f * error[i])) &&
     264                ((-2.0f * error[i]) <= B[i]))) {
     265            *flag = 0;
     266        }
     267    }
     268
     269    // Free all memory allocated in this routine.
     270    psFree(error);
     271    psFree(col);
     272    for(j=1;j<=N;j++) {
     273        psFree(y[j]);
     274    }
     275    psFree(y);
     276}
     277
     278
     279
     280
     281
     282
     283
     284
     285
    45286/******************************************************************************
    46     This routine must minimize an arbotrary function.
     287    This routine must fit a polynomial of degree myPoly to the data points
     288    (x, y) and return the coefficients of that polynomial, as well as the
     289    error for each data poiny (yErr).
    47290 *****************************************************************************/
    48291psPolynomial1D *
Note: See TracChangeset for help on using the changeset viewer.