Changeset 1629 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Aug 26, 2004, 10:10:25 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
r1610 r1629 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.3 2$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-2 4 19:59:05 $11 * @version $Revision: 1.33 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-26 20:10:25 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 939 939 } 940 940 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 *****************************************************************************/ 952 psVector *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 *****************************************************************************/ 1043 bool 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 941 1104 bool psMinimizePowell(psMinimization *min, 942 1105 psVector *params,
Note:
See TracChangeset
for help on using the changeset viewer.
