Changeset 750 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- May 20, 2004, 3:04:45 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r738 r750 13 13 #include "psFunctions.h" 14 14 #include "psSort.h" 15 16 15 #include "float.h" 17 16 #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) 20 int MyInfoLevel = 0; 19 21 /****************************************************************************** 20 22 This routine must minimize an arbitrary function. … … 43 45 } 44 46 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 */ 51 void 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 */ 95 void 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 */ 154 void 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 */ 211 void 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 45 286 /****************************************************************************** 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). 47 290 *****************************************************************************/ 48 291 psPolynomial1D *
Note:
See TracChangeset
for help on using the changeset viewer.
