Changeset 1921 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Sep 28, 2004, 1:27:37 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r1907 r1921 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1. 49$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09-2 7 23:41:42$11 * @version $Revision: 1.50 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-28 23:27:37 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 656 656 657 657 658 /***************************************************************************** 659 CreateChebyshevPolys(n): this routine takes as input the required order n, 660 and returns as output as a pointer to an array of n psPolynomial1D 661 structures, corresponding to the first n Chebyshev polynomials. 662 663 XXX: The output should be static since the Chebyshev polynomials might be 664 used frequently and the data structure created here does not contain the 665 outer coefficients of the Chebyshev polynomials. 658 /****************************************************************************** 659 p_psVectorFitPolynomial1DCheb(): This routine will fit a Chebyshev 660 polynomial of degree myPoly to the data points (x, y) and return the 661 coefficients of that polynomial. 662 663 XXX: yErr is currently ignored. 664 665 XXX: must add type F32 (currently F64 only). 666 667 XXX: Use private name? 666 668 *****************************************************************************/ 667 static psPolynomial1D **CreateChebyshevPolys(int maxChebyPoly) 668 { 669 psPolynomial1D **chebPolys = NULL; 670 int i = 0; 671 int j = 0; 672 673 chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *)); 674 for (i = 0; i < maxChebyPoly; i++) { 675 chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD); 676 } 677 678 // Create the Chebyshev polynomials. 679 // Polynomial i has i-th order. 680 chebPolys[0]->coeff[0] = 1; 681 chebPolys[1]->coeff[1] = 1; 682 for (i = 2; i < maxChebyPoly; i++) { 683 for (j = 0; j < chebPolys[i - 1]->n; j++) { 684 chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j]; 685 } 686 for (j = 0; j < chebPolys[i - 2]->n; j++) { 687 chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j]; 688 } 689 } 690 691 return (chebPolys); 692 } 693 694 695 696 psPolynomial1D* p_psVectorFitPolynomial1DCheby(psPolynomial1D* myPoly, 669 psPolynomial1D *p_psVectorFitPolynomial1DCheby(psPolynomial1D* myPoly, 697 670 const psVector* restrict x, 698 671 const psVector* restrict y, … … 702 675 int k; 703 676 int n = x->n; 704 psPolynomial1D **chebPolys = CreateChebyshevPolys(myPoly->n); 705 ; 706 float fac; 707 float sum; 708 /* 709 fac = 2.0/((float) n); 710 for (j=0;j<n;j++) { 711 sum = 0.0; 712 for (k=0;k<n;k++) { 713 sum+= y->data.F64[k] * 714 cos(M_PI * ((float) j) * (0.5 + ((float) k)) / ((float) n)); 715 // sum+= y->data.F64[k] * 716 // cos(M_PI * ((float) j) * (-0.5 + ((float) k)) / ((float) n)) * 717 // cos(M_PI * (-0.5 + ((float) k)) / ((float) n)); 718 719 } 720 myPoly->coeff[j] = fac * sum; 721 722 } 723 return(myPoly); 724 */ 725 677 psVector *f = psVectorAlloc(n, PS_TYPE_F64); 678 double fac; 679 double sum; 680 // XXX: Use static memory here. 681 psScalar *tmpScalar = psScalarAlloc(0.0, PS_TYPE_F32); 682 psScalar *fScalar; 683 684 685 // XXX: These assignments appear too simple to warrant code and 686 // variable declarations. I retain them here to maintain coherence 687 // with the NR code. 688 double min = -1.0; 689 double max = 1.0; 690 double bma = 0.5 * (max-min); // 1 691 double bpa = 0.5 * (max+min); // 0 692 693 // XXX: Eliminate this later by generating a F64 version of the 694 // LaGrange interpolation routines. 695 PS_VECTOR_F64_TO_F32(x, x32); 696 PS_VECTOR_F64_TO_F32(y, y32); 697 698 // In this loop, we first calculate the values of X for which the 699 // Chebyshev polynomials are zero (see NR, section 5.4). Then we 700 // calculate the value of the function we are fitting the Chebyshev 701 // polynomials to at those values of X. This is a bit tricky since 702 // we don't know that function. So, we instead do 3-order LaGrange 703 // interpolation at the point X for the psVectors x,y for which we 704 // are fitting this ChebyShev polynomial to. 705 706 for (int i=0;i<n;i++) { 707 // NR 5.8.4 708 double Y = cos(M_PI * (0.5 + ((float) i)) / ((float) n)); 709 double X = (Y + bma + bpa) - 1.0; 710 tmpScalar->data.F32 = (float) X; 711 712 // We interpolate against are tabluated x,y vectors to determine the 713 // function value at X. 714 fScalar = p_psVectorInterpolate((psVector *) x32, (psVector *) y32, 715 3, tmpScalar); 716 f->data.F64[i] = (double) fScalar->data.F32; 717 718 psTrace(".psLib.dataManip.p_psVectorFitPolynomial1DCheby", 6, 719 "(x, X, y, f(X)) is (%f, %f, %f, %f)\n", 720 x->data.F64[i], X, y->data.F64[i], f->data.F64[i]); 721 } 722 723 // We have the values for f() at the zero points, we now calculate the 724 // coefficients of the Chebyshev polynomial: NR 5.8.7. 726 725 fac = 2.0/((float) n); 727 for (j=0;j< myPoly->n;j++) {726 for (j=0;j<n;j++) { 728 727 sum = 0.0; 729 for (k= 1;k<n;k++) {730 sum+= (y->data.F64[k] *731 psPolynomial1DEval((float) x->data.F64[k], chebPolys[j]));728 for (k=0;k<n;k++) { 729 sum+= f->data.F64[k] * 730 cos(M_PI * ((float) j) * (0.5 + ((float) k)) / ((float) n)); 732 731 } 733 732 myPoly->coeff[j] = fac * sum; 734 733 } 734 735 // XXX: Must free memory. 736 psFree(x32); 737 psFree(y32); 738 psFree(tmpScalar); 739 psFree(fScalar); 735 740 return(myPoly); 736 741 } 737 742 738 743 /****************************************************************************** 739 p sVectorFitPolynomial1D(): This routine must fit a polynomial of degree740 myPoly to the data points (x, y) and return the coefficients of that 741 polynomial, as well as the error for each data point (yErr).744 p_psVectorFitPolynomial1DOrd(): This routine will fit an ordinary 745 polynomial of degree myPoly to the data points (x, y) and return the 746 coefficients of that polynomial. 742 747 743 748 XXX: yErr is currently ignored. … … 745 750 XXX: must add type F32 (currently F64 only). 746 751 747 XXX: Must do: if x==NULL, use the index vector (???). 748 749 XXX: Must do: if yErr==NULL, set all errors equal. 750 751 XXX: type is currently ignored. Must implement this for Chebyshev 752 polynomials. 752 XXX: Use private name? 753 753 *****************************************************************************/ 754 psPolynomial1D* p sVectorFitPolynomial1D(psPolynomial1D* myPoly,755 const psVector* restrict x,756 const psVector* restrict y,757 const psVector* restrict yErr)754 psPolynomial1D* p_psVectorFitPolynomial1DOrd(psPolynomial1D* myPoly, 755 const psVector* restrict x, 756 const psVector* restrict y, 757 const psVector* restrict yErr) 758 758 { 759 // XXX: Create a p_psVectorFitPolynomial1DOrd() function. Here, we760 // should only be calling that or the Cheby function.761 762 if (myPoly->type == PS_POLYNOMIAL_CHEB) {763 return(p_psVectorFitPolynomial1DCheby(myPoly, x, y, yErr));764 }765 766 759 int polyOrder = myPoly->n; 767 760 psImage* A = NULL; … … 783 776 // } 784 777 778 // XXX: Some of these are redundant. 785 779 PS_CHECK_NULL_1DPOLY(myPoly); 786 780 PS_CHECK_NULL_VECTOR(y); 787 781 PS_CHECK_EMPTY_VECTOR(y); 788 789 // XXX: Verify that this is the correct action.790 if (x == NULL) {791 x = psVectorAlloc(y->n, PS_TYPE_F32);792 for (i=0;i<x->n;i++) {793 x->data.F32[i] = (float) i;794 }795 }796 797 782 PS_CHECK_EMPTY_VECTOR(x); 798 783 PS_CHECK_NULL_VECTOR(yErr); … … 863 848 return (myPoly); 864 849 } 850 851 /****************************************************************************** 852 psVectorFitPolynomial1D(): This routine must fit a polynomial of degree 853 myPoly to the data points (x, y) and return the coefficients of that 854 polynomial. 855 856 XXX: yErr is currently ignored. 857 858 XXX: must add type F32 (currently F64 only). 859 *****************************************************************************/ 860 psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly, 861 const psVector* restrict x, 862 const psVector* restrict y, 863 const psVector* restrict yErr) 864 { 865 bool mustFreeMyYErr = false; 866 bool mustFreemyX = false; 867 int i; 868 psPolynomial1D *tmpPoly; 869 psVector *myX = NULL; 870 psVector *myYErr = NULL; 871 872 PS_CHECK_NULL_1DPOLY(myPoly); 873 PS_CHECK_NULL_VECTOR(y); 874 PS_CHECK_EMPTY_VECTOR(y); 875 876 // If yErr==NULL, set all errors equal. 877 if (yErr == NULL) { 878 myYErr = psVectorAlloc(y->n, y->type.type); 879 mustFreeMyYErr = true; 880 881 if (y->type.type == PS_TYPE_F32) { 882 for (i=0;i<yErr->n;i++) { 883 myYErr->data.F32[i] = 1.0; 884 } 885 } else if (y->type.type == PS_TYPE_F64) { 886 for (i=0;i<yErr->n;i++) { 887 myYErr->data.F64[i] = 1.0; 888 } 889 } 890 } else { 891 myYErr = (psVector *) yErr; 892 } 893 894 // If x==NULL, create an myX vector with x values set to (0:n), and if 895 // this is a CHebyshev polynomial, we must scale to (-1:1). 896 897 // XXX: Verify that this is the correct action. 898 if (x == NULL) { 899 myX = psVectorAlloc(y->n, y->type.type); 900 mustFreemyX = true; 901 902 if (y->type.type == PS_TYPE_F32) { 903 if (myPoly->type == PS_POLYNOMIAL_ORD) { 904 for (i=0;i<yErr->n;i++) { 905 myX->data.F32[i] = (float) i; 906 } 907 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 908 float min = 0.0; 909 float max = (float) (y->n - 1); 910 911 for (i=0;i<yErr->n;i++) { 912 myX->data.F32[i] = (((float) i) - 0.5 * (min + max)) / 913 (0.5 * (max - min)); 914 } 915 } 916 } else if (y->type.type == PS_TYPE_F64) { 917 if (myPoly->type == PS_POLYNOMIAL_ORD) { 918 for (i=0;i<yErr->n;i++) { 919 myX->data.F64[i] = (float) i; 920 } 921 } else if (myPoly->type == PS_POLYNOMIAL_CHEB) { 922 double min = 0.0; 923 double max = (double) (y->n - 1); 924 925 for (i=0;i<yErr->n;i++) { 926 myX->data.F64[i] = (((float) i) - 0.5 * (min + max)) / 927 (0.5 * (max - min)); 928 } 929 } 930 } 931 } else { 932 myX = (psVector *) x; 933 } 934 935 PS_CHECK_VECTOR_SIZE_EQUAL(y, myX); 936 PS_CHECK_VECTOR_SIZE_EQUAL(y, myYErr); 937 938 // Call the appropriate vector fitting routine. 939 if (myPoly->type == PS_POLYNOMIAL_CHEB) { 940 tmpPoly = p_psVectorFitPolynomial1DCheby(myPoly, myX, y, myYErr); 941 } else if (myPoly->type == PS_POLYNOMIAL_ORD) { 942 tmpPoly = p_psVectorFitPolynomial1DOrd(myPoly, myX, y, myYErr); 943 } else { 944 // XXX: psErrorMsg() 945 return(NULL); 946 } 947 948 // Free any allocated memory. 949 if (mustFreeMyYErr == true) { 950 psFree(myYErr); 951 } 952 if (mustFreemyX == true) { 953 psFree(myX); 954 } 955 956 return(myPoly); 957 } 958 865 959 866 960
Note:
See TracChangeset
for help on using the changeset viewer.
