IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 26, 2004, 10:10:25 AM (22 years ago)
Author:
gusciora
Message:

...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psMinimize.c

    r1610 r1629  
    99 *  @author George Gusciora, MHPCC
    1010 *
    11  *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-08-24 19:59:05 $
     11 *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-08-26 20:10:25 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    939939}
    940940
     941#define STEP_SIZE 0.10
     942/******************************************************************************
     943    This routine takes as input an arbitrary function of a single parameter.
     944    This function produces as output a bracket [a, b, c] such that f(b) is
     945    less than f(a) and f(b).
     946 
     947    Algorithm: XXX completely ad hoc: start with the user-supplied starting
     948    parameter and call that b.  Calculate a/c as a fractional amount
     949    smaller/larger than b.  Repeat this process until a local minimum is
     950    found.
     951 *****************************************************************************/
     952psVector *p_psDetermineBracket(psVector *params,
     953                               const psArray *coords,
     954                               psMinimizePowellFunc func)
     955{
     956    float a = 0.0;
     957    float b = 0.0;
     958    float c = 0.0;
     959    float fa = 0.0;
     960    float fb = 0.0;
     961    float fc = 0.0;
     962    int iter = 100;
     963    float aDir = 0.0;
     964    float cDir = 0.0;
     965    float new_aDir = 0.0;
     966    float new_cDir = 0.0;
     967    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
     968    psVector *dummyParams = psVectorAlloc(1, PS_TYPE_F32);
     969
     970    a = b = c = params->data.F32[0];
     971    a = a * (1.0 - STEP_SIZE);
     972    c = c * (1.0 + STEP_SIZE);
     973
     974    dummyParams->data.F32[0] = a;
     975    fa = func(dummyParams, coords);
     976    dummyParams->data.F32[0] = b;
     977    fb = func(dummyParams, coords);
     978    dummyParams->data.F32[0] = c;
     979    fc = func(dummyParams, coords);
     980    if (fa < fb) {
     981        aDir = -1;
     982    } else {
     983        aDir = 1;
     984    }
     985
     986    if (fc < fb) {
     987        cDir = -1;
     988    } else {
     989        cDir = 1;
     990    }
     991
     992    while (iter > 0) {
     993        if ((b < a) && (b < c)) {
     994            bracket->data.F32[0] = a;
     995            bracket->data.F32[1] = b;
     996            bracket->data.F32[2] = c;
     997            return(bracket);
     998        }
     999        a = a * (1.0 - STEP_SIZE);
     1000        c = c * (1.0 + STEP_SIZE);
     1001        dummyParams->data.F32[0] = a;
     1002        fa = func(dummyParams, coords);
     1003        dummyParams->data.F32[0] = c;
     1004        fc = func(dummyParams, coords);
     1005
     1006        if (fa < fb) {
     1007            new_aDir = -1;
     1008        } else {
     1009            new_aDir = 1;
     1010        }
     1011
     1012        if (fc < fb) {
     1013            new_cDir = -1;
     1014        } else {
     1015            new_cDir = 1;
     1016        }
     1017        if ((new_aDir == 1) && (aDir == -1)) {
     1018            bracket->data.F32[0] = a;
     1019            bracket->data.F32[1] = bracket->data.F32[0] / (1.0 - STEP_SIZE);
     1020            bracket->data.F32[2] = bracket->data.F32[1] / (1.0 - STEP_SIZE);
     1021            return(bracket);
     1022        }
     1023
     1024        if ((new_cDir == 1) && (cDir == -1)) {
     1025            bracket->data.F32[2] = c;
     1026            bracket->data.F32[1] = bracket->data.F32[0] / (1.0 + STEP_SIZE);
     1027            bracket->data.F32[0] = bracket->data.F32[1] / (1.0 + STEP_SIZE);
     1028            return(bracket);
     1029        }
     1030        aDir = new_aDir;
     1031        cDir = new_cDir;
     1032    }
     1033    psFree(dummyParams);
     1034    psFree(bracket);
     1035    return(NULL);
     1036}
     1037
     1038
     1039
     1040/******************************************************************************
     1041    This routine must minimize a function of exactly one parameter.
     1042 *****************************************************************************/
     1043bool psMinimize1DFunc(psMinimization *min,
     1044                      psVector *params,
     1045                      const psArray *coords,
     1046                      psMinimizePowellFunc func)
     1047{
     1048    psVector *bracket;
     1049    psVector *dummyParams = psVectorAlloc(1, PS_TYPE_F32);
     1050    float a = 0.0;
     1051    float b = 0.0;
     1052    float c = 0.0;
     1053    float n = 0.0;
     1054    float fb = 0.0;
     1055    float fn = 0.0;
     1056
     1057    if (params->n != 1) {
     1058        psAbort(__func__, "params is larger than a single dimension.");
     1059    }
     1060    bracket = p_psDetermineBracket(params, coords, func);
     1061
     1062
     1063    min->iter = 0;
     1064    while (1) {
     1065        min->iter++;
     1066
     1067        a = bracket->data.F32[0];
     1068        b = bracket->data.F32[1];
     1069        c = bracket->data.F32[2];
     1070        dummyParams->data.F32[0] = b;
     1071        fb = func(dummyParams, coords);
     1072
     1073        // We determine which is the biggest segment in [a,b,c] then split
     1074        // that with the point n.
     1075        if ((b-a) > (c-b)) {
     1076            // This is the golden section formula
     1077            dummyParams->data.F32[0] = n = a + (0.69 * (b-a));
     1078            fn = func(dummyParams, coords);
     1079            if (fn > fb) {
     1080                // a = n, b = b, c = c
     1081                bracket->data.F32[0] = n;
     1082            } else {
     1083                // a = a, b = n, c = b
     1084                bracket->data.F32[1] = n;
     1085                bracket->data.F32[2] = b;
     1086            }
     1087        } else {
     1088            dummyParams->data.F32[0] = b + (0.69 * (c-b));
     1089            fn = func(dummyParams, coords);
     1090            if (fn > fb) {
     1091                // a = a, b = b, c = n
     1092                bracket->data.F32[2] = n;
     1093            } else {
     1094                // a = b, b = n, c = c
     1095                bracket->data.F32[0] = b;
     1096                bracket->data.F32[1] = n;
     1097            }
     1098        }
     1099    }
     1100
     1101    psFree(dummyParams);
     1102}
     1103
    9411104bool psMinimizePowell(psMinimization *min,
    9421105                      psVector *params,
Note: See TracChangeset for help on using the changeset viewer.