Changeset 5813 for trunk/psLib/src/math/psPolynomial.c
- Timestamp:
- Dec 19, 2005, 1:58:47 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psPolynomial.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psPolynomial.c
r5624 r5813 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.13 3$ $Name: not supported by cvs2svn $10 * @date $Date: 2005-1 1-30 02:00:09$9 * @version $Revision: 1.134 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2005-12-19 23:58:47 $ 11 11 * 12 12 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 165 165 not nOrder. 166 166 *****************************************************************************/ 167 static psPolynomial1D **createChebyshevPolys(psS32 maxChebyPoly) 167 psPolynomial1D **createChebyshevPolys(psS32 numPolys) 168 { 169 PS_ASSERT_INT_LARGER_THAN_OR_EQUAL(numPolys, 1, NULL); 170 171 if (0) { 172 psPolynomial1D **chebPolys = (psPolynomial1D **) psAlloc(numPolys * sizeof(psPolynomial1D *)); 173 for (psS32 i = 0; i < numPolys; i++) { 174 chebPolys[i] = psPolynomial1DAlloc(i, PS_POLYNOMIAL_ORD); 175 chebPolys[i]->coeff[i] = 1; 176 } 177 return (chebPolys); 178 } else { 179 psPolynomial1D **chebPolys = (psPolynomial1D **) psAlloc(numPolys * sizeof(psPolynomial1D *)); 180 for (psS32 i = 0; i < numPolys; i++) { 181 chebPolys[i] = psPolynomial1DAlloc(i, PS_POLYNOMIAL_ORD); 182 } 183 184 // Create the Chebyshev polynomials. 185 // Polynomial i has i-th order. 186 chebPolys[0]->coeff[0] = 1.0; 187 if (numPolys >= 2) { 188 chebPolys[1]->coeff[1] = 1.0; 189 190 for (psS32 i = 2; i < numPolys; i++) { 191 for (psS32 j = 0; j < chebPolys[i - 1]->nX+1; j++) { 192 chebPolys[i]->coeff[j + 1] = 2.0 * chebPolys[i - 1]->coeff[j]; 193 } 194 for (psS32 j = 0; j < chebPolys[i - 2]->nX+1; j++) { 195 chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j]; 196 } 197 } 198 } 199 200 return (chebPolys); 201 } 202 } 203 204 /* 205 static psPolynomial1D **createChebyshevPolysOld(psS32 maxChebyPoly) 168 206 { 169 207 PS_ASSERT_INT_NONNEGATIVE(maxChebyPoly, NULL); 170 208 171 209 psPolynomial1D **chebPolys = NULL; 172 210 173 211 chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *)); 174 212 for (psS32 i = 0; i < maxChebyPoly; i++) { 175 213 chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD); 176 214 } 177 215 178 216 // Create the Chebyshev polynomials. 179 217 // Polynomial i has i-th order. 180 218 chebPolys[0]->coeff[0] = 1; 181 219 182 220 // XXX: Bug 296 183 221 if (maxChebyPoly > 1) { 184 222 chebPolys[1]->coeff[1] = 1; 185 223 186 224 for (psS32 i = 2; i < maxChebyPoly; i++) { 187 225 for (psS32 j = 0; j < chebPolys[i - 1]->nX; j++) { … … 196 234 printf("WARNING: %u-order chebyshev polynomials not correctly implemented.\n", maxChebyPoly); 197 235 } 198 236 199 237 return (chebPolys); 200 238 } 239 */ 201 240 202 241 /***************************************************************************** … … 236 275 // XXX: How does the mask vector effect Crenshaw's formula? 237 276 // XXX: We assume that x is scaled between -1.0 and 1.0; 238 static psF64 chebPolynomial1DEval(psF64 x, 239 const psPolynomial1D* poly) 240 { 241 PS_ASSERT_DOUBLE_WITHIN_RANGE(x, -1.0, 1.0, 0.0); 242 // XXX: Create a macro for this in psConstants.h 243 if (poly->nX < 1) { 244 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Error: Chebyshev polynomial is order %u.", poly->nX); 245 return(NAN); 246 } 277 // XXX: Create a faster version for low-order Chebyshevs. 278 static psF64 chebPolynomial1DEval( 279 psF64 x, 280 const psPolynomial1D* poly) 281 { 282 PS_ASSERT_DOUBLE_WITHIN_RANGE(x, -1.0, 1.0, NAN); 283 PS_ASSERT_INT_LARGER_THAN_OR_EQUAL(poly->nX, 0, NAN); 247 284 psVector *d; 285 248 286 // XXX: n should be nTerms here (for clarity). Or get rid of the variable. 249 unsigned int n = 1 + poly->nX;287 unsigned int nTerms = 1 + poly->nX; 250 288 unsigned int i; 251 289 psF64 tmp = 0.0; 252 290 253 291 // Special case where the Chebyshev poly is constant. 254 if (n == 1) {292 if (nTerms == 1) { 255 293 if (poly->mask[0] == 0) { 256 294 tmp += poly->coeff[0]; … … 260 298 261 299 // Special case where the Chebyshev poly is linear. 262 if (n == 2) {300 if (nTerms == 2) { 263 301 if (poly->mask[0] == 0) { 264 302 tmp+= poly->coeff[0]; … … 270 308 } 271 309 272 // General case where the Chebyshev poly has 2 or more terms. 273 d = psVectorAlloc(n, PS_TYPE_F64); 274 if(poly->mask[n-1] == 0) { 275 d->data.F64[n-1] = poly->coeff[n-1]; 310 if (1) { 311 // General case where the Chebyshev poly has 2 or more terms. 312 d = psVectorAlloc(nTerms, PS_TYPE_F64); 313 if(poly->mask[nTerms-1] == 0) { 314 d->data.F64[nTerms-1] = poly->coeff[nTerms-1]; 315 } else { 316 d->data.F64[nTerms-1] = 0.0; 317 } 318 319 d->data.F64[nTerms-2] = (2.0 * x * d->data.F64[nTerms-1]); 320 if(poly->mask[nTerms-2] == 0) { 321 d->data.F64[nTerms-2] += poly->coeff[nTerms-2]; 322 } 323 324 for (i=nTerms-3;i>=1;i--) { 325 d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) - 326 (d->data.F64[i+2]); 327 if(poly->mask[i] == 0) { 328 d->data.F64[i] += poly->coeff[i]; 329 } 330 } 331 332 tmp = (x * d->data.F64[1]) - 333 (d->data.F64[2]); 334 if(poly->mask[0] == 0) { 335 tmp += (0.5 * poly->coeff[0]); 336 } 337 psFree(d); 276 338 } else { 277 d->data.F64[n-1] = 0.0; 278 } 279 280 d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]); 281 if(poly->mask[n-2] == 0) { 282 d->data.F64[n-2] += poly->coeff[n-2]; 283 } 284 285 for (i=n-3;i>=1;i--) { 286 d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) - 287 (d->data.F64[i+2]); 288 if(poly->mask[i] == 0) { 289 d->data.F64[i] += poly->coeff[i]; 290 } 291 } 292 293 tmp = (x * d->data.F64[1]) - 294 (d->data.F64[2]); 295 if(poly->mask[0] == 0) { 296 tmp += (0.5 * poly->coeff[0]); 297 } 298 psFree(d); 339 // This is old code that does not use Clenshaw's formula. Get rid of it. 340 psPolynomial1D **chebPolys = createChebyshevPolys(1 + poly->nX); 341 342 tmp = 0.0; 343 for (psS32 i=0;i<(1 + poly->nX);i++) { 344 tmp+= (poly->coeff[i] * psPolynomial1DEval(chebPolys[i], x)); 345 } 346 tmp-= (poly->coeff[0]/2.0); 347 348 for (psS32 i=0;i<(1 + poly->nX);i++) { 349 psFree(chebPolys[i]); 350 } 351 psFree(chebPolys); 352 } 353 299 354 return(tmp); 300 301 /* This is old code that does not use Clenshaw's formula. Get rid of it.302 303 psS32 i;304 psF32 tmp;305 psPolynomial1D **chebPolys = NULL;306 307 chebPolys = createChebyshevPolys(1 + poly->nX);308 309 tmp = 0.0;310 for (i=0;i<(1 + poly->nX);i++) {311 tmp+= (poly->coeff[i] * psPolynomial1DEval(x, chebPolys[i]));312 }313 tmp-= (poly->coeff[0]/2.0);314 315 316 return(tmp);317 */318 355 } 319 356 … … 628 665 newPoly->type = type; 629 666 newPoly->nX = n; 667 newPoly->p_min = NAN; 668 newPoly->p_max = NAN; 630 669 newPoly->coeff = psAlloc((n + 1) * sizeof(psF64)); 631 670 newPoly->coeffErr = psAlloc((n + 1) * sizeof(psF64));
Note:
See TracChangeset
for help on using the changeset viewer.
