- Timestamp:
- Jun 9, 2013, 3:27:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20130509/psLib/src/math/psMinimizeLMM.c
r35629 r35637 680 680 } 681 681 682 psImage *alpha = psImageAlloc(Alpha->numCols, Alpha->numRows, PS_TYPE_F32); 683 psVector *beta = psVectorAlloc(Beta->n, PS_TYPE_F32); 682 int nFitParams = Beta->n; 683 psImage *alpha = psImageAlloc(nFitParams, nFitParams, PS_TYPE_F32); 684 psVector *beta = psVectorAlloc(nFitParams, PS_TYPE_F32); 684 685 psVector *Params = psVectorAlloc(params->n, PS_TYPE_F32); 685 686 … … 687 688 psF32 Chisq = 0.0; 688 689 psF32 lambda = 0.001; 690 psF32 dLinear = 0.0; 689 691 psF32 nu = 2.0; 690 psF32 dLinear = 0.0;691 692 692 693 // the user provides the error or NULL. we need to convert … … 700 701 701 702 // number of degrees of freedom for this fit 702 int nDOF = dy->n - params->n;703 int nDOF = dy->n - nFitParams; 703 704 704 705 // calculate initial alpha and beta, set chisq (min->value) … … 722 723 } 723 724 724 // iterate until: (a) nIter = min->iter or (b) (chisq / ndof) < maxChisq and deltaChisq < minTol (but don't stop unless Chisq is finite)725 725 bool done = (min->iter >= min->maxIter); 726 726 while (!done) { 727 727 psTrace("psLib.math", 5, "Iteration number %d. (max iterations is %d).\n", min->iter, min->maxIter); 728 psTrace("psLib.math", 5, "Last delta is %f. stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol); 728 729 if (min->chisqConvergence) { 730 psTrace("psLib.math", 5, "Last delta is %f. stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol); 731 } else { 732 psTrace("psLib.math", 5, "Last delta is %f. stop if < %f, accept if < %f\n", min->rParSigma, min->minTol*nFitParams, min->maxTol*nFitParams); 733 } 729 734 730 735 // set a new guess for Alpha, Beta, Params … … 732 737 min->iter ++; 733 738 if (min->iter >= min->maxIter) break; 734 //lambda *= 10.0;735 lambda *= 2.0;739 lambda *= 10.0; 740 // ALT? lambda *= 2.0; 736 741 continue; 737 742 } … … 754 759 // Beta is the actual parameter change for this pass 755 760 756 // note that Alpha & Beta only represent unmasked parameters 761 // note that Alpha & Beta only represent unmasked parameters, while params and Params have all 757 762 758 763 // dParSigma = Alpha[i][i] : error (squared) on parameter i 759 // dParDelta = Beta[i]^2 : change (squared) in parameter i764 // dParDelta = Params->data.F32[i] - params->data.F32[i] : change on parameter i 760 765 float rParSigma = 0.0; 761 // for (int j = 0; j < Beta->n; j++) {762 // rParSigma += PS_SQR(Beta->data.F32[j]) / Alpha->data.F32[j][j];763 // }764 766 for (int j = 0, J = 0; j < Params->n; j++) { 765 767 if (paramMask && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[j])) { 766 768 continue; 767 769 } 768 // fprintf (stderr, "del: %f - %f vs %f : %f\n", Params->data.F32[j], params->data.F32[j], sqrt(Alpha->data.F32[J][J]), PS_SQR(Params->data.F32[j] - params->data.F32[j]) / Alpha->data.F32[J][J]);769 770 rParSigma += PS_SQR(Params->data.F32[j] - params->data.F32[j]) / Alpha->data.F32[J][J]; 770 771 J++; … … 779 780 min->iter ++; 780 781 if (min->iter >= min->maxIter) break; 781 //lambda *= 10.0;782 lambda *= 2.0;782 lambda *= 10.0; 783 // ALT lambda *= 2.0; 783 784 continue; 784 785 } … … 807 808 // XXX the old version of lambda changes: 808 809 // XXX : Madsen gives suggestion for better use of rho 809 # if (0)810 if (rho >= -1e-6) {811 min->value = Chisq;812 alpha = psImageCopy(alpha, Alpha, PS_TYPE_F32);813 beta = psVectorCopy(beta, Beta, PS_TYPE_F32);814 params = psVectorCopy(params, Params, PS_TYPE_F32);815 lambda *= 0.25;816 } else {817 lambda *= 10.0;818 }819 # endif820 821 810 // rho is positive if the new chisq is smaller 822 811 if (rho >= -1e-6) { … … 826 815 params = psVectorCopy(params, Params, PS_TYPE_F32); 827 816 } 828 829 # if (0) 830 // adjust the gain ratio (lambda) based on rho 831 if (rho < 0.25) { 832 lambda *= 2.0; 833 } 834 if (rho > 0.75) { 835 lambda *= 0.333; 836 } 837 # else 838 if (rho > 0.0) { 839 lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0))); 840 nu = 2.0; 841 } else { 842 lambda *= nu; 843 nu *= 2.0; 817 switch (min->gainFactorMode) { 818 case 0: 819 if (rho >= -1e-6) { 820 lambda *= 0.25; 821 } else { 822 lambda *= 10.0; 823 } 824 break; 825 826 case 1: 827 // adjust the gain ratio (lambda) based on rho 828 if (rho < 0.25) { 829 lambda *= 2.0; 830 } 831 if (rho > 0.75) { 832 lambda *= 0.333; 833 } 834 break; 835 836 case 2: 837 if (rho > 0.0) { 838 lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0))); 839 nu = 2.0; 840 } else { 841 lambda *= nu; 842 nu *= 2.0; 843 } 844 break; 844 845 } 845 # endif846 846 min->iter++; 847 847 … … 850 850 done = (min->iter >= min->maxIter); 851 851 852 // 2) require deltaChi > 1e-6 (ie, chisq is decreasing, but accept an insignificant change) 853 if (min->lastDelta < -1e-6) { 854 continue; 855 } 856 857 // save this value in case we stop iterating 858 min->rParSigma = rParSigma; 859 852 860 // 2) require chisqDOF < maxChisqDOF (if maxChisqDOF is not NAN) 861 // keep iterating regardless of rParSigma in this case 853 862 float chisqDOF = Chisq / nDOF; 854 863 if (isfinite(min->maxChisqDOF) && (chisqDOF > min->maxChisqDOF)) { … … 856 865 } 857 866 858 // 3) require deltaChi > 1e-6 (ie, chisq is decreasing, but accept an insignificant change) 859 if (min->lastDelta < -1e-6) { 860 continue; 867 // delta-chisq or rParSigma ? 868 if (min->chisqConvergence) { 869 done |= (min->lastDelta < min->minTol); 870 } else { 871 done |= (rParSigma < min->minTol*nFitParams); 861 872 } 862 863 // 4) require rParDelta < \eta * rParSigma 864 done |= (rParSigma < 0.01); 865 } 866 psTrace("psLib.math", 5, "chisq: %f, last delta: %f, Niter: %d\n", min->value, min->lastDelta, min->iter); 873 } 874 psTrace("psLib.math", 5, "chisq: %f, last delta: %f, rParSigma: %f, Niter: %d\n", min->value, min->lastDelta, min->rParSigma, min->iter); 867 875 868 876 // construct & return the covariance matrix (if requested) … … 898 906 899 907 // if the last improvement was at least as good as maxTol, accept the fit: 900 // XXX : maybe re-work this to use rParSigma & maxTol901 if (min->lastDelta <= min->maxTol) {908 if (min->chisqConvergence) { 909 if (min->lastDelta <= min->maxTol) { 902 910 psTrace("psLib.math", 6, "---- end (true) ----\n"); 903 911 return(true); 912 } 913 } else { 914 if (min->rParSigma <= min->maxTol*nFitParams) { 915 psTrace("psLib.math", 6, "---- end (true) ----\n"); 916 return(true); 917 } 904 918 } 905 919 psTrace("psLib.math", 6, "---- end (false) ----\n"); … … 952 966 min->iter = 0; 953 967 min->lastDelta = NAN; 968 min->rParSigma = NAN; 954 969 min->maxChisqDOF = NAN; 955 970 971 // we default to the old algorithm for convergence 972 min->chisqConvergence = true; 973 min->gainFactorMode = 0; 974 956 975 return(min); 957 976 }
Note:
See TracChangeset
for help on using the changeset viewer.
