int calc_reflection(t_detail *detail, t_color *color, t_light *light, double *vector) { static int i; t_camera camera; t_object *tmp; if (i >= CONST_REFL || detail->object == NULL || !detail->object->effect[REFLECTION]) { if (detail->object) return (refraction_management(detail, &color[i], light, vector)); else return (restat_color(&color[i])); } refraction_management(detail, &color[i], light, vector); cpy_point(detail->position, camera.position); get_vector_reflechie(vector, detail->normal, vector); ++i; tmp = detail->object; get_object_reflechie(&camera, detail, vector, &color[i]); calc_reflection(detail, color, light, vector); --i; if (tmp != NULL && tmp->effect[REFLECTION] && (color[i + 1].red >= 0.0F && color[i + 1].green >= 0.0F && color[i + 1].blue >= 0.0F)) get_color_reflechie(color, tmp, i); return (EXIT_SUCCESS); }
int calc_effect(t_detail *detail, t_color *color, t_light *light, double *vector) { t_color tmp[CONST_REFL + 1]; int i; i = -1; while (++i <= CONST_REFL) { tmp[i].red = -1.0F; tmp[i].green = -1.0F; tmp[i].blue = -1.0F; } if (detail == NULL || color == NULL || light == NULL || vector == NULL) return (EXIT_FAILURE); tmp[0].red = color->red; tmp[0].green = color->green; tmp[0].blue = color->blue; calc_reflection(detail, tmp, light, vector); color->red = tmp[0].red; color->green = tmp[0].green; color->blue = tmp[0].blue; return (EXIT_SUCCESS); }
void simplex_optimization (float * parameters, float * sse) { const int MAX_ITERATIONS = 100; const int MAX_RESTARTS = 25; const float EXPANSION_COEF = 2.0; const float REFLECTION_COEF = 1.0; const float CONTRACTION_COEF = 0.5; const float TOLERANCE = 1.0e-10; float ** simplex = NULL; float * centroid = NULL; float * response = NULL; float * step_size = NULL; float * test1 = NULL; float * test2 = NULL; float resp1, resp2; int i, worst, best, next; int num_iter, num_restarts; int done; float fit; allocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); simplex_initialize (parameters, simplex, response, step_size); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /* find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex */ eval_vertices (response, &worst, &next, &best); calc_centroid (simplex, worst, centroid); /* reflect the worst point through the centroid */ calc_reflection (simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_error (test1); /* test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection */ if (resp1 < response[best]) { /* try expanding */ calc_reflection (simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_error (test2); if (resp2 <= resp1) /* keep expansion */ replace (simplex, response, worst, test2, resp2); else /* keep reflection */ replace (simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /* new response is between the best and next worst so keep reflection */ replace (simplex, response, worst, test1, resp1); } else { /* try contraction */ if (resp1 >= response[worst]) calc_reflection (simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_error (test2); /* test the contracted response against the worst response */ if (resp2 > response[worst]) { /* new contracted response is worse, so decrease step size and restart */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } else /* keep contraction */ replace (simplex, response, worst, test2, resp2); } /* test to determine when to stop. first, check the number of iterations */ num_iter += 1; /* increment iteration counter */ if (num_iter >= MAX_ITERATIONS) { /* restart with smaller steps */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } /* limit the number of restarts */ if (num_restarts == MAX_RESTARTS) done = 1; /* compare relative standard deviation of vertex responses against a defined tolerance limit */ fit = calc_good_fit (response); if (fit <= TOLERANCE) done = 1; /* if done, copy the best solution to the output array */ if (done) { eval_vertices (response, &worst, &next, &best); for (i = 0; i < DIMENSION; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /* while (!done) */ number_restarts = num_restarts; deallocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); }
void simplex_optimization ( vfp nmodel, /* pointer to noise model */ vfp smodel, /* pointer to signal model */ int r, /* number of parameters in the noise model */ int p, /* number of parameters in the signal model */ float * min_nconstr, /* minimum parameter constraints for noise model */ float * max_nconstr, /* maximum parameter constraints for noise model */ float * min_sconstr, /* minimum parameter constraints for signal model */ float * max_sconstr, /* maximum parameter constraints for signal model */ int nabs, /* use absolute constraints for noise parameters */ int ts_length, /* length of time series array */ float ** x_array, /* independent variable matrix */ float * ts_array, /* observed time series */ float * par_rdcd, /* estimated parameters for the reduced model */ float * parameters, /* estimated parameters */ float * sse /* error sum of squares */ ) { const int MAX_ITERATIONS = 50; /* maximum number of iterations */ const int MAX_RESTARTS = 5; /* maximum number of restarts */ const float EXPANSION_COEF = 2.0; /* expansion coefficient */ const float REFLECTION_COEF = 1.0; /* reflection coefficient */ const float CONTRACTION_COEF = 0.5; /* contraction coefficient */ const float TOLERANCE = 1.0e-4; /* solution convergence tolerance */ float ** simplex = NULL; /* the simplex itself */ float * centroid = NULL; /* center of mass of the simplex */ float * response = NULL; /* error sum of squares at each vertex */ float * step_size = NULL; /* controls random placement of new vertex */ float * test1 = NULL; /* test vertex */ float * test2 = NULL; /* test vertex */ float resp1, resp2; /* error sum of squares for test vertex */ int i; /* vertex index */ int worst; /* index of worst vertex in simplex */ int best; /* index of best vertex in simplex */ int next; /* index of next-to-worst vertex in simplex */ int num_iter; /* number of simplex algorithm iterations */ int num_restarts; /* number of restarts of simplex algorithm */ int done; /* boolean for search finished */ float fit; /* array of fitted time series values */ int dimension; /* dimension of parameter space */ /*----- dimension of parameter space -----*/ dimension = r + p; /*----- allocate memory -----*/ allocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); /*----- initialization for simplex algorithm -----*/ initialize_simplex (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, parameters, simplex, response, step_size, ts_length, x_array, ts_array); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /*----- find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex -----*/ eval_vertices (dimension, response, &worst, &next, &best); calc_centroid (dimension, simplex, worst, centroid); /*----- reflect the worst point through the centroid -----*/ calc_reflection (dimension, simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test1, ts_length, x_array, ts_array); /*----- test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection -----*/ if (resp1 < response[best]) { /*----- try expanding -----*/ calc_reflection (dimension, simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); if (resp2 <= resp1) /* keep expansion */ replace (dimension, simplex, response, worst, test2, resp2); else /* keep reflection */ replace (dimension, simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /*----- new response is between the best and next worst so keep reflection -----*/ replace (dimension, simplex, response, worst, test1, resp1); } else { /*----- try contraction -----*/ if (resp1 >= response[worst]) calc_reflection (dimension, simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (dimension, simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); /*---- test the contracted response against the worst response ----*/ if (resp2 > response[worst]) { /*----- new contracted response is worse, so decrease step size and restart -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } else /*----- keep contraction -----*/ replace (dimension, simplex, response, worst, test2, resp2); } /*----- test to determine when to stop. first, check the number of iterations -----*/ num_iter += 1; /*----- increment iteration counter -----*/ if (num_iter >= MAX_ITERATIONS) { /*----- restart with smaller steps -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } /*----- limit the number of restarts -----*/ if (num_restarts == MAX_RESTARTS) done = 1; /*----- compare relative standard deviation of vertex responses against a defined tolerance limit -----*/ fit = calc_good_fit (dimension, response); if (fit <= TOLERANCE) done = 1; /*----- if done, copy the best solution to the output array -----*/ if (done) { eval_vertices (dimension, response, &worst, &next, &best); for (i = 0; i < dimension; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /*----- while (!done) -----*/ deallocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); }