Changeset 2273 for trunk/psLib/src/math/psSpline.c
- Timestamp:
- Nov 3, 2004, 3:05:00 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psSpline.c (modified) (40 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psSpline.c
r2224 r2273 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.5 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-1 0-28 00:22:53$9 * @version $Revision: 1.59 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-11-04 01:04:59 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 35 35 #include "psFunctions.h" 36 36 #include "psConstants.h" 37 38 #include "psDataManipErrors.h" 39 37 40 /*****************************************************************************/ 38 41 /* DEFINE STATEMENTS */ … … 50 53 static void dPolynomial3DFree(psDPolynomial3D* myPoly); 51 54 static void dPolynomial4DFree(psDPolynomial4D* myPoly); 55 static void spline1DFree(psSpline1D *tmpSpline); 56 static psS32 vectorBinDisectF32(float *bins,psS32 numBins,float x); 57 static psS32 vectorBinDisectS32(psS32 *bins,psS32 numBins,psS32 x); 52 58 53 59 /*****************************************************************************/ … … 67 73 /*****************************************************************************/ 68 74 75 static void spline1DFree(psSpline1D *tmpSpline) 76 { 77 psS32 i; 78 79 if (tmpSpline == NULL) { 80 return; 81 } 82 83 if (tmpSpline->spline != NULL) { 84 for (i=0;i<tmpSpline->n;i++) { 85 psFree((tmpSpline->spline)[i]); 86 } 87 psFree(tmpSpline->spline); 88 } 89 90 if (tmpSpline->p_psDeriv2 != NULL) { 91 psFree(tmpSpline->p_psDeriv2); 92 } 93 psFree(tmpSpline->domains); 94 95 return; 96 } 97 98 static void polynomial1DFree(psPolynomial1D* myPoly) 99 { 100 psFree(myPoly->coeff); 101 psFree(myPoly->coeffErr); 102 psFree(myPoly->mask); 103 } 104 105 static void polynomial2DFree(psPolynomial2D* myPoly) 106 { 107 psS32 x = 0; 108 109 for (x = 0; x < myPoly->nX; x++) { 110 psFree(myPoly->coeff[x]); 111 psFree(myPoly->coeffErr[x]); 112 psFree(myPoly->mask[x]); 113 } 114 psFree(myPoly->coeff); 115 psFree(myPoly->coeffErr); 116 psFree(myPoly->mask); 117 } 118 119 static void polynomial3DFree(psPolynomial3D* myPoly) 120 { 121 psS32 x = 0; 122 psS32 y = 0; 123 124 for (x = 0; x < myPoly->nX; x++) { 125 for (y = 0; y < myPoly->nY; y++) { 126 psFree(myPoly->coeff[x][y]); 127 psFree(myPoly->coeffErr[x][y]); 128 psFree(myPoly->mask[x][y]); 129 } 130 psFree(myPoly->coeff[x]); 131 psFree(myPoly->coeffErr[x]); 132 psFree(myPoly->mask[x]); 133 } 134 135 psFree(myPoly->coeff); 136 psFree(myPoly->coeffErr); 137 psFree(myPoly->mask); 138 } 139 140 static void polynomial4DFree(psPolynomial4D* myPoly) 141 { 142 psS32 w = 0; 143 psS32 x = 0; 144 psS32 y = 0; 145 146 for (w = 0; w < myPoly->nW; w++) { 147 for (x = 0; x < myPoly->nX; x++) { 148 for (y = 0; y < myPoly->nY; y++) { 149 psFree(myPoly->coeff[w][x][y]); 150 psFree(myPoly->coeffErr[w][x][y]); 151 psFree(myPoly->mask[w][x][y]); 152 } 153 psFree(myPoly->coeff[w][x]); 154 psFree(myPoly->coeffErr[w][x]); 155 psFree(myPoly->mask[w][x]); 156 } 157 psFree(myPoly->coeff[w]); 158 psFree(myPoly->coeffErr[w]); 159 psFree(myPoly->mask[w]); 160 } 161 162 psFree(myPoly->coeff); 163 psFree(myPoly->coeffErr); 164 psFree(myPoly->mask); 165 } 166 167 static void dPolynomial1DFree(psDPolynomial1D* myPoly) 168 { 169 psFree(myPoly->coeff); 170 psFree(myPoly->coeffErr); 171 psFree(myPoly->mask); 172 } 173 174 static void dPolynomial2DFree(psDPolynomial2D* myPoly) 175 { 176 psS32 x = 0; 177 178 for (x = 0; x < myPoly->nX; x++) { 179 psFree(myPoly->coeff[x]); 180 psFree(myPoly->coeffErr[x]); 181 psFree(myPoly->mask[x]); 182 } 183 psFree(myPoly->coeff); 184 psFree(myPoly->coeffErr); 185 psFree(myPoly->mask); 186 } 187 188 static void dPolynomial3DFree(psDPolynomial3D* myPoly) 189 { 190 psS32 x = 0; 191 psS32 y = 0; 192 193 for (x = 0; x < myPoly->nX; x++) { 194 for (y = 0; y < myPoly->nY; y++) { 195 psFree(myPoly->coeff[x][y]); 196 psFree(myPoly->coeffErr[x][y]); 197 psFree(myPoly->mask[x][y]); 198 } 199 psFree(myPoly->coeff[x]); 200 psFree(myPoly->coeffErr[x]); 201 psFree(myPoly->mask[x]); 202 } 203 204 psFree(myPoly->coeff); 205 psFree(myPoly->coeffErr); 206 psFree(myPoly->mask); 207 } 208 209 static void dPolynomial4DFree(psDPolynomial4D* myPoly) 210 { 211 psS32 w = 0; 212 psS32 x = 0; 213 psS32 y = 0; 214 215 for (w = 0; w < myPoly->nW; w++) { 216 for (x = 0; x < myPoly->nX; x++) { 217 for (y = 0; y < myPoly->nY; y++) { 218 psFree(myPoly->coeff[w][x][y]); 219 psFree(myPoly->coeffErr[w][x][y]); 220 psFree(myPoly->mask[w][x][y]); 221 } 222 psFree(myPoly->coeff[w][x]); 223 psFree(myPoly->coeffErr[w][x]); 224 psFree(myPoly->mask[w][x]); 225 } 226 psFree(myPoly->coeff[w]); 227 psFree(myPoly->coeffErr[w]); 228 psFree(myPoly->mask[w]); 229 } 230 231 psFree(myPoly->coeff); 232 psFree(myPoly->coeffErr); 233 psFree(myPoly->mask); 234 } 235 69 236 /***************************************************************************** 70 CreateChebyshevPolys(n): this routine takes as input the required order n,237 createChebyshevPolys(n): this routine takes as input the required order n, 71 238 and returns as output as a pointer to an array of n psPolynomial1D 72 239 structures, corresponding to the first n Chebyshev polynomials. … … 76 243 outer coefficients of the Chebyshev polynomials. 77 244 *****************************************************************************/ 78 static psPolynomial1D ** CreateChebyshevPolys(psS32 maxChebyPoly)245 static psPolynomial1D **createChebyshevPolys(psS32 maxChebyPoly) 79 246 { 80 247 PS_INT_CHECK_NON_NEGATIVE(maxChebyPoly, NULL); … … 103 270 104 271 return (chebPolys); 272 } 273 274 /***************************************************************************** 275 Polynomial coefficients will be accessed in [w][x][y][z] fashion. 276 277 XXX: Should the "coeffErr[]" should be used as well? 278 *****************************************************************************/ 279 static float ordPolynomial1DEval(float x, const psPolynomial1D* myPoly) 280 { 281 psS32 loop_x = 0; 282 float polySum = 0.0; 283 float xSum = 1.0; 284 285 psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4, 286 "---- Calling ordPolynomial1DEval(%f)\n", x); 287 psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4, 288 "Polynomial order is %d\n", myPoly->n); 289 for (loop_x = 0; loop_x < myPoly->n; loop_x++) { 290 psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4, 291 "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]); 292 } 293 294 for (loop_x = 0; loop_x < myPoly->n; loop_x++) { 295 if (myPoly->mask[loop_x] == 0) { 296 psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 10, 297 "polysum+= sum*coeff [%f+= (%f * %f)\n", polySum, xSum, myPoly->coeff[loop_x]); 298 polySum += xSum * myPoly->coeff[loop_x]; 299 xSum *= x; 300 } 301 } 302 303 return(polySum); 304 } 305 306 // XXX: You can do this without having to psAlloc() vector d. 307 // XXX: How does the mask vector effect Crenshaw's formula? 308 static float chebPolynomial1DEval(float x, const psPolynomial1D* myPoly) 309 { 310 psVector *d; 311 psS32 n; 312 psS32 i; 313 float tmp; 314 315 n = myPoly->n; 316 d = psVectorAlloc(n, PS_TYPE_F32); 317 d->data.F32[n-1] = myPoly->coeff[n-1]; 318 d->data.F32[n-2] = (2.0 * x * d->data.F32[n-1]) + myPoly->coeff[n-2]; 319 for (i=n-3;i>=1;i--) { 320 d->data.F32[i] = (2.0 * x * d->data.F32[i+1]) - 321 (d->data.F32[i+2]) + 322 (myPoly->coeff[i]); 323 } 324 325 tmp = (x * d->data.F32[1]) - 326 (d->data.F32[2]) + 327 (0.5 * myPoly->coeff[0]); 328 329 psFree(d); 330 return(tmp); 331 /* 332 333 psS32 n; 334 psS32 i; 335 float tmp; 336 psPolynomial1D **chebPolys = NULL; 337 338 n = myPoly->n; 339 chebPolys = createChebyshevPolys(n); 340 341 tmp = 0.0; 342 for (i=0;i<myPoly->n;i++) { 343 tmp+= (myPoly->coeff[i] * psPolynomial1DEval(x, chebPolys[i])); 344 // printf("HMMM: psPolynomial1DEval(%f, chebPolys[%d]) is %f\n", x, i, psPolynomial1DEval(x, chebPolys[i])); 345 } 346 tmp-= (myPoly->coeff[0]/2.0); 347 348 349 return(tmp); 350 */ 351 } 352 353 static float ordPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly) 354 { 355 PS_POLY_CHECK_NULL(myPoly, NAN); 356 357 psS32 loop_x = 0; 358 psS32 loop_y = 0; 359 float polySum = 0.0; 360 float xSum = 1.0; 361 float ySum = 1.0; 362 363 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 364 ySum = xSum; 365 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 366 if (myPoly->mask[loop_x][loop_y] == 0) { 367 polySum += ySum * myPoly->coeff[loop_x][loop_y]; 368 ySum *= y; 369 } 370 } 371 xSum *= x; 372 } 373 374 return(polySum); 375 } 376 377 static float chebPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly) 378 { 379 PS_POLY_CHECK_NULL(myPoly, NAN); 380 381 psS32 loop_x = 0; 382 psS32 loop_y = 0; 383 psS32 i = 0; 384 float polySum = 0.0; 385 psPolynomial1D* *chebPolys = NULL; 386 psS32 maxChebyPoly = 0; 387 388 // Determine how many Chebyshev polynomials 389 // are needed, then create them. 390 maxChebyPoly = myPoly->nX; 391 if (myPoly->nY > maxChebyPoly) { 392 maxChebyPoly = myPoly->nY; 393 } 394 chebPolys = createChebyshevPolys(maxChebyPoly); 395 396 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 397 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 398 if (myPoly->mask[loop_x][loop_y] == 0) { 399 polySum += myPoly->coeff[loop_x][loop_y] * 400 psPolynomial1DEval(x, chebPolys[loop_x]) * 401 psPolynomial1DEval(y, chebPolys[loop_y]); 402 } 403 } 404 } 405 for (i=0;i<maxChebyPoly;i++) { 406 psFree(chebPolys[i]); 407 } 408 psFree(chebPolys); 409 return(polySum); 410 } 411 412 static float ordPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly) 413 { 414 psS32 loop_x = 0; 415 psS32 loop_y = 0; 416 psS32 loop_z = 0; 417 float polySum = 0.0; 418 float xSum = 1.0; 419 float ySum = 1.0; 420 float zSum = 1.0; 421 422 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 423 ySum = xSum; 424 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 425 zSum = ySum; 426 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 427 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) { 428 polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z]; 429 zSum *= z; 430 } 431 } 432 ySum *= y; 433 } 434 xSum *= x; 435 } 436 437 return(polySum); 438 } 439 440 static float chebPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly) 441 { 442 psS32 loop_x = 0; 443 psS32 loop_y = 0; 444 psS32 loop_z = 0; 445 psS32 i = 0; 446 float polySum = 0.0; 447 psPolynomial1D* *chebPolys = NULL; 448 psS32 maxChebyPoly = 0; 449 450 // Determine how many Chebyshev polynomials 451 // are needed, then create them. 452 maxChebyPoly = myPoly->nX; 453 if (myPoly->nY > maxChebyPoly) { 454 maxChebyPoly = myPoly->nY; 455 } 456 if (myPoly->nZ > maxChebyPoly) { 457 maxChebyPoly = myPoly->nZ; 458 } 459 chebPolys = createChebyshevPolys(maxChebyPoly); 460 461 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 462 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 463 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 464 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) { 465 polySum += myPoly->coeff[loop_x][loop_y][loop_z] * 466 psPolynomial1DEval(x, chebPolys[loop_x]) * 467 psPolynomial1DEval(y, chebPolys[loop_y]) * 468 psPolynomial1DEval(z, chebPolys[loop_z]); 469 } 470 } 471 } 472 } 473 474 for (i=0;i<maxChebyPoly;i++) { 475 psFree(chebPolys[i]); 476 } 477 psFree(chebPolys); 478 return(polySum); 479 } 480 481 static float ordPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly) 482 { 483 psS32 loop_w = 0; 484 psS32 loop_x = 0; 485 psS32 loop_y = 0; 486 psS32 loop_z = 0; 487 float polySum = 0.0; 488 float wSum = 1.0; 489 float xSum = 1.0; 490 float ySum = 1.0; 491 float zSum = 1.0; 492 493 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) { 494 xSum = wSum; 495 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 496 ySum = xSum; 497 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 498 zSum = ySum; 499 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 500 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) { 501 polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z]; 502 zSum *= z; 503 } 504 } 505 ySum *= y; 506 } 507 xSum *= x; 508 } 509 wSum *= w; 510 } 511 512 return(polySum); 513 } 514 515 static float chebPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly) 516 { 517 psS32 loop_w = 0; 518 psS32 loop_x = 0; 519 psS32 loop_y = 0; 520 psS32 loop_z = 0; 521 psS32 i = 0; 522 float polySum = 0.0; 523 psPolynomial1D* *chebPolys = NULL; 524 psS32 maxChebyPoly = 0; 525 526 // Determine how many Chebyshev polynomials 527 // are needed, then create them. 528 maxChebyPoly = myPoly->nW; 529 if (myPoly->nX > maxChebyPoly) { 530 maxChebyPoly = myPoly->nX; 531 } 532 if (myPoly->nY > maxChebyPoly) { 533 maxChebyPoly = myPoly->nY; 534 } 535 if (myPoly->nZ > maxChebyPoly) { 536 maxChebyPoly = myPoly->nZ; 537 } 538 chebPolys = createChebyshevPolys(maxChebyPoly); 539 540 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) { 541 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 542 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 543 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 544 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) { 545 polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] * 546 psPolynomial1DEval(w, chebPolys[loop_w]) * 547 psPolynomial1DEval(x, chebPolys[loop_x]) * 548 psPolynomial1DEval(y, chebPolys[loop_y]) * 549 psPolynomial1DEval(z, chebPolys[loop_z]); 550 } 551 } 552 } 553 } 554 } 555 556 for (i=0;i<maxChebyPoly;i++) { 557 psFree(chebPolys[i]); 558 } 559 psFree(chebPolys); 560 return(polySum); 561 } 562 563 /***************************************************************************** 564 Polynomial coefficients will be accessed in [w][x][y][z] fashion. 565 *****************************************************************************/ 566 static double dOrdPolynomial1DEval(double x, const psDPolynomial1D* myPoly) 567 { 568 psS32 loop_x = 0; 569 double polySum = 0.0; 570 double xSum = 1.0; 571 572 for (loop_x = 0; loop_x < myPoly->n; loop_x++) { 573 if (myPoly->mask[loop_x] == 0) { 574 polySum += xSum * myPoly->coeff[loop_x]; 575 xSum *= x; 576 } 577 } 578 579 return(polySum); 580 } 581 582 // XXX: You can do this without having to psAlloc() vector d. 583 // XXX: How does the mask vector effect Crenshaw's formula? 584 static double dChebPolynomial1DEval(double x, const psDPolynomial1D* myPoly) 585 { 586 psVector *d; 587 psS32 n; 588 psS32 i; 589 double tmp; 590 591 n = myPoly->n; 592 d = psVectorAlloc(n, PS_TYPE_F64); 593 d->data.F64[n-1] = myPoly->coeff[n-1]; 594 d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]) + myPoly->coeff[n-2]; 595 for (i=n-3;i>=1;i--) { 596 d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) - 597 (d->data.F64[i+2]) + 598 (myPoly->coeff[i]); 599 } 600 601 tmp = (x * d->data.F64[1]) - 602 (d->data.F64[2]) + 603 (0.5 * myPoly->coeff[0]); 604 605 psFree(d); 606 return(tmp); 607 } 608 609 static double dOrdPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly) 610 { 611 psS32 loop_x = 0; 612 psS32 loop_y = 0; 613 double polySum = 0.0; 614 double xSum = 1.0; 615 double ySum = 1.0; 616 617 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 618 ySum = xSum; 619 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 620 if (myPoly->mask[loop_x][loop_y] == 0) { 621 polySum += ySum * myPoly->coeff[loop_x][loop_y]; 622 ySum *= y; 623 } 624 } 625 xSum *= x; 626 } 627 628 return(polySum); 629 } 630 631 static double dChebPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly) 632 { 633 psS32 loop_x = 0; 634 psS32 loop_y = 0; 635 psS32 i = 0; 636 double polySum = 0.0; 637 psPolynomial1D* *chebPolys = NULL; 638 psS32 maxChebyPoly = 0; 639 640 // Determine how many Chebyshev polynomials 641 // are needed, then create them. 642 maxChebyPoly = myPoly->nX; 643 if (myPoly->nY > maxChebyPoly) { 644 maxChebyPoly = myPoly->nY; 645 } 646 chebPolys = createChebyshevPolys(maxChebyPoly); 647 648 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 649 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 650 if (myPoly->mask[loop_x][loop_y] == 0) { 651 polySum += myPoly->coeff[loop_x][loop_y] * 652 psPolynomial1DEval(x, chebPolys[loop_x]) * 653 psPolynomial1DEval(y, chebPolys[loop_y]); 654 } 655 } 656 } 657 658 for (i=0;i<maxChebyPoly;i++) { 659 psFree(chebPolys[i]); 660 } 661 psFree(chebPolys); 662 return(polySum); 663 } 664 665 static double dOrdPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly) 666 { 667 psS32 loop_x = 0; 668 psS32 loop_y = 0; 669 psS32 loop_z = 0; 670 double polySum = 0.0; 671 double xSum = 1.0; 672 double ySum = 1.0; 673 double zSum = 1.0; 674 675 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 676 ySum = xSum; 677 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 678 zSum = ySum; 679 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 680 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) { 681 polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z]; 682 zSum *= z; 683 } 684 } 685 ySum *= y; 686 } 687 xSum *= x; 688 } 689 690 return(polySum); 691 } 692 693 static double dChebPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly) 694 { 695 psS32 loop_x = 0; 696 psS32 loop_y = 0; 697 psS32 loop_z = 0; 698 psS32 i = 0; 699 double polySum = 0.0; 700 psPolynomial1D* *chebPolys = NULL; 701 psS32 maxChebyPoly = 0; 702 703 // Determine how many Chebyshev polynomials 704 // are needed, then create them. 705 maxChebyPoly = myPoly->nX; 706 if (myPoly->nY > maxChebyPoly) { 707 maxChebyPoly = myPoly->nY; 708 } 709 if (myPoly->nZ > maxChebyPoly) { 710 maxChebyPoly = myPoly->nZ; 711 } 712 chebPolys = createChebyshevPolys(maxChebyPoly); 713 714 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 715 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 716 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 717 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) { 718 polySum += myPoly->coeff[loop_x][loop_y][loop_z] * 719 psPolynomial1DEval(x, chebPolys[loop_x]) * 720 psPolynomial1DEval(y, chebPolys[loop_y]) * 721 psPolynomial1DEval(z, chebPolys[loop_z]); 722 } 723 } 724 } 725 } 726 727 for (i=0;i<maxChebyPoly;i++) { 728 psFree(chebPolys[i]); 729 } 730 psFree(chebPolys); 731 return(polySum); 732 } 733 734 static double dOrdPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly) 735 { 736 psS32 loop_w = 0; 737 psS32 loop_x = 0; 738 psS32 loop_y = 0; 739 psS32 loop_z = 0; 740 double polySum = 0.0; 741 double wSum = 1.0; 742 double xSum = 1.0; 743 double ySum = 1.0; 744 double zSum = 1.0; 745 746 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) { 747 xSum = wSum; 748 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 749 ySum = xSum; 750 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 751 zSum = ySum; 752 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 753 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) { 754 polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z]; 755 zSum *= z; 756 } 757 } 758 ySum *= y; 759 } 760 xSum *= x; 761 } 762 wSum *= w; 763 } 764 765 return(polySum); 766 } 767 768 static double dChebPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly) 769 { 770 psS32 loop_w = 0; 771 psS32 loop_x = 0; 772 psS32 loop_y = 0; 773 psS32 loop_z = 0; 774 psS32 i = 0; 775 double polySum = 0.0; 776 psPolynomial1D* *chebPolys = NULL; 777 psS32 maxChebyPoly = 0; 778 779 // Determine how many Chebyshev polynomials 780 // are needed, then create them. 781 maxChebyPoly = myPoly->nW; 782 if (myPoly->nX > maxChebyPoly) { 783 maxChebyPoly = myPoly->nX; 784 } 785 if (myPoly->nY > maxChebyPoly) { 786 maxChebyPoly = myPoly->nY; 787 } 788 if (myPoly->nZ > maxChebyPoly) { 789 maxChebyPoly = myPoly->nZ; 790 } 791 chebPolys = createChebyshevPolys(maxChebyPoly); 792 793 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) { 794 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) { 795 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) { 796 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) { 797 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) { 798 polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] * 799 psPolynomial1DEval(w, chebPolys[loop_w]) * 800 psPolynomial1DEval(x, chebPolys[loop_x]) * 801 psPolynomial1DEval(y, chebPolys[loop_y]) * 802 psPolynomial1DEval(z, chebPolys[loop_z]); 803 } 804 } 805 } 806 } 807 } 808 809 for (i=0;i<maxChebyPoly;i++) { 810 psFree(chebPolys[i]); 811 } 812 psFree(chebPolys); 813 return(polySum); 814 } 815 816 817 /***************************************************************************** 818 p_psInterpolate1D(): This routine will take as input n-element floating 819 point arrays domain and range, and the x value, assumed to lie with the 820 domain vector. It produces as output the (n-1)-order LaGrange interpolated 821 value of x. 822 823 XXX: do we error check for non-distinct domain values? 824 *****************************************************************************/ 825 static float fullInterpolate1DF32(float *domain, 826 float *range, 827 psS32 n, 828 float x) 829 { 830 PS_INT_CHECK_NON_NEGATIVE(n, NAN); 831 PS_PTR_CHECK_NULL(domain, NAN); 832 PS_PTR_CHECK_NULL(range, NAN); 833 834 psS32 i; 835 psS32 m; 836 static psVector *p = NULL; 837 p = psVectorRecycle(p, n, PS_TYPE_F32); 838 p_psMemSetPersistent(p, true); 839 p_psMemSetPersistent(p->data.F32, true); 840 /* 841 psVector *p = psVectorAlloc(n, PS_TYPE_F32); 842 float tmp; 843 */ 844 845 psTrace(".psLib.dataManip.psFunctions.fullInterpolate1DF32", 4, 846 "---- fullInterpolate1DF32() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n); 847 848 for (i=0;i<n;i++) { 849 psTrace(".psLib.dataManip.psFunctions.fullInterpolate1DF32", 6, 850 "domain/range is (%f %f)\n", domain[i], range[i]); 851 } 852 853 for (i=0;i<n;i++) { 854 p->data.F32[i] = range[i]; 855 psTrace(".psLib.dataManip.psFunctions.fullInterpolate1DF32", 6, 856 "p->data.F32[%d] is %f\n", i, p->data.F32[i]); 857 858 } 859 860 // From NR, during each iteration of the m loop, we are computing the 861 // p_{i ... i+m} terms. 862 for (m=1;m<n;m++) { 863 for (i=0;i<n-m;i++) { 864 // From NR: we are computing P_{i ... i+m} 865 p->data.F32[i] = (((x-domain[i+m]) * p->data.F32[i]) + 866 ((domain[i]-x) * p->data.F32[i+1])) / 867 (domain[i] - domain[i+m]); 868 //printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.F32[i], domain[i], x, p->data.F32[i+1], domain[i], domain[i+m]); 869 psTrace(".psLib.dataManip.psFunctions.fullInterpolate1DF32", 6, 870 "p->data.F32[%d] is %f\n", i, p->data.F32[i]); 871 } 872 } 873 psTrace(".psLib.dataManip.psFunctions.fullInterpolate1DF32", 4, 874 "---- fullInterpolate1DF32() end ----\n"); 875 876 /* 877 tmp = p->data.F32[0]; 878 psFree(p); 879 return(tmp); 880 */ 881 return(p->data.F32[0]); 882 } 883 884 885 /***************************************************************************** 886 interpolate1DF32(): this is the base 1-D flat memory routine to perform 887 LaGrange interpolation. 888 *****************************************************************************/ 889 static float interpolate1DF32(float *domain, 890 float *range, 891 psS32 n, 892 psS32 order, 893 float x) 894 { 895 psS32 binNum; 896 psS32 numIntPoints = order+1; 897 psS32 origin; 898 899 psTrace(".psLib.dataManip.psFunctions.interpolate1DF32", 4, 900 "---- interpolate1DF32() begin ----\n"); 901 902 binNum = vectorBinDisectF32(domain, n, x); 903 904 if (0 == numIntPoints%2) { 905 origin = binNum - ((numIntPoints/2) - 1); 906 } else { 907 origin = binNum - (numIntPoints/2); 908 if ((x-domain[binNum]) > (domain[binNum+1]-x)) { 909 // x is closer to binNum+1. 910 origin = 1 + (binNum - (numIntPoints/2)); 911 } 912 } 913 if (origin < 0) { 914 origin = 0; 915 } 916 if ((origin + numIntPoints) > n) { 917 origin = n - numIntPoints; 918 } 919 920 psTrace(".psLib.dataManip.psFunctions.interpolate1DF32", 4, 921 "---- interpolate1DF32() end ----\n"); 922 return(fullInterpolate1DF32(&domain[origin], &range[origin], order+1, x)); 105 923 } 106 924 … … 336 1154 } 337 1155 338 static void polynomial1DFree(psPolynomial1D* myPoly)339 {340 psFree(myPoly->coeff);341 psFree(myPoly->coeffErr);342 psFree(myPoly->mask);343 }344 345 static void polynomial2DFree(psPolynomial2D* myPoly)346 {347 psS32 x = 0;348 349 for (x = 0; x < myPoly->nX; x++) {350 psFree(myPoly->coeff[x]);351 psFree(myPoly->coeffErr[x]);352 psFree(myPoly->mask[x]);353 }354 psFree(myPoly->coeff);355 psFree(myPoly->coeffErr);356 psFree(myPoly->mask);357 }358 359 static void polynomial3DFree(psPolynomial3D* myPoly)360 {361 psS32 x = 0;362 psS32 y = 0;363 364 for (x = 0; x < myPoly->nX; x++) {365 for (y = 0; y < myPoly->nY; y++) {366 psFree(myPoly->coeff[x][y]);367 psFree(myPoly->coeffErr[x][y]);368 psFree(myPoly->mask[x][y]);369 }370 psFree(myPoly->coeff[x]);371 psFree(myPoly->coeffErr[x]);372 psFree(myPoly->mask[x]);373 }374 375 psFree(myPoly->coeff);376 psFree(myPoly->coeffErr);377 psFree(myPoly->mask);378 }379 380 static void polynomial4DFree(psPolynomial4D* myPoly)381 {382 psS32 w = 0;383 psS32 x = 0;384 psS32 y = 0;385 386 for (w = 0; w < myPoly->nW; w++) {387 for (x = 0; x < myPoly->nX; x++) {388 for (y = 0; y < myPoly->nY; y++) {389 psFree(myPoly->coeff[w][x][y]);390 psFree(myPoly->coeffErr[w][x][y]);391 psFree(myPoly->mask[w][x][y]);392 }393 psFree(myPoly->coeff[w][x]);394 psFree(myPoly->coeffErr[w][x]);395 psFree(myPoly->mask[w][x]);396 }397 psFree(myPoly->coeff[w]);398 psFree(myPoly->coeffErr[w]);399 psFree(myPoly->mask[w]);400 }401 402 psFree(myPoly->coeff);403 psFree(myPoly->coeffErr);404 psFree(myPoly->mask);405 }406 407 /*****************************************************************************408 Polynomial coefficients will be accessed in [w][x][y][z] fashion.409 410 XXX: Should the "coeffErr[]" should be used as well?411 *****************************************************************************/412 float p_psOrdPolynomial1DEval(float x, const psPolynomial1D* myPoly)413 {414 psS32 loop_x = 0;415 float polySum = 0.0;416 float xSum = 1.0;417 418 psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,419 "---- Calling p_psOrdPolynomial1DEval(%f)\n", x);420 psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,421 "Polynomial order is %d\n", myPoly->n);422 for (loop_x = 0; loop_x < myPoly->n; loop_x++) {423 psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,424 "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);425 }426 427 for (loop_x = 0; loop_x < myPoly->n; loop_x++) {428 if (myPoly->mask[loop_x] == 0) {429 psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 10,430 "polysum+= sum*coeff [%f+= (%f * %f)\n", polySum, xSum, myPoly->coeff[loop_x]);431 polySum += xSum * myPoly->coeff[loop_x];432 xSum *= x;433 }434 }435 436 return(polySum);437 }438 439 // XXX: You can do this without having to psAlloc() vector d.440 // XXX: How does the mask vector effect Crenshaw's formula?441 float p_psChebPolynomial1DEval(float x, const psPolynomial1D* myPoly)442 {443 psVector *d;444 psS32 n;445 psS32 i;446 float tmp;447 448 n = myPoly->n;449 d = psVectorAlloc(n, PS_TYPE_F32);450 d->data.F32[n-1] = myPoly->coeff[n-1];451 d->data.F32[n-2] = (2.0 * x * d->data.F32[n-1]) + myPoly->coeff[n-2];452 for (i=n-3;i>=1;i--) {453 d->data.F32[i] = (2.0 * x * d->data.F32[i+1]) -454 (d->data.F32[i+2]) +455 (myPoly->coeff[i]);456 }457 458 tmp = (x * d->data.F32[1]) -459 (d->data.F32[2]) +460 (0.5 * myPoly->coeff[0]);461 462 psFree(d);463 return(tmp);464 /*465 466 psS32 n;467 psS32 i;468 float tmp;469 psPolynomial1D **chebPolys = NULL;470 471 n = myPoly->n;472 chebPolys = CreateChebyshevPolys(n);473 474 tmp = 0.0;475 for (i=0;i<myPoly->n;i++) {476 tmp+= (myPoly->coeff[i] * psPolynomial1DEval(x, chebPolys[i]));477 // printf("HMMM: psPolynomial1DEval(%f, chebPolys[%d]) is %f\n", x, i, psPolynomial1DEval(x, chebPolys[i]));478 }479 tmp-= (myPoly->coeff[0]/2.0);480 481 482 return(tmp);483 */484 }485 486 1156 float psPolynomial1DEval(float x, const psPolynomial1D* myPoly) 487 1157 { … … 489 1159 490 1160 if (myPoly->type == PS_POLYNOMIAL_ORD) { 491 return( p_psOrdPolynomial1DEval(x, myPoly));1161 return(ordPolynomial1DEval(x, myPoly)); 492 1162 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 493 return( p_psChebPolynomial1DEval(x, myPoly));1163 return(chebPolynomial1DEval(x, myPoly)); 494 1164 } else { 495 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1165 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1166 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1167 myPoly->type); 496 1168 } 497 1169 return(0.0); … … 520 1192 } 521 1193 522 523 float p_psOrdPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly) 1194 float psPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly) 524 1195 { 525 1196 PS_POLY_CHECK_NULL(myPoly, NAN); 526 1197 527 psS32 loop_x = 0;528 psS32 loop_y = 0;529 float polySum = 0.0;530 float xSum = 1.0;531 float ySum = 1.0;532 533 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {534 ySum = xSum;535 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {536 if (myPoly->mask[loop_x][loop_y] == 0) {537 polySum += ySum * myPoly->coeff[loop_x][loop_y];538 ySum *= y;539 }540 }541 xSum *= x;542 }543 544 return(polySum);545 }546 547 float p_psChebPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)548 {549 PS_POLY_CHECK_NULL(myPoly, NAN);550 551 psS32 loop_x = 0;552 psS32 loop_y = 0;553 psS32 i = 0;554 float polySum = 0.0;555 psPolynomial1D* *chebPolys = NULL;556 psS32 maxChebyPoly = 0;557 558 // Determine how many Chebyshev polynomials559 // are needed, then create them.560 maxChebyPoly = myPoly->nX;561 if (myPoly->nY > maxChebyPoly) {562 maxChebyPoly = myPoly->nY;563 }564 chebPolys = CreateChebyshevPolys(maxChebyPoly);565 566 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {567 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {568 if (myPoly->mask[loop_x][loop_y] == 0) {569 polySum += myPoly->coeff[loop_x][loop_y] *570 psPolynomial1DEval(x, chebPolys[loop_x]) *571 psPolynomial1DEval(y, chebPolys[loop_y]);572 }573 }574 }575 for (i=0;i<maxChebyPoly;i++) {576 psFree(chebPolys[i]);577 }578 psFree(chebPolys);579 return(polySum);580 }581 582 float psPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)583 {584 PS_POLY_CHECK_NULL(myPoly, NAN);585 586 1198 if (myPoly->type == PS_POLYNOMIAL_ORD) { 587 return( p_psOrdPolynomial2DEval(x, y, myPoly));1199 return(ordPolynomial2DEval(x, y, myPoly)); 588 1200 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 589 return( p_psChebPolynomial2DEval(x, y, myPoly));1201 return(chebPolynomial2DEval(x, y, myPoly)); 590 1202 } else { 591 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1203 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1204 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1205 myPoly->type); 592 1206 } 593 1207 return(0.0); 594 1208 } 595 596 1209 597 1210 psVector *psPolynomial2DEvalVector(const psVector *x, … … 632 1245 } 633 1246 634 635 636 float p_psOrdPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)637 {638 psS32 loop_x = 0;639 psS32 loop_y = 0;640 psS32 loop_z = 0;641 float polySum = 0.0;642 float xSum = 1.0;643 float ySum = 1.0;644 float zSum = 1.0;645 646 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {647 ySum = xSum;648 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {649 zSum = ySum;650 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {651 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {652 polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];653 zSum *= z;654 }655 }656 ySum *= y;657 }658 xSum *= x;659 }660 661 return(polySum);662 }663 664 float p_psChebPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)665 {666 psS32 loop_x = 0;667 psS32 loop_y = 0;668 psS32 loop_z = 0;669 psS32 i = 0;670 float polySum = 0.0;671 psPolynomial1D* *chebPolys = NULL;672 psS32 maxChebyPoly = 0;673 674 // Determine how many Chebyshev polynomials675 // are needed, then create them.676 maxChebyPoly = myPoly->nX;677 if (myPoly->nY > maxChebyPoly) {678 maxChebyPoly = myPoly->nY;679 }680 if (myPoly->nZ > maxChebyPoly) {681 maxChebyPoly = myPoly->nZ;682 }683 chebPolys = CreateChebyshevPolys(maxChebyPoly);684 685 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {686 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {687 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {688 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {689 polySum += myPoly->coeff[loop_x][loop_y][loop_z] *690 psPolynomial1DEval(x, chebPolys[loop_x]) *691 psPolynomial1DEval(y, chebPolys[loop_y]) *692 psPolynomial1DEval(z, chebPolys[loop_z]);693 }694 }695 }696 }697 698 for (i=0;i<maxChebyPoly;i++) {699 psFree(chebPolys[i]);700 }701 psFree(chebPolys);702 return(polySum);703 }704 705 1247 float psPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly) 706 1248 { … … 708 1250 709 1251 if (myPoly->type == PS_POLYNOMIAL_ORD) { 710 return( p_psOrdPolynomial3DEval(x, y, z, myPoly));1252 return(ordPolynomial3DEval(x, y, z, myPoly)); 711 1253 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 712 return( p_psChebPolynomial3DEval(x, y, z, myPoly));1254 return(chebPolynomial3DEval(x, y, z, myPoly)); 713 1255 } else { 714 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1256 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1257 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1258 myPoly->type); 715 1259 } 716 1260 return(0.0); … … 765 1309 } 766 1310 767 768 769 770 771 772 float p_psOrdPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)773 {774 psS32 loop_w = 0;775 psS32 loop_x = 0;776 psS32 loop_y = 0;777 psS32 loop_z = 0;778 float polySum = 0.0;779 float wSum = 1.0;780 float xSum = 1.0;781 float ySum = 1.0;782 float zSum = 1.0;783 784 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {785 xSum = wSum;786 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {787 ySum = xSum;788 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {789 zSum = ySum;790 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {791 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {792 polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];793 zSum *= z;794 }795 }796 ySum *= y;797 }798 xSum *= x;799 }800 wSum *= w;801 }802 803 return(polySum);804 }805 806 float p_psChebPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)807 {808 psS32 loop_w = 0;809 psS32 loop_x = 0;810 psS32 loop_y = 0;811 psS32 loop_z = 0;812 psS32 i = 0;813 float polySum = 0.0;814 psPolynomial1D* *chebPolys = NULL;815 psS32 maxChebyPoly = 0;816 817 // Determine how many Chebyshev polynomials818 // are needed, then create them.819 maxChebyPoly = myPoly->nW;820 if (myPoly->nX > maxChebyPoly) {821 maxChebyPoly = myPoly->nX;822 }823 if (myPoly->nY > maxChebyPoly) {824 maxChebyPoly = myPoly->nY;825 }826 if (myPoly->nZ > maxChebyPoly) {827 maxChebyPoly = myPoly->nZ;828 }829 chebPolys = CreateChebyshevPolys(maxChebyPoly);830 831 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {832 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {833 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {834 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {835 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {836 polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *837 psPolynomial1DEval(w, chebPolys[loop_w]) *838 psPolynomial1DEval(x, chebPolys[loop_x]) *839 psPolynomial1DEval(y, chebPolys[loop_y]) *840 psPolynomial1DEval(z, chebPolys[loop_z]);841 }842 }843 }844 }845 }846 847 for (i=0;i<maxChebyPoly;i++) {848 psFree(chebPolys[i]);849 }850 psFree(chebPolys);851 return(polySum);852 }853 854 1311 float psPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly) 855 1312 { … … 857 1314 858 1315 if (myPoly->type == PS_POLYNOMIAL_ORD) { 859 return( p_psOrdPolynomial4DEval(w,x,y,z, myPoly));1316 return(ordPolynomial4DEval(w,x,y,z, myPoly)); 860 1317 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 861 return( p_psChebPolynomial4DEval(w,x,y,z, myPoly));1318 return(chebPolynomial4DEval(w,x,y,z, myPoly)); 862 1319 } else { 863 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1320 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1321 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1322 myPoly->type); 864 1323 } 865 1324 return(0.0); … … 924 1383 return(tmp); 925 1384 } 926 927 928 929 1385 930 1386 … … 1092 1548 } 1093 1549 1094 static void dPolynomial1DFree(psDPolynomial1D* myPoly)1095 {1096 psFree(myPoly->coeff);1097 psFree(myPoly->coeffErr);1098 psFree(myPoly->mask);1099 }1100 1101 static void dPolynomial2DFree(psDPolynomial2D* myPoly)1102 {1103 psS32 x = 0;1104 1105 for (x = 0; x < myPoly->nX; x++) {1106 psFree(myPoly->coeff[x]);1107 psFree(myPoly->coeffErr[x]);1108 psFree(myPoly->mask[x]);1109 }1110 psFree(myPoly->coeff);1111 psFree(myPoly->coeffErr);1112 psFree(myPoly->mask);1113 }1114 1115 static void dPolynomial3DFree(psDPolynomial3D* myPoly)1116 {1117 psS32 x = 0;1118 psS32 y = 0;1119 1120 for (x = 0; x < myPoly->nX; x++) {1121 for (y = 0; y < myPoly->nY; y++) {1122 psFree(myPoly->coeff[x][y]);1123 psFree(myPoly->coeffErr[x][y]);1124 psFree(myPoly->mask[x][y]);1125 }1126 psFree(myPoly->coeff[x]);1127 psFree(myPoly->coeffErr[x]);1128 psFree(myPoly->mask[x]);1129 }1130 1131 psFree(myPoly->coeff);1132 psFree(myPoly->coeffErr);1133 psFree(myPoly->mask);1134 }1135 1136 static void dPolynomial4DFree(psDPolynomial4D* myPoly)1137 {1138 psS32 w = 0;1139 psS32 x = 0;1140 psS32 y = 0;1141 1142 for (w = 0; w < myPoly->nW; w++) {1143 for (x = 0; x < myPoly->nX; x++) {1144 for (y = 0; y < myPoly->nY; y++) {1145 psFree(myPoly->coeff[w][x][y]);1146 psFree(myPoly->coeffErr[w][x][y]);1147 psFree(myPoly->mask[w][x][y]);1148 }1149 psFree(myPoly->coeff[w][x]);1150 psFree(myPoly->coeffErr[w][x]);1151 psFree(myPoly->mask[w][x]);1152 }1153 psFree(myPoly->coeff[w]);1154 psFree(myPoly->coeffErr[w]);1155 psFree(myPoly->mask[w]);1156 }1157 1158 psFree(myPoly->coeff);1159 psFree(myPoly->coeffErr);1160 psFree(myPoly->mask);1161 }1162 1163 /*****************************************************************************1164 Polynomial coefficients will be accessed in [w][x][y][z] fashion.1165 *****************************************************************************/1166 double p_psDOrdPolynomial1DEval(double x, const psDPolynomial1D* myPoly)1167 {1168 psS32 loop_x = 0;1169 double polySum = 0.0;1170 double xSum = 1.0;1171 1172 for (loop_x = 0; loop_x < myPoly->n; loop_x++) {1173 if (myPoly->mask[loop_x] == 0) {1174 polySum += xSum * myPoly->coeff[loop_x];1175 xSum *= x;1176 }1177 }1178 1179 return(polySum);1180 }1181 1182 // XXX: You can do this without having to psAlloc() vector d.1183 // XXX: How does the mask vector effect Crenshaw's formula?1184 double p_psDChebPolynomial1DEval(double x, const psDPolynomial1D* myPoly)1185 {1186 psVector *d;1187 psS32 n;1188 psS32 i;1189 double tmp;1190 1191 n = myPoly->n;1192 d = psVectorAlloc(n, PS_TYPE_F64);1193 d->data.F64[n-1] = myPoly->coeff[n-1];1194 d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]) + myPoly->coeff[n-2];1195 for (i=n-3;i>=1;i--) {1196 d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) -1197 (d->data.F64[i+2]) +1198 (myPoly->coeff[i]);1199 }1200 1201 tmp = (x * d->data.F64[1]) -1202 (d->data.F64[2]) +1203 (0.5 * myPoly->coeff[0]);1204 1205 psFree(d);1206 return(tmp);1207 }1208 1550 1209 1551 double psDPolynomial1DEval(double x, const psDPolynomial1D* myPoly) … … 1212 1554 1213 1555 if (myPoly->type == PS_POLYNOMIAL_ORD) { 1214 return( p_psDOrdPolynomial1DEval(x, myPoly));1556 return(dOrdPolynomial1DEval(x, myPoly)); 1215 1557 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 1216 return( p_psDChebPolynomial1DEval(x, myPoly));1558 return(dChebPolynomial1DEval(x, myPoly)); 1217 1559 } else { 1218 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1560 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1561 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1562 myPoly->type); 1219 1563 } 1220 1564 return(0.0); … … 1244 1588 1245 1589 1246 1247 double p_psDOrdPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)1248 {1249 psS32 loop_x = 0;1250 psS32 loop_y = 0;1251 double polySum = 0.0;1252 double xSum = 1.0;1253 double ySum = 1.0;1254 1255 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1256 ySum = xSum;1257 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1258 if (myPoly->mask[loop_x][loop_y] == 0) {1259 polySum += ySum * myPoly->coeff[loop_x][loop_y];1260 ySum *= y;1261 }1262 }1263 xSum *= x;1264 }1265 1266 return(polySum);1267 }1268 1269 double p_psDChebPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)1270 {1271 psS32 loop_x = 0;1272 psS32 loop_y = 0;1273 psS32 i = 0;1274 double polySum = 0.0;1275 psPolynomial1D* *chebPolys = NULL;1276 psS32 maxChebyPoly = 0;1277 1278 // Determine how many Chebyshev polynomials1279 // are needed, then create them.1280 maxChebyPoly = myPoly->nX;1281 if (myPoly->nY > maxChebyPoly) {1282 maxChebyPoly = myPoly->nY;1283 }1284 chebPolys = CreateChebyshevPolys(maxChebyPoly);1285 1286 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1287 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1288 if (myPoly->mask[loop_x][loop_y] == 0) {1289 polySum += myPoly->coeff[loop_x][loop_y] *1290 psPolynomial1DEval(x, chebPolys[loop_x]) *1291 psPolynomial1DEval(y, chebPolys[loop_y]);1292 }1293 }1294 }1295 1296 for (i=0;i<maxChebyPoly;i++) {1297 psFree(chebPolys[i]);1298 }1299 psFree(chebPolys);1300 return(polySum);1301 }1302 1303 1590 double psDPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly) 1304 1591 { … … 1306 1593 1307 1594 if (myPoly->type == PS_POLYNOMIAL_ORD) { 1308 return( p_psDOrdPolynomial2DEval(x, y, myPoly));1595 return(dOrdPolynomial2DEval(x, y, myPoly)); 1309 1596 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 1310 return( p_psDChebPolynomial2DEval(x, y, myPoly));1597 return(dChebPolynomial2DEval(x, y, myPoly)); 1311 1598 } else { 1312 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1599 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1600 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1601 myPoly->type); 1313 1602 } 1314 1603 return(0.0); … … 1353 1642 1354 1643 1355 1356 double p_psDOrdPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)1357 {1358 psS32 loop_x = 0;1359 psS32 loop_y = 0;1360 psS32 loop_z = 0;1361 double polySum = 0.0;1362 double xSum = 1.0;1363 double ySum = 1.0;1364 double zSum = 1.0;1365 1366 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1367 ySum = xSum;1368 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1369 zSum = ySum;1370 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {1371 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {1372 polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];1373 zSum *= z;1374 }1375 }1376 ySum *= y;1377 }1378 xSum *= x;1379 }1380 1381 return(polySum);1382 }1383 1384 double p_psDChebPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)1385 {1386 psS32 loop_x = 0;1387 psS32 loop_y = 0;1388 psS32 loop_z = 0;1389 psS32 i = 0;1390 double polySum = 0.0;1391 psPolynomial1D* *chebPolys = NULL;1392 psS32 maxChebyPoly = 0;1393 1394 // Determine how many Chebyshev polynomials1395 // are needed, then create them.1396 maxChebyPoly = myPoly->nX;1397 if (myPoly->nY > maxChebyPoly) {1398 maxChebyPoly = myPoly->nY;1399 }1400 if (myPoly->nZ > maxChebyPoly) {1401 maxChebyPoly = myPoly->nZ;1402 }1403 chebPolys = CreateChebyshevPolys(maxChebyPoly);1404 1405 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1406 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1407 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {1408 if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {1409 polySum += myPoly->coeff[loop_x][loop_y][loop_z] *1410 psPolynomial1DEval(x, chebPolys[loop_x]) *1411 psPolynomial1DEval(y, chebPolys[loop_y]) *1412 psPolynomial1DEval(z, chebPolys[loop_z]);1413 }1414 }1415 }1416 }1417 1418 for (i=0;i<maxChebyPoly;i++) {1419 psFree(chebPolys[i]);1420 }1421 psFree(chebPolys);1422 return(polySum);1423 }1424 1425 1644 double psDPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly) 1426 1645 { … … 1428 1647 1429 1648 if (myPoly->type == PS_POLYNOMIAL_ORD) { 1430 return( p_psDOrdPolynomial3DEval(x, y, z, myPoly));1649 return(dOrdPolynomial3DEval(x, y, z, myPoly)); 1431 1650 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 1432 return( p_psDChebPolynomial3DEval(x, y, z, myPoly));1651 return(dChebPolynomial3DEval(x, y, z, myPoly)); 1433 1652 } else { 1434 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1653 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1654 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1655 myPoly->type); 1435 1656 } 1436 1657 return(0.0); … … 1485 1706 } 1486 1707 1487 1488 1489 1490 1491 1492 1493 1494 double p_psDOrdPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)1495 {1496 psS32 loop_w = 0;1497 psS32 loop_x = 0;1498 psS32 loop_y = 0;1499 psS32 loop_z = 0;1500 double polySum = 0.0;1501 double wSum = 1.0;1502 double xSum = 1.0;1503 double ySum = 1.0;1504 double zSum = 1.0;1505 1506 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {1507 xSum = wSum;1508 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1509 ySum = xSum;1510 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1511 zSum = ySum;1512 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {1513 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {1514 polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];1515 zSum *= z;1516 }1517 }1518 ySum *= y;1519 }1520 xSum *= x;1521 }1522 wSum *= w;1523 }1524 1525 return(polySum);1526 }1527 1528 double p_psDChebPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)1529 {1530 psS32 loop_w = 0;1531 psS32 loop_x = 0;1532 psS32 loop_y = 0;1533 psS32 loop_z = 0;1534 psS32 i = 0;1535 double polySum = 0.0;1536 psPolynomial1D* *chebPolys = NULL;1537 psS32 maxChebyPoly = 0;1538 1539 // Determine how many Chebyshev polynomials1540 // are needed, then create them.1541 maxChebyPoly = myPoly->nW;1542 if (myPoly->nX > maxChebyPoly) {1543 maxChebyPoly = myPoly->nX;1544 }1545 if (myPoly->nY > maxChebyPoly) {1546 maxChebyPoly = myPoly->nY;1547 }1548 if (myPoly->nZ > maxChebyPoly) {1549 maxChebyPoly = myPoly->nZ;1550 }1551 chebPolys = CreateChebyshevPolys(maxChebyPoly);1552 1553 for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {1554 for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {1555 for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {1556 for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {1557 if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {1558 polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *1559 psPolynomial1DEval(w, chebPolys[loop_w]) *1560 psPolynomial1DEval(x, chebPolys[loop_x]) *1561 psPolynomial1DEval(y, chebPolys[loop_y]) *1562 psPolynomial1DEval(z, chebPolys[loop_z]);1563 }1564 }1565 }1566 }1567 }1568 1569 for (i=0;i<maxChebyPoly;i++) {1570 psFree(chebPolys[i]);1571 }1572 psFree(chebPolys);1573 return(polySum);1574 }1575 1576 1708 double psDPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly) 1577 1709 { … … 1579 1711 1580 1712 if (myPoly->type == PS_POLYNOMIAL_ORD) { 1581 return( p_psDOrdPolynomial4DEval(w,x,y,z, myPoly));1713 return(dOrdPolynomial4DEval(w,x,y,z, myPoly)); 1582 1714 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 1583 return( p_psDChebPolynomial4DEval(w,x,y,z, myPoly));1715 return(dChebPolynomial4DEval(w,x,y,z, myPoly)); 1584 1716 } else { 1585 psError(__func__, "Unknown polynomial type 0x%x\n", myPoly->type); 1717 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1718 PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE, 1719 myPoly->type); 1586 1720 } 1587 1721 return(0.0); … … 1699 1833 (tmp->domains)[numSplines] = max; 1700 1834 1835 p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree); 1701 1836 return(tmp); 1702 1837 } 1703 1838 1704 // XXX: Have Robert put the dealocator in the memory file.1705 psS32 p_psSpline1DFree(psSpline1D *tmpSpline)1706 {1707 psS32 i;1708 1709 if (tmpSpline == NULL) {1710 return(0);1711 }1712 1713 if (tmpSpline->spline != NULL) {1714 for (i=0;i<tmpSpline->n;i++) {1715 psFree((tmpSpline->spline)[i]);1716 }1717 psFree(tmpSpline->spline);1718 }1719 1720 if (tmpSpline->p_psDeriv2 != NULL) {1721 psFree(tmpSpline->p_psDeriv2);1722 }1723 psFree(tmpSpline->domains);1724 psFree(tmpSpline);1725 1726 return(0);1727 }1728 1839 1729 1840 /***************************************************************************** … … 1765 1876 1766 1877 /***************************************************************************** 1767 p_psVectorBinDisectF32(): This is a private function which takes as input a1878 vectorBinDisectF32(): This is a private function which takes as input a 1768 1879 vector of floating point data as well as a single floating point values. 1769 1880 The input vector values are assumed to be non-decreasing (v[i-1] <= v[j] for … … 1776 1887 XXX: name since we don't take psVectors as input. 1777 1888 *****************************************************************************/ 1778 psS32 p_psVectorBinDisectF32(float *bins,1779 psS32 numBins,1780 float x)1889 static psS32 vectorBinDisectF32(float *bins, 1890 psS32 numBins, 1891 float x) 1781 1892 { 1782 1893 psS32 min; … … 1784 1895 psS32 mid; 1785 1896 1786 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectF32", 4,1787 "---- Calling p_psVectorBinDisectF32(%f)\n", x);1897 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectF32", 4, 1898 "---- Calling vectorBinDisectF32(%f)\n", x); 1788 1899 1789 1900 if (x < bins[0]) { 1790 1901 psLogMsg(__func__, PS_LOG_WARN, 1791 " p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",1902 "vectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).", 1792 1903 x, bins[0], bins[numBins-1]); 1793 1904 return(-2); … … 1796 1907 if (x > bins[numBins-1]) { 1797 1908 psLogMsg(__func__, PS_LOG_WARN, 1798 " p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",1909 "vectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).", 1799 1910 x, bins[0], bins[numBins-1]); 1800 1911 return(-1); … … 1806 1917 1807 1918 while (min != max) { 1808 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectF32", 4,1919 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectF32", 4, 1809 1920 "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n", 1810 1921 min, mid, max, x, bins[mid]); 1811 1922 1812 1923 if (x == bins[mid]) { 1813 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectF32", 4,1814 "---- Exiting p_psVectorBinDisectF32(): bin %d\n", mid);1924 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectF32", 4, 1925 "---- Exiting vectorBinDisectF32(): bin %d\n", mid); 1815 1926 return(mid); 1816 1927 } else if (x < bins[mid]) { … … 1822 1933 } 1823 1934 1824 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectF32", 4,1825 "---- Exiting p_psVectorBinDisectF32(): bin %d\n", min);1935 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectF32", 4, 1936 "---- Exiting vectorBinDisectF32(): bin %d\n", min); 1826 1937 return(min); 1827 1938 } 1828 1939 1829 1940 /***************************************************************************** 1830 p_psVectorBinDisectS32(): integer version of above.1941 vectorBinDisectS32(): integer version of above. 1831 1942 *****************************************************************************/ 1832 psS32 p_psVectorBinDisectS32(psS32 *bins,1833 psS32 numBins,1834 psS32 x)1943 static psS32 vectorBinDisectS32(psS32 *bins, 1944 psS32 numBins, 1945 psS32 x) 1835 1946 { 1836 1947 psS32 min; … … 1838 1949 psS32 mid; 1839 1950 1840 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectS32", 4,1841 "---- Calling p_psVectorBinDisectS32(%f)\n", x);1951 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectS32", 4, 1952 "---- Calling vectorBinDisectS32(%f)\n", x); 1842 1953 1843 1954 if ((x < bins[0]) || 1844 1955 (x > bins[numBins-1])) { 1845 1956 psLogMsg(__func__, PS_LOG_WARN, 1846 " p_psVectorBinDisectS32(): ordinate %f is outside vector range (%f - %f).",1957 "vectorBinDisectS32(): ordinate %f is outside vector range (%f - %f).", 1847 1958 x, bins[0], bins[numBins-1]); 1848 1959 return(-1); … … 1854 1965 1855 1966 while (min != max) { 1856 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectS32", 4,1967 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectS32", 4, 1857 1968 "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n", 1858 1969 min, mid, max, x, bins[mid]); 1859 1970 1860 1971 if (x == bins[mid]) { 1861 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectS32", 4,1862 "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);1972 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectS32", 4, 1973 "---- Exiting vectorBinDisectS32(): bin %d\n", min); 1863 1974 return(min); 1864 1975 } else if (x < bins[mid]) { … … 1870 1981 } 1871 1982 1872 psTrace(".psLib.dataManip.psFunctions. p_psVectorBinDisectS32", 4,1873 "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);1983 psTrace(".psLib.dataManip.psFunctions.vectorBinDisectS32", 4, 1984 "---- Exiting vectorBinDisectS32(): bin %d\n", min); 1874 1985 return(min); 1875 1986 } … … 1884 1995 1885 1996 if (x->type.type == PS_TYPE_S32) { 1886 return( p_psVectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));1997 return(vectorBinDisectS32(bins->data.S32, bins->n, x->data.S32)); 1887 1998 } else if (x->type.type == PS_TYPE_F32) { 1888 return( p_psVectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));1999 return(vectorBinDisectF32(bins->data.F32, bins->n, x->data.F32)); 1889 2000 } else { 1890 psError(__func__, "Unallowable data type."); 2001 char* strType; 2002 PS_TYPE_NAME(strType,x->type.type); 2003 psError(PS_ERR_BAD_PARAMETER_TYPE, 2004 PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED, 2005 strType); 1891 2006 return(-2); 1892 2007 } 1893 2008 return(-1); 1894 }1895 1896 /*****************************************************************************1897 p_psInterpolate1D(): This routine will take as input n-element floating1898 point arrays domain and range, and the x value, assumed to lie with the1899 domain vector. It produces as output the (n-1)-order LaGrange interpolated1900 value of x.1901 1902 XXX: do we error check for non-distinct domain values?1903 *****************************************************************************/1904 float p_ps1DFullInterpolateF32(float *domain,1905 float *range,1906 psS32 n,1907 float x)1908 {1909 PS_INT_CHECK_NON_NEGATIVE(n, NAN);1910 PS_PTR_CHECK_NULL(domain, NAN);1911 PS_PTR_CHECK_NULL(range, NAN);1912 1913 psS32 i;1914 psS32 m;1915 static psVector *p = NULL;1916 p = psVectorRecycle(p, n, PS_TYPE_F32);1917 p_psMemSetPersistent(p, true);1918 p_psMemSetPersistent(p->data.F32, true);1919 /*1920 psVector *p = psVectorAlloc(n, PS_TYPE_F32);1921 float tmp;1922 */1923 1924 psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,1925 "---- p_ps1DFullInterpolateF32() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n);1926 1927 for (i=0;i<n;i++) {1928 psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,1929 "domain/range is (%f %f)\n", domain[i], range[i]);1930 }1931 1932 for (i=0;i<n;i++) {1933 p->data.F32[i] = range[i];1934 psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,1935 "p->data.F32[%d] is %f\n", i, p->data.F32[i]);1936 1937 }1938 1939 // From NR, during each iteration of the m loop, we are computing the1940 // p_{i ... i+m} terms.1941 for (m=1;m<n;m++) {1942 for (i=0;i<n-m;i++) {1943 // From NR: we are computing P_{i ... i+m}1944 p->data.F32[i] = (((x-domain[i+m]) * p->data.F32[i]) +1945 ((domain[i]-x) * p->data.F32[i+1])) /1946 (domain[i] - domain[i+m]);1947 //printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.F32[i], domain[i], x, p->data.F32[i+1], domain[i], domain[i+m]);1948 psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,1949 "p->data.F32[%d] is %f\n", i, p->data.F32[i]);1950 }1951 }1952 psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,1953 "---- p_ps1DFullInterpolateF32() end ----\n");1954 1955 /*1956 tmp = p->data.F32[0];1957 psFree(p);1958 return(tmp);1959 */1960 return(p->data.F32[0]);1961 }1962 1963 1964 /*****************************************************************************1965 p_ps1DInterpolateF32(): this is the base 1-D flat memory routine to perform1966 LaGrange interpolation.1967 *****************************************************************************/1968 float p_ps1DInterpolateF32(float *domain,1969 float *range,1970 psS32 n,1971 psS32 order,1972 float x)1973 {1974 psS32 binNum;1975 psS32 numIntPoints = order+1;1976 psS32 origin;1977 1978 psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,1979 "---- p_ps1DInterpolateF32() begin ----\n");1980 1981 binNum = p_psVectorBinDisectF32(domain, n, x);1982 1983 if (0 == numIntPoints%2) {1984 origin = binNum - ((numIntPoints/2) - 1);1985 } else {1986 origin = binNum - (numIntPoints/2);1987 if ((x-domain[binNum]) > (domain[binNum+1]-x)) {1988 // x is closer to binNum+1.1989 origin = 1 + (binNum - (numIntPoints/2));1990 }1991 }1992 if (origin < 0) {1993 origin = 0;1994 }1995 if ((origin + numIntPoints) > n) {1996 origin = n - numIntPoints;1997 }1998 1999 psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,2000 "---- p_ps1DInterpolateF32() end ----\n");2001 return(p_ps1DFullInterpolateF32(&domain[origin], &range[origin], order+1, x));2002 2009 } 2003 2010 … … 2035 2042 2036 2043 if (order > (domain->n - 1)) { 2037 psError(__func__, "not enough data points for %d-order interpolation.\n", order); 2044 psError(PS_ERR_BAD_PARAMETER_SIZE, true, 2045 PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS, 2046 order); 2038 2047 return(NULL); 2039 2048 } … … 2042 2051 psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4, 2043 2052 "---- p_psVectorInterpolate() end ----\n"); 2044 return(psScalarAlloc( p_ps1DInterpolateF32(domain->data.F32,2045 range->data.F32,2046 domain->n,2047 order,2048 x->data.F32), PS_TYPE_F32));2053 return(psScalarAlloc(interpolate1DF32(domain->data.F32, 2054 range->data.F32, 2055 domain->n, 2056 order, 2057 x->data.F32), PS_TYPE_F32)); 2049 2058 } else if (x->type.type == PS_TYPE_F64) { 2050 2059 // XXX: use recycled vectors here. … … 2053 2062 2054 2063 psScalar *tmpScalar = psScalarAlloc((double) 2055 p_ps1DInterpolateF32(domain32->data.F32,2056 range32->data.F32,2057 domain32->n,2058 order,2059 (float) x->data.F64), PS_TYPE_F64);2064 interpolate1DF32(domain32->data.F32, 2065 range32->data.F32, 2066 domain32->n, 2067 order, 2068 (float) x->data.F64), PS_TYPE_F64); 2060 2069 psFree(range32); 2061 2070 psFree(domain32); … … 2067 2076 2068 2077 } else { 2069 // XXX psError: type not supported 2070 psError(__func__, "type %d not supported\n", x->type.type); 2078 char* strType; 2079 PS_TYPE_NAME(strType,x->type.type); 2080 psError(PS_ERR_BAD_PARAMETER_TYPE, 2081 PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED, 2082 strType); 2071 2083 } 2072 2084 … … 2084 2096 and an independent x value. Each determines which spline that x corresponds 2085 2097 to by doing a bracket disection on the domains of the spline data structure 2086 ( p_psVectorBinDisectF32()). Then it evaluates the spline at that x location2098 (vectorBinDisectF32()). Then it evaluates the spline at that x location 2087 2099 by a call to the 1D polynomial functions. 2088 2100 … … 2100 2112 2101 2113 n = spline->n; 2102 binNum = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, x);2114 binNum = vectorBinDisectF32(spline->domains, (spline->n)+1, x); 2103 2115 if (binNum < 0) { 2104 2116 psLogMsg(__func__, PS_LOG_WARN, … … 2139 2151 } 2140 2152 } else { 2141 psError(__func__, "Unknown data type.\n"); 2153 char* strType; 2154 PS_TYPE_NAME(strType,x->type.type); 2155 psError(PS_ERR_BAD_PARAMETER_TYPE, 2156 PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED, 2157 strType); 2142 2158 return(NULL); 2143 2159 }
Note:
See TracChangeset
for help on using the changeset viewer.
