home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: cml2.v256.c
- * By: Dave Hiebeler
- * hiebeler@turing.cs.rpi.edu
- * Feb. 1990
- *
- * Coupled map lattice rule (coupled logistics eqn) using single-precision
- * floating-point. At least, that's what it was supposed to be; I think
- * I still have a bug in it somewhere, I'm not convinced that it behaves
- * the way it should. In any event, it's still a valid example of a
- * floating-point rule being run under Cellsim.
- *
- * The logistics eqn: x(t+1) = K x(t) (1 - x(t))
- * is run, except instead of just plugging in the local value for x(t),
- * we use a weighted average.
- *
- * Parm1 is the parameter K (usually called lambda with the logistics eqn);
- * it's been scaled here, so that parm1=100 corresponds to K=4, and parm1=0
- * corresponds to K=0. (So basically, parm1 = K*25).
- *
- * Parm2 is the coupling strength: parm2=0 means no coupling (only the
- * current value of the center cell will be used), parm2=100 means that
- * all the cells in the neighborhood will be averaged as the value for x(t).
- *
- * Parm1 and parm2 both range between 0 and 100
- */
-
-
- #include "CMnborhood.h"
-
- byte cml_rule(), cml_exit();
- static CM_field_id_t x_val, avg_x, x_tmp, scell;
-
-
- void
- init_function()
- {
- update_function = cml_rule;
- exit_function = cml_exit;
- parm1 = 90;
- parm2 = 20;
- x_val = CM_allocate_heap_field(32); /* x_val holds the current floating
- * value of the cell */
- avg_x = CM_allocate_heap_field(32); /* used to find weighted average */
- x_tmp = CM_allocate_heap_field(32); /* scratch space */
- scell = CM_allocate_heap_field(9); /* used in the process of converting
- * our floating-point value back into
- * an 8-bit unsigned value to display */
-
- /* Now, we convert the "cell" field into a floating-point value, and
- * rescale it to be between 0 and 1 rather than 0 and 255.
- */
- CM_f_u_float_2_2L(x_val, cell, 8, 23, 8);
- CM_f_divide_constant_2_1L(x_val, (double)256.0, 23, 8);
- }
-
-
- byte
- cml_rule()
- {
- double fparm1, fparm2; /* hold floating-point copy of parm1&2 */
-
- /* get new values of parm1 & parm2, since user might have changed
- * them since we were last called
- */
- fparm1 = ((double) parm1) / (double)100.0;
- fparm2 = ((double) parm2) / (double)100.0;
-
-
- CM_f_move_zero_always_1L(avg_x, 23, 8);
-
- /* get neighbors' floating-point values, and add into avg_x */
- CM_get_from_news_1L(x_tmp, x_val, North, 32);
- CM_f_add_always_2_1L(avg_x, x_tmp, 23, 8);
-
- CM_get_from_news_1L(x_tmp, x_val, South, 32);
- CM_f_add_always_2_1L(avg_x, x_tmp, 23, 8);
-
- CM_get_from_news_1L(x_tmp, x_val, East, 32);
- CM_f_add_always_2_1L(avg_x, x_tmp, 23, 8);
-
- CM_get_from_news_1L(x_tmp, x_val, West, 32);
- CM_f_add_always_2_1L(avg_x, x_tmp, 23, 8);
-
- CM_f_move_always_1L(x_tmp, x_val, 23, 8);
-
- /* Now, do weighted average of neighbors and center, and store in avg_x */
- CM_f_multiply_const_always_2_1L(x_tmp, fparm2,23,8);
- CM_f_multiply_const_always_2_1L(avg_x, (((double)1.0)-fparm2)/(double)4.0,
- 23, 8);
- CM_f_add_always_2_1L(avg_x, x_tmp, 23, 8);
-
-
- /* Do x <- K x(1-x) */
- CM_f_negate_2_1L(x_val, avg_x, 23, 8);
- CM_f_add_const_always_2_1L(x_val, (double)1.0, 23, 8);
- CM_f_multiply_2_1L(x_val, avg_x, 23, 8);
- CM_f_multiply_const_always_2_1L(x_val, (double)4.0*fparm1, 23, 8);
-
- /* Now scale up to the 0..255 range and copy into cell for display */
- CM_f_multiply_const_always_3_1L(x_tmp, x_val, (double)255.0,23,8);
- CM_s_f_floor_2_2L(scell, x_tmp, 9, 23,8);
- CM_u_move_1L(cell, scell, 8);
- }
-
-
- byte
- cml_exit()
- {
- /* deallocate local fields */
- CM_deallocate_heap_field(x_val);
- CM_deallocate_heap_field(avg_x);
- CM_deallocate_heap_field(x_tmp);
- CM_deallocate_heap_field(scell);
- }
-
-