Changeset 2197 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Oct 26, 2004, 11:25:59 AM (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
r2106 r2197 9 9 * @author GLF, MHPCC 10 10 * 11 * @version $Revision: 1.5 8$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-10- 14 01:44:48$11 * @version $Revision: 1.59 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-10-26 21:24:42 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 636 636 psFree(currValueVec); 637 637 psFree(newValueVec); 638 639 if ((min->iter < min->maxIter) || 640 (min->lastDelta <= min->tol)) { 641 return(true); 642 } 643 644 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 645 "---- psMinimizeLMChi2() end (false) ----\n"); 646 return(false); 647 } 648 649 /****************************************************************************** 650 psMyMinimizeLMChi2(): This routine will take an procedure which calculates 651 an arbitrary function and it's derivative and minimize the chi-squared match 652 between that function at the specified coords and the specified value at 653 those coords. 654 655 XXX: Do this: 656 After checking that all entries in the paramMask are 1 or 0, when 657 forming the A matrix from alpha, try this: 658 659 A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i]; 660 661 XXX: This is very different from what is specified in the SDR. Must 662 coordinate with IfA on new SDR. 663 664 XXX: Do vector/image recycles. 665 666 XXX: probably yErr will be part of the SDR. 667 668 XXX: This must work for both F32 and F64. F32 is currently implemented. 669 Note: since the LUD routines are only implemented in F64, then we 670 will have to convert all F32 input vectors to F64 regardless. So, 671 the F64 port might be. 672 *****************************************************************************/ 673 bool psMyMinimizeLMChi2(psMinimization *min, 674 psImage *covar, 675 psVector *params, 676 const psVector *paramMask, 677 const psArray *x, 678 const psVector *y, 679 const psVector *yErr, 680 psMyMinimizeLMChi2Func func) 681 { 682 PS_CHECK_NULL_PTR_RETURN_NULL(min); 683 PS_CHECK_NULL_VECTOR_RETURN_NULL(params); 684 PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params); 685 PS_CHECK_NULL_PTR_RETURN_NULL(x); 686 PS_CHECK_NULL_VECTOR_RETURN_NULL(y); 687 PS_CHECK_EMPTY_VECTOR_RETURN_NULL(y); 688 PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x, y); 689 if (paramMask != NULL) { 690 PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, paramMask); 691 } 692 if (yErr != NULL) { 693 PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(y, yErr); 694 } 695 696 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 697 "---- psMinimizeLMChi2() begin ----\n"); 698 int numData = y->n; 699 int numParams = params->n; 700 int i; 701 int j; 702 int k; 703 int l; 704 int n; 705 int p; 706 psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64); 707 psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64); 708 709 psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64); 710 psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32); 711 psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32); 712 713 psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32); 714 psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64); 715 psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64); 716 717 // psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *)); 718 // for (i=0;i<numData;i++) { 719 // deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32); 720 // } 721 psImage *deriv = psImageAlloc(numParams, numData, PS_TYPE_F32); 722 723 psVector *currValueVec; 724 psVector *newValueVec; 725 726 float currChi2 = 0.0; 727 float newChi2 = 0.0; 728 float lamda = 0.00005; 729 730 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 731 "min->maxIter is %d\n", min->maxIter); 732 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 733 "min->tol is %f\n", min->tol); 734 735 for (p=0;p<numParams;p++) { 736 origParams->data.F32[p] = params->data.F32[p]; 737 } 738 739 min->lastDelta = HUGE; 740 min->iter = 0; 741 742 while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) { 743 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 744 "------------------------------------------------------\n"); 745 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 746 "Iteration %d. Delta is %f\n", min->iter, min->lastDelta); 747 748 // 749 // Calculate the current values and chi-squared of the function. 750 // 751 currChi2 = 0.0; 752 currValueVec = func(deriv, params, x); 753 for (n=0;n<numData;n++) { 754 currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]); 755 } 756 757 for (p=0;p<numParams;p++) { 758 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 759 "params->data.F32[%d] is %f.\n", p, params->data.F32[p]); 760 } 761 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 762 "Current chi-squared is (%f)\n", currChi2); 763 764 // 765 // Mask elements of the derivative for each data point. 766 // 767 for (p=0;p<numParams;p++) { 768 if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) { 769 for (n=0;n<numData;n++) { 770 deriv->data.F32[n][p] = 0.0; 771 } 772 } 773 } 774 775 // 776 // Calculate the BETA vector. 777 // 778 for (p=0;p<numParams;p++) { 779 beta->data.F64[p] = 0.0; 780 for (n=0;n<numData;n++) { 781 (beta->data.F64[p])+= 782 (y->data.F32[n] - currValueVec->data.F32[n]) * 783 deriv->data.F32[n][p]; 784 } 785 // XXX: multiple by -1 here? 786 (beta->data.F64[p])*= -1.0; 787 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 788 "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]); 789 } 790 psFree(currValueVec); 791 792 // 793 // Calculate the ALPHA matrix. 794 // 795 for (k=0;k<numParams;k++) { 796 for (l=0;l<numParams;l++) { 797 alpha->data.F32[k][l] = 0.0; 798 for (n=0;n<numData;n++) { 799 alpha->data.F32[k][l]+= deriv->data.F32[n][k] * 800 deriv->data.F32[n][l]; 801 } 802 } 803 } 804 805 // 806 // Calculate the matrix A. 807 // 808 for (j=0;j<numParams;j++) { 809 for (k=0;k<numParams;k++) { 810 if (j == k) { 811 A->data.F64[j][k] = 812 (double) ((1.0 + lamda) * alpha->data.F32[j][k]); 813 } else { 814 A->data.F64[j][k] = (double) alpha->data.F32[j][k]; 815 } 816 } 817 } 818 for (j=0;j<numParams;j++) { 819 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n"); 820 for (k=0;k<numParams;k++) { 821 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]); 822 } 823 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n"); 824 } 825 826 // 827 // Solve A * alpha = Beta 828 // 829 aOut = psMatrixLUD(aOut, perm, A); 830 paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm); 831 832 // 833 // Mask any masked parameters. 834 // 835 for (i=0;i<numParams;i++) { 836 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 837 "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]); 838 if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) { 839 newParams->data.F32[i] = origParams->data.F32[i]; 840 } else { 841 newParams->data.F32[i] = params->data.F32[i] - 842 (float) paramDeltasF64->data.F64[i]; 843 } 844 } 845 846 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 847 "Calling func() with new parameters:\n"); 848 for (i=0;i<numParams;i++) { 849 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 850 "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]); 851 } 852 853 854 // 855 // Calculate new function values. 856 // 857 newChi2 = 0.0; 858 newValueVec = func(deriv, newParams, x); 859 for (n=0;n<numData;n++) { 860 newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]); 861 } 862 psFree(newValueVec); 863 864 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 865 "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2); 866 867 // 868 // If the new chi-squared is lower, then keep it. 869 // 870 if (currChi2 > newChi2) { 871 min->lastDelta = currChi2 - newChi2; 872 min->value = newChi2; 873 874 // We already masked params. 875 for (i=0;i<numParams;i++) { 876 params->data.F32[i] = (float) newParams->data.F32[i]; 877 } 878 lamda*= 0.1; 879 } else { 880 lamda*= 10.0; 881 } 882 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 883 "lamda is %f\n", lamda); 884 min->iter++; 885 } 886 psFree(beta); 887 psFree(perm); 888 psFree(paramDeltasF64); 889 psFree(origParams); 890 psFree(newParams); 891 psFree(alpha); 892 psFree(A); 893 psFree(aOut); 894 psFree(deriv); 638 895 639 896 if ((min->iter < min->maxIter) ||
Note:
See TracChangeset
for help on using the changeset viewer.
