Changeset 7130
- Timestamp:
- May 17, 2006, 2:24:13 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/test/math/tst_psMinimizeLMM.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/test/math/tst_psMinimizeLMM.c
r7085 r7130 12 12 #include <math.h> 13 13 #define NUM_ITERATIONS 100 14 #define ERR_TOL 0.115 #define NUM_DATA_POINTS 2016 #define NUM_PARAMS 514 #define ERR_TOL 1e-6 15 #define NUM_DATA_POINTS 100 16 #define NUM_PARAMS 3 17 17 float expectedParm[NUM_PARAMS]; 18 19 20 float function(const psVector *params, // Paramters 21 const psVector *x // Ordinate 22 ) 23 { 24 return params->data.F32[0] * 25 expf(- params->data.F32[1] * (PS_SQR(x->data.F32[0]) + PS_SQR(x->data.F32[1]))) + 26 params->data.F32[2]; 27 } 28 29 void derivatives(psVector *deriv, // Derivatives 30 const psVector *params, // Paramters 31 const psVector *x // Ordinate 32 ) 33 { 34 deriv->data.F32[0] = expf(- params->data.F32[1] * (PS_SQR(x->data.F32[0]) + PS_SQR(x->data.F32[1]))); 35 deriv->data.F32[1] = - params->data.F32[0] * (PS_SQR(x->data.F32[0]) + PS_SQR(x->data.F32[1])) * 36 expf(- params->data.F32[1] * (PS_SQR(x->data.F32[0]) + PS_SQR(x->data.F32[1]))); 37 deriv->data.F32[2] = 1.0; 38 } 39 40 18 41 19 42 /***************************************************************************** 20 43 myFunc(): 21 sum = param[0] +x[0] * x[1] +44 sum = param[0] * x[0] * x[1] + 22 45 param[1] * x[0] + 23 46 param[2] * x[0]^2 + … … 26 49 27 50 *****************************************************************************/ 28 psF32 myFunc(psVector *deriv,29 psVector *params,30 psVector *x)51 psF32 fitFunc(psVector *deriv, 52 psVector *params, 53 psVector *x) 31 54 { 32 55 if ((deriv == NULL) || (params == NULL) || (x == NULL)) { … … 34 57 } 35 58 36 psF32 sum = (params->data.F32[0] * x->data.F32[0] * x->data.F32[1]) + 37 (params->data.F32[1] * x->data.F32[0]) + 38 (params->data.F32[2] * PS_SQR(x->data.F32[0])) + 39 (params->data.F32[3] * x->data.F32[1]) + 40 (params->data.F32[4] * PS_SQR(x->data.F32[1])); 41 42 deriv->data.F32[0] = x->data.F32[0] * x->data.F32[1]; 43 deriv->data.F32[1] = x->data.F32[0]; 44 deriv->data.F32[2] = PS_SQR(x->data.F32[0]); 45 deriv->data.F32[3] = x->data.F32[1]; 46 deriv->data.F32[4] = PS_SQR(x->data.F32[1]); 47 48 return(sum); 59 derivatives(deriv, params, x); 60 return function(params, x); 49 61 } 50 62 … … 54 66 psBool testStatus = true; 55 67 68 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 1); // Random number generator; using known seed 56 69 psMinimization *min = psMinimizationAlloc(NUM_ITERATIONS, ERR_TOL); 57 psImage *myCovar = psImageAlloc(NUM_PARAMS, NUM_PARAMS, PS_TYPE_F32); 58 psVector *myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32); 59 psVector *myDerivs = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32); 60 psArray *myCoords = psArrayAlloc(NUM_DATA_POINTS); 61 myCoords->n = NUM_DATA_POINTS; 62 psVector *y = psVectorAlloc(NUM_DATA_POINTS, PS_TYPE_F32); 63 myParams->n = NUM_PARAMS; 64 myDerivs->n = NUM_PARAMS; 65 y->n = NUM_DATA_POINTS; 66 67 for (psS32 i=0;i<NUM_DATA_POINTS;i++) { 68 myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32); 69 ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) (i+10); 70 ((psVector *) (myCoords->data[i]))->data.F32[1] = (float) (i+3); 71 ((psVector *) (myCoords->data[i]))->n = 2; 72 psTrace(__func__, 5, "x[%d] is vector (%f, %f)\n", i, ((psVector *) (myCoords->data[i]))->data.F32[0], 73 ((psVector *) (myCoords->data[i]))->data.F32[1]); 74 y->data.F32[i] = (float) i; 75 } 76 for (psS32 i=0;i<NUM_PARAMS;i++) { 77 expectedParm[i] = 2.42 + (float) (2 * i); 78 myParams->data.F32[i] = (float) (2 * i); 79 } 80 81 psBool rc = psMinimizeLMChi2(min, NULL, myParams, NULL, myCoords, y, NULL, 82 (psMinimizeLMChi2Func) myFunc); 83 if (rc == false) { 70 psArray *ordinates = psArrayAlloc(NUM_DATA_POINTS); 71 psVector *coordinates = psVectorAlloc(NUM_DATA_POINTS, PS_TYPE_F32); 72 psVector *errors = psVectorAlloc(NUM_DATA_POINTS, PS_TYPE_F32); 73 ordinates->n = NUM_DATA_POINTS; 74 coordinates->n = NUM_DATA_POINTS; 75 errors->n = NUM_DATA_POINTS; 76 psVector *params = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32); 77 params->n = NUM_PARAMS; 78 psVector *trueParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32); 79 trueParams->n = NUM_PARAMS; 80 81 trueParams->data.F32[0] = 100.0; // Normalisation 82 trueParams->data.F32[1] = 0.1; // Shape 83 trueParams->data.F32[2] = 10.0; // Background 84 85 // Set parameters 86 for (long i = 0; i < NUM_PARAMS; i++) { 87 // So we're not starting right on the true value: 88 params->data.F32[i] = trueParams->data.F32[i] * (1.0 - psRandomGaussian(rng) / 10.0); 89 } 90 91 for (long i = 0; i < NUM_DATA_POINTS; i++) { 92 psVector *x = psVectorAlloc(2, PS_TYPE_F32); 93 x->data.F32[0] = 10.0 * psRandomUniform(rng) - 5.0; 94 x->data.F32[1] = 10.0 * psRandomUniform(rng) - 5.0; 95 ordinates->data[i] = x; 96 coordinates->data.F32[i] = function(params, x) + 0.1 * psRandomGaussian(rng); // Add some noise 97 errors->data.F32[i] = 0.1; 98 printf("Data %ld: (%f, %f) --> %f\n", i, x->data.F32[0], x->data.F32[1], coordinates->data.F32[i]); 99 } 100 101 if (!psMinimizeLMChi2(min, NULL, params, NULL, ordinates, coordinates, errors, 102 (psMinimizeLMChi2Func)fitFunc)) { 84 103 printf("TEST ERROR: psMinimizeLMChi2() returned FALSE.\n"); 85 104 fflush(stdout); 86 105 testStatus = false; 87 106 } else { 88 printf("\nThe value of the function at the minimum is %f\n", min->value); 89 for (psS32 i=0;i<NUM_DATA_POINTS;i++) { 90 float myFuncValue = (float)(myFunc(myDerivs, myParams, (psVector *) myCoords->data[i])); 91 myFuncValue += 0.001; 92 printf("The minimum for data point number %d: f is %.2f\n", 93 i, myFuncValue); 107 printf("Minimisation took %d iterations\n", min->iter); 108 printf("chi^2 at the minimum is %f\n", min->value); 109 for (long i = 0; i < NUM_PARAMS; i++) { 110 printf("Parameter %ld at the minimum is %f, expected: %f\n", i, 111 params->data.F32[i], trueParams->data.F32[i]); 94 112 fflush(stdout); 95 113 } 96 97 for (psS32 i=0;i<NUM_PARAMS;i++) { 98 printf("Parameter %d at the minimum is %.1f (expected: %.1f)\n", i, 99 myParams->data.F32[i], expectedParm[i]); 114 float diff = 0.0; 115 for (long i = 0; i < NUM_DATA_POINTS; i++) { 116 psVector *x = ordinates->data[i]; 117 float fitted = function(trueParams, x); 118 float expected = function(params, x); 119 diff += (fitted - expected) / fabsf(expected); 120 printf("Data point %ld: Fitted: %f, expected: %f\n", i, fitted, expected); 100 121 fflush(stdout); 101 122 } 123 printf("Mean relative difference is %f\n", diff/(float)NUM_DATA_POINTS); 124 102 125 } 103 126 104 127 psFree(min); 105 psFree(myCovar); 106 psFree(myParams); 107 psFree(myDerivs); 108 psFree(myCoords); 109 psFree(y); 128 psFree(params); 129 psFree(trueParams); 130 psFree(ordinates); 131 psFree(coordinates); 132 psFree(errors); 133 psFree(rng); 110 134 psMemCheckCorruption(1); 111 135 psS32 memLeaks = psMemCheckLeaks(currentId, NULL, NULL, false);
Note:
See TracChangeset
for help on using the changeset viewer.
