home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: bz.m256.c
- * By: Dave Hiebeler
- * hiebeler@turing.cs.rpi.edu
- * February 1990
- *
- * The version of the Belousov-Zhabotinski ("BZ") reaction described in
- * the CAM book by Toffoli and Margolus (also discussed as the "hodgepodge"
- * model in A.K. Dewdney's "Computer Recreations" colum in Scientific
- * American, sometime in 1989). This rule is basically a model of phase
- * waves in excitable media with latency.
- *
- * The two parameters are used as a threshold and annealing factor.
- * Basically, each cell counts the number of "active" neighbors, call
- * that N. Then, if N >= parm1 *or* N == parm2, the current cell will
- * become inactive for a few time-steps.
- *
- * So with parm1=3 and parm2=3, you get a fairly simple system of propagating
- * phase waves. With parm1=4 and parm2=2, you get a kind of "annealing"
- * version of the system. See the CAM book, section 9.3, for more details.
- *
- * The rule actually only uses values between 0 and 15 (the lower 4 bitplanes).
- * It is a computed-function rule because a 16-state moore lookup table
- * would be huge (2^36 entries!). But you can start with a "quick random"
- * image, as the rule will ignore the high bitplanes, and clear them out
- * after the first time-step.
- *
- */
-
-
- #include "CMnborhood.h"
-
-
-
- byte bz(), bz_exit();
-
- static CM_field_id_t nbor_sum, bool1;
-
- void
- init_function()
- {
- update_function = bz;
- exit_function = bz_exit;
- parm1 = 4;
- parm2 = 2;
- nbor_sum = CM_allocate_heap_field(4);
- bool1 = CM_allocate_heap_field(1); /* used to store intermediate results
- * for boolean logic */
- }
-
-
- byte
- bz()
- {
- CM_set_context();
-
- /* add up neighbors */
- /* the "active" flag is kept up in the third bit-plane, or 2 bits above
- * the start of the field, which is why there's a "+2" on all the
- * neighbors used
- */
- CM_u_move_2L(nbor_sum, MNW+2, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MWest+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MSW+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MNorth+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MSouth+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MNE+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MEast+2, 4, 4, 1);
- CM_u_add_3_3L(nbor_sum, nbor_sum, MSE+2, 4, 4, 1);
-
- /* zero out cell */
- CM_u_move_zero_1L(cell, 8);
-
- /* if clock == 0, set active flag */
- CM_set_context();
- CM_u_eq_zero_1L(MCenter,2);
- CM_logand_context_with_test();
- CM_u_move_constant_1L(cell, 4, 8);
-
- /* if nborsum >= parm1 or nborsum == parm2, set alarm meaning we're
- * about to become inactive */
- CM_set_context();
- CM_u_ge_constant_1L(nbor_sum, parm1%256, 4);
- CM_store_test(bool1);
- CM_u_eq_constant_1L(nbor_sum, parm2%256, 4);
- CM_logand_context_with_test();
- CM_logior_context(bool1);
- CM_u_move_constant_1L(cell+3, 1, 1);
-
- /* if active and alarm, set clock to 3 */
- CM_set_context();
- CM_u_eq_constant_1L(MCenter+2, 3, 2);
- CM_logand_context_with_test();
- CM_u_move_constant_1L(cell, 3, 2);
-
- /* else if clock is non-zero, decrement it */
- CM_invert_context();
- CM_u_ne_zero_1L(MCenter, 2);
- CM_logand_context_with_test();
- CM_u_subtract_constant_2_1L(MCenter, 1, 2);
- CM_u_move_1L(cell, MCenter, 2);
- CM_set_context();
- }
-
-
- byte
- bz_exit()
- {
- CM_deallocate_heap_field(nbor_sum);
- CM_deallocate_heap_field(bool1);
- }
-