chaos-0.2/0000755000076500007650000000000012076110675011133 5ustar hanshanschaos-0.2/latoocarfian-help.pd0000644000076500007650000000214412076105251015043 0ustar hanshans#N canvas 527 258 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X msg 111 243 param -0.966918 2.87988 0.756145 0.744728; #X msg 111 264 param -2.90515 -2.03043 1.44055 0.70307; #X floatatom 136 407 10 0 0 0 Y - -; #X floatatom 43 367 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 43 347 latoocarfian 0.1 0.1 -2.90515 -2.03043 1.44055 0.70307 ; #X obj 283 376 search-tools; #X connect 0 0 12 0; #X connect 1 0 12 1; #X connect 4 0 15 0; #X connect 5 0 15 0; #X connect 6 0 15 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 15 0 8 0; #X connect 15 1 7 0; #X connect 15 2 16 0; #X connect 15 3 16 1; #X connect 15 4 16 2; #X connect 16 0 15 0; chaos-0.2/unity-help.pd0000644000076500007650000000203212076105251013545 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 unity 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Unity Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0; chaos-0.2/latoomutgamma-help.pd0000644000076500007650000000214512076105251015251 0ustar hanshans#N canvas 527 258 581 484 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X msg 111 243 param -0.966918 2.87988 0.756145 0.744728; #X msg 111 264 param -2.90515 -2.03043 1.44055 0.70307; #X floatatom 138 406 10 0 0 0 Y - -; #X floatatom 43 367 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 43 347 latoomutgamma 0.1 0.1 -2.90515 -2.03043 1.44055 0.70307 ; #X obj 289 374 search-tools; #X connect 0 0 12 0; #X connect 1 0 12 1; #X connect 4 0 15 0; #X connect 5 0 15 0; #X connect 6 0 15 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 15 0 8 0; #X connect 15 1 7 0; #X connect 15 2 16 0; #X connect 15 3 16 1; #X connect 15 4 16 2; #X connect 16 0 15 0; chaos-0.2/dejong-help.pd0000644000076500007650000000203412076105251013645 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 dejong 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Dejong Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0; chaos-0.2/threeply.c0000644000076500007650000002770712076105251013142 0ustar hanshans/* threeply Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_x 0 #define M_y 1 #define M_param_count 3 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "threeply v0.0, by Michael McGonagle, from ??????, 2003"; t_class *threeply_class; typedef struct threeply_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } threeply_struct; static void calc(threeply_struct *threeply, double *vars) { double x_0, y_0; x_0 =vars[M_y]-((vars[M_x]<0)?-1:1)*abs(sin(vars[M_x])*cos(threeply -> b)+threeply -> c-vars[M_x]*sin(threeply -> a+threeply -> b+threeply -> c)); y_0 =threeply -> a-vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(threeply_struct *threeply) { calc(threeply, threeply -> vars); outlet_float(threeply -> outlets[M_y - 1], threeply -> vars[M_y]); outlet_float(threeply -> x_obj.ob_outlet, threeply -> vars[M_x]); } // end calculate static void reset(threeply_struct *threeply, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { threeply -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); threeply -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { threeply -> vars[M_x] = threeply -> vars_init[M_x]; threeply -> vars[M_y] = threeply -> vars_init[M_y]; } // end if } // end reset static char *classify(threeply_struct *threeply) { static char buff[4]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((threeply -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((threeply -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((threeply -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = '\0'; return buff; } static void make_results(threeply_struct *threeply) { SETFLOAT(&threeply -> search_out[0], threeply -> lyap_exp); SETSYMBOL(&threeply -> search_out[1], gensym(classify(threeply))); SETFLOAT(&threeply -> search_out[2], threeply -> failure_ratio); SETFLOAT(&threeply -> vars_out[M_x], threeply -> vars[M_x]); SETFLOAT(&threeply -> vars_out[M_y], threeply -> vars[M_y]); SETFLOAT(&threeply -> params_out[M_a], threeply -> a); SETFLOAT(&threeply -> params_out[M_b], threeply -> b); SETFLOAT(&threeply -> params_out[M_c], threeply -> c); outlet_list(threeply -> params_outlet, gensym("list"), M_param_count, threeply -> params_out); outlet_list(threeply -> vars_outlet, gensym("list"), M_var_count, threeply -> vars_out); } static void show(threeply_struct *threeply) { make_results(threeply); outlet_anything(threeply -> search_outlet, gensym("show"), M_search_count, threeply -> search_out); } static void param(threeply_struct *threeply, t_symbol *s, int argc, t_atom *argv) { if (argc != 3) { post("Incorrect number of arguments for threeply fractal. Expecting 3 arguments."); return; } threeply -> a = (double) atom_getfloatarg(0, argc, argv); threeply -> b = (double) atom_getfloatarg(1, argc, argv); threeply -> c = (double) atom_getfloatarg(2, argc, argv); } static void seed(threeply_struct *threeply, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(threeply_struct *threeply, t_floatarg l, t_floatarg h, t_floatarg lim) { threeply -> lyap_lo = l; threeply -> lyap_hi = h; threeply -> lyap_limit = (double) ((int) lim); } static void elyap(threeply_struct *threeply) { double results[M_var_count]; int i; if (lyapunov_full((void *) threeply, (t_gotfn) calc, M_var_count, threeply -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(threeply_struct *threeply) { if (threeply -> a_lo < M_a_lo) { threeply -> a_lo = M_a_lo; } if (threeply -> a_lo > M_a_hi) { threeply -> a_lo = M_a_hi; } if (threeply -> a_hi < M_a_lo) { threeply -> a_hi = M_a_lo; } if (threeply -> a_hi > M_a_hi) { threeply -> a_hi = M_a_hi; } if (threeply -> b_lo < M_b_lo) { threeply -> b_lo = M_b_lo; } if (threeply -> b_lo > M_b_hi) { threeply -> b_lo = M_b_hi; } if (threeply -> b_hi < M_b_lo) { threeply -> b_hi = M_b_lo; } if (threeply -> b_hi > M_b_hi) { threeply -> b_hi = M_b_hi; } if (threeply -> c_lo < M_c_lo) { threeply -> c_lo = M_c_lo; } if (threeply -> c_lo > M_c_hi) { threeply -> c_lo = M_c_hi; } if (threeply -> c_hi < M_c_lo) { threeply -> c_hi = M_c_lo; } if (threeply -> c_hi > M_c_hi) { threeply -> c_hi = M_c_hi; } } static void constrain(threeply_struct *threeply, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges threeply -> a_lo = M_a_lo; threeply -> a_hi = M_a_hi; threeply -> b_lo = M_b_lo; threeply -> b_hi = M_b_hi; threeply -> c_lo = M_c_lo; threeply -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; threeply -> a_lo = threeply -> a - a_spread; threeply -> a_hi = threeply -> a + a_spread; threeply -> b_lo = threeply -> b - b_spread; threeply -> b_hi = threeply -> b + b_spread; threeply -> c_lo = threeply -> c - c_spread; threeply -> c_hi = threeply -> c + c_spread; limiter(threeply); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for threeply constraints, requires 6 values, got %d", argc); return; } threeply -> a_lo = atom_getfloat(arg++); threeply -> a_hi = atom_getfloat(arg++); threeply -> b_lo = atom_getfloat(arg++); threeply -> b_hi = atom_getfloat(arg++); threeply -> c_lo = atom_getfloat(arg++); threeply -> c_hi = atom_getfloat(arg++); limiter(threeply); } static void search(threeply_struct *threeply, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = threeply -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = threeply -> a; double temp_b = threeply -> b; double temp_c = threeply -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], threeply -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: threeply -> a = (drand48() * (threeply -> a_hi - threeply -> a_lo)) + threeply -> a_lo; threeply -> b = (drand48() * (threeply -> b_hi - threeply -> b_lo)) + threeply -> b_lo; threeply -> c = (drand48() * (threeply -> c_hi - threeply -> c_lo)) + threeply -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(threeply, NULL, argc, vars); do { calc(threeply, threeply -> vars); } while(jump--); threeply -> lyap_exp = lyapunov((void *) threeply, (t_gotfn) calc, M_var_count, (double *) threeply -> vars); if (isnan(threeply -> lyap_exp)) { not_found = 1; } if (threeply -> lyap_exp < threeply -> lyap_lo || threeply -> lyap_exp > threeply -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(threeply, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) threeply -> lyap_limit); post("Try using wider constraints."); threeply -> a = temp_a; threeply -> b = temp_b; threeply -> c = temp_c; outlet_anything(threeply -> search_outlet, gensym("invalid"), 0, NULL); } else { threeply -> failure_ratio = (threeply -> lyap_limit - not_expired) / threeply -> lyap_limit; make_results(threeply); outlet_anything(threeply -> search_outlet, gensym("search"), M_search_count, threeply -> search_out); } } void *threeply_new(t_symbol *s, int argc, t_atom *argv) { threeply_struct *threeply = (threeply_struct *) pd_new(threeply_class); if (threeply != NULL) { outlet_new(&threeply -> x_obj, &s_float); threeply -> outlets[0] = outlet_new(&threeply -> x_obj, &s_float); threeply -> search_outlet = outlet_new(&threeply -> x_obj, &s_list); threeply -> vars_outlet = outlet_new(&threeply -> x_obj, &s_list); threeply -> params_outlet = outlet_new(&threeply -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { threeply -> vars_init[M_x] = threeply -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); threeply -> vars_init[M_y] = threeply -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); threeply -> a = (double) atom_getfloatarg(2, argc, argv); threeply -> b = (double) atom_getfloatarg(3, argc, argv); threeply -> c = (double) atom_getfloatarg(4, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for threeply fractal. Expecting 5 arguments."); } threeply -> vars_init[M_x] = 0; threeply -> vars_init[M_y] = 0; threeply -> a = -55; threeply -> b = -1; threeply -> c = -42; } constrain(threeply, NULL, 0, NULL); lyap(threeply, -1000000.0, 1000000.0, M_failure_limit); } return (void *)threeply; } void threeply_setup(void) { threeply_class = class_new(gensym("threeply"), (t_newmethod) threeply_new, 0, sizeof(threeply_struct), 0, A_GIMME, 0); class_addbang(threeply_class, (t_method) calculate); class_addmethod(threeply_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(threeply_class, (t_method) show, gensym("show"), 0); class_addmethod(threeply_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(threeply_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(threeply_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(threeply_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(threeply_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(threeply_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/ikeda-help.pd0000644000076500007650000000312612076105251013457 0ustar hanshans#N canvas 395 111 669 437 10; #X obj 260 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 311 116 5 0 0 0 - - -; #X floatatom 302 379 10 0 0 0 Y - -; #X floatatom 260 352 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 260 132 metro 50; #X obj 235 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 308 215 param 0.4 0.9 6 1; #X msg 308 193 param 0.4 0.8 20 1; #X text 20 18 Ikeda Attractor; #X text 19 33 Chaos PD Externals - Copyright Ben Bogart 2002; #X obj 458 104 examples/readme-fractals; #X obj 260 316 ikeda 0.1 0.1 0.4 0.9 6 1; #X msg 292 156 reset; #X text 336 156 Reset to initial state from creation arguments; #X text 442 193 Modify parameters; #X obj 372 349 search-tools; #X obj 20 181 metro 50; #X obj 20 157 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 71 156 5 0 0 0 - - -; #X floatatom 65 372 5 0 0 0 - - -; #X text 52 221 Reset To Initial Conditions; #X text 53 294 Modify Parameters; #X floatatom 20 372 5 0 0 0 - - -; #X text 14 351 Output; #X obj 20 315 ikeda; #X msg 55 275 param 0.4 0.9 6 1; #X msg 55 253 param 0.4 0.8 20 1; #X msg 53 203 reset 0.1 0.1; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 12 0; #X connect 6 0 12 0; #X connect 7 0 12 0; #X connect 8 0 12 0; #X connect 12 0 3 0; #X connect 12 1 2 0; #X connect 12 2 16 0; #X connect 12 3 16 1; #X connect 12 4 16 2; #X connect 13 0 12 0; #X connect 16 0 12 0; #X connect 17 0 25 0; #X connect 18 0 17 0; #X connect 19 0 17 1; #X connect 25 0 23 0; #X connect 25 1 20 0; #X connect 26 0 25 0; #X connect 27 0 25 0; #X connect 28 0 25 0; chaos-0.2/standardmap-help.pd0000644000076500007650000000165012076105251014700 0ustar hanshans#N canvas 527 258 585 488 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 112 265 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X floatatom 61 452 10 0 0 0 Y - -; #X floatatom 43 427 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X text 21 19 Standard Map; #X obj 43 369 standardmap; #X msg 110 242 param 0.89; #X obj 70 398 search-tools; #X connect 0 0 9 0; #X connect 1 0 9 1; #X connect 4 0 13 0; #X connect 9 0 13 0; #X connect 10 0 13 0; #X connect 13 0 6 0; #X connect 13 1 5 0; #X connect 13 2 15 0; #X connect 13 3 15 1; #X connect 13 4 15 2; #X connect 14 0 13 0; #X connect 15 0 13 0; chaos-0.2/base-help.pd0000644000076500007650000000147012076105251013314 0ustar hanshans#N canvas 680 295 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X floatatom 43 332 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 20 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 436 18 examples/readme-fractals; #X text 21 19 Base Attractor; #X obj 53 262 fractal-tools; #X obj 43 285 base3 0.1 1.18939 2.24148; #X msg 61 240 lyapunov 0 100 1000; #X obj 126 320 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 9 0 10 0; #X connect 10 0 2 0; #X connect 10 1 12 0; #X connect 10 2 12 1; #X connect 10 3 12 2; #X connect 11 0 9 0; #X connect 12 0 10 0; chaos-0.2/unity.c0000644000076500007650000000746612076105251012456 0ustar hanshans/* unity Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "m_pd.h" #define M_x 0 #define M_y 1 #define M_param_count 0 #define M_var_count 2 #define M_search_count 0 #define M_failure_limit 1000 static char *version = "unity v0.0, by Michael McGonagle, from ??????, 2003"; t_class *unity_class; typedef struct unity_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_outlet *outlets[M_var_count - 1]; } unity_struct; static void calc(unity_struct *unity, double *vars) { double k, x_0, y_0; k=(vars[M_x]*vars[M_x])+(vars[M_y]*vars[M_y]); x_0 =(2-k)*vars[M_y]; y_0 =(2-k)*vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(unity_struct *unity) { calc(unity, unity -> vars); outlet_float(unity -> outlets[M_y - 1], unity -> vars[M_y]); outlet_float(unity -> x_obj.ob_outlet, unity -> vars[M_x]); } // end calculate static void reset(unity_struct *unity, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { unity -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); unity -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { unity -> vars[M_x] = unity -> vars_init[M_x]; unity -> vars[M_y] = unity -> vars_init[M_y]; } // end if } // end reset void *unity_new(t_symbol *s, int argc, t_atom *argv) { unity_struct *unity = (unity_struct *) pd_new(unity_class); if (unity != NULL) { outlet_new(&unity -> x_obj, &s_float); unity -> outlets[0] = outlet_new(&unity -> x_obj, &s_float); if (argc == M_param_count + M_var_count) { unity -> vars_init[M_x] = unity -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); unity -> vars_init[M_y] = unity -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for unity fractal. Expecting 2 arguments."); } unity -> vars_init[M_x] = 0; unity -> vars_init[M_y] = 0; } } return (void *)unity; } void unity_setup(void) { unity_class = class_new(gensym("unity"), (t_newmethod) unity_new, 0, sizeof(unity_struct), 0, A_GIMME, 0); class_addbang(unity_class, (t_method) calculate); class_addmethod(unity_class, (t_method) reset, gensym("reset"), A_GIMME, 0); } chaos-0.2/tinkerbell-help.pd0000644000076500007650000000204412076105251014533 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 tinkerbell 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Tinkerbell Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0; chaos-0.2/latoomutbeta.c0000644000076500007650000003361312076105251013777 0ustar hanshans/* latoomutbeta Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -3 #define M_a_hi 3 #define M_b_lo -3 #define M_b_hi 3 #define M_c_lo 0.5 #define M_c_hi 1.5 #define M_d_lo 0.5 #define M_d_hi 1.5 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "latoomutbeta v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *latoomutbeta_class; typedef struct latoomutbeta_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } latoomutbeta_struct; static void calc(latoomutbeta_struct *latoomutbeta, double *vars) { double x_0, y_0; x_0 =sin(vars[M_y]*latoomutbeta -> b)+pow(sin(vars[M_x]*latoomutbeta -> b),2); y_0 =sin(vars[M_x]*latoomutbeta -> a)+pow(sin(vars[M_y]*latoomutbeta -> a),2); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(latoomutbeta_struct *latoomutbeta) { calc(latoomutbeta, latoomutbeta -> vars); outlet_float(latoomutbeta -> outlets[M_y - 1], latoomutbeta -> vars[M_y]); outlet_float(latoomutbeta -> x_obj.ob_outlet, latoomutbeta -> vars[M_x]); } // end calculate static void reset(latoomutbeta_struct *latoomutbeta, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { latoomutbeta -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); latoomutbeta -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { latoomutbeta -> vars[M_x] = latoomutbeta -> vars_init[M_x]; latoomutbeta -> vars[M_y] = latoomutbeta -> vars_init[M_y]; } // end if } // end reset static char *classify(latoomutbeta_struct *latoomutbeta) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((latoomutbeta -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((latoomutbeta -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((latoomutbeta -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((latoomutbeta -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(latoomutbeta_struct *latoomutbeta) { SETFLOAT(&latoomutbeta -> search_out[0], latoomutbeta -> lyap_exp); SETSYMBOL(&latoomutbeta -> search_out[1], gensym(classify(latoomutbeta))); SETFLOAT(&latoomutbeta -> search_out[2], latoomutbeta -> failure_ratio); SETFLOAT(&latoomutbeta -> vars_out[M_x], latoomutbeta -> vars[M_x]); SETFLOAT(&latoomutbeta -> vars_out[M_y], latoomutbeta -> vars[M_y]); SETFLOAT(&latoomutbeta -> params_out[M_a], latoomutbeta -> a); SETFLOAT(&latoomutbeta -> params_out[M_b], latoomutbeta -> b); SETFLOAT(&latoomutbeta -> params_out[M_c], latoomutbeta -> c); SETFLOAT(&latoomutbeta -> params_out[M_d], latoomutbeta -> d); outlet_list(latoomutbeta -> params_outlet, gensym("list"), M_param_count, latoomutbeta -> params_out); outlet_list(latoomutbeta -> vars_outlet, gensym("list"), M_var_count, latoomutbeta -> vars_out); } static void show(latoomutbeta_struct *latoomutbeta) { make_results(latoomutbeta); outlet_anything(latoomutbeta -> search_outlet, gensym("show"), M_search_count, latoomutbeta -> search_out); } static void param(latoomutbeta_struct *latoomutbeta, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for latoomutbeta fractal. Expecting 4 arguments."); return; } latoomutbeta -> a = (double) atom_getfloatarg(0, argc, argv); latoomutbeta -> b = (double) atom_getfloatarg(1, argc, argv); latoomutbeta -> c = (double) atom_getfloatarg(2, argc, argv); latoomutbeta -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(latoomutbeta_struct *latoomutbeta, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(latoomutbeta_struct *latoomutbeta, t_floatarg l, t_floatarg h, t_floatarg lim) { latoomutbeta -> lyap_lo = l; latoomutbeta -> lyap_hi = h; latoomutbeta -> lyap_limit = (double) ((int) lim); } static void elyap(latoomutbeta_struct *latoomutbeta) { double results[M_var_count]; int i; if (lyapunov_full((void *) latoomutbeta, (t_gotfn) calc, M_var_count, latoomutbeta -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(latoomutbeta_struct *latoomutbeta) { if (latoomutbeta -> a_lo < M_a_lo) { latoomutbeta -> a_lo = M_a_lo; } if (latoomutbeta -> a_lo > M_a_hi) { latoomutbeta -> a_lo = M_a_hi; } if (latoomutbeta -> a_hi < M_a_lo) { latoomutbeta -> a_hi = M_a_lo; } if (latoomutbeta -> a_hi > M_a_hi) { latoomutbeta -> a_hi = M_a_hi; } if (latoomutbeta -> b_lo < M_b_lo) { latoomutbeta -> b_lo = M_b_lo; } if (latoomutbeta -> b_lo > M_b_hi) { latoomutbeta -> b_lo = M_b_hi; } if (latoomutbeta -> b_hi < M_b_lo) { latoomutbeta -> b_hi = M_b_lo; } if (latoomutbeta -> b_hi > M_b_hi) { latoomutbeta -> b_hi = M_b_hi; } if (latoomutbeta -> c_lo < M_c_lo) { latoomutbeta -> c_lo = M_c_lo; } if (latoomutbeta -> c_lo > M_c_hi) { latoomutbeta -> c_lo = M_c_hi; } if (latoomutbeta -> c_hi < M_c_lo) { latoomutbeta -> c_hi = M_c_lo; } if (latoomutbeta -> c_hi > M_c_hi) { latoomutbeta -> c_hi = M_c_hi; } if (latoomutbeta -> d_lo < M_d_lo) { latoomutbeta -> d_lo = M_d_lo; } if (latoomutbeta -> d_lo > M_d_hi) { latoomutbeta -> d_lo = M_d_hi; } if (latoomutbeta -> d_hi < M_d_lo) { latoomutbeta -> d_hi = M_d_lo; } if (latoomutbeta -> d_hi > M_d_hi) { latoomutbeta -> d_hi = M_d_hi; } } static void constrain(latoomutbeta_struct *latoomutbeta, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges latoomutbeta -> a_lo = M_a_lo; latoomutbeta -> a_hi = M_a_hi; latoomutbeta -> b_lo = M_b_lo; latoomutbeta -> b_hi = M_b_hi; latoomutbeta -> c_lo = M_c_lo; latoomutbeta -> c_hi = M_c_hi; latoomutbeta -> d_lo = M_d_lo; latoomutbeta -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; latoomutbeta -> a_lo = latoomutbeta -> a - a_spread; latoomutbeta -> a_hi = latoomutbeta -> a + a_spread; latoomutbeta -> b_lo = latoomutbeta -> b - b_spread; latoomutbeta -> b_hi = latoomutbeta -> b + b_spread; latoomutbeta -> c_lo = latoomutbeta -> c - c_spread; latoomutbeta -> c_hi = latoomutbeta -> c + c_spread; latoomutbeta -> d_lo = latoomutbeta -> d - d_spread; latoomutbeta -> d_hi = latoomutbeta -> d + d_spread; limiter(latoomutbeta); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for latoomutbeta constraints, requires 8 values, got %d", argc); return; } latoomutbeta -> a_lo = atom_getfloat(arg++); latoomutbeta -> a_hi = atom_getfloat(arg++); latoomutbeta -> b_lo = atom_getfloat(arg++); latoomutbeta -> b_hi = atom_getfloat(arg++); latoomutbeta -> c_lo = atom_getfloat(arg++); latoomutbeta -> c_hi = atom_getfloat(arg++); latoomutbeta -> d_lo = atom_getfloat(arg++); latoomutbeta -> d_hi = atom_getfloat(arg++); limiter(latoomutbeta); } static void search(latoomutbeta_struct *latoomutbeta, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = latoomutbeta -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = latoomutbeta -> a; double temp_b = latoomutbeta -> b; double temp_c = latoomutbeta -> c; double temp_d = latoomutbeta -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], latoomutbeta -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: latoomutbeta -> a = (drand48() * (latoomutbeta -> a_hi - latoomutbeta -> a_lo)) + latoomutbeta -> a_lo; latoomutbeta -> b = (drand48() * (latoomutbeta -> b_hi - latoomutbeta -> b_lo)) + latoomutbeta -> b_lo; latoomutbeta -> c = (drand48() * (latoomutbeta -> c_hi - latoomutbeta -> c_lo)) + latoomutbeta -> c_lo; latoomutbeta -> d = (drand48() * (latoomutbeta -> d_hi - latoomutbeta -> d_lo)) + latoomutbeta -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(latoomutbeta, NULL, argc, vars); do { calc(latoomutbeta, latoomutbeta -> vars); } while(jump--); latoomutbeta -> lyap_exp = lyapunov((void *) latoomutbeta, (t_gotfn) calc, M_var_count, (double *) latoomutbeta -> vars); if (isnan(latoomutbeta -> lyap_exp)) { not_found = 1; } if (latoomutbeta -> lyap_exp < latoomutbeta -> lyap_lo || latoomutbeta -> lyap_exp > latoomutbeta -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(latoomutbeta, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) latoomutbeta -> lyap_limit); post("Try using wider constraints."); latoomutbeta -> a = temp_a; latoomutbeta -> b = temp_b; latoomutbeta -> c = temp_c; latoomutbeta -> d = temp_d; outlet_anything(latoomutbeta -> search_outlet, gensym("invalid"), 0, NULL); } else { latoomutbeta -> failure_ratio = (latoomutbeta -> lyap_limit - not_expired) / latoomutbeta -> lyap_limit; make_results(latoomutbeta); outlet_anything(latoomutbeta -> search_outlet, gensym("search"), M_search_count, latoomutbeta -> search_out); } } void *latoomutbeta_new(t_symbol *s, int argc, t_atom *argv) { latoomutbeta_struct *latoomutbeta = (latoomutbeta_struct *) pd_new(latoomutbeta_class); if (latoomutbeta != NULL) { outlet_new(&latoomutbeta -> x_obj, &s_float); latoomutbeta -> outlets[0] = outlet_new(&latoomutbeta -> x_obj, &s_float); latoomutbeta -> search_outlet = outlet_new(&latoomutbeta -> x_obj, &s_list); latoomutbeta -> vars_outlet = outlet_new(&latoomutbeta -> x_obj, &s_list); latoomutbeta -> params_outlet = outlet_new(&latoomutbeta -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { latoomutbeta -> vars_init[M_x] = latoomutbeta -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); latoomutbeta -> vars_init[M_y] = latoomutbeta -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); latoomutbeta -> a = (double) atom_getfloatarg(2, argc, argv); latoomutbeta -> b = (double) atom_getfloatarg(3, argc, argv); latoomutbeta -> c = (double) atom_getfloatarg(4, argc, argv); latoomutbeta -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for latoomutbeta fractal. Expecting 6 arguments."); } latoomutbeta -> vars_init[M_x] = 0.1; latoomutbeta -> vars_init[M_y] = 0.1; latoomutbeta -> a = 1; latoomutbeta -> b = 1; latoomutbeta -> c = 1; latoomutbeta -> d = 1; } constrain(latoomutbeta, NULL, 0, NULL); lyap(latoomutbeta, -1000000.0, 1000000.0, M_failure_limit); } return (void *)latoomutbeta; } void latoomutbeta_setup(void) { latoomutbeta_class = class_new(gensym("latoomutbeta"), (t_newmethod) latoomutbeta_new, 0, sizeof(latoomutbeta_struct), 0, A_GIMME, 0); class_addbang(latoomutbeta_class, (t_method) calculate); class_addmethod(latoomutbeta_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(latoomutbeta_class, (t_method) show, gensym("show"), 0); class_addmethod(latoomutbeta_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(latoomutbeta_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(latoomutbeta_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(latoomutbeta_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(latoomutbeta_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(latoomutbeta_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/quadruptwo.c0000644000076500007650000003057012076105251013511 0ustar hanshans/* quadruptwo Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_x 0 #define M_y 1 #define M_param_count 3 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "quadruptwo v0.0, by Michael McGonagle, from ??????, 2003"; t_class *quadruptwo_class; typedef struct quadruptwo_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } quadruptwo_struct; static void calc(quadruptwo_struct *quadruptwo, double *vars) { double x_0, y_0; x_0 =vars[M_y]-((vars[M_x]<0)?-1:1)*sin(log(abs(quadruptwo -> b*vars[M_x]-quadruptwo -> c)))*atan(pow(abs(quadruptwo -> c*vars[M_x]-quadruptwo -> b),2)); y_0 =quadruptwo -> a-vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(quadruptwo_struct *quadruptwo) { calc(quadruptwo, quadruptwo -> vars); outlet_float(quadruptwo -> outlets[M_y - 1], quadruptwo -> vars[M_y]); outlet_float(quadruptwo -> x_obj.ob_outlet, quadruptwo -> vars[M_x]); } // end calculate static void reset(quadruptwo_struct *quadruptwo, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { quadruptwo -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); quadruptwo -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { quadruptwo -> vars[M_x] = quadruptwo -> vars_init[M_x]; quadruptwo -> vars[M_y] = quadruptwo -> vars_init[M_y]; } // end if } // end reset static char *classify(quadruptwo_struct *quadruptwo) { static char buff[4]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((quadruptwo -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((quadruptwo -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((quadruptwo -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = '\0'; return buff; } static void make_results(quadruptwo_struct *quadruptwo) { SETFLOAT(&quadruptwo -> search_out[0], quadruptwo -> lyap_exp); SETSYMBOL(&quadruptwo -> search_out[1], gensym(classify(quadruptwo))); SETFLOAT(&quadruptwo -> search_out[2], quadruptwo -> failure_ratio); SETFLOAT(&quadruptwo -> vars_out[M_x], quadruptwo -> vars[M_x]); SETFLOAT(&quadruptwo -> vars_out[M_y], quadruptwo -> vars[M_y]); SETFLOAT(&quadruptwo -> params_out[M_a], quadruptwo -> a); SETFLOAT(&quadruptwo -> params_out[M_b], quadruptwo -> b); SETFLOAT(&quadruptwo -> params_out[M_c], quadruptwo -> c); outlet_list(quadruptwo -> params_outlet, gensym("list"), M_param_count, quadruptwo -> params_out); outlet_list(quadruptwo -> vars_outlet, gensym("list"), M_var_count, quadruptwo -> vars_out); } static void show(quadruptwo_struct *quadruptwo) { make_results(quadruptwo); outlet_anything(quadruptwo -> search_outlet, gensym("show"), M_search_count, quadruptwo -> search_out); } static void param(quadruptwo_struct *quadruptwo, t_symbol *s, int argc, t_atom *argv) { if (argc != 3) { post("Incorrect number of arguments for quadruptwo fractal. Expecting 3 arguments."); return; } quadruptwo -> a = (double) atom_getfloatarg(0, argc, argv); quadruptwo -> b = (double) atom_getfloatarg(1, argc, argv); quadruptwo -> c = (double) atom_getfloatarg(2, argc, argv); } static void seed(quadruptwo_struct *quadruptwo, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(quadruptwo_struct *quadruptwo, t_floatarg l, t_floatarg h, t_floatarg lim) { quadruptwo -> lyap_lo = l; quadruptwo -> lyap_hi = h; quadruptwo -> lyap_limit = (double) ((int) lim); } static void elyap(quadruptwo_struct *quadruptwo) { double results[M_var_count]; int i; if (lyapunov_full((void *) quadruptwo, (t_gotfn) calc, M_var_count, quadruptwo -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(quadruptwo_struct *quadruptwo) { if (quadruptwo -> a_lo < M_a_lo) { quadruptwo -> a_lo = M_a_lo; } if (quadruptwo -> a_lo > M_a_hi) { quadruptwo -> a_lo = M_a_hi; } if (quadruptwo -> a_hi < M_a_lo) { quadruptwo -> a_hi = M_a_lo; } if (quadruptwo -> a_hi > M_a_hi) { quadruptwo -> a_hi = M_a_hi; } if (quadruptwo -> b_lo < M_b_lo) { quadruptwo -> b_lo = M_b_lo; } if (quadruptwo -> b_lo > M_b_hi) { quadruptwo -> b_lo = M_b_hi; } if (quadruptwo -> b_hi < M_b_lo) { quadruptwo -> b_hi = M_b_lo; } if (quadruptwo -> b_hi > M_b_hi) { quadruptwo -> b_hi = M_b_hi; } if (quadruptwo -> c_lo < M_c_lo) { quadruptwo -> c_lo = M_c_lo; } if (quadruptwo -> c_lo > M_c_hi) { quadruptwo -> c_lo = M_c_hi; } if (quadruptwo -> c_hi < M_c_lo) { quadruptwo -> c_hi = M_c_lo; } if (quadruptwo -> c_hi > M_c_hi) { quadruptwo -> c_hi = M_c_hi; } } static void constrain(quadruptwo_struct *quadruptwo, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges quadruptwo -> a_lo = M_a_lo; quadruptwo -> a_hi = M_a_hi; quadruptwo -> b_lo = M_b_lo; quadruptwo -> b_hi = M_b_hi; quadruptwo -> c_lo = M_c_lo; quadruptwo -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; quadruptwo -> a_lo = quadruptwo -> a - a_spread; quadruptwo -> a_hi = quadruptwo -> a + a_spread; quadruptwo -> b_lo = quadruptwo -> b - b_spread; quadruptwo -> b_hi = quadruptwo -> b + b_spread; quadruptwo -> c_lo = quadruptwo -> c - c_spread; quadruptwo -> c_hi = quadruptwo -> c + c_spread; limiter(quadruptwo); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for quadruptwo constraints, requires 6 values, got %d", argc); return; } quadruptwo -> a_lo = atom_getfloat(arg++); quadruptwo -> a_hi = atom_getfloat(arg++); quadruptwo -> b_lo = atom_getfloat(arg++); quadruptwo -> b_hi = atom_getfloat(arg++); quadruptwo -> c_lo = atom_getfloat(arg++); quadruptwo -> c_hi = atom_getfloat(arg++); limiter(quadruptwo); } static void search(quadruptwo_struct *quadruptwo, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = quadruptwo -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = quadruptwo -> a; double temp_b = quadruptwo -> b; double temp_c = quadruptwo -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], quadruptwo -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: quadruptwo -> a = (drand48() * (quadruptwo -> a_hi - quadruptwo -> a_lo)) + quadruptwo -> a_lo; quadruptwo -> b = (drand48() * (quadruptwo -> b_hi - quadruptwo -> b_lo)) + quadruptwo -> b_lo; quadruptwo -> c = (drand48() * (quadruptwo -> c_hi - quadruptwo -> c_lo)) + quadruptwo -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(quadruptwo, NULL, argc, vars); do { calc(quadruptwo, quadruptwo -> vars); } while(jump--); quadruptwo -> lyap_exp = lyapunov((void *) quadruptwo, (t_gotfn) calc, M_var_count, (double *) quadruptwo -> vars); if (isnan(quadruptwo -> lyap_exp)) { not_found = 1; } if (quadruptwo -> lyap_exp < quadruptwo -> lyap_lo || quadruptwo -> lyap_exp > quadruptwo -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(quadruptwo, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) quadruptwo -> lyap_limit); post("Try using wider constraints."); quadruptwo -> a = temp_a; quadruptwo -> b = temp_b; quadruptwo -> c = temp_c; outlet_anything(quadruptwo -> search_outlet, gensym("invalid"), 0, NULL); } else { quadruptwo -> failure_ratio = (quadruptwo -> lyap_limit - not_expired) / quadruptwo -> lyap_limit; make_results(quadruptwo); outlet_anything(quadruptwo -> search_outlet, gensym("search"), M_search_count, quadruptwo -> search_out); } } void *quadruptwo_new(t_symbol *s, int argc, t_atom *argv) { quadruptwo_struct *quadruptwo = (quadruptwo_struct *) pd_new(quadruptwo_class); if (quadruptwo != NULL) { outlet_new(&quadruptwo -> x_obj, &s_float); quadruptwo -> outlets[0] = outlet_new(&quadruptwo -> x_obj, &s_float); quadruptwo -> search_outlet = outlet_new(&quadruptwo -> x_obj, &s_list); quadruptwo -> vars_outlet = outlet_new(&quadruptwo -> x_obj, &s_list); quadruptwo -> params_outlet = outlet_new(&quadruptwo -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { quadruptwo -> vars_init[M_x] = quadruptwo -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); quadruptwo -> vars_init[M_y] = quadruptwo -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); quadruptwo -> a = (double) atom_getfloatarg(2, argc, argv); quadruptwo -> b = (double) atom_getfloatarg(3, argc, argv); quadruptwo -> c = (double) atom_getfloatarg(4, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for quadruptwo fractal. Expecting 5 arguments."); } quadruptwo -> vars_init[M_x] = 0; quadruptwo -> vars_init[M_y] = 0; quadruptwo -> a = 34; quadruptwo -> b = 1; quadruptwo -> c = 5; } constrain(quadruptwo, NULL, 0, NULL); lyap(quadruptwo, -1000000.0, 1000000.0, M_failure_limit); } return (void *)quadruptwo; } void quadruptwo_setup(void) { quadruptwo_class = class_new(gensym("quadruptwo"), (t_newmethod) quadruptwo_new, 0, sizeof(quadruptwo_struct), 0, A_GIMME, 0); class_addbang(quadruptwo_class, (t_method) calculate); class_addmethod(quadruptwo_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(quadruptwo_class, (t_method) show, gensym("show"), 0); class_addmethod(quadruptwo_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(quadruptwo_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(quadruptwo_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(quadruptwo_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(quadruptwo_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(quadruptwo_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/lotkavolterra.c0000644000076500007650000003421612076105251014170 0ustar hanshans/* lotkavolterra Attractor PD External */ /* Copyright Michael McGonagle, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_e_lo -1000 #define M_e_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_e 3 #define M_r 0 #define M_f 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "lotkavolterra v0.0, by Michael McGonagle, 2003"; t_class *lotkavolterra_class; typedef struct lotkavolterra_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, e, e_lo, e_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } lotkavolterra_struct; static void calc(lotkavolterra_struct *lotkavolterra, double *vars) { double r_0, f_0; r_0 =vars[M_r]+lotkavolterra -> a*vars[M_r]-lotkavolterra -> b*vars[M_r]*vars[M_f]; f_0 =vars[M_f]+lotkavolterra -> e*lotkavolterra -> b*vars[M_r]*vars[M_f]-lotkavolterra -> c*vars[M_f]; vars[M_r] = r_0; vars[M_f] = f_0; } // end calc static void calculate(lotkavolterra_struct *lotkavolterra) { calc(lotkavolterra, lotkavolterra -> vars); outlet_float(lotkavolterra -> outlets[M_f - 1], lotkavolterra -> vars[M_f]); outlet_float(lotkavolterra -> x_obj.ob_outlet, lotkavolterra -> vars[M_r]); } // end calculate static void reset(lotkavolterra_struct *lotkavolterra, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { lotkavolterra -> vars[M_r] = (double) atom_getfloatarg(M_r, argc, argv); lotkavolterra -> vars[M_f] = (double) atom_getfloatarg(M_f, argc, argv); } else { lotkavolterra -> vars[M_r] = lotkavolterra -> vars_init[M_r]; lotkavolterra -> vars[M_f] = lotkavolterra -> vars_init[M_f]; } // end if } // end reset static char *classify(lotkavolterra_struct *lotkavolterra) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((lotkavolterra -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((lotkavolterra -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((lotkavolterra -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((lotkavolterra -> e - M_e_lo) * (1.0 / (M_e_hi - M_e_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(lotkavolterra_struct *lotkavolterra) { SETFLOAT(&lotkavolterra -> search_out[0], lotkavolterra -> lyap_exp); SETSYMBOL(&lotkavolterra -> search_out[1], gensym(classify(lotkavolterra))); SETFLOAT(&lotkavolterra -> search_out[2], lotkavolterra -> failure_ratio); SETFLOAT(&lotkavolterra -> vars_out[M_r], lotkavolterra -> vars[M_r]); SETFLOAT(&lotkavolterra -> vars_out[M_f], lotkavolterra -> vars[M_f]); SETFLOAT(&lotkavolterra -> params_out[M_a], lotkavolterra -> a); SETFLOAT(&lotkavolterra -> params_out[M_b], lotkavolterra -> b); SETFLOAT(&lotkavolterra -> params_out[M_c], lotkavolterra -> c); SETFLOAT(&lotkavolterra -> params_out[M_e], lotkavolterra -> e); outlet_list(lotkavolterra -> params_outlet, gensym("list"), M_param_count, lotkavolterra -> params_out); outlet_list(lotkavolterra -> vars_outlet, gensym("list"), M_var_count, lotkavolterra -> vars_out); } static void show(lotkavolterra_struct *lotkavolterra) { make_results(lotkavolterra); outlet_anything(lotkavolterra -> search_outlet, gensym("show"), M_search_count, lotkavolterra -> search_out); } static void param(lotkavolterra_struct *lotkavolterra, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for lotkavolterra fractal. Expecting 4 arguments."); return; } lotkavolterra -> a = (double) atom_getfloatarg(0, argc, argv); lotkavolterra -> b = (double) atom_getfloatarg(1, argc, argv); lotkavolterra -> c = (double) atom_getfloatarg(2, argc, argv); lotkavolterra -> e = (double) atom_getfloatarg(3, argc, argv); } static void seed(lotkavolterra_struct *lotkavolterra, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(lotkavolterra_struct *lotkavolterra, t_floatarg l, t_floatarg h, t_floatarg lim) { lotkavolterra -> lyap_lo = l; lotkavolterra -> lyap_hi = h; lotkavolterra -> lyap_limit = (double) ((int) lim); } static void elyap(lotkavolterra_struct *lotkavolterra) { double results[M_var_count]; int i; if (lyapunov_full((void *) lotkavolterra, (t_gotfn) calc, M_var_count, lotkavolterra -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(lotkavolterra_struct *lotkavolterra) { if (lotkavolterra -> a_lo < M_a_lo) { lotkavolterra -> a_lo = M_a_lo; } if (lotkavolterra -> a_lo > M_a_hi) { lotkavolterra -> a_lo = M_a_hi; } if (lotkavolterra -> a_hi < M_a_lo) { lotkavolterra -> a_hi = M_a_lo; } if (lotkavolterra -> a_hi > M_a_hi) { lotkavolterra -> a_hi = M_a_hi; } if (lotkavolterra -> b_lo < M_b_lo) { lotkavolterra -> b_lo = M_b_lo; } if (lotkavolterra -> b_lo > M_b_hi) { lotkavolterra -> b_lo = M_b_hi; } if (lotkavolterra -> b_hi < M_b_lo) { lotkavolterra -> b_hi = M_b_lo; } if (lotkavolterra -> b_hi > M_b_hi) { lotkavolterra -> b_hi = M_b_hi; } if (lotkavolterra -> c_lo < M_c_lo) { lotkavolterra -> c_lo = M_c_lo; } if (lotkavolterra -> c_lo > M_c_hi) { lotkavolterra -> c_lo = M_c_hi; } if (lotkavolterra -> c_hi < M_c_lo) { lotkavolterra -> c_hi = M_c_lo; } if (lotkavolterra -> c_hi > M_c_hi) { lotkavolterra -> c_hi = M_c_hi; } if (lotkavolterra -> e_lo < M_e_lo) { lotkavolterra -> e_lo = M_e_lo; } if (lotkavolterra -> e_lo > M_e_hi) { lotkavolterra -> e_lo = M_e_hi; } if (lotkavolterra -> e_hi < M_e_lo) { lotkavolterra -> e_hi = M_e_lo; } if (lotkavolterra -> e_hi > M_e_hi) { lotkavolterra -> e_hi = M_e_hi; } } static void constrain(lotkavolterra_struct *lotkavolterra, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges lotkavolterra -> a_lo = M_a_lo; lotkavolterra -> a_hi = M_a_hi; lotkavolterra -> b_lo = M_b_lo; lotkavolterra -> b_hi = M_b_hi; lotkavolterra -> c_lo = M_c_lo; lotkavolterra -> c_hi = M_c_hi; lotkavolterra -> e_lo = M_e_lo; lotkavolterra -> e_hi = M_e_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double e_spread = ((M_e_hi - M_e_lo) * percent) / 2; lotkavolterra -> a_lo = lotkavolterra -> a - a_spread; lotkavolterra -> a_hi = lotkavolterra -> a + a_spread; lotkavolterra -> b_lo = lotkavolterra -> b - b_spread; lotkavolterra -> b_hi = lotkavolterra -> b + b_spread; lotkavolterra -> c_lo = lotkavolterra -> c - c_spread; lotkavolterra -> c_hi = lotkavolterra -> c + c_spread; lotkavolterra -> e_lo = lotkavolterra -> e - e_spread; lotkavolterra -> e_hi = lotkavolterra -> e + e_spread; limiter(lotkavolterra); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for lotkavolterra constraints, requires 8 values, got %d", argc); return; } lotkavolterra -> a_lo = atom_getfloat(arg++); lotkavolterra -> a_hi = atom_getfloat(arg++); lotkavolterra -> b_lo = atom_getfloat(arg++); lotkavolterra -> b_hi = atom_getfloat(arg++); lotkavolterra -> c_lo = atom_getfloat(arg++); lotkavolterra -> c_hi = atom_getfloat(arg++); lotkavolterra -> e_lo = atom_getfloat(arg++); lotkavolterra -> e_hi = atom_getfloat(arg++); limiter(lotkavolterra); } static void search(lotkavolterra_struct *lotkavolterra, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = lotkavolterra -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = lotkavolterra -> a; double temp_b = lotkavolterra -> b; double temp_c = lotkavolterra -> c; double temp_e = lotkavolterra -> e; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], lotkavolterra -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: lotkavolterra -> a = (drand48() * (lotkavolterra -> a_hi - lotkavolterra -> a_lo)) + lotkavolterra -> a_lo; lotkavolterra -> b = (drand48() * (lotkavolterra -> b_hi - lotkavolterra -> b_lo)) + lotkavolterra -> b_lo; lotkavolterra -> c = (drand48() * (lotkavolterra -> c_hi - lotkavolterra -> c_lo)) + lotkavolterra -> c_lo; lotkavolterra -> e = (drand48() * (lotkavolterra -> e_hi - lotkavolterra -> e_lo)) + lotkavolterra -> e_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(lotkavolterra, NULL, argc, vars); do { calc(lotkavolterra, lotkavolterra -> vars); } while(jump--); lotkavolterra -> lyap_exp = lyapunov((void *) lotkavolterra, (t_gotfn) calc, M_var_count, (double *) lotkavolterra -> vars); if (isnan(lotkavolterra -> lyap_exp)) { not_found = 1; } if (lotkavolterra -> lyap_exp < lotkavolterra -> lyap_lo || lotkavolterra -> lyap_exp > lotkavolterra -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(lotkavolterra, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) lotkavolterra -> lyap_limit); post("Try using wider constraints."); lotkavolterra -> a = temp_a; lotkavolterra -> b = temp_b; lotkavolterra -> c = temp_c; lotkavolterra -> e = temp_e; outlet_anything(lotkavolterra -> search_outlet, gensym("invalid"), 0, NULL); } else { lotkavolterra -> failure_ratio = (lotkavolterra -> lyap_limit - not_expired) / lotkavolterra -> lyap_limit; make_results(lotkavolterra); outlet_anything(lotkavolterra -> search_outlet, gensym("search"), M_search_count, lotkavolterra -> search_out); } } void *lotkavolterra_new(t_symbol *s, int argc, t_atom *argv) { lotkavolterra_struct *lotkavolterra = (lotkavolterra_struct *) pd_new(lotkavolterra_class); if (lotkavolterra != NULL) { outlet_new(&lotkavolterra -> x_obj, &s_float); lotkavolterra -> outlets[0] = outlet_new(&lotkavolterra -> x_obj, &s_float); lotkavolterra -> search_outlet = outlet_new(&lotkavolterra -> x_obj, &s_list); lotkavolterra -> vars_outlet = outlet_new(&lotkavolterra -> x_obj, &s_list); lotkavolterra -> params_outlet = outlet_new(&lotkavolterra -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { lotkavolterra -> vars_init[M_r] = lotkavolterra -> vars[M_r] = (double) atom_getfloatarg(0, argc, argv); lotkavolterra -> vars_init[M_f] = lotkavolterra -> vars[M_f] = (double) atom_getfloatarg(1, argc, argv); lotkavolterra -> a = (double) atom_getfloatarg(2, argc, argv); lotkavolterra -> b = (double) atom_getfloatarg(3, argc, argv); lotkavolterra -> c = (double) atom_getfloatarg(4, argc, argv); lotkavolterra -> e = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for lotkavolterra fractal. Expecting 6 arguments."); } lotkavolterra -> vars_init[M_r] = 0.1; lotkavolterra -> vars_init[M_f] = 0.1; lotkavolterra -> a = 0.04; lotkavolterra -> b = 0.0005; lotkavolterra -> c = 0.2; lotkavolterra -> e = 0.1; } constrain(lotkavolterra, NULL, 0, NULL); lyap(lotkavolterra, -1000000.0, 1000000.0, M_failure_limit); } return (void *)lotkavolterra; } void lotkavolterra_setup(void) { lotkavolterra_class = class_new(gensym("lotkavolterra"), (t_newmethod) lotkavolterra_new, 0, sizeof(lotkavolterra_struct), 0, A_GIMME, 0); class_addbang(lotkavolterra_class, (t_method) calculate); class_addmethod(lotkavolterra_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(lotkavolterra_class, (t_method) show, gensym("show"), 0); class_addmethod(lotkavolterra_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(lotkavolterra_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(lotkavolterra_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(lotkavolterra_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(lotkavolterra_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(lotkavolterra_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/chaos.ncb0000644000076500007650000006600012076105251012710 0ustar hanshansMicrosoft C/C++ MSF 7.00 DS”àþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑ  #; Ø@0""€n %%U -1D 3C¸((–())Ä**r ++¢  ##æŒ_fPPPPPªr… ";… 3 h… $5R… ^… CO¸ Rj—…@0 ®@0 …@0¾@0 Ð@0 â@0 !! =A<… 7;_    PBŒ_P§§æ§§ùPB PB”.1ãHn=ïÓ·É'ÚN²ÊÔ!Ÿ“;4Ž… #;e A 3 h… %=xô „… M[– ^x³…@0!!Ã…@0!!Ó…@0!!›…@0 õ…@0 !!@0 !!ã…@0 !!@0 "" EK<… ?Cù ^    PhŒ_P§§§æ§§§ùPh 0=PhºhJS #; 3 hhJS %<­hJS ¢hJS M]Ä `{óhJS@0  hJS@0  hJS@0  âhJS@0 ÈhJS@0 &hJS@0 9@0 L@0 _@0 !!w@0 "" EK<hJS >C_     vP‘Œ_P§§§§æ§§§ùùP‘ 0P‘ô #; 3 h %< EK< >CÏ Ý M\r _y+@0  =@0  O@0  @0  a@0  u@0  ‰@0  @0 @0 !!¶@0 ""_^     vPâPâ 0PâŒ_P§§§§§§§æùù­ÚV÷Ø   @oGn=ï@€€@@ÃGn=$ B„ bGn=l Lw  BB @€]Gn=TAœÝ  B @€@€@WGn=hoÑh€UDR^¸rx„–Ž­¢Äº<ÏÝrô¢=^¿ƒòôšýØß/ú+= È Ø& —³<\©€O Ø8ô9 ôö®â R–; \©a Ó LD^¾ óx¢ ÏhÀ[©„ã u ¢_UÐ Ž¸rÝ­õ  Ä› +  â ‰ºwrÑ 3Ø[© þïþïéE:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.vcproj|Debug|Win32E:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.vcproj|Release|Win32C:\Program Files\Microsoft Visual Studio .NET\Vc7\vcpackages\prebuilt.ncbe:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.c"m_pd.h"chaos_setupvoidchaos_newvoid *t_symbol *srossler_setupchaos_classt_class *ikeda_setupt_chaosstruct _chaoshenon_setuplorenz_setup_chaos_chaos::x_objt_objecte:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\henon.cresethenon_struct *xhenon_classhenon_newcalculatehenon_structhenon_struct::henon_objhenon_struct::adoublehenon_struct::bhenon_struct::lx0henon_struct::ly0henon_struct::y_outlett_outlet *paramt_floatarg at_floatarg be:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\ikeda.cikeda_struct *xikeda_classikeda_newikeda_structikeda_struct::ikeda_objikeda_struct::aikeda_struct::bikeda_struct::cikeda_struct::rhoikeda_struct::lx0ikeda_struct::ly0ikeda_struct::y_outlett_floatarg ct_floatarg rhoe:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\lorenz.clorenz_struct *xlorenz_newlorenz_classlorenz_structlorenz_struct::lorenz_objlorenz_struct::hlorenz_struct::alorenz_struct::blorenz_struct::clorenz_struct::lx0lorenz_struct::ly0lorenz_struct::lz0lorenz_struct::y_outletlorenz_struct::z_outlett_floatarg he:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\rossler.crossler_struct *xrossler_structrossler_struct::myobjrossler_struct::hrossler_struct::arossler_struct::brossler_struct::crossler_struct::lx0rossler_struct::ly0rossler_struct::lz0rossler_struct::y_outletrossler_struct::z_outletrossler_classrossler_new‹ï <ãªù÷;€Ž3UBw­h›‘­ô$‰_fxМRâÈPDr„â–+Ñ_=OuLÏ=¸®—Ýaó¢ÃÓ³V^L&9ÄæŒâº¾§Øõh¢¶r0V”.1ãHn=ïÓ·É'ÚN²ÊÔ!Ÿ“;À/names/ncb/targetinfo/ncb/moduleinfo/ncb/storeinfo/ncb/iinstdefs/ncb/referenceInfo/ncb/module/e:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.c/ncb/module/e:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\henon.c/ncb/module/e:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\ikeda.c/ncb/module/e:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\lorenz.c/ncb/module/e:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\rossler.c/ncb/target/E:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.vcproj|Debug|Win32/ncb/target/E:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.vcproj|Release|Win32/ncb/versioninfoãþ'LE ™¨ X H 6ø ¯ëh) ü´ˆÈ  chaos-0.2/martin.c0000644000076500007650000002275612076105251012577 0ustar hanshans/* martin Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo 0 #define M_a_hi 1000 #define M_a 0 #define M_x 0 #define M_y 1 #define M_param_count 1 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "martin v0.0, by Michael McGonagle, from ??????, 2003"; t_class *martin_class; typedef struct martin_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } martin_struct; static void calc(martin_struct *martin, double *vars) { double x_0, y_0; x_0 =vars[M_y]-sin(vars[M_x]); y_0 =martin -> a-vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(martin_struct *martin) { calc(martin, martin -> vars); outlet_float(martin -> outlets[M_y - 1], martin -> vars[M_y]); outlet_float(martin -> x_obj.ob_outlet, martin -> vars[M_x]); } // end calculate static void reset(martin_struct *martin, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { martin -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); martin -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { martin -> vars[M_x] = martin -> vars_init[M_x]; martin -> vars[M_y] = martin -> vars_init[M_y]; } // end if } // end reset static char *classify(martin_struct *martin) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((martin -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(martin_struct *martin) { SETFLOAT(&martin -> search_out[0], martin -> lyap_exp); SETSYMBOL(&martin -> search_out[1], gensym(classify(martin))); SETFLOAT(&martin -> search_out[2], martin -> failure_ratio); SETFLOAT(&martin -> vars_out[M_x], martin -> vars[M_x]); SETFLOAT(&martin -> vars_out[M_y], martin -> vars[M_y]); SETFLOAT(&martin -> params_out[M_a], martin -> a); outlet_list(martin -> params_outlet, gensym("list"), M_param_count, martin -> params_out); outlet_list(martin -> vars_outlet, gensym("list"), M_var_count, martin -> vars_out); } static void show(martin_struct *martin) { make_results(martin); outlet_anything(martin -> search_outlet, gensym("show"), M_search_count, martin -> search_out); } static void param(martin_struct *martin, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for martin fractal. Expecting 1 arguments."); return; } martin -> a = (double) atom_getfloatarg(0, argc, argv); } static void seed(martin_struct *martin, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(martin_struct *martin, t_floatarg l, t_floatarg h, t_floatarg lim) { martin -> lyap_lo = l; martin -> lyap_hi = h; martin -> lyap_limit = (double) ((int) lim); } static void elyap(martin_struct *martin) { double results[M_var_count]; int i; if (lyapunov_full((void *) martin, (t_gotfn) calc, M_var_count, martin -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(martin_struct *martin) { if (martin -> a_lo < M_a_lo) { martin -> a_lo = M_a_lo; } if (martin -> a_lo > M_a_hi) { martin -> a_lo = M_a_hi; } if (martin -> a_hi < M_a_lo) { martin -> a_hi = M_a_lo; } if (martin -> a_hi > M_a_hi) { martin -> a_hi = M_a_hi; } } static void constrain(martin_struct *martin, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges martin -> a_lo = M_a_lo; martin -> a_hi = M_a_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; martin -> a_lo = martin -> a - a_spread; martin -> a_hi = martin -> a + a_spread; limiter(martin); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for martin constraints, requires 2 values, got %d", argc); return; } martin -> a_lo = atom_getfloat(arg++); martin -> a_hi = atom_getfloat(arg++); limiter(martin); } static void search(martin_struct *martin, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = martin -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = martin -> a; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], martin -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: martin -> a = (drand48() * (martin -> a_hi - martin -> a_lo)) + martin -> a_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(martin, NULL, argc, vars); do { calc(martin, martin -> vars); } while(jump--); martin -> lyap_exp = lyapunov((void *) martin, (t_gotfn) calc, M_var_count, (double *) martin -> vars); if (isnan(martin -> lyap_exp)) { not_found = 1; } if (martin -> lyap_exp < martin -> lyap_lo || martin -> lyap_exp > martin -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(martin, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) martin -> lyap_limit); post("Try using wider constraints."); martin -> a = temp_a; outlet_anything(martin -> search_outlet, gensym("invalid"), 0, NULL); } else { martin -> failure_ratio = (martin -> lyap_limit - not_expired) / martin -> lyap_limit; make_results(martin); outlet_anything(martin -> search_outlet, gensym("search"), M_search_count, martin -> search_out); } } void *martin_new(t_symbol *s, int argc, t_atom *argv) { martin_struct *martin = (martin_struct *) pd_new(martin_class); if (martin != NULL) { outlet_new(&martin -> x_obj, &s_float); martin -> outlets[0] = outlet_new(&martin -> x_obj, &s_float); martin -> search_outlet = outlet_new(&martin -> x_obj, &s_list); martin -> vars_outlet = outlet_new(&martin -> x_obj, &s_list); martin -> params_outlet = outlet_new(&martin -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { martin -> vars_init[M_x] = martin -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); martin -> vars_init[M_y] = martin -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); martin -> a = (double) atom_getfloatarg(2, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for martin fractal. Expecting 3 arguments."); } martin -> vars_init[M_x] = 0.01; martin -> vars_init[M_y] = 0; martin -> a = 3.14; } constrain(martin, NULL, 0, NULL); lyap(martin, -1000000.0, 1000000.0, M_failure_limit); } return (void *)martin; } void martin_setup(void) { martin_class = class_new(gensym("martin"), (t_newmethod) martin_new, 0, sizeof(martin_struct), 0, A_GIMME, 0); class_addbang(martin_class, (t_method) calculate); class_addmethod(martin_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(martin_class, (t_method) show, gensym("show"), 0); class_addmethod(martin_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(martin_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(martin_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(martin_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(martin_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(martin_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/dejong.c0000644000076500007650000003072712076105251012550 0ustar hanshans/* dejong Attractor PD External */ /* Copyright Michael McGonagle, from ???pbourke???, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_d_lo -1000 #define M_d_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "dejong v0.0, by Michael McGonagle, from ???pbourke???, 2003"; t_class *dejong_class; typedef struct dejong_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } dejong_struct; static void calc(dejong_struct *dejong, double *vars) { double x_0, y_0; x_0 =sin(dejong -> a*vars[M_y])-cos(dejong -> b*vars[M_x]); y_0 =sin(dejong -> c*vars[M_x])-cos(dejong -> d*vars[M_y]); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(dejong_struct *dejong) { calc(dejong, dejong -> vars); outlet_float(dejong -> outlets[M_y - 1], dejong -> vars[M_y]); outlet_float(dejong -> x_obj.ob_outlet, dejong -> vars[M_x]); } // end calculate static void reset(dejong_struct *dejong, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { dejong -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); dejong -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { dejong -> vars[M_x] = dejong -> vars_init[M_x]; dejong -> vars[M_y] = dejong -> vars_init[M_y]; } // end if } // end reset static char *classify(dejong_struct *dejong) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((dejong -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((dejong -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((dejong -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((dejong -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(dejong_struct *dejong) { SETFLOAT(&dejong -> search_out[0], dejong -> lyap_exp); SETSYMBOL(&dejong -> search_out[1], gensym(classify(dejong))); SETFLOAT(&dejong -> search_out[2], dejong -> failure_ratio); SETFLOAT(&dejong -> vars_out[M_x], dejong -> vars[M_x]); SETFLOAT(&dejong -> vars_out[M_y], dejong -> vars[M_y]); SETFLOAT(&dejong -> params_out[M_a], dejong -> a); SETFLOAT(&dejong -> params_out[M_b], dejong -> b); SETFLOAT(&dejong -> params_out[M_c], dejong -> c); SETFLOAT(&dejong -> params_out[M_d], dejong -> d); outlet_list(dejong -> params_outlet, gensym("list"), M_param_count, dejong -> params_out); outlet_list(dejong -> vars_outlet, gensym("list"), M_var_count, dejong -> vars_out); } static void show(dejong_struct *dejong) { make_results(dejong); outlet_anything(dejong -> search_outlet, gensym("show"), M_search_count, dejong -> search_out); } static void param(dejong_struct *dejong, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for dejong fractal. Expecting 4 arguments."); return; } dejong -> a = (double) atom_getfloatarg(0, argc, argv); dejong -> b = (double) atom_getfloatarg(1, argc, argv); dejong -> c = (double) atom_getfloatarg(2, argc, argv); dejong -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(dejong_struct *dejong, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(dejong_struct *dejong, t_floatarg l, t_floatarg h, t_floatarg lim) { dejong -> lyap_lo = l; dejong -> lyap_hi = h; dejong -> lyap_limit = (double) ((int) lim); } static void elyap(dejong_struct *dejong) { double results[M_var_count]; int i; if (lyapunov_full((void *) dejong, (t_gotfn) calc, M_var_count, dejong -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(dejong_struct *dejong) { if (dejong -> a_lo < M_a_lo) { dejong -> a_lo = M_a_lo; } if (dejong -> a_lo > M_a_hi) { dejong -> a_lo = M_a_hi; } if (dejong -> a_hi < M_a_lo) { dejong -> a_hi = M_a_lo; } if (dejong -> a_hi > M_a_hi) { dejong -> a_hi = M_a_hi; } if (dejong -> b_lo < M_b_lo) { dejong -> b_lo = M_b_lo; } if (dejong -> b_lo > M_b_hi) { dejong -> b_lo = M_b_hi; } if (dejong -> b_hi < M_b_lo) { dejong -> b_hi = M_b_lo; } if (dejong -> b_hi > M_b_hi) { dejong -> b_hi = M_b_hi; } if (dejong -> c_lo < M_c_lo) { dejong -> c_lo = M_c_lo; } if (dejong -> c_lo > M_c_hi) { dejong -> c_lo = M_c_hi; } if (dejong -> c_hi < M_c_lo) { dejong -> c_hi = M_c_lo; } if (dejong -> c_hi > M_c_hi) { dejong -> c_hi = M_c_hi; } if (dejong -> d_lo < M_d_lo) { dejong -> d_lo = M_d_lo; } if (dejong -> d_lo > M_d_hi) { dejong -> d_lo = M_d_hi; } if (dejong -> d_hi < M_d_lo) { dejong -> d_hi = M_d_lo; } if (dejong -> d_hi > M_d_hi) { dejong -> d_hi = M_d_hi; } } static void constrain(dejong_struct *dejong, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges dejong -> a_lo = M_a_lo; dejong -> a_hi = M_a_hi; dejong -> b_lo = M_b_lo; dejong -> b_hi = M_b_hi; dejong -> c_lo = M_c_lo; dejong -> c_hi = M_c_hi; dejong -> d_lo = M_d_lo; dejong -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; dejong -> a_lo = dejong -> a - a_spread; dejong -> a_hi = dejong -> a + a_spread; dejong -> b_lo = dejong -> b - b_spread; dejong -> b_hi = dejong -> b + b_spread; dejong -> c_lo = dejong -> c - c_spread; dejong -> c_hi = dejong -> c + c_spread; dejong -> d_lo = dejong -> d - d_spread; dejong -> d_hi = dejong -> d + d_spread; limiter(dejong); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for dejong constraints, requires 8 values, got %d", argc); return; } dejong -> a_lo = atom_getfloat(arg++); dejong -> a_hi = atom_getfloat(arg++); dejong -> b_lo = atom_getfloat(arg++); dejong -> b_hi = atom_getfloat(arg++); dejong -> c_lo = atom_getfloat(arg++); dejong -> c_hi = atom_getfloat(arg++); dejong -> d_lo = atom_getfloat(arg++); dejong -> d_hi = atom_getfloat(arg++); limiter(dejong); } static void search(dejong_struct *dejong, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = dejong -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = dejong -> a; double temp_b = dejong -> b; double temp_c = dejong -> c; double temp_d = dejong -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], dejong -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: dejong -> a = (drand48() * (dejong -> a_hi - dejong -> a_lo)) + dejong -> a_lo; dejong -> b = (drand48() * (dejong -> b_hi - dejong -> b_lo)) + dejong -> b_lo; dejong -> c = (drand48() * (dejong -> c_hi - dejong -> c_lo)) + dejong -> c_lo; dejong -> d = (drand48() * (dejong -> d_hi - dejong -> d_lo)) + dejong -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(dejong, NULL, argc, vars); do { calc(dejong, dejong -> vars); } while(jump--); dejong -> lyap_exp = lyapunov((void *) dejong, (t_gotfn) calc, M_var_count, (double *) dejong -> vars); if (isnan(dejong -> lyap_exp)) { not_found = 1; } if (dejong -> lyap_exp < dejong -> lyap_lo || dejong -> lyap_exp > dejong -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(dejong, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) dejong -> lyap_limit); post("Try using wider constraints."); dejong -> a = temp_a; dejong -> b = temp_b; dejong -> c = temp_c; dejong -> d = temp_d; outlet_anything(dejong -> search_outlet, gensym("invalid"), 0, NULL); } else { dejong -> failure_ratio = (dejong -> lyap_limit - not_expired) / dejong -> lyap_limit; make_results(dejong); outlet_anything(dejong -> search_outlet, gensym("search"), M_search_count, dejong -> search_out); } } void *dejong_new(t_symbol *s, int argc, t_atom *argv) { dejong_struct *dejong = (dejong_struct *) pd_new(dejong_class); if (dejong != NULL) { outlet_new(&dejong -> x_obj, &s_float); dejong -> outlets[0] = outlet_new(&dejong -> x_obj, &s_float); dejong -> search_outlet = outlet_new(&dejong -> x_obj, &s_list); dejong -> vars_outlet = outlet_new(&dejong -> x_obj, &s_list); dejong -> params_outlet = outlet_new(&dejong -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { dejong -> vars_init[M_x] = dejong -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); dejong -> vars_init[M_y] = dejong -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); dejong -> a = (double) atom_getfloatarg(2, argc, argv); dejong -> b = (double) atom_getfloatarg(3, argc, argv); dejong -> c = (double) atom_getfloatarg(4, argc, argv); dejong -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for dejong fractal. Expecting 6 arguments."); } dejong -> vars_init[M_x] = 0.01; dejong -> vars_init[M_y] = 0; dejong -> a = -2.24; dejong -> b = -0.65; dejong -> c = 0.43; dejong -> d = -2.43; } constrain(dejong, NULL, 0, NULL); lyap(dejong, -1000000.0, 1000000.0, M_failure_limit); } return (void *)dejong; } void dejong_setup(void) { dejong_class = class_new(gensym("dejong"), (t_newmethod) dejong_new, 0, sizeof(dejong_struct), 0, A_GIMME, 0); class_addbang(dejong_class, (t_method) calculate); class_addmethod(dejong_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(dejong_class, (t_method) show, gensym("show"), 0); class_addmethod(dejong_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(dejong_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(dejong_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(dejong_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(dejong_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(dejong_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/logistic-help.pd0000644000076500007650000000017012076105251014213 0ustar hanshans#N canvas 149 395 450 300 10; #X text 71 41 1 variable; #X obj 248 24 examples/readme-fractals; #X obj 90 148 logistic; chaos-0.2/popcorn.c0000644000076500007650000002333412076105251012756 0ustar hanshans/* popcorn Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_h_lo -1000 #define M_h_hi 1000 #define M_h 0 #define M_x 0 #define M_y 1 #define M_param_count 1 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "popcorn v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *popcorn_class; typedef struct popcorn_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double h, h_lo, h_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } popcorn_struct; static void calc(popcorn_struct *popcorn, double *vars) { double x_0, y_0; x_0 =vars[M_x]-popcorn -> h*sin(vars[M_y]+tan(3*vars[M_y])); y_0 =vars[M_y]-popcorn -> h*sin(vars[M_x]+tan(3*vars[M_x])); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(popcorn_struct *popcorn) { calc(popcorn, popcorn -> vars); outlet_float(popcorn -> outlets[M_y - 1], popcorn -> vars[M_y]); outlet_float(popcorn -> x_obj.ob_outlet, popcorn -> vars[M_x]); } // end calculate static void reset(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { popcorn -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); popcorn -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { popcorn -> vars[M_x] = popcorn -> vars_init[M_x]; popcorn -> vars[M_y] = popcorn -> vars_init[M_y]; } // end if } // end reset static char *classify(popcorn_struct *popcorn) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((popcorn -> h - M_h_lo) * (1.0 / (M_h_hi - M_h_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(popcorn_struct *popcorn) { SETFLOAT(&popcorn -> search_out[0], popcorn -> lyap_exp); SETSYMBOL(&popcorn -> search_out[1], gensym(classify(popcorn))); SETFLOAT(&popcorn -> search_out[2], popcorn -> failure_ratio); SETFLOAT(&popcorn -> vars_out[M_x], popcorn -> vars[M_x]); SETFLOAT(&popcorn -> vars_out[M_y], popcorn -> vars[M_y]); SETFLOAT(&popcorn -> params_out[M_h], popcorn -> h); outlet_list(popcorn -> params_outlet, gensym("list"), M_param_count, popcorn -> params_out); outlet_list(popcorn -> vars_outlet, gensym("list"), M_var_count, popcorn -> vars_out); } static void show(popcorn_struct *popcorn) { make_results(popcorn); outlet_anything(popcorn -> search_outlet, gensym("show"), M_search_count, popcorn -> search_out); } static void param(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for popcorn fractal. Expecting 1 arguments."); return; } popcorn -> h = (double) atom_getfloatarg(0, argc, argv); } static void seed(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(popcorn_struct *popcorn, t_floatarg l, t_floatarg h, t_floatarg lim) { popcorn -> lyap_lo = l; popcorn -> lyap_hi = h; popcorn -> lyap_limit = (double) ((int) lim); } static void elyap(popcorn_struct *popcorn) { double results[M_var_count]; int i; if (lyapunov_full((void *) popcorn, (t_gotfn) calc, M_var_count, popcorn -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(popcorn_struct *popcorn) { if (popcorn -> h_lo < M_h_lo) { popcorn -> h_lo = M_h_lo; } if (popcorn -> h_lo > M_h_hi) { popcorn -> h_lo = M_h_hi; } if (popcorn -> h_hi < M_h_lo) { popcorn -> h_hi = M_h_lo; } if (popcorn -> h_hi > M_h_hi) { popcorn -> h_hi = M_h_hi; } } static void constrain(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges popcorn -> h_lo = M_h_lo; popcorn -> h_hi = M_h_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double h_spread = ((M_h_hi - M_h_lo) * percent) / 2; popcorn -> h_lo = popcorn -> h - h_spread; popcorn -> h_hi = popcorn -> h + h_spread; limiter(popcorn); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for popcorn constraints, requires 2 values, got %d", argc); return; } popcorn -> h_lo = atom_getfloat(arg++); popcorn -> h_hi = atom_getfloat(arg++); limiter(popcorn); } static void search(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = popcorn -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_h = popcorn -> h; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], popcorn -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: popcorn -> h = (drand48() * (popcorn -> h_hi - popcorn -> h_lo)) + popcorn -> h_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(popcorn, NULL, argc, vars); do { calc(popcorn, popcorn -> vars); } while(jump--); popcorn -> lyap_exp = lyapunov((void *) popcorn, (t_gotfn) calc, M_var_count, (double *) popcorn -> vars); if (isnan(popcorn -> lyap_exp)) { not_found = 1; } if (popcorn -> lyap_exp < popcorn -> lyap_lo || popcorn -> lyap_exp > popcorn -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(popcorn, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) popcorn -> lyap_limit); post("Try using wider constraints."); popcorn -> h = temp_h; outlet_anything(popcorn -> search_outlet, gensym("invalid"), 0, NULL); } else { popcorn -> failure_ratio = (popcorn -> lyap_limit - not_expired) / popcorn -> lyap_limit; make_results(popcorn); outlet_anything(popcorn -> search_outlet, gensym("search"), M_search_count, popcorn -> search_out); } } void *popcorn_new(t_symbol *s, int argc, t_atom *argv) { popcorn_struct *popcorn = (popcorn_struct *) pd_new(popcorn_class); if (popcorn != NULL) { outlet_new(&popcorn -> x_obj, &s_float); popcorn -> outlets[0] = outlet_new(&popcorn -> x_obj, &s_float); popcorn -> search_outlet = outlet_new(&popcorn -> x_obj, &s_list); popcorn -> vars_outlet = outlet_new(&popcorn -> x_obj, &s_list); popcorn -> params_outlet = outlet_new(&popcorn -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { popcorn -> vars_init[M_x] = popcorn -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); popcorn -> vars_init[M_y] = popcorn -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); popcorn -> h = (double) atom_getfloatarg(2, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for popcorn fractal. Expecting 3 arguments."); } popcorn -> vars_init[M_x] = 0; popcorn -> vars_init[M_y] = 0; popcorn -> h = 0.05; } constrain(popcorn, NULL, 0, NULL); lyap(popcorn, -1000000.0, 1000000.0, M_failure_limit); } return (void *)popcorn; } void popcorn_setup(void) { popcorn_class = class_new(gensym("popcorn"), (t_newmethod) popcorn_new, 0, sizeof(popcorn_struct), 0, A_GIMME, 0); class_addbang(popcorn_class, (t_method) calculate); class_addmethod(popcorn_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(popcorn_class, (t_method) show, gensym("show"), 0); class_addmethod(popcorn_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(popcorn_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(popcorn_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(popcorn_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(popcorn_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(popcorn_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/mlogistic.c0000644000076500007650000002262012076105251013265 0ustar hanshans/* mlogistic Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_c_lo 0 #define M_c_hi 4 #define M_c 0 #define M_x 0 #define M_param_count 1 #define M_var_count 1 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "mlogistic v0.0, by Michael McGonagle, from ??????, 2003"; t_class *mlogistic_class; typedef struct mlogistic_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; } mlogistic_struct; static void calc(mlogistic_struct *mlogistic, double *vars) { double x_0; x_0 =(vars[M_x]*vars[M_x])+mlogistic -> c; vars[M_x] = x_0; } // end calc static void calculate(mlogistic_struct *mlogistic) { calc(mlogistic, mlogistic -> vars); outlet_float(mlogistic -> x_obj.ob_outlet, mlogistic -> vars[M_x]); } // end calculate static void reset(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { mlogistic -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); } else { mlogistic -> vars[M_x] = mlogistic -> vars_init[M_x]; } // end if } // end reset static char *classify(mlogistic_struct *mlogistic) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((mlogistic -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(mlogistic_struct *mlogistic) { SETFLOAT(&mlogistic -> search_out[0], mlogistic -> lyap_exp); SETSYMBOL(&mlogistic -> search_out[1], gensym(classify(mlogistic))); SETFLOAT(&mlogistic -> search_out[2], mlogistic -> failure_ratio); SETFLOAT(&mlogistic -> vars_out[M_x], mlogistic -> vars[M_x]); SETFLOAT(&mlogistic -> params_out[M_c], mlogistic -> c); outlet_list(mlogistic -> params_outlet, gensym("list"), M_param_count, mlogistic -> params_out); outlet_list(mlogistic -> vars_outlet, gensym("list"), M_var_count, mlogistic -> vars_out); } static void show(mlogistic_struct *mlogistic) { make_results(mlogistic); outlet_anything(mlogistic -> search_outlet, gensym("show"), M_search_count, mlogistic -> search_out); } static void param(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for mlogistic fractal. Expecting 1 arguments."); return; } mlogistic -> c = (double) atom_getfloatarg(0, argc, argv); } static void seed(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(mlogistic_struct *mlogistic, t_floatarg l, t_floatarg h, t_floatarg lim) { mlogistic -> lyap_lo = l; mlogistic -> lyap_hi = h; mlogistic -> lyap_limit = (double) ((int) lim); } static void elyap(mlogistic_struct *mlogistic) { double results[M_var_count]; int i; if (lyapunov_full((void *) mlogistic, (t_gotfn) calc, M_var_count, mlogistic -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(mlogistic_struct *mlogistic) { if (mlogistic -> c_lo < M_c_lo) { mlogistic -> c_lo = M_c_lo; } if (mlogistic -> c_lo > M_c_hi) { mlogistic -> c_lo = M_c_hi; } if (mlogistic -> c_hi < M_c_lo) { mlogistic -> c_hi = M_c_lo; } if (mlogistic -> c_hi > M_c_hi) { mlogistic -> c_hi = M_c_hi; } } static void constrain(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges mlogistic -> c_lo = M_c_lo; mlogistic -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; mlogistic -> c_lo = mlogistic -> c - c_spread; mlogistic -> c_hi = mlogistic -> c + c_spread; limiter(mlogistic); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for mlogistic constraints, requires 2 values, got %d", argc); return; } mlogistic -> c_lo = atom_getfloat(arg++); mlogistic -> c_hi = atom_getfloat(arg++); limiter(mlogistic); } static void search(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = mlogistic -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_c = mlogistic -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], mlogistic -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: mlogistic -> c = (drand48() * (mlogistic -> c_hi - mlogistic -> c_lo)) + mlogistic -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(mlogistic, NULL, argc, vars); do { calc(mlogistic, mlogistic -> vars); } while(jump--); mlogistic -> lyap_exp = lyapunov((void *) mlogistic, (t_gotfn) calc, M_var_count, (double *) mlogistic -> vars); if (isnan(mlogistic -> lyap_exp)) { not_found = 1; } if (mlogistic -> lyap_exp < mlogistic -> lyap_lo || mlogistic -> lyap_exp > mlogistic -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(mlogistic, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) mlogistic -> lyap_limit); post("Try using wider constraints."); mlogistic -> c = temp_c; outlet_anything(mlogistic -> search_outlet, gensym("invalid"), 0, NULL); } else { mlogistic -> failure_ratio = (mlogistic -> lyap_limit - not_expired) / mlogistic -> lyap_limit; make_results(mlogistic); outlet_anything(mlogistic -> search_outlet, gensym("search"), M_search_count, mlogistic -> search_out); } } void *mlogistic_new(t_symbol *s, int argc, t_atom *argv) { mlogistic_struct *mlogistic = (mlogistic_struct *) pd_new(mlogistic_class); if (mlogistic != NULL) { outlet_new(&mlogistic -> x_obj, &s_float); mlogistic -> search_outlet = outlet_new(&mlogistic -> x_obj, &s_list); mlogistic -> vars_outlet = outlet_new(&mlogistic -> x_obj, &s_list); mlogistic -> params_outlet = outlet_new(&mlogistic -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { mlogistic -> vars_init[M_x] = mlogistic -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); mlogistic -> c = (double) atom_getfloatarg(1, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for mlogistic fractal. Expecting 2 arguments."); } mlogistic -> vars_init[M_x] = 0.1; mlogistic -> c = 4; } constrain(mlogistic, NULL, 0, NULL); lyap(mlogistic, -1000000.0, 1000000.0, M_failure_limit); } return (void *)mlogistic; } void mlogistic_setup(void) { mlogistic_class = class_new(gensym("mlogistic"), (t_newmethod) mlogistic_new, 0, sizeof(mlogistic_struct), 0, A_GIMME, 0); class_addbang(mlogistic_class, (t_method) calculate); class_addmethod(mlogistic_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(mlogistic_class, (t_method) show, gensym("show"), 0); class_addmethod(mlogistic_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(mlogistic_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(mlogistic_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(mlogistic_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(mlogistic_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(mlogistic_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/rossler-help.pd0000644000076500007650000000131012076105251014064 0ustar hanshans#N canvas 48 298 368 335 10; #X obj 29 114 metro 50; #X obj 29 90 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 80 89 5 0 0; #X floatatom 74 285 5 0 0; #X text 5 66 Calculate; #X text 113 161 Reset To Initial Conditions; #X text 115 212 Modify Parameters; #X floatatom 29 285 5 0 0; #X floatatom 120 285 5 0 0; #X text 58 258 Output; #X text 4 21 Chaos PD Externals - Copyright Ben Bogart 2002; #X obj 29 177 rossler; #X msg 115 193 param 0.01 0.39 0.4 5.8; #X text 5 6 Rossler's Attractor; #X msg 114 143 reset 0.1 0 0; #X connect 0 0 11 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 11 0 7 0; #X connect 11 1 3 0; #X connect 11 2 8 0; #X connect 12 0 11 0; #X connect 14 0 11 0; chaos-0.2/hopalong-help.pd0000644000076500007650000000174312076105251014214 0ustar hanshans#N canvas 473 208 581 484 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 102 251 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X floatatom 115 419 10 0 0 0 Y - -; #X floatatom 43 388 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X text 21 19 Hopalong Attractor; #X msg 99 234 param -639.064 886.792 -150.226; #X obj 43 348 hopalong 0.1 0.1 -639.064 886.792 -150.226; #X obj 220 378 search-tools; #X connect 0 0 9 0; #X connect 1 0 9 1; #X connect 4 0 14 0; #X connect 9 0 14 0; #X connect 10 0 14 0; #X connect 13 0 14 0; #X connect 14 0 6 0; #X connect 14 1 5 0; #X connect 14 2 15 0; #X connect 14 3 15 1; #X connect 14 4 15 2; #X connect 15 0 14 0; chaos-0.2/lotkavolterra-help.pd0000644000076500007650000000214612076105251015274 0ustar hanshans#N canvas 527 258 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X msg 111 243 param -0.966918 2.87988 0.756145 0.744728; #X msg 111 264 param -2.90515 -2.03043 1.44055 0.70307; #X floatatom 136 407 10 0 0 0 Y - -; #X floatatom 43 367 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Lotkavolterra Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 43 347 lotkavolterra 0.1 0.1 -2.90515 -2.03043 1.44055 0.70307 ; #X obj 283 376 search-tools; #X connect 0 0 12 0; #X connect 1 0 12 1; #X connect 4 0 15 0; #X connect 5 0 15 0; #X connect 6 0 15 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 15 0 8 0; #X connect 15 1 7 0; #X connect 15 2 16 0; #X connect 15 3 16 1; #X connect 15 4 16 2; #X connect 16 0 15 0; chaos-0.2/standardmap.c0000644000076500007650000002443712076105251013601 0ustar hanshans/* standardmap Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_k_lo -1000 #define M_k_hi 1000 #define M_k 0 #define M_p 0 #define M_q 1 #define M_param_count 1 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "standardmap v0.0, by Michael McGonagle, from ??????, 2003"; t_class *standardmap_class; typedef struct standardmap_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double k, k_lo, k_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } standardmap_struct; static void calc(standardmap_struct *standardmap, double *vars) { double p_0, q_0; p_0 =vars[M_p]+standardmap -> k*sin(vars[M_q]+vars[M_p]); q_0 =vars[M_q]+vars[M_p]; vars[M_p] = p_0; vars[M_q] = q_0; } // end calc static void calculate(standardmap_struct *standardmap) { calc(standardmap, standardmap -> vars); outlet_float(standardmap -> outlets[M_q - 1], standardmap -> vars[M_q]); outlet_float(standardmap -> x_obj.ob_outlet, standardmap -> vars[M_p]); } // end calculate static void reset(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { standardmap -> vars[M_p] = (double) atom_getfloatarg(M_p, argc, argv); standardmap -> vars[M_q] = (double) atom_getfloatarg(M_q, argc, argv); } else { standardmap -> vars[M_p] = standardmap -> vars_init[M_p]; standardmap -> vars[M_q] = standardmap -> vars_init[M_q]; } // end if } // end reset static char *classify(standardmap_struct *standardmap) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((standardmap -> k - M_k_lo) * (1.0 / (M_k_hi - M_k_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(standardmap_struct *standardmap) { SETFLOAT(&standardmap -> search_out[0], standardmap -> lyap_exp); SETSYMBOL(&standardmap -> search_out[1], gensym(classify(standardmap))); SETFLOAT(&standardmap -> search_out[2], standardmap -> failure_ratio); SETFLOAT(&standardmap -> vars_out[M_p], standardmap -> vars[M_p]); SETFLOAT(&standardmap -> vars_out[M_q], standardmap -> vars[M_q]); SETFLOAT(&standardmap -> params_out[M_k], standardmap -> k); outlet_list(standardmap -> params_outlet, gensym("list"), M_param_count, standardmap -> params_out); outlet_list(standardmap -> vars_outlet, gensym("list"), M_var_count, standardmap -> vars_out); } static void show(standardmap_struct *standardmap) { make_results(standardmap); outlet_anything(standardmap -> search_outlet, gensym("show"), M_search_count, standardmap -> search_out); } static void param(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for standardmap fractal. Expecting 1 arguments."); return; } standardmap -> k = (double) atom_getfloatarg(0, argc, argv); } static void seed(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(standardmap_struct *standardmap, t_floatarg l, t_floatarg h, t_floatarg lim) { standardmap -> lyap_lo = l; standardmap -> lyap_hi = h; standardmap -> lyap_limit = (double) ((int) lim); } static void elyap(standardmap_struct *standardmap) { double results[M_var_count]; int i; if (lyapunov_full((void *) standardmap, (t_gotfn) calc, M_var_count, standardmap -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(standardmap_struct *standardmap) { if (standardmap -> k_lo < M_k_lo) { standardmap -> k_lo = M_k_lo; } if (standardmap -> k_lo > M_k_hi) { standardmap -> k_lo = M_k_hi; } if (standardmap -> k_hi < M_k_lo) { standardmap -> k_hi = M_k_lo; } if (standardmap -> k_hi > M_k_hi) { standardmap -> k_hi = M_k_hi; } } static void constrain(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges standardmap -> k_lo = M_k_lo; standardmap -> k_hi = M_k_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double k_spread = ((M_k_hi - M_k_lo) * percent) / 2; standardmap -> k_lo = standardmap -> k - k_spread; standardmap -> k_hi = standardmap -> k + k_spread; limiter(standardmap); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for standardmap constraints, requires 2 values, got %d", argc); return; } standardmap -> k_lo = atom_getfloat(arg++); standardmap -> k_hi = atom_getfloat(arg++); limiter(standardmap); } static void search(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = standardmap -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_k = standardmap -> k; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], standardmap -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: standardmap -> k = (drand48() * (standardmap -> k_hi - standardmap -> k_lo)) + standardmap -> k_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(standardmap, NULL, argc, vars); do { calc(standardmap, standardmap -> vars); } while(jump--); standardmap -> lyap_exp = lyapunov((void *) standardmap, (t_gotfn) calc, M_var_count, (double *) standardmap -> vars); if (isnan(standardmap -> lyap_exp)) { not_found = 1; } if (standardmap -> lyap_exp < standardmap -> lyap_lo || standardmap -> lyap_exp > standardmap -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(standardmap, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) standardmap -> lyap_limit); post("Try using wider constraints."); standardmap -> k = temp_k; outlet_anything(standardmap -> search_outlet, gensym("invalid"), 0, NULL); } else { standardmap -> failure_ratio = (standardmap -> lyap_limit - not_expired) / standardmap -> lyap_limit; make_results(standardmap); outlet_anything(standardmap -> search_outlet, gensym("search"), M_search_count, standardmap -> search_out); } } void *standardmap_new(t_symbol *s, int argc, t_atom *argv) { standardmap_struct *standardmap = (standardmap_struct *) pd_new(standardmap_class); if (standardmap != NULL) { outlet_new(&standardmap -> x_obj, &s_float); standardmap -> outlets[0] = outlet_new(&standardmap -> x_obj, &s_float); standardmap -> search_outlet = outlet_new(&standardmap -> x_obj, &s_list); standardmap -> vars_outlet = outlet_new(&standardmap -> x_obj, &s_list); standardmap -> params_outlet = outlet_new(&standardmap -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { standardmap -> vars_init[M_p] = standardmap -> vars[M_p] = (double) atom_getfloatarg(0, argc, argv); standardmap -> vars_init[M_q] = standardmap -> vars[M_q] = (double) atom_getfloatarg(1, argc, argv); standardmap -> k = (double) atom_getfloatarg(2, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for standardmap fractal. Expecting 3 arguments."); } standardmap -> vars_init[M_p] = 0.1; standardmap -> vars_init[M_q] = 0.1; standardmap -> k = 1; } constrain(standardmap, NULL, 0, NULL); lyap(standardmap, -1000000.0, 1000000.0, M_failure_limit); } return (void *)standardmap; } void standardmap_setup(void) { standardmap_class = class_new(gensym("standardmap"), (t_newmethod) standardmap_new, 0, sizeof(standardmap_struct), 0, A_GIMME, 0); class_addbang(standardmap_class, (t_method) calculate); class_addmethod(standardmap_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(standardmap_class, (t_method) show, gensym("show"), 0); class_addmethod(standardmap_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(standardmap_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(standardmap_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(standardmap_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(standardmap_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(standardmap_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/chaos.vcproj0000644000076500007650000000722212076105251013452 0ustar hanshans chaos-0.2/tent-help.pd0000644000076500007650000000016412076105251013353 0ustar hanshans#N canvas 149 395 450 300 10; #X obj 90 148 tent; #X text 71 41 1 variable; #X obj 248 24 examples/readme-fractals; chaos-0.2/fractal-tools.pd0000644000076500007650000000147312076105251014231 0ustar hanshans#N canvas 0 22 454 304 10; #X obj 27 252 outlet; #X msg 149 80 reset; #X msg 158 101 show; #X msg 167 122 param; #X msg 175 143 lyapunov -100 100 1000; #X msg 183 164 elyapunov; #X msg 192 186 constrain; #X msg 198 208 search; #X obj 27 23 inlet; #N canvas 0 22 454 304 iterator-tools 0; #X obj 17 264 outlet; #X text 17 19 This abstraction is intended to be used to iterate over the parameter space. Repeatedly performs the following:; #X text 46 65 1 'param' to set a centerpoint around which to search ; #X text 46 80 2 'constrain ' to limit the search area; #X text 46 95 3 'search' to find a fractal within the area; #X restore 48 53 pd iterator-tools; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 8 0 0 0; chaos-0.2/strange1.c0000644000076500007650000005356212076105251013030 0ustar hanshans/* strange1 Attractor PD External */ /* Copyright Michael McGonagle, from ???pbourke???, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a0_lo -2 #define M_a0_hi 2 #define M_a1_lo -2 #define M_a1_hi 2 #define M_a2_lo -2 #define M_a2_hi 2 #define M_a3_lo -2 #define M_a3_hi 2 #define M_a4_lo -2 #define M_a4_hi 2 #define M_a5_lo -2 #define M_a5_hi 2 #define M_b0_lo -2 #define M_b0_hi 2 #define M_b1_lo -2 #define M_b1_hi 2 #define M_b2_lo -2 #define M_b2_hi 2 #define M_b3_lo -2 #define M_b3_hi 2 #define M_b4_lo -2 #define M_b4_hi 2 #define M_b5_lo -2 #define M_b5_hi 2 #define M_a0 0 #define M_a1 1 #define M_a2 2 #define M_a3 3 #define M_a4 4 #define M_a5 5 #define M_b0 6 #define M_b1 7 #define M_b2 8 #define M_b3 9 #define M_b4 10 #define M_b5 11 #define M_x 0 #define M_y 1 #define M_param_count 12 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "strange1 v0.0, by Michael McGonagle, from ???pbourke???, 2003"; t_class *strange1_class; typedef struct strange1_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a0, a0_lo, a0_hi, a1, a1_lo, a1_hi, a2, a2_lo, a2_hi, a3, a3_lo, a3_hi, a4, a4_lo, a4_hi, a5, a5_lo, a5_hi, b0, b0_lo, b0_hi, b1, b1_lo, b1_hi, b2, b2_lo, b2_hi, b3, b3_lo, b3_hi, b4, b4_lo, b4_hi, b5, b5_lo, b5_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } strange1_struct; static void calc(strange1_struct *strange1, double *vars) { double x_0, y_0; x_0 =strange1 -> a0+strange1 -> a1*vars[M_x]+strange1 -> a2*vars[M_x]*vars[M_x]+strange1 -> a3*vars[M_x]*vars[M_y]+strange1 -> a4*vars[M_y]+strange1 -> a5*vars[M_y]*vars[M_y]; y_0 =strange1 -> b0+strange1 -> b1*vars[M_x]+strange1 -> b2*vars[M_x]*vars[M_x]+strange1 -> b3*vars[M_x]*vars[M_y]+strange1 -> b4*vars[M_y]+strange1 -> b5*vars[M_y]*vars[M_y]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(strange1_struct *strange1) { calc(strange1, strange1 -> vars); outlet_float(strange1 -> outlets[M_y - 1], strange1 -> vars[M_y]); outlet_float(strange1 -> x_obj.ob_outlet, strange1 -> vars[M_x]); } // end calculate static void reset(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { strange1 -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); strange1 -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { strange1 -> vars[M_x] = strange1 -> vars_init[M_x]; strange1 -> vars[M_y] = strange1 -> vars_init[M_y]; } // end if } // end reset static char *classify(strange1_struct *strange1) { static char buff[13]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((strange1 -> a0 - M_a0_lo) * (1.0 / (M_a0_hi - M_a0_lo))) * 26)]; buff[1] = c[(int) (((strange1 -> a1 - M_a1_lo) * (1.0 / (M_a1_hi - M_a1_lo))) * 26)]; buff[2] = c[(int) (((strange1 -> a2 - M_a2_lo) * (1.0 / (M_a2_hi - M_a2_lo))) * 26)]; buff[3] = c[(int) (((strange1 -> a3 - M_a3_lo) * (1.0 / (M_a3_hi - M_a3_lo))) * 26)]; buff[4] = c[(int) (((strange1 -> a4 - M_a4_lo) * (1.0 / (M_a4_hi - M_a4_lo))) * 26)]; buff[5] = c[(int) (((strange1 -> a5 - M_a5_lo) * (1.0 / (M_a5_hi - M_a5_lo))) * 26)]; buff[6] = c[(int) (((strange1 -> b0 - M_b0_lo) * (1.0 / (M_b0_hi - M_b0_lo))) * 26)]; buff[7] = c[(int) (((strange1 -> b1 - M_b1_lo) * (1.0 / (M_b1_hi - M_b1_lo))) * 26)]; buff[8] = c[(int) (((strange1 -> b2 - M_b2_lo) * (1.0 / (M_b2_hi - M_b2_lo))) * 26)]; buff[9] = c[(int) (((strange1 -> b3 - M_b3_lo) * (1.0 / (M_b3_hi - M_b3_lo))) * 26)]; buff[10] = c[(int) (((strange1 -> b4 - M_b4_lo) * (1.0 / (M_b4_hi - M_b4_lo))) * 26)]; buff[11] = c[(int) (((strange1 -> b5 - M_b5_lo) * (1.0 / (M_b5_hi - M_b5_lo))) * 26)]; buff[12] = '\0'; return buff; } static void make_results(strange1_struct *strange1) { SETFLOAT(&strange1 -> search_out[0], strange1 -> lyap_exp); SETSYMBOL(&strange1 -> search_out[1], gensym(classify(strange1))); SETFLOAT(&strange1 -> search_out[2], strange1 -> failure_ratio); SETFLOAT(&strange1 -> vars_out[M_x], strange1 -> vars[M_x]); SETFLOAT(&strange1 -> vars_out[M_y], strange1 -> vars[M_y]); SETFLOAT(&strange1 -> params_out[M_a0], strange1 -> a0); SETFLOAT(&strange1 -> params_out[M_a1], strange1 -> a1); SETFLOAT(&strange1 -> params_out[M_a2], strange1 -> a2); SETFLOAT(&strange1 -> params_out[M_a3], strange1 -> a3); SETFLOAT(&strange1 -> params_out[M_a4], strange1 -> a4); SETFLOAT(&strange1 -> params_out[M_a5], strange1 -> a5); SETFLOAT(&strange1 -> params_out[M_b0], strange1 -> b0); SETFLOAT(&strange1 -> params_out[M_b1], strange1 -> b1); SETFLOAT(&strange1 -> params_out[M_b2], strange1 -> b2); SETFLOAT(&strange1 -> params_out[M_b3], strange1 -> b3); SETFLOAT(&strange1 -> params_out[M_b4], strange1 -> b4); SETFLOAT(&strange1 -> params_out[M_b5], strange1 -> b5); outlet_list(strange1 -> params_outlet, gensym("list"), M_param_count, strange1 -> params_out); outlet_list(strange1 -> vars_outlet, gensym("list"), M_var_count, strange1 -> vars_out); } static void show(strange1_struct *strange1) { make_results(strange1); outlet_anything(strange1 -> search_outlet, gensym("show"), M_search_count, strange1 -> search_out); } static void param(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) { if (argc != 12) { post("Incorrect number of arguments for strange1 fractal. Expecting 12 arguments."); return; } strange1 -> a0 = (double) atom_getfloatarg(0, argc, argv); strange1 -> a1 = (double) atom_getfloatarg(1, argc, argv); strange1 -> a2 = (double) atom_getfloatarg(2, argc, argv); strange1 -> a3 = (double) atom_getfloatarg(3, argc, argv); strange1 -> a4 = (double) atom_getfloatarg(4, argc, argv); strange1 -> a5 = (double) atom_getfloatarg(5, argc, argv); strange1 -> b0 = (double) atom_getfloatarg(6, argc, argv); strange1 -> b1 = (double) atom_getfloatarg(7, argc, argv); strange1 -> b2 = (double) atom_getfloatarg(8, argc, argv); strange1 -> b3 = (double) atom_getfloatarg(9, argc, argv); strange1 -> b4 = (double) atom_getfloatarg(10, argc, argv); strange1 -> b5 = (double) atom_getfloatarg(11, argc, argv); } static void seed(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(strange1_struct *strange1, t_floatarg l, t_floatarg h, t_floatarg lim) { strange1 -> lyap_lo = l; strange1 -> lyap_hi = h; strange1 -> lyap_limit = (double) ((int) lim); } static void elyap(strange1_struct *strange1) { double results[M_var_count]; int i; if (lyapunov_full((void *) strange1, (t_gotfn) calc, M_var_count, strange1 -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(strange1_struct *strange1) { if (strange1 -> a0_lo < M_a0_lo) { strange1 -> a0_lo = M_a0_lo; } if (strange1 -> a0_lo > M_a0_hi) { strange1 -> a0_lo = M_a0_hi; } if (strange1 -> a0_hi < M_a0_lo) { strange1 -> a0_hi = M_a0_lo; } if (strange1 -> a0_hi > M_a0_hi) { strange1 -> a0_hi = M_a0_hi; } if (strange1 -> a1_lo < M_a1_lo) { strange1 -> a1_lo = M_a1_lo; } if (strange1 -> a1_lo > M_a1_hi) { strange1 -> a1_lo = M_a1_hi; } if (strange1 -> a1_hi < M_a1_lo) { strange1 -> a1_hi = M_a1_lo; } if (strange1 -> a1_hi > M_a1_hi) { strange1 -> a1_hi = M_a1_hi; } if (strange1 -> a2_lo < M_a2_lo) { strange1 -> a2_lo = M_a2_lo; } if (strange1 -> a2_lo > M_a2_hi) { strange1 -> a2_lo = M_a2_hi; } if (strange1 -> a2_hi < M_a2_lo) { strange1 -> a2_hi = M_a2_lo; } if (strange1 -> a2_hi > M_a2_hi) { strange1 -> a2_hi = M_a2_hi; } if (strange1 -> a3_lo < M_a3_lo) { strange1 -> a3_lo = M_a3_lo; } if (strange1 -> a3_lo > M_a3_hi) { strange1 -> a3_lo = M_a3_hi; } if (strange1 -> a3_hi < M_a3_lo) { strange1 -> a3_hi = M_a3_lo; } if (strange1 -> a3_hi > M_a3_hi) { strange1 -> a3_hi = M_a3_hi; } if (strange1 -> a4_lo < M_a4_lo) { strange1 -> a4_lo = M_a4_lo; } if (strange1 -> a4_lo > M_a4_hi) { strange1 -> a4_lo = M_a4_hi; } if (strange1 -> a4_hi < M_a4_lo) { strange1 -> a4_hi = M_a4_lo; } if (strange1 -> a4_hi > M_a4_hi) { strange1 -> a4_hi = M_a4_hi; } if (strange1 -> a5_lo < M_a5_lo) { strange1 -> a5_lo = M_a5_lo; } if (strange1 -> a5_lo > M_a5_hi) { strange1 -> a5_lo = M_a5_hi; } if (strange1 -> a5_hi < M_a5_lo) { strange1 -> a5_hi = M_a5_lo; } if (strange1 -> a5_hi > M_a5_hi) { strange1 -> a5_hi = M_a5_hi; } if (strange1 -> b0_lo < M_b0_lo) { strange1 -> b0_lo = M_b0_lo; } if (strange1 -> b0_lo > M_b0_hi) { strange1 -> b0_lo = M_b0_hi; } if (strange1 -> b0_hi < M_b0_lo) { strange1 -> b0_hi = M_b0_lo; } if (strange1 -> b0_hi > M_b0_hi) { strange1 -> b0_hi = M_b0_hi; } if (strange1 -> b1_lo < M_b1_lo) { strange1 -> b1_lo = M_b1_lo; } if (strange1 -> b1_lo > M_b1_hi) { strange1 -> b1_lo = M_b1_hi; } if (strange1 -> b1_hi < M_b1_lo) { strange1 -> b1_hi = M_b1_lo; } if (strange1 -> b1_hi > M_b1_hi) { strange1 -> b1_hi = M_b1_hi; } if (strange1 -> b2_lo < M_b2_lo) { strange1 -> b2_lo = M_b2_lo; } if (strange1 -> b2_lo > M_b2_hi) { strange1 -> b2_lo = M_b2_hi; } if (strange1 -> b2_hi < M_b2_lo) { strange1 -> b2_hi = M_b2_lo; } if (strange1 -> b2_hi > M_b2_hi) { strange1 -> b2_hi = M_b2_hi; } if (strange1 -> b3_lo < M_b3_lo) { strange1 -> b3_lo = M_b3_lo; } if (strange1 -> b3_lo > M_b3_hi) { strange1 -> b3_lo = M_b3_hi; } if (strange1 -> b3_hi < M_b3_lo) { strange1 -> b3_hi = M_b3_lo; } if (strange1 -> b3_hi > M_b3_hi) { strange1 -> b3_hi = M_b3_hi; } if (strange1 -> b4_lo < M_b4_lo) { strange1 -> b4_lo = M_b4_lo; } if (strange1 -> b4_lo > M_b4_hi) { strange1 -> b4_lo = M_b4_hi; } if (strange1 -> b4_hi < M_b4_lo) { strange1 -> b4_hi = M_b4_lo; } if (strange1 -> b4_hi > M_b4_hi) { strange1 -> b4_hi = M_b4_hi; } if (strange1 -> b5_lo < M_b5_lo) { strange1 -> b5_lo = M_b5_lo; } if (strange1 -> b5_lo > M_b5_hi) { strange1 -> b5_lo = M_b5_hi; } if (strange1 -> b5_hi < M_b5_lo) { strange1 -> b5_hi = M_b5_lo; } if (strange1 -> b5_hi > M_b5_hi) { strange1 -> b5_hi = M_b5_hi; } } static void constrain(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges strange1 -> a0_lo = M_a0_lo; strange1 -> a0_hi = M_a0_hi; strange1 -> a1_lo = M_a1_lo; strange1 -> a1_hi = M_a1_hi; strange1 -> a2_lo = M_a2_lo; strange1 -> a2_hi = M_a2_hi; strange1 -> a3_lo = M_a3_lo; strange1 -> a3_hi = M_a3_hi; strange1 -> a4_lo = M_a4_lo; strange1 -> a4_hi = M_a4_hi; strange1 -> a5_lo = M_a5_lo; strange1 -> a5_hi = M_a5_hi; strange1 -> b0_lo = M_b0_lo; strange1 -> b0_hi = M_b0_hi; strange1 -> b1_lo = M_b1_lo; strange1 -> b1_hi = M_b1_hi; strange1 -> b2_lo = M_b2_lo; strange1 -> b2_hi = M_b2_hi; strange1 -> b3_lo = M_b3_lo; strange1 -> b3_hi = M_b3_hi; strange1 -> b4_lo = M_b4_lo; strange1 -> b4_hi = M_b4_hi; strange1 -> b5_lo = M_b5_lo; strange1 -> b5_hi = M_b5_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a0_spread = ((M_a0_hi - M_a0_lo) * percent) / 2; double a1_spread = ((M_a1_hi - M_a1_lo) * percent) / 2; double a2_spread = ((M_a2_hi - M_a2_lo) * percent) / 2; double a3_spread = ((M_a3_hi - M_a3_lo) * percent) / 2; double a4_spread = ((M_a4_hi - M_a4_lo) * percent) / 2; double a5_spread = ((M_a5_hi - M_a5_lo) * percent) / 2; double b0_spread = ((M_b0_hi - M_b0_lo) * percent) / 2; double b1_spread = ((M_b1_hi - M_b1_lo) * percent) / 2; double b2_spread = ((M_b2_hi - M_b2_lo) * percent) / 2; double b3_spread = ((M_b3_hi - M_b3_lo) * percent) / 2; double b4_spread = ((M_b4_hi - M_b4_lo) * percent) / 2; double b5_spread = ((M_b5_hi - M_b5_lo) * percent) / 2; strange1 -> a0_lo = strange1 -> a0 - a0_spread; strange1 -> a0_hi = strange1 -> a0 + a0_spread; strange1 -> a1_lo = strange1 -> a1 - a1_spread; strange1 -> a1_hi = strange1 -> a1 + a1_spread; strange1 -> a2_lo = strange1 -> a2 - a2_spread; strange1 -> a2_hi = strange1 -> a2 + a2_spread; strange1 -> a3_lo = strange1 -> a3 - a3_spread; strange1 -> a3_hi = strange1 -> a3 + a3_spread; strange1 -> a4_lo = strange1 -> a4 - a4_spread; strange1 -> a4_hi = strange1 -> a4 + a4_spread; strange1 -> a5_lo = strange1 -> a5 - a5_spread; strange1 -> a5_hi = strange1 -> a5 + a5_spread; strange1 -> b0_lo = strange1 -> b0 - b0_spread; strange1 -> b0_hi = strange1 -> b0 + b0_spread; strange1 -> b1_lo = strange1 -> b1 - b1_spread; strange1 -> b1_hi = strange1 -> b1 + b1_spread; strange1 -> b2_lo = strange1 -> b2 - b2_spread; strange1 -> b2_hi = strange1 -> b2 + b2_spread; strange1 -> b3_lo = strange1 -> b3 - b3_spread; strange1 -> b3_hi = strange1 -> b3 + b3_spread; strange1 -> b4_lo = strange1 -> b4 - b4_spread; strange1 -> b4_hi = strange1 -> b4 + b4_spread; strange1 -> b5_lo = strange1 -> b5 - b5_spread; strange1 -> b5_hi = strange1 -> b5 + b5_spread; limiter(strange1); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for strange1 constraints, requires 24 values, got %d", argc); return; } strange1 -> a0_lo = atom_getfloat(arg++); strange1 -> a0_hi = atom_getfloat(arg++); strange1 -> a1_lo = atom_getfloat(arg++); strange1 -> a1_hi = atom_getfloat(arg++); strange1 -> a2_lo = atom_getfloat(arg++); strange1 -> a2_hi = atom_getfloat(arg++); strange1 -> a3_lo = atom_getfloat(arg++); strange1 -> a3_hi = atom_getfloat(arg++); strange1 -> a4_lo = atom_getfloat(arg++); strange1 -> a4_hi = atom_getfloat(arg++); strange1 -> a5_lo = atom_getfloat(arg++); strange1 -> a5_hi = atom_getfloat(arg++); strange1 -> b0_lo = atom_getfloat(arg++); strange1 -> b0_hi = atom_getfloat(arg++); strange1 -> b1_lo = atom_getfloat(arg++); strange1 -> b1_hi = atom_getfloat(arg++); strange1 -> b2_lo = atom_getfloat(arg++); strange1 -> b2_hi = atom_getfloat(arg++); strange1 -> b3_lo = atom_getfloat(arg++); strange1 -> b3_hi = atom_getfloat(arg++); strange1 -> b4_lo = atom_getfloat(arg++); strange1 -> b4_hi = atom_getfloat(arg++); strange1 -> b5_lo = atom_getfloat(arg++); strange1 -> b5_hi = atom_getfloat(arg++); limiter(strange1); } static void search(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = strange1 -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a0 = strange1 -> a0; double temp_a1 = strange1 -> a1; double temp_a2 = strange1 -> a2; double temp_a3 = strange1 -> a3; double temp_a4 = strange1 -> a4; double temp_a5 = strange1 -> a5; double temp_b0 = strange1 -> b0; double temp_b1 = strange1 -> b1; double temp_b2 = strange1 -> b2; double temp_b3 = strange1 -> b3; double temp_b4 = strange1 -> b4; double temp_b5 = strange1 -> b5; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], strange1 -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: strange1 -> a0 = (drand48() * (strange1 -> a0_hi - strange1 -> a0_lo)) + strange1 -> a0_lo; strange1 -> a1 = (drand48() * (strange1 -> a1_hi - strange1 -> a1_lo)) + strange1 -> a1_lo; strange1 -> a2 = (drand48() * (strange1 -> a2_hi - strange1 -> a2_lo)) + strange1 -> a2_lo; strange1 -> a3 = (drand48() * (strange1 -> a3_hi - strange1 -> a3_lo)) + strange1 -> a3_lo; strange1 -> a4 = (drand48() * (strange1 -> a4_hi - strange1 -> a4_lo)) + strange1 -> a4_lo; strange1 -> a5 = (drand48() * (strange1 -> a5_hi - strange1 -> a5_lo)) + strange1 -> a5_lo; strange1 -> b0 = (drand48() * (strange1 -> b0_hi - strange1 -> b0_lo)) + strange1 -> b0_lo; strange1 -> b1 = (drand48() * (strange1 -> b1_hi - strange1 -> b1_lo)) + strange1 -> b1_lo; strange1 -> b2 = (drand48() * (strange1 -> b2_hi - strange1 -> b2_lo)) + strange1 -> b2_lo; strange1 -> b3 = (drand48() * (strange1 -> b3_hi - strange1 -> b3_lo)) + strange1 -> b3_lo; strange1 -> b4 = (drand48() * (strange1 -> b4_hi - strange1 -> b4_lo)) + strange1 -> b4_lo; strange1 -> b5 = (drand48() * (strange1 -> b5_hi - strange1 -> b5_lo)) + strange1 -> b5_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(strange1, NULL, argc, vars); do { calc(strange1, strange1 -> vars); } while(jump--); strange1 -> lyap_exp = lyapunov((void *) strange1, (t_gotfn) calc, M_var_count, (double *) strange1 -> vars); if (isnan(strange1 -> lyap_exp)) { not_found = 1; } if (strange1 -> lyap_exp < strange1 -> lyap_lo || strange1 -> lyap_exp > strange1 -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(strange1, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) strange1 -> lyap_limit); post("Try using wider constraints."); strange1 -> a0 = temp_a0; strange1 -> a1 = temp_a1; strange1 -> a2 = temp_a2; strange1 -> a3 = temp_a3; strange1 -> a4 = temp_a4; strange1 -> a5 = temp_a5; strange1 -> b0 = temp_b0; strange1 -> b1 = temp_b1; strange1 -> b2 = temp_b2; strange1 -> b3 = temp_b3; strange1 -> b4 = temp_b4; strange1 -> b5 = temp_b5; outlet_anything(strange1 -> search_outlet, gensym("invalid"), 0, NULL); } else { strange1 -> failure_ratio = (strange1 -> lyap_limit - not_expired) / strange1 -> lyap_limit; make_results(strange1); outlet_anything(strange1 -> search_outlet, gensym("search"), M_search_count, strange1 -> search_out); } } void *strange1_new(t_symbol *s, int argc, t_atom *argv) { strange1_struct *strange1 = (strange1_struct *) pd_new(strange1_class); if (strange1 != NULL) { outlet_new(&strange1 -> x_obj, &s_float); strange1 -> outlets[0] = outlet_new(&strange1 -> x_obj, &s_float); strange1 -> search_outlet = outlet_new(&strange1 -> x_obj, &s_list); strange1 -> vars_outlet = outlet_new(&strange1 -> x_obj, &s_list); strange1 -> params_outlet = outlet_new(&strange1 -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { strange1 -> vars_init[M_x] = strange1 -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); strange1 -> vars_init[M_y] = strange1 -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); strange1 -> a0 = (double) atom_getfloatarg(2, argc, argv); strange1 -> a1 = (double) atom_getfloatarg(3, argc, argv); strange1 -> a2 = (double) atom_getfloatarg(4, argc, argv); strange1 -> a3 = (double) atom_getfloatarg(5, argc, argv); strange1 -> a4 = (double) atom_getfloatarg(6, argc, argv); strange1 -> a5 = (double) atom_getfloatarg(7, argc, argv); strange1 -> b0 = (double) atom_getfloatarg(8, argc, argv); strange1 -> b1 = (double) atom_getfloatarg(9, argc, argv); strange1 -> b2 = (double) atom_getfloatarg(10, argc, argv); strange1 -> b3 = (double) atom_getfloatarg(11, argc, argv); strange1 -> b4 = (double) atom_getfloatarg(12, argc, argv); strange1 -> b5 = (double) atom_getfloatarg(13, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for strange1 fractal. Expecting 14 arguments."); } strange1 -> vars_init[M_x] = 0; strange1 -> vars_init[M_y] = 0; strange1 -> a0 = 1; strange1 -> a1 = 1; strange1 -> a2 = 1; strange1 -> a3 = 1; strange1 -> a4 = 1; strange1 -> a5 = 1; strange1 -> b0 = 1; strange1 -> b1 = 1; strange1 -> b2 = 1; strange1 -> b3 = 1; strange1 -> b4 = 1; strange1 -> b5 = 1; } constrain(strange1, NULL, 0, NULL); lyap(strange1, -1000000.0, 1000000.0, M_failure_limit); } return (void *)strange1; } void strange1_setup(void) { strange1_class = class_new(gensym("strange1"), (t_newmethod) strange1_new, 0, sizeof(strange1_struct), 0, A_GIMME, 0); class_addbang(strange1_class, (t_method) calculate); class_addmethod(strange1_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(strange1_class, (t_method) show, gensym("show"), 0); class_addmethod(strange1_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(strange1_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(strange1_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(strange1_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(strange1_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(strange1_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/gingerbreadman-help.pd0000644000076500007650000000175312076105251015353 0ustar hanshans#N canvas 615 23 577 480 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 32 8 -262144 -1 -1 0 1; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 131 348 10 0 0 0 Y - -; #X floatatom 44 348 10 0 0 0 X - -; #X text 17 48 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 113 272 show; #X msg 76 156 reset; #X text 120 156 Reset to initial state from creation arguments; #X text 19 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X text 20 18 Gingerbreadman Attractor; #X obj 44 316 gingerbreadman; #X text 91 193 This fractal equation does not have any parameters \, and thus does not allow the messages 'param' or any of the searching functions.; #X msg 96 235 param; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 13 0; #X connect 6 0 13 0; #X connect 8 0 13 0; #X connect 9 0 13 0; #X connect 13 0 3 0; #X connect 13 1 2 0; #X connect 15 0 13 0; chaos-0.2/chaos-meta.pd0000644000076500007650000000040512076105251013472 0ustar hanshans#N canvas 15 49 200 200 10; #N canvas 25 49 420 300 META 1; #X text 13 41 NAME chaos; #X text 10 25 AUTHOR Ben Bogart \, Michael McGonagle ; #X text 10 10 VERSION 0.2; #X text 10 100 LICENSE GPLv2+; #X restore 10 10 pd META; chaos-0.2/base3.c0000644000076500007650000002336312076105251012275 0ustar hanshans/* base3 Attractor PD External */ /* Copyright Michael McGonagle, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo 0 #define M_a_hi 3 #define M_b_lo 0.001 #define M_b_hi 2.6667 #define M_a 0 #define M_b 1 #define M_x 0 #define M_param_count 2 #define M_var_count 1 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "base3 v0.0, by Michael McGonagle, 2003"; t_class *base3_class; typedef struct base3_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; } base3_struct; static void calc(base3_struct *base3, double *vars) { double x_0; x_0 =base3 -> a*sin(pow(vars[M_x],base3 -> b)); vars[M_x] = x_0; } // end calc static void calculate(base3_struct *base3) { calc(base3, base3 -> vars); outlet_float(base3 -> x_obj.ob_outlet, base3 -> vars[M_x]); } // end calculate static void reset(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { base3 -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); } else { base3 -> vars[M_x] = base3 -> vars_init[M_x]; } // end if } // end reset static char *classify(base3_struct *base3) { static char buff[3]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((base3 -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((base3 -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = '\0'; return buff; } static void make_results(base3_struct *base3) { SETFLOAT(&base3 -> search_out[0], base3 -> lyap_exp); SETSYMBOL(&base3 -> search_out[1], gensym(classify(base3))); SETFLOAT(&base3 -> search_out[2], base3 -> failure_ratio); SETFLOAT(&base3 -> vars_out[M_x], base3 -> vars[M_x]); SETFLOAT(&base3 -> params_out[M_a], base3 -> a); SETFLOAT(&base3 -> params_out[M_b], base3 -> b); outlet_list(base3 -> params_outlet, gensym("list"), M_param_count, base3 -> params_out); outlet_list(base3 -> vars_outlet, gensym("list"), M_var_count, base3 -> vars_out); } static void show(base3_struct *base3) { make_results(base3); outlet_anything(base3 -> search_outlet, gensym("show"), M_search_count, base3 -> search_out); } static void param(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) { if (argc != 2) { post("Incorrect number of arguments for base3 fractal. Expecting 2 arguments."); return; } base3 -> a = (double) atom_getfloatarg(0, argc, argv); base3 -> b = (double) atom_getfloatarg(1, argc, argv); } static void seed(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(base3_struct *base3, t_floatarg l, t_floatarg h, t_floatarg lim) { base3 -> lyap_lo = l; base3 -> lyap_hi = h; base3 -> lyap_limit = (double) ((int) lim); } static void elyap(base3_struct *base3) { double results[M_var_count]; int i; if (lyapunov_full((void *) base3, (t_gotfn) calc, M_var_count, base3 -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(base3_struct *base3) { if (base3 -> a_lo < M_a_lo) { base3 -> a_lo = M_a_lo; } if (base3 -> a_lo > M_a_hi) { base3 -> a_lo = M_a_hi; } if (base3 -> a_hi < M_a_lo) { base3 -> a_hi = M_a_lo; } if (base3 -> a_hi > M_a_hi) { base3 -> a_hi = M_a_hi; } if (base3 -> b_lo < M_b_lo) { base3 -> b_lo = M_b_lo; } if (base3 -> b_lo > M_b_hi) { base3 -> b_lo = M_b_hi; } if (base3 -> b_hi < M_b_lo) { base3 -> b_hi = M_b_lo; } if (base3 -> b_hi > M_b_hi) { base3 -> b_hi = M_b_hi; } } static void constrain(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges base3 -> a_lo = M_a_lo; base3 -> a_hi = M_a_hi; base3 -> b_lo = M_b_lo; base3 -> b_hi = M_b_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; base3 -> a_lo = base3 -> a - a_spread; base3 -> a_hi = base3 -> a + a_spread; base3 -> b_lo = base3 -> b - b_spread; base3 -> b_hi = base3 -> b + b_spread; limiter(base3); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for base3 constraints, requires 4 values, got %d", argc); return; } base3 -> a_lo = atom_getfloat(arg++); base3 -> a_hi = atom_getfloat(arg++); base3 -> b_lo = atom_getfloat(arg++); base3 -> b_hi = atom_getfloat(arg++); limiter(base3); } static void search(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = base3 -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = base3 -> a; double temp_b = base3 -> b; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], base3 -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: base3 -> a = (drand48() * (base3 -> a_hi - base3 -> a_lo)) + base3 -> a_lo; base3 -> b = (drand48() * (base3 -> b_hi - base3 -> b_lo)) + base3 -> b_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(base3, NULL, argc, vars); do { calc(base3, base3 -> vars); } while(jump--); base3 -> lyap_exp = lyapunov((void *) base3, (t_gotfn) calc, M_var_count, (double *) base3 -> vars); if (isnan(base3 -> lyap_exp)) { not_found = 1; } if (base3 -> lyap_exp < base3 -> lyap_lo || base3 -> lyap_exp > base3 -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(base3, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) base3 -> lyap_limit); post("Try using wider constraints."); base3 -> a = temp_a; base3 -> b = temp_b; outlet_anything(base3 -> search_outlet, gensym("invalid"), 0, NULL); } else { base3 -> failure_ratio = (base3 -> lyap_limit - not_expired) / base3 -> lyap_limit; make_results(base3); outlet_anything(base3 -> search_outlet, gensym("search"), M_search_count, base3 -> search_out); } } void *base3_new(t_symbol *s, int argc, t_atom *argv) { base3_struct *base3 = (base3_struct *) pd_new(base3_class); if (base3 != NULL) { outlet_new(&base3 -> x_obj, &s_float); base3 -> search_outlet = outlet_new(&base3 -> x_obj, &s_list); base3 -> vars_outlet = outlet_new(&base3 -> x_obj, &s_list); base3 -> params_outlet = outlet_new(&base3 -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { base3 -> vars_init[M_x] = base3 -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); base3 -> a = (double) atom_getfloatarg(1, argc, argv); base3 -> b = (double) atom_getfloatarg(2, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for base3 fractal. Expecting 3 arguments."); } base3 -> vars_init[M_x] = 0.1; base3 -> a = 1; base3 -> b = 1; } constrain(base3, NULL, 0, NULL); lyap(base3, -1000000.0, 1000000.0, M_failure_limit); } return (void *)base3; } void base3_setup(void) { base3_class = class_new(gensym("base3"), (t_newmethod) base3_new, 0, sizeof(base3_struct), 0, A_GIMME, 0); class_addbang(base3_class, (t_method) calculate); class_addmethod(base3_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(base3_class, (t_method) show, gensym("show"), 0); class_addmethod(base3_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(base3_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(base3_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(base3_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(base3_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(base3_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/README.txt0000644000076500007650000000454712076105251012635 0ustar hanshansThis is the readme for "Chaos PD Externals" a set of objects for PD which calculate various "Chaotic Attractors"; including: lorenz, rossler, henon, ikeda, attract1, base, base3, dejong, gingerbreadman, hopalong, latoocarfian, latoomutalpha, latoomutbeta, latoomutgamma, logistic, lotka_volterra, martin, mlogistic, pickover, popcorn, quadruptwo, standardmap, strange1, tent, three_d, threeply, tinkerbell and unity. If you have any questions/comments you can reach the co-authors at: Ben Bogart ben@ekran.org Michael McGonagle mjmogo@comcast.net Please Note: These programs are Copyright Ben Bogart 2002, Ben Bogart and Michael McGonagle 2003. These programs are distributed under the terms of the GNU General Public License Chaos PD Externals are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Chaos PD Externals are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the Chaos PD Externals; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA USAGE: The package includes 1, 2 and 3 dimentional attractors. There are outlets for each dimention, starting from the left, followed by three outlets for attractor data (see the help patches for details). The scale of the values vary between the different attractors. To run pd with the chaos externals use: pd -lib chaos The basic object methods are as follows: bang: Calculate one iteration of the attractor. reset: Reset to initial conditions defined by the two or three arguments. [reset a b c] will reset the xyz values to abc respectively. param: Modify the paramaters of the equation, the number of args depend on the attractor. (Be careful with the parameters, an attractor will go from stable to infinity in very few interations.) See the example patches for other methods (parameter searching etc.) The next release will include a script to generate your own attractor object for chaos from the attractor attributes. Have Fun. chaos-0.2/tent.c0000644000076500007650000002135312076105251012247 0ustar hanshans/* tent Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_r_lo -1000 #define M_r_hi 1000 #define M_r 0 #define M_x 0 #define M_param_count 1 #define M_var_count 1 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "tent v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *tent_class; typedef struct tent_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double r, r_lo, r_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; } tent_struct; static void calc(tent_struct *tent, double *vars) { double x_0; x_0 =(vars[M_x]<=0.5)?2*tent -> r*vars[M_x]:2*tent -> r*(1.0-vars[M_x]); vars[M_x] = x_0; } // end calc static void calculate(tent_struct *tent) { calc(tent, tent -> vars); outlet_float(tent -> x_obj.ob_outlet, tent -> vars[M_x]); } // end calculate static void reset(tent_struct *tent, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { tent -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); } else { tent -> vars[M_x] = tent -> vars_init[M_x]; } // end if } // end reset static char *classify(tent_struct *tent) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((tent -> r - M_r_lo) * (1.0 / (M_r_hi - M_r_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(tent_struct *tent) { SETFLOAT(&tent -> search_out[0], tent -> lyap_exp); SETSYMBOL(&tent -> search_out[1], gensym(classify(tent))); SETFLOAT(&tent -> search_out[2], tent -> failure_ratio); SETFLOAT(&tent -> vars_out[M_x], tent -> vars[M_x]); SETFLOAT(&tent -> params_out[M_r], tent -> r); outlet_list(tent -> params_outlet, gensym("list"), M_param_count, tent -> params_out); outlet_list(tent -> vars_outlet, gensym("list"), M_var_count, tent -> vars_out); } static void show(tent_struct *tent) { make_results(tent); outlet_anything(tent -> search_outlet, gensym("show"), M_search_count, tent -> search_out); } static void param(tent_struct *tent, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for tent fractal. Expecting 1 arguments."); return; } tent -> r = (double) atom_getfloatarg(0, argc, argv); } static void seed(tent_struct *tent, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(tent_struct *tent, t_floatarg l, t_floatarg h, t_floatarg lim) { tent -> lyap_lo = l; tent -> lyap_hi = h; tent -> lyap_limit = (double) ((int) lim); } static void elyap(tent_struct *tent) { double results[M_var_count]; int i; if (lyapunov_full((void *) tent, (t_gotfn) calc, M_var_count, tent -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(tent_struct *tent) { if (tent -> r_lo < M_r_lo) { tent -> r_lo = M_r_lo; } if (tent -> r_lo > M_r_hi) { tent -> r_lo = M_r_hi; } if (tent -> r_hi < M_r_lo) { tent -> r_hi = M_r_lo; } if (tent -> r_hi > M_r_hi) { tent -> r_hi = M_r_hi; } } static void constrain(tent_struct *tent, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges tent -> r_lo = M_r_lo; tent -> r_hi = M_r_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double r_spread = ((M_r_hi - M_r_lo) * percent) / 2; tent -> r_lo = tent -> r - r_spread; tent -> r_hi = tent -> r + r_spread; limiter(tent); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for tent constraints, requires 2 values, got %d", argc); return; } tent -> r_lo = atom_getfloat(arg++); tent -> r_hi = atom_getfloat(arg++); limiter(tent); } static void search(tent_struct *tent, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = tent -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_r = tent -> r; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], tent -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: tent -> r = (drand48() * (tent -> r_hi - tent -> r_lo)) + tent -> r_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(tent, NULL, argc, vars); do { calc(tent, tent -> vars); } while(jump--); tent -> lyap_exp = lyapunov((void *) tent, (t_gotfn) calc, M_var_count, (double *) tent -> vars); if (isnan(tent -> lyap_exp)) { not_found = 1; } if (tent -> lyap_exp < tent -> lyap_lo || tent -> lyap_exp > tent -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(tent, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) tent -> lyap_limit); post("Try using wider constraints."); tent -> r = temp_r; outlet_anything(tent -> search_outlet, gensym("invalid"), 0, NULL); } else { tent -> failure_ratio = (tent -> lyap_limit - not_expired) / tent -> lyap_limit; make_results(tent); outlet_anything(tent -> search_outlet, gensym("search"), M_search_count, tent -> search_out); } } void *tent_new(t_symbol *s, int argc, t_atom *argv) { tent_struct *tent = (tent_struct *) pd_new(tent_class); if (tent != NULL) { outlet_new(&tent -> x_obj, &s_float); tent -> search_outlet = outlet_new(&tent -> x_obj, &s_list); tent -> vars_outlet = outlet_new(&tent -> x_obj, &s_list); tent -> params_outlet = outlet_new(&tent -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { tent -> vars_init[M_x] = tent -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); tent -> r = (double) atom_getfloatarg(1, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for tent fractal. Expecting 2 arguments."); } tent -> vars_init[M_x] = 0.1; tent -> r = 1; } constrain(tent, NULL, 0, NULL); lyap(tent, -1000000.0, 1000000.0, M_failure_limit); } return (void *)tent; } void tent_setup(void) { tent_class = class_new(gensym("tent"), (t_newmethod) tent_new, 0, sizeof(tent_struct), 0, A_GIMME, 0); class_addbang(tent_class, (t_method) calculate); class_addmethod(tent_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(tent_class, (t_method) show, gensym("show"), 0); class_addmethod(tent_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(tent_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(tent_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(tent_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(tent_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(tent_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/pickover-help.pd0000644000076500007650000000311312076105251014220 0ustar hanshans#N canvas 185 66 689 426 10; #X obj 318 105 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 369 106 5 0 0 0 - - -; #X text 407 162 Reset To Initial Conditions; #X floatatom 363 372 10 0 0 0 Y - -; #X floatatom 318 350 10 0 0 0 X - -; #X obj 318 122 metro 50; #X obj 293 121 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 373 192 param 0.02 10 28 2.66667; #X floatatom 408 399 10 0 0 0 Z - -; #X text 20 18 Pickover Attractor; #X text 19 33 Chaos PD Externals - Copyright Ben Bogart 2002; #X obj 20 62 examples/readme-fractals; #X obj 318 318 pickover 0.1 0 0 0.02 10 28 2.66667; #X text 550 194 Modify parameters; #X msg 363 162 reset; #X obj 459 345 search-tools; #X obj 29 174 metro 50; #X obj 29 150 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 80 149 5 0 0 0 - - -; #X obj 29 237 pickover; #X floatatom 74 345 5 0 0 0 - - -; #X msg 115 254 param 0.02 10 28 2.667; #X text 5 126 Calculate; #X text 113 221 Reset To Initial Conditions; #X text 115 272 Modify Parameters; #X floatatom 29 345 5 0 0 0 - - -; #X floatatom 120 345 5 0 0 0 - - -; #X text 58 318 Output; #X msg 114 203 reset 0.1 0 0; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 12 0; #X connect 6 0 12 0; #X connect 7 0 12 0; #X connect 12 0 4 0; #X connect 12 1 3 0; #X connect 12 2 8 0; #X connect 12 3 15 0; #X connect 12 4 15 1; #X connect 12 5 15 2; #X connect 14 0 12 0; #X connect 15 0 12 0; #X connect 16 0 19 0; #X connect 17 0 16 0; #X connect 18 0 16 1; #X connect 19 0 25 0; #X connect 19 1 20 0; #X connect 19 2 26 0; #X connect 21 0 19 0; #X connect 28 0 19 0; chaos-0.2/three_d-help.pd0000644000076500007650000000311012076105251014005 0ustar hanshans#N canvas 185 66 689 426 10; #X obj 318 105 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 369 106 5 0 0 0 - - -; #X text 407 162 Reset To Initial Conditions; #X floatatom 363 372 10 0 0 0 Y - -; #X floatatom 318 350 10 0 0 0 X - -; #X obj 318 122 metro 50; #X obj 293 121 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 373 192 param 0.02 10 28 2.66667; #X floatatom 408 399 10 0 0 0 Z - -; #X text 20 18 Three_D Attractor; #X text 19 33 Chaos PD Externals - Copyright Ben Bogart 2002; #X obj 20 62 examples/readme-fractals; #X obj 318 318 three_d 0.1 0 0 0.02 10 28 2.66667; #X text 550 194 Modify parameters; #X msg 363 162 reset; #X obj 459 345 search-tools; #X obj 29 174 metro 50; #X obj 29 150 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 80 149 5 0 0 0 - - -; #X obj 29 237 three_d; #X floatatom 74 345 5 0 0 0 - - -; #X msg 115 254 param 0.02 10 28 2.667; #X text 5 126 Calculate; #X text 113 221 Reset To Initial Conditions; #X text 115 272 Modify Parameters; #X floatatom 29 345 5 0 0 0 - - -; #X floatatom 120 345 5 0 0 0 - - -; #X text 58 318 Output; #X msg 114 203 reset 0.1 0 0; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 12 0; #X connect 6 0 12 0; #X connect 7 0 12 0; #X connect 12 0 4 0; #X connect 12 1 3 0; #X connect 12 2 8 0; #X connect 12 3 15 0; #X connect 12 4 15 1; #X connect 12 5 15 2; #X connect 14 0 12 0; #X connect 15 0 12 0; #X connect 16 0 19 0; #X connect 17 0 16 0; #X connect 18 0 16 1; #X connect 19 0 25 0; #X connect 19 1 20 0; #X connect 19 2 26 0; #X connect 21 0 19 0; #X connect 28 0 19 0; chaos-0.2/ikeda.c0000644000076500007650000003052712076105251012355 0ustar hanshans/* ikeda Attractor PD External */ /* Copyright Ben Bogart, 2002 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -350 #define M_a_hi 350 #define M_b_lo -2 #define M_b_hi 2 #define M_c_lo -350 #define M_c_hi 350 #define M_rho_lo -250 #define M_rho_hi 250 #define M_a 0 #define M_b 1 #define M_c 2 #define M_rho 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "ikeda v0.0, by Ben Bogart, 2002"; t_class *ikeda_class; typedef struct ikeda_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, rho, rho_lo, rho_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } ikeda_struct; static void calc(ikeda_struct *ikeda, double *vars) { double t, s, d, x_0, y_0; t=ikeda -> a-ikeda -> c/(1.0+vars[M_x]*vars[M_x]+vars[M_y]*vars[M_y]); s=sin(t); d=cos(t); x_0 =ikeda -> rho+ikeda -> b*(vars[M_x]*d-vars[M_y]*s); y_0 =ikeda -> b*(vars[M_x]*s+vars[M_y]*d); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(ikeda_struct *ikeda) { calc(ikeda, ikeda -> vars); outlet_float(ikeda -> outlets[M_y - 1], ikeda -> vars[M_y]); outlet_float(ikeda -> x_obj.ob_outlet, ikeda -> vars[M_x]); } // end calculate static void reset(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { ikeda -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); ikeda -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { ikeda -> vars[M_x] = ikeda -> vars_init[M_x]; ikeda -> vars[M_y] = ikeda -> vars_init[M_y]; } // end if } // end reset static char *classify(ikeda_struct *ikeda) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((ikeda -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((ikeda -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((ikeda -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((ikeda -> rho - M_rho_lo) * (1.0 / (M_rho_hi - M_rho_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(ikeda_struct *ikeda) { SETFLOAT(&ikeda -> search_out[0], ikeda -> lyap_exp); SETSYMBOL(&ikeda -> search_out[1], gensym(classify(ikeda))); SETFLOAT(&ikeda -> search_out[2], ikeda -> failure_ratio); SETFLOAT(&ikeda -> vars_out[M_x], ikeda -> vars[M_x]); SETFLOAT(&ikeda -> vars_out[M_y], ikeda -> vars[M_y]); SETFLOAT(&ikeda -> params_out[M_a], ikeda -> a); SETFLOAT(&ikeda -> params_out[M_b], ikeda -> b); SETFLOAT(&ikeda -> params_out[M_c], ikeda -> c); SETFLOAT(&ikeda -> params_out[M_rho], ikeda -> rho); outlet_list(ikeda -> params_outlet, gensym("list"), M_param_count, ikeda -> params_out); outlet_list(ikeda -> vars_outlet, gensym("list"), M_var_count, ikeda -> vars_out); } static void show(ikeda_struct *ikeda) { make_results(ikeda); outlet_anything(ikeda -> search_outlet, gensym("show"), M_search_count, ikeda -> search_out); } static void param(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for ikeda fractal. Expecting 4 arguments."); return; } ikeda -> a = (double) atom_getfloatarg(0, argc, argv); ikeda -> b = (double) atom_getfloatarg(1, argc, argv); ikeda -> c = (double) atom_getfloatarg(2, argc, argv); ikeda -> rho = (double) atom_getfloatarg(3, argc, argv); } static void seed(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(ikeda_struct *ikeda, t_floatarg l, t_floatarg h, t_floatarg lim) { ikeda -> lyap_lo = l; ikeda -> lyap_hi = h; ikeda -> lyap_limit = (double) ((int) lim); } static void elyap(ikeda_struct *ikeda) { double results[M_var_count]; int i; if (lyapunov_full((void *) ikeda, (t_gotfn) calc, M_var_count, ikeda -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(ikeda_struct *ikeda) { if (ikeda -> a_lo < M_a_lo) { ikeda -> a_lo = M_a_lo; } if (ikeda -> a_lo > M_a_hi) { ikeda -> a_lo = M_a_hi; } if (ikeda -> a_hi < M_a_lo) { ikeda -> a_hi = M_a_lo; } if (ikeda -> a_hi > M_a_hi) { ikeda -> a_hi = M_a_hi; } if (ikeda -> b_lo < M_b_lo) { ikeda -> b_lo = M_b_lo; } if (ikeda -> b_lo > M_b_hi) { ikeda -> b_lo = M_b_hi; } if (ikeda -> b_hi < M_b_lo) { ikeda -> b_hi = M_b_lo; } if (ikeda -> b_hi > M_b_hi) { ikeda -> b_hi = M_b_hi; } if (ikeda -> c_lo < M_c_lo) { ikeda -> c_lo = M_c_lo; } if (ikeda -> c_lo > M_c_hi) { ikeda -> c_lo = M_c_hi; } if (ikeda -> c_hi < M_c_lo) { ikeda -> c_hi = M_c_lo; } if (ikeda -> c_hi > M_c_hi) { ikeda -> c_hi = M_c_hi; } if (ikeda -> rho_lo < M_rho_lo) { ikeda -> rho_lo = M_rho_lo; } if (ikeda -> rho_lo > M_rho_hi) { ikeda -> rho_lo = M_rho_hi; } if (ikeda -> rho_hi < M_rho_lo) { ikeda -> rho_hi = M_rho_lo; } if (ikeda -> rho_hi > M_rho_hi) { ikeda -> rho_hi = M_rho_hi; } } static void constrain(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges ikeda -> a_lo = M_a_lo; ikeda -> a_hi = M_a_hi; ikeda -> b_lo = M_b_lo; ikeda -> b_hi = M_b_hi; ikeda -> c_lo = M_c_lo; ikeda -> c_hi = M_c_hi; ikeda -> rho_lo = M_rho_lo; ikeda -> rho_hi = M_rho_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double rho_spread = ((M_rho_hi - M_rho_lo) * percent) / 2; ikeda -> a_lo = ikeda -> a - a_spread; ikeda -> a_hi = ikeda -> a + a_spread; ikeda -> b_lo = ikeda -> b - b_spread; ikeda -> b_hi = ikeda -> b + b_spread; ikeda -> c_lo = ikeda -> c - c_spread; ikeda -> c_hi = ikeda -> c + c_spread; ikeda -> rho_lo = ikeda -> rho - rho_spread; ikeda -> rho_hi = ikeda -> rho + rho_spread; limiter(ikeda); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for ikeda constraints, requires 8 values, got %d", argc); return; } ikeda -> a_lo = atom_getfloat(arg++); ikeda -> a_hi = atom_getfloat(arg++); ikeda -> b_lo = atom_getfloat(arg++); ikeda -> b_hi = atom_getfloat(arg++); ikeda -> c_lo = atom_getfloat(arg++); ikeda -> c_hi = atom_getfloat(arg++); ikeda -> rho_lo = atom_getfloat(arg++); ikeda -> rho_hi = atom_getfloat(arg++); limiter(ikeda); } static void search(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = ikeda -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = ikeda -> a; double temp_b = ikeda -> b; double temp_c = ikeda -> c; double temp_rho = ikeda -> rho; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], ikeda -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: ikeda -> a = (drand48() * (ikeda -> a_hi - ikeda -> a_lo)) + ikeda -> a_lo; ikeda -> b = (drand48() * (ikeda -> b_hi - ikeda -> b_lo)) + ikeda -> b_lo; ikeda -> c = (drand48() * (ikeda -> c_hi - ikeda -> c_lo)) + ikeda -> c_lo; ikeda -> rho = (drand48() * (ikeda -> rho_hi - ikeda -> rho_lo)) + ikeda -> rho_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(ikeda, NULL, argc, vars); do { calc(ikeda, ikeda -> vars); } while(jump--); ikeda -> lyap_exp = lyapunov((void *) ikeda, (t_gotfn) calc, M_var_count, (double *) ikeda -> vars); if (isnan(ikeda -> lyap_exp)) { not_found = 1; } if (ikeda -> lyap_exp < ikeda -> lyap_lo || ikeda -> lyap_exp > ikeda -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(ikeda, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) ikeda -> lyap_limit); post("Try using wider constraints."); ikeda -> a = temp_a; ikeda -> b = temp_b; ikeda -> c = temp_c; ikeda -> rho = temp_rho; outlet_anything(ikeda -> search_outlet, gensym("invalid"), 0, NULL); } else { ikeda -> failure_ratio = (ikeda -> lyap_limit - not_expired) / ikeda -> lyap_limit; make_results(ikeda); outlet_anything(ikeda -> search_outlet, gensym("search"), M_search_count, ikeda -> search_out); } } void *ikeda_new(t_symbol *s, int argc, t_atom *argv) { ikeda_struct *ikeda = (ikeda_struct *) pd_new(ikeda_class); if (ikeda != NULL) { outlet_new(&ikeda -> x_obj, &s_float); ikeda -> outlets[0] = outlet_new(&ikeda -> x_obj, &s_float); ikeda -> search_outlet = outlet_new(&ikeda -> x_obj, &s_list); ikeda -> vars_outlet = outlet_new(&ikeda -> x_obj, &s_list); ikeda -> params_outlet = outlet_new(&ikeda -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { ikeda -> vars_init[M_x] = ikeda -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); ikeda -> vars_init[M_y] = ikeda -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); ikeda -> a = (double) atom_getfloatarg(2, argc, argv); ikeda -> b = (double) atom_getfloatarg(3, argc, argv); ikeda -> c = (double) atom_getfloatarg(4, argc, argv); ikeda -> rho = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for ikeda fractal. Expecting 6 arguments."); } ikeda -> vars_init[M_x] = 0.1; ikeda -> vars_init[M_y] = 0.1; ikeda -> a = 0.4; ikeda -> b = 0.9; ikeda -> c = 6; ikeda -> rho = 1; } constrain(ikeda, NULL, 0, NULL); lyap(ikeda, -1000000.0, 1000000.0, M_failure_limit); } return (void *)ikeda; } void ikeda_setup(void) { ikeda_class = class_new(gensym("ikeda"), (t_newmethod) ikeda_new, 0, sizeof(ikeda_struct), 0, A_GIMME, 0); class_addbang(ikeda_class, (t_method) calculate); class_addmethod(ikeda_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(ikeda_class, (t_method) show, gensym("show"), 0); class_addmethod(ikeda_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(ikeda_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(ikeda_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(ikeda_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(ikeda_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(ikeda_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/attract1-help.pd0000644000076500007650000000204012076105251014117 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 attract1 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Attract1 Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0; chaos-0.2/latoomutgamma.c0000644000076500007650000003421312076105251014143 0ustar hanshans/* latoomutgamma Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -3 #define M_a_hi 3 #define M_b_lo -3 #define M_b_hi 3 #define M_c_lo 0.5 #define M_c_hi 1.5 #define M_d_lo 0.5 #define M_d_hi 1.5 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "latoomutgamma v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *latoomutgamma_class; typedef struct latoomutgamma_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } latoomutgamma_struct; static void calc(latoomutgamma_struct *latoomutgamma, double *vars) { double x_0, y_0; x_0 =abs(sin(vars[M_y]*latoomutgamma -> b))+pow(sin(vars[M_x]*latoomutgamma -> b),2); y_0 =abs(sin(vars[M_x]*latoomutgamma -> a))+pow(sin(vars[M_y]*latoomutgamma -> b),2); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(latoomutgamma_struct *latoomutgamma) { calc(latoomutgamma, latoomutgamma -> vars); outlet_float(latoomutgamma -> outlets[M_y - 1], latoomutgamma -> vars[M_y]); outlet_float(latoomutgamma -> x_obj.ob_outlet, latoomutgamma -> vars[M_x]); } // end calculate static void reset(latoomutgamma_struct *latoomutgamma, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { latoomutgamma -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); latoomutgamma -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { latoomutgamma -> vars[M_x] = latoomutgamma -> vars_init[M_x]; latoomutgamma -> vars[M_y] = latoomutgamma -> vars_init[M_y]; } // end if } // end reset static char *classify(latoomutgamma_struct *latoomutgamma) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((latoomutgamma -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((latoomutgamma -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((latoomutgamma -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((latoomutgamma -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(latoomutgamma_struct *latoomutgamma) { SETFLOAT(&latoomutgamma -> search_out[0], latoomutgamma -> lyap_exp); SETSYMBOL(&latoomutgamma -> search_out[1], gensym(classify(latoomutgamma))); SETFLOAT(&latoomutgamma -> search_out[2], latoomutgamma -> failure_ratio); SETFLOAT(&latoomutgamma -> vars_out[M_x], latoomutgamma -> vars[M_x]); SETFLOAT(&latoomutgamma -> vars_out[M_y], latoomutgamma -> vars[M_y]); SETFLOAT(&latoomutgamma -> params_out[M_a], latoomutgamma -> a); SETFLOAT(&latoomutgamma -> params_out[M_b], latoomutgamma -> b); SETFLOAT(&latoomutgamma -> params_out[M_c], latoomutgamma -> c); SETFLOAT(&latoomutgamma -> params_out[M_d], latoomutgamma -> d); outlet_list(latoomutgamma -> params_outlet, gensym("list"), M_param_count, latoomutgamma -> params_out); outlet_list(latoomutgamma -> vars_outlet, gensym("list"), M_var_count, latoomutgamma -> vars_out); } static void show(latoomutgamma_struct *latoomutgamma) { make_results(latoomutgamma); outlet_anything(latoomutgamma -> search_outlet, gensym("show"), M_search_count, latoomutgamma -> search_out); } static void param(latoomutgamma_struct *latoomutgamma, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for latoomutgamma fractal. Expecting 4 arguments."); return; } latoomutgamma -> a = (double) atom_getfloatarg(0, argc, argv); latoomutgamma -> b = (double) atom_getfloatarg(1, argc, argv); latoomutgamma -> c = (double) atom_getfloatarg(2, argc, argv); latoomutgamma -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(latoomutgamma_struct *latoomutgamma, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(latoomutgamma_struct *latoomutgamma, t_floatarg l, t_floatarg h, t_floatarg lim) { latoomutgamma -> lyap_lo = l; latoomutgamma -> lyap_hi = h; latoomutgamma -> lyap_limit = (double) ((int) lim); } static void elyap(latoomutgamma_struct *latoomutgamma) { double results[M_var_count]; int i; if (lyapunov_full((void *) latoomutgamma, (t_gotfn) calc, M_var_count, latoomutgamma -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(latoomutgamma_struct *latoomutgamma) { if (latoomutgamma -> a_lo < M_a_lo) { latoomutgamma -> a_lo = M_a_lo; } if (latoomutgamma -> a_lo > M_a_hi) { latoomutgamma -> a_lo = M_a_hi; } if (latoomutgamma -> a_hi < M_a_lo) { latoomutgamma -> a_hi = M_a_lo; } if (latoomutgamma -> a_hi > M_a_hi) { latoomutgamma -> a_hi = M_a_hi; } if (latoomutgamma -> b_lo < M_b_lo) { latoomutgamma -> b_lo = M_b_lo; } if (latoomutgamma -> b_lo > M_b_hi) { latoomutgamma -> b_lo = M_b_hi; } if (latoomutgamma -> b_hi < M_b_lo) { latoomutgamma -> b_hi = M_b_lo; } if (latoomutgamma -> b_hi > M_b_hi) { latoomutgamma -> b_hi = M_b_hi; } if (latoomutgamma -> c_lo < M_c_lo) { latoomutgamma -> c_lo = M_c_lo; } if (latoomutgamma -> c_lo > M_c_hi) { latoomutgamma -> c_lo = M_c_hi; } if (latoomutgamma -> c_hi < M_c_lo) { latoomutgamma -> c_hi = M_c_lo; } if (latoomutgamma -> c_hi > M_c_hi) { latoomutgamma -> c_hi = M_c_hi; } if (latoomutgamma -> d_lo < M_d_lo) { latoomutgamma -> d_lo = M_d_lo; } if (latoomutgamma -> d_lo > M_d_hi) { latoomutgamma -> d_lo = M_d_hi; } if (latoomutgamma -> d_hi < M_d_lo) { latoomutgamma -> d_hi = M_d_lo; } if (latoomutgamma -> d_hi > M_d_hi) { latoomutgamma -> d_hi = M_d_hi; } } static void constrain(latoomutgamma_struct *latoomutgamma, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges latoomutgamma -> a_lo = M_a_lo; latoomutgamma -> a_hi = M_a_hi; latoomutgamma -> b_lo = M_b_lo; latoomutgamma -> b_hi = M_b_hi; latoomutgamma -> c_lo = M_c_lo; latoomutgamma -> c_hi = M_c_hi; latoomutgamma -> d_lo = M_d_lo; latoomutgamma -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; latoomutgamma -> a_lo = latoomutgamma -> a - a_spread; latoomutgamma -> a_hi = latoomutgamma -> a + a_spread; latoomutgamma -> b_lo = latoomutgamma -> b - b_spread; latoomutgamma -> b_hi = latoomutgamma -> b + b_spread; latoomutgamma -> c_lo = latoomutgamma -> c - c_spread; latoomutgamma -> c_hi = latoomutgamma -> c + c_spread; latoomutgamma -> d_lo = latoomutgamma -> d - d_spread; latoomutgamma -> d_hi = latoomutgamma -> d + d_spread; limiter(latoomutgamma); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for latoomutgamma constraints, requires 8 values, got %d", argc); return; } latoomutgamma -> a_lo = atom_getfloat(arg++); latoomutgamma -> a_hi = atom_getfloat(arg++); latoomutgamma -> b_lo = atom_getfloat(arg++); latoomutgamma -> b_hi = atom_getfloat(arg++); latoomutgamma -> c_lo = atom_getfloat(arg++); latoomutgamma -> c_hi = atom_getfloat(arg++); latoomutgamma -> d_lo = atom_getfloat(arg++); latoomutgamma -> d_hi = atom_getfloat(arg++); limiter(latoomutgamma); } static void search(latoomutgamma_struct *latoomutgamma, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = latoomutgamma -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = latoomutgamma -> a; double temp_b = latoomutgamma -> b; double temp_c = latoomutgamma -> c; double temp_d = latoomutgamma -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], latoomutgamma -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: latoomutgamma -> a = (drand48() * (latoomutgamma -> a_hi - latoomutgamma -> a_lo)) + latoomutgamma -> a_lo; latoomutgamma -> b = (drand48() * (latoomutgamma -> b_hi - latoomutgamma -> b_lo)) + latoomutgamma -> b_lo; latoomutgamma -> c = (drand48() * (latoomutgamma -> c_hi - latoomutgamma -> c_lo)) + latoomutgamma -> c_lo; latoomutgamma -> d = (drand48() * (latoomutgamma -> d_hi - latoomutgamma -> d_lo)) + latoomutgamma -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(latoomutgamma, NULL, argc, vars); do { calc(latoomutgamma, latoomutgamma -> vars); } while(jump--); latoomutgamma -> lyap_exp = lyapunov((void *) latoomutgamma, (t_gotfn) calc, M_var_count, (double *) latoomutgamma -> vars); if (isnan(latoomutgamma -> lyap_exp)) { not_found = 1; } if (latoomutgamma -> lyap_exp < latoomutgamma -> lyap_lo || latoomutgamma -> lyap_exp > latoomutgamma -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(latoomutgamma, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) latoomutgamma -> lyap_limit); post("Try using wider constraints."); latoomutgamma -> a = temp_a; latoomutgamma -> b = temp_b; latoomutgamma -> c = temp_c; latoomutgamma -> d = temp_d; outlet_anything(latoomutgamma -> search_outlet, gensym("invalid"), 0, NULL); } else { latoomutgamma -> failure_ratio = (latoomutgamma -> lyap_limit - not_expired) / latoomutgamma -> lyap_limit; make_results(latoomutgamma); outlet_anything(latoomutgamma -> search_outlet, gensym("search"), M_search_count, latoomutgamma -> search_out); } } void *latoomutgamma_new(t_symbol *s, int argc, t_atom *argv) { latoomutgamma_struct *latoomutgamma = (latoomutgamma_struct *) pd_new(latoomutgamma_class); if (latoomutgamma != NULL) { outlet_new(&latoomutgamma -> x_obj, &s_float); latoomutgamma -> outlets[0] = outlet_new(&latoomutgamma -> x_obj, &s_float); latoomutgamma -> search_outlet = outlet_new(&latoomutgamma -> x_obj, &s_list); latoomutgamma -> vars_outlet = outlet_new(&latoomutgamma -> x_obj, &s_list); latoomutgamma -> params_outlet = outlet_new(&latoomutgamma -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { latoomutgamma -> vars_init[M_x] = latoomutgamma -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); latoomutgamma -> vars_init[M_y] = latoomutgamma -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); latoomutgamma -> a = (double) atom_getfloatarg(2, argc, argv); latoomutgamma -> b = (double) atom_getfloatarg(3, argc, argv); latoomutgamma -> c = (double) atom_getfloatarg(4, argc, argv); latoomutgamma -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for latoomutgamma fractal. Expecting 6 arguments."); } latoomutgamma -> vars_init[M_x] = 0.1; latoomutgamma -> vars_init[M_y] = 0.1; latoomutgamma -> a = 1; latoomutgamma -> b = 1; latoomutgamma -> c = 1; latoomutgamma -> d = 1; } constrain(latoomutgamma, NULL, 0, NULL); lyap(latoomutgamma, -1000000.0, 1000000.0, M_failure_limit); } return (void *)latoomutgamma; } void latoomutgamma_setup(void) { latoomutgamma_class = class_new(gensym("latoomutgamma"), (t_newmethod) latoomutgamma_new, 0, sizeof(latoomutgamma_struct), 0, A_GIMME, 0); class_addbang(latoomutgamma_class, (t_method) calculate); class_addmethod(latoomutgamma_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(latoomutgamma_class, (t_method) show, gensym("show"), 0); class_addmethod(latoomutgamma_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(latoomutgamma_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(latoomutgamma_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(latoomutgamma_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(latoomutgamma_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(latoomutgamma_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/chaos.h0000644000076500007650000000134112076105251012372 0ustar hanshans/* a test file for chaos.h */ #ifndef PD_VERSION #include "m_pd.h" #endif #define MAX_VARS 20 /* * fractal - pointer to the object under test * calc - the iteration function * var_count - the number of variables for this fractal class * vars - pointer to the fractal variables array */ double lyapunov(void *fractal, t_gotfn calc, int var_count, double *vars); /* * CAUTION: ON FRACTALS WITH LOTS OF VARIABLES, THIS WILL TAKE A WHILE. * This is an experimental function to test the ability of the function to * calculate an accurate exponent by aberating each variable in the fractal. * returns 'results' on completion. */ double *lyapunov_full(void *fractal, t_gotfn calc, int var_count, double *vars, double *results); chaos-0.2/logistic.c0000644000076500007650000002240112076105251013105 0ustar hanshans/* logistic Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo 0 #define M_a_hi 4 #define M_a 0 #define M_x 0 #define M_param_count 1 #define M_var_count 1 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "logistic v0.0, by Michael McGonagle, from ??????, 2003"; t_class *logistic_class; typedef struct logistic_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; } logistic_struct; static void calc(logistic_struct *logistic, double *vars) { double x_0; x_0 =logistic -> a*vars[M_x]*(1.0-vars[M_x]); vars[M_x] = x_0; } // end calc static void calculate(logistic_struct *logistic) { calc(logistic, logistic -> vars); outlet_float(logistic -> x_obj.ob_outlet, logistic -> vars[M_x]); } // end calculate static void reset(logistic_struct *logistic, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { logistic -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); } else { logistic -> vars[M_x] = logistic -> vars_init[M_x]; } // end if } // end reset static char *classify(logistic_struct *logistic) { static char buff[2]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((logistic -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = '\0'; return buff; } static void make_results(logistic_struct *logistic) { SETFLOAT(&logistic -> search_out[0], logistic -> lyap_exp); SETSYMBOL(&logistic -> search_out[1], gensym(classify(logistic))); SETFLOAT(&logistic -> search_out[2], logistic -> failure_ratio); SETFLOAT(&logistic -> vars_out[M_x], logistic -> vars[M_x]); SETFLOAT(&logistic -> params_out[M_a], logistic -> a); outlet_list(logistic -> params_outlet, gensym("list"), M_param_count, logistic -> params_out); outlet_list(logistic -> vars_outlet, gensym("list"), M_var_count, logistic -> vars_out); } static void show(logistic_struct *logistic) { make_results(logistic); outlet_anything(logistic -> search_outlet, gensym("show"), M_search_count, logistic -> search_out); } static void param(logistic_struct *logistic, t_symbol *s, int argc, t_atom *argv) { if (argc != 1) { post("Incorrect number of arguments for logistic fractal. Expecting 1 arguments."); return; } logistic -> a = (double) atom_getfloatarg(0, argc, argv); } static void seed(logistic_struct *logistic, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(logistic_struct *logistic, t_floatarg l, t_floatarg h, t_floatarg lim) { logistic -> lyap_lo = l; logistic -> lyap_hi = h; logistic -> lyap_limit = (double) ((int) lim); } static void elyap(logistic_struct *logistic) { double results[M_var_count]; int i; if (lyapunov_full((void *) logistic, (t_gotfn) calc, M_var_count, logistic -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(logistic_struct *logistic) { if (logistic -> a_lo < M_a_lo) { logistic -> a_lo = M_a_lo; } if (logistic -> a_lo > M_a_hi) { logistic -> a_lo = M_a_hi; } if (logistic -> a_hi < M_a_lo) { logistic -> a_hi = M_a_lo; } if (logistic -> a_hi > M_a_hi) { logistic -> a_hi = M_a_hi; } } static void constrain(logistic_struct *logistic, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges logistic -> a_lo = M_a_lo; logistic -> a_hi = M_a_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; logistic -> a_lo = logistic -> a - a_spread; logistic -> a_hi = logistic -> a + a_spread; limiter(logistic); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for logistic constraints, requires 2 values, got %d", argc); return; } logistic -> a_lo = atom_getfloat(arg++); logistic -> a_hi = atom_getfloat(arg++); limiter(logistic); } static void search(logistic_struct *logistic, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = logistic -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = logistic -> a; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], logistic -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: logistic -> a = (drand48() * (logistic -> a_hi - logistic -> a_lo)) + logistic -> a_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(logistic, NULL, argc, vars); do { calc(logistic, logistic -> vars); } while(jump--); logistic -> lyap_exp = lyapunov((void *) logistic, (t_gotfn) calc, M_var_count, (double *) logistic -> vars); if (isnan(logistic -> lyap_exp)) { not_found = 1; } if (logistic -> lyap_exp < logistic -> lyap_lo || logistic -> lyap_exp > logistic -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(logistic, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) logistic -> lyap_limit); post("Try using wider constraints."); logistic -> a = temp_a; outlet_anything(logistic -> search_outlet, gensym("invalid"), 0, NULL); } else { logistic -> failure_ratio = (logistic -> lyap_limit - not_expired) / logistic -> lyap_limit; make_results(logistic); outlet_anything(logistic -> search_outlet, gensym("search"), M_search_count, logistic -> search_out); } } void *logistic_new(t_symbol *s, int argc, t_atom *argv) { logistic_struct *logistic = (logistic_struct *) pd_new(logistic_class); if (logistic != NULL) { outlet_new(&logistic -> x_obj, &s_float); logistic -> search_outlet = outlet_new(&logistic -> x_obj, &s_list); logistic -> vars_outlet = outlet_new(&logistic -> x_obj, &s_list); logistic -> params_outlet = outlet_new(&logistic -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { logistic -> vars_init[M_x] = logistic -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); logistic -> a = (double) atom_getfloatarg(1, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for logistic fractal. Expecting 2 arguments."); } logistic -> vars_init[M_x] = 0.1; logistic -> a = 4; } constrain(logistic, NULL, 0, NULL); lyap(logistic, -1000000.0, 1000000.0, M_failure_limit); } return (void *)logistic; } void logistic_setup(void) { logistic_class = class_new(gensym("logistic"), (t_newmethod) logistic_new, 0, sizeof(logistic_struct), 0, A_GIMME, 0); class_addbang(logistic_class, (t_method) calculate); class_addmethod(logistic_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(logistic_class, (t_method) show, gensym("show"), 0); class_addmethod(logistic_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(logistic_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(logistic_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(logistic_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(logistic_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(logistic_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/pickover.c0000644000076500007650000003273312076105251013123 0ustar hanshans/* pickover Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_d_lo -1000 #define M_d_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_z 2 #define M_param_count 4 #define M_var_count 3 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "pickover v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *pickover_class; typedef struct pickover_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } pickover_struct; static void calc(pickover_struct *pickover, double *vars) { double x_0, y_0, z_0; x_0 =sin(pickover -> a*vars[M_y])-vars[M_z]*cos(pickover -> b*vars[M_x]); y_0 =vars[M_z]*sin(pickover -> c*vars[M_x])-cos(pickover -> d*vars[M_y]); z_0 =sin(vars[M_x]); vars[M_x] = x_0; vars[M_y] = y_0; vars[M_z] = z_0; } // end calc static void calculate(pickover_struct *pickover) { calc(pickover, pickover -> vars); outlet_float(pickover -> outlets[M_z - 1], pickover -> vars[M_z]); outlet_float(pickover -> outlets[M_y - 1], pickover -> vars[M_y]); outlet_float(pickover -> x_obj.ob_outlet, pickover -> vars[M_x]); } // end calculate static void reset(pickover_struct *pickover, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { pickover -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); pickover -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); pickover -> vars[M_z] = (double) atom_getfloatarg(M_z, argc, argv); } else { pickover -> vars[M_x] = pickover -> vars_init[M_x]; pickover -> vars[M_y] = pickover -> vars_init[M_y]; pickover -> vars[M_z] = pickover -> vars_init[M_z]; } // end if } // end reset static char *classify(pickover_struct *pickover) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((pickover -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((pickover -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((pickover -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((pickover -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(pickover_struct *pickover) { SETFLOAT(&pickover -> search_out[0], pickover -> lyap_exp); SETSYMBOL(&pickover -> search_out[1], gensym(classify(pickover))); SETFLOAT(&pickover -> search_out[2], pickover -> failure_ratio); SETFLOAT(&pickover -> vars_out[M_x], pickover -> vars[M_x]); SETFLOAT(&pickover -> vars_out[M_y], pickover -> vars[M_y]); SETFLOAT(&pickover -> vars_out[M_z], pickover -> vars[M_z]); SETFLOAT(&pickover -> params_out[M_a], pickover -> a); SETFLOAT(&pickover -> params_out[M_b], pickover -> b); SETFLOAT(&pickover -> params_out[M_c], pickover -> c); SETFLOAT(&pickover -> params_out[M_d], pickover -> d); outlet_list(pickover -> params_outlet, gensym("list"), M_param_count, pickover -> params_out); outlet_list(pickover -> vars_outlet, gensym("list"), M_var_count, pickover -> vars_out); } static void show(pickover_struct *pickover) { make_results(pickover); outlet_anything(pickover -> search_outlet, gensym("show"), M_search_count, pickover -> search_out); } static void param(pickover_struct *pickover, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for pickover fractal. Expecting 4 arguments."); return; } pickover -> a = (double) atom_getfloatarg(0, argc, argv); pickover -> b = (double) atom_getfloatarg(1, argc, argv); pickover -> c = (double) atom_getfloatarg(2, argc, argv); pickover -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(pickover_struct *pickover, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(pickover_struct *pickover, t_floatarg l, t_floatarg h, t_floatarg lim) { pickover -> lyap_lo = l; pickover -> lyap_hi = h; pickover -> lyap_limit = (double) ((int) lim); } static void elyap(pickover_struct *pickover) { double results[M_var_count]; int i; if (lyapunov_full((void *) pickover, (t_gotfn) calc, M_var_count, pickover -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(pickover_struct *pickover) { if (pickover -> a_lo < M_a_lo) { pickover -> a_lo = M_a_lo; } if (pickover -> a_lo > M_a_hi) { pickover -> a_lo = M_a_hi; } if (pickover -> a_hi < M_a_lo) { pickover -> a_hi = M_a_lo; } if (pickover -> a_hi > M_a_hi) { pickover -> a_hi = M_a_hi; } if (pickover -> b_lo < M_b_lo) { pickover -> b_lo = M_b_lo; } if (pickover -> b_lo > M_b_hi) { pickover -> b_lo = M_b_hi; } if (pickover -> b_hi < M_b_lo) { pickover -> b_hi = M_b_lo; } if (pickover -> b_hi > M_b_hi) { pickover -> b_hi = M_b_hi; } if (pickover -> c_lo < M_c_lo) { pickover -> c_lo = M_c_lo; } if (pickover -> c_lo > M_c_hi) { pickover -> c_lo = M_c_hi; } if (pickover -> c_hi < M_c_lo) { pickover -> c_hi = M_c_lo; } if (pickover -> c_hi > M_c_hi) { pickover -> c_hi = M_c_hi; } if (pickover -> d_lo < M_d_lo) { pickover -> d_lo = M_d_lo; } if (pickover -> d_lo > M_d_hi) { pickover -> d_lo = M_d_hi; } if (pickover -> d_hi < M_d_lo) { pickover -> d_hi = M_d_lo; } if (pickover -> d_hi > M_d_hi) { pickover -> d_hi = M_d_hi; } } static void constrain(pickover_struct *pickover, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges pickover -> a_lo = M_a_lo; pickover -> a_hi = M_a_hi; pickover -> b_lo = M_b_lo; pickover -> b_hi = M_b_hi; pickover -> c_lo = M_c_lo; pickover -> c_hi = M_c_hi; pickover -> d_lo = M_d_lo; pickover -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; pickover -> a_lo = pickover -> a - a_spread; pickover -> a_hi = pickover -> a + a_spread; pickover -> b_lo = pickover -> b - b_spread; pickover -> b_hi = pickover -> b + b_spread; pickover -> c_lo = pickover -> c - c_spread; pickover -> c_hi = pickover -> c + c_spread; pickover -> d_lo = pickover -> d - d_spread; pickover -> d_hi = pickover -> d + d_spread; limiter(pickover); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for pickover constraints, requires 8 values, got %d", argc); return; } pickover -> a_lo = atom_getfloat(arg++); pickover -> a_hi = atom_getfloat(arg++); pickover -> b_lo = atom_getfloat(arg++); pickover -> b_hi = atom_getfloat(arg++); pickover -> c_lo = atom_getfloat(arg++); pickover -> c_hi = atom_getfloat(arg++); pickover -> d_lo = atom_getfloat(arg++); pickover -> d_hi = atom_getfloat(arg++); limiter(pickover); } static void search(pickover_struct *pickover, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = pickover -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = pickover -> a; double temp_b = pickover -> b; double temp_c = pickover -> c; double temp_d = pickover -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], pickover -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: pickover -> a = (drand48() * (pickover -> a_hi - pickover -> a_lo)) + pickover -> a_lo; pickover -> b = (drand48() * (pickover -> b_hi - pickover -> b_lo)) + pickover -> b_lo; pickover -> c = (drand48() * (pickover -> c_hi - pickover -> c_lo)) + pickover -> c_lo; pickover -> d = (drand48() * (pickover -> d_hi - pickover -> d_lo)) + pickover -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(pickover, NULL, argc, vars); do { calc(pickover, pickover -> vars); } while(jump--); pickover -> lyap_exp = lyapunov((void *) pickover, (t_gotfn) calc, M_var_count, (double *) pickover -> vars); if (isnan(pickover -> lyap_exp)) { not_found = 1; } if (pickover -> lyap_exp < pickover -> lyap_lo || pickover -> lyap_exp > pickover -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(pickover, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) pickover -> lyap_limit); post("Try using wider constraints."); pickover -> a = temp_a; pickover -> b = temp_b; pickover -> c = temp_c; pickover -> d = temp_d; outlet_anything(pickover -> search_outlet, gensym("invalid"), 0, NULL); } else { pickover -> failure_ratio = (pickover -> lyap_limit - not_expired) / pickover -> lyap_limit; make_results(pickover); outlet_anything(pickover -> search_outlet, gensym("search"), M_search_count, pickover -> search_out); } } void *pickover_new(t_symbol *s, int argc, t_atom *argv) { pickover_struct *pickover = (pickover_struct *) pd_new(pickover_class); if (pickover != NULL) { outlet_new(&pickover -> x_obj, &s_float); pickover -> outlets[0] = outlet_new(&pickover -> x_obj, &s_float); pickover -> outlets[1] = outlet_new(&pickover -> x_obj, &s_float); pickover -> search_outlet = outlet_new(&pickover -> x_obj, &s_list); pickover -> vars_outlet = outlet_new(&pickover -> x_obj, &s_list); pickover -> params_outlet = outlet_new(&pickover -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { pickover -> vars_init[M_x] = pickover -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); pickover -> vars_init[M_y] = pickover -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); pickover -> vars_init[M_z] = pickover -> vars[M_z] = (double) atom_getfloatarg(2, argc, argv); pickover -> a = (double) atom_getfloatarg(3, argc, argv); pickover -> b = (double) atom_getfloatarg(4, argc, argv); pickover -> c = (double) atom_getfloatarg(5, argc, argv); pickover -> d = (double) atom_getfloatarg(6, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for pickover fractal. Expecting 7 arguments."); } pickover -> vars_init[M_x] = 0.01; pickover -> vars_init[M_y] = 0; pickover -> vars_init[M_z] = 0; pickover -> a = 2.24; pickover -> b = 0.43; pickover -> c = -0.65; pickover -> d = -2.43; } constrain(pickover, NULL, 0, NULL); lyap(pickover, -1000000.0, 1000000.0, M_failure_limit); } return (void *)pickover; } void pickover_setup(void) { pickover_class = class_new(gensym("pickover"), (t_newmethod) pickover_new, 0, sizeof(pickover_struct), 0, A_GIMME, 0); class_addbang(pickover_class, (t_method) calculate); class_addmethod(pickover_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(pickover_class, (t_method) show, gensym("show"), 0); class_addmethod(pickover_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(pickover_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(pickover_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pickover_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(pickover_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(pickover_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/search-tools-help.pd0000644000076500007650000000147012076105251015005 0ustar hanshans#N canvas 680 295 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X floatatom 43 332 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 20 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 436 18 examples/readme-fractals; #X text 21 19 Base Attractor; #X obj 53 262 fractal-tools; #X obj 43 285 base3 0.1 1.18939 2.24148; #X msg 61 240 lyapunov 0 100 1000; #X obj 126 320 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 9 0 10 0; #X connect 10 0 2 0; #X connect 10 1 12 0; #X connect 10 2 12 1; #X connect 10 3 12 2; #X connect 11 0 9 0; #X connect 12 0 10 0; chaos-0.2/three_d.c0000644000076500007650000003433212076105251012710 0ustar hanshans/* three_d Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_d_lo -1000 #define M_d_hi 1000 #define M_e_lo -1000 #define M_e_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_e 4 #define M_x 0 #define M_y 1 #define M_z 2 #define M_param_count 5 #define M_var_count 3 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "three_d v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *three_d_class; typedef struct three_d_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi, e, e_lo, e_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } three_d_struct; static void calc(three_d_struct *three_d, double *vars) { double x_0, y_0, z_0; x_0 =sin(three_d -> a*vars[M_y])-vars[M_z]*cos(three_d -> b*vars[M_x]); y_0 =vars[M_z]*sin(three_d -> c*vars[M_x])-cos(three_d -> d*vars[M_y]); z_0 =three_d -> e*sin(vars[M_x]); vars[M_x] = x_0; vars[M_y] = y_0; vars[M_z] = z_0; } // end calc static void calculate(three_d_struct *three_d) { calc(three_d, three_d -> vars); outlet_float(three_d -> outlets[M_z - 1], three_d -> vars[M_z]); outlet_float(three_d -> outlets[M_y - 1], three_d -> vars[M_y]); outlet_float(three_d -> x_obj.ob_outlet, three_d -> vars[M_x]); } // end calculate static void reset(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { three_d -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); three_d -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); three_d -> vars[M_z] = (double) atom_getfloatarg(M_z, argc, argv); } else { three_d -> vars[M_x] = three_d -> vars_init[M_x]; three_d -> vars[M_y] = three_d -> vars_init[M_y]; three_d -> vars[M_z] = three_d -> vars_init[M_z]; } // end if } // end reset static char *classify(three_d_struct *three_d) { static char buff[6]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((three_d -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((three_d -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((three_d -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((three_d -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = c[(int) (((three_d -> e - M_e_lo) * (1.0 / (M_e_hi - M_e_lo))) * 26)]; buff[5] = '\0'; return buff; } static void make_results(three_d_struct *three_d) { SETFLOAT(&three_d -> search_out[0], three_d -> lyap_exp); SETSYMBOL(&three_d -> search_out[1], gensym(classify(three_d))); SETFLOAT(&three_d -> search_out[2], three_d -> failure_ratio); SETFLOAT(&three_d -> vars_out[M_x], three_d -> vars[M_x]); SETFLOAT(&three_d -> vars_out[M_y], three_d -> vars[M_y]); SETFLOAT(&three_d -> vars_out[M_z], three_d -> vars[M_z]); SETFLOAT(&three_d -> params_out[M_a], three_d -> a); SETFLOAT(&three_d -> params_out[M_b], three_d -> b); SETFLOAT(&three_d -> params_out[M_c], three_d -> c); SETFLOAT(&three_d -> params_out[M_d], three_d -> d); SETFLOAT(&three_d -> params_out[M_e], three_d -> e); outlet_list(three_d -> params_outlet, gensym("list"), M_param_count, three_d -> params_out); outlet_list(three_d -> vars_outlet, gensym("list"), M_var_count, three_d -> vars_out); } static void show(three_d_struct *three_d) { make_results(three_d); outlet_anything(three_d -> search_outlet, gensym("show"), M_search_count, three_d -> search_out); } static void param(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) { if (argc != 5) { post("Incorrect number of arguments for three_d fractal. Expecting 5 arguments."); return; } three_d -> a = (double) atom_getfloatarg(0, argc, argv); three_d -> b = (double) atom_getfloatarg(1, argc, argv); three_d -> c = (double) atom_getfloatarg(2, argc, argv); three_d -> d = (double) atom_getfloatarg(3, argc, argv); three_d -> e = (double) atom_getfloatarg(4, argc, argv); } static void seed(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(three_d_struct *three_d, t_floatarg l, t_floatarg h, t_floatarg lim) { three_d -> lyap_lo = l; three_d -> lyap_hi = h; three_d -> lyap_limit = (double) ((int) lim); } static void elyap(three_d_struct *three_d) { double results[M_var_count]; int i; if (lyapunov_full((void *) three_d, (t_gotfn) calc, M_var_count, three_d -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(three_d_struct *three_d) { if (three_d -> a_lo < M_a_lo) { three_d -> a_lo = M_a_lo; } if (three_d -> a_lo > M_a_hi) { three_d -> a_lo = M_a_hi; } if (three_d -> a_hi < M_a_lo) { three_d -> a_hi = M_a_lo; } if (three_d -> a_hi > M_a_hi) { three_d -> a_hi = M_a_hi; } if (three_d -> b_lo < M_b_lo) { three_d -> b_lo = M_b_lo; } if (three_d -> b_lo > M_b_hi) { three_d -> b_lo = M_b_hi; } if (three_d -> b_hi < M_b_lo) { three_d -> b_hi = M_b_lo; } if (three_d -> b_hi > M_b_hi) { three_d -> b_hi = M_b_hi; } if (three_d -> c_lo < M_c_lo) { three_d -> c_lo = M_c_lo; } if (three_d -> c_lo > M_c_hi) { three_d -> c_lo = M_c_hi; } if (three_d -> c_hi < M_c_lo) { three_d -> c_hi = M_c_lo; } if (three_d -> c_hi > M_c_hi) { three_d -> c_hi = M_c_hi; } if (three_d -> d_lo < M_d_lo) { three_d -> d_lo = M_d_lo; } if (three_d -> d_lo > M_d_hi) { three_d -> d_lo = M_d_hi; } if (three_d -> d_hi < M_d_lo) { three_d -> d_hi = M_d_lo; } if (three_d -> d_hi > M_d_hi) { three_d -> d_hi = M_d_hi; } if (three_d -> e_lo < M_e_lo) { three_d -> e_lo = M_e_lo; } if (three_d -> e_lo > M_e_hi) { three_d -> e_lo = M_e_hi; } if (three_d -> e_hi < M_e_lo) { three_d -> e_hi = M_e_lo; } if (three_d -> e_hi > M_e_hi) { three_d -> e_hi = M_e_hi; } } static void constrain(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges three_d -> a_lo = M_a_lo; three_d -> a_hi = M_a_hi; three_d -> b_lo = M_b_lo; three_d -> b_hi = M_b_hi; three_d -> c_lo = M_c_lo; three_d -> c_hi = M_c_hi; three_d -> d_lo = M_d_lo; three_d -> d_hi = M_d_hi; three_d -> e_lo = M_e_lo; three_d -> e_hi = M_e_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; double e_spread = ((M_e_hi - M_e_lo) * percent) / 2; three_d -> a_lo = three_d -> a - a_spread; three_d -> a_hi = three_d -> a + a_spread; three_d -> b_lo = three_d -> b - b_spread; three_d -> b_hi = three_d -> b + b_spread; three_d -> c_lo = three_d -> c - c_spread; three_d -> c_hi = three_d -> c + c_spread; three_d -> d_lo = three_d -> d - d_spread; three_d -> d_hi = three_d -> d + d_spread; three_d -> e_lo = three_d -> e - e_spread; three_d -> e_hi = three_d -> e + e_spread; limiter(three_d); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for three_d constraints, requires 10 values, got %d", argc); return; } three_d -> a_lo = atom_getfloat(arg++); three_d -> a_hi = atom_getfloat(arg++); three_d -> b_lo = atom_getfloat(arg++); three_d -> b_hi = atom_getfloat(arg++); three_d -> c_lo = atom_getfloat(arg++); three_d -> c_hi = atom_getfloat(arg++); three_d -> d_lo = atom_getfloat(arg++); three_d -> d_hi = atom_getfloat(arg++); three_d -> e_lo = atom_getfloat(arg++); three_d -> e_hi = atom_getfloat(arg++); limiter(three_d); } static void search(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = three_d -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = three_d -> a; double temp_b = three_d -> b; double temp_c = three_d -> c; double temp_d = three_d -> d; double temp_e = three_d -> e; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], three_d -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: three_d -> a = (drand48() * (three_d -> a_hi - three_d -> a_lo)) + three_d -> a_lo; three_d -> b = (drand48() * (three_d -> b_hi - three_d -> b_lo)) + three_d -> b_lo; three_d -> c = (drand48() * (three_d -> c_hi - three_d -> c_lo)) + three_d -> c_lo; three_d -> d = (drand48() * (three_d -> d_hi - three_d -> d_lo)) + three_d -> d_lo; three_d -> e = (drand48() * (three_d -> e_hi - three_d -> e_lo)) + three_d -> e_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(three_d, NULL, argc, vars); do { calc(three_d, three_d -> vars); } while(jump--); three_d -> lyap_exp = lyapunov((void *) three_d, (t_gotfn) calc, M_var_count, (double *) three_d -> vars); if (isnan(three_d -> lyap_exp)) { not_found = 1; } if (three_d -> lyap_exp < three_d -> lyap_lo || three_d -> lyap_exp > three_d -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(three_d, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) three_d -> lyap_limit); post("Try using wider constraints."); three_d -> a = temp_a; three_d -> b = temp_b; three_d -> c = temp_c; three_d -> d = temp_d; three_d -> e = temp_e; outlet_anything(three_d -> search_outlet, gensym("invalid"), 0, NULL); } else { three_d -> failure_ratio = (three_d -> lyap_limit - not_expired) / three_d -> lyap_limit; make_results(three_d); outlet_anything(three_d -> search_outlet, gensym("search"), M_search_count, three_d -> search_out); } } void *three_d_new(t_symbol *s, int argc, t_atom *argv) { three_d_struct *three_d = (three_d_struct *) pd_new(three_d_class); if (three_d != NULL) { outlet_new(&three_d -> x_obj, &s_float); three_d -> outlets[0] = outlet_new(&three_d -> x_obj, &s_float); three_d -> outlets[1] = outlet_new(&three_d -> x_obj, &s_float); three_d -> search_outlet = outlet_new(&three_d -> x_obj, &s_list); three_d -> vars_outlet = outlet_new(&three_d -> x_obj, &s_list); three_d -> params_outlet = outlet_new(&three_d -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { three_d -> vars_init[M_x] = three_d -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); three_d -> vars_init[M_y] = three_d -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); three_d -> vars_init[M_z] = three_d -> vars[M_z] = (double) atom_getfloatarg(2, argc, argv); three_d -> a = (double) atom_getfloatarg(3, argc, argv); three_d -> b = (double) atom_getfloatarg(4, argc, argv); three_d -> c = (double) atom_getfloatarg(5, argc, argv); three_d -> d = (double) atom_getfloatarg(6, argc, argv); three_d -> e = (double) atom_getfloatarg(7, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for three_d fractal. Expecting 8 arguments."); } three_d -> vars_init[M_x] = 0; three_d -> vars_init[M_y] = 0; three_d -> vars_init[M_z] = 0; three_d -> a = 2.24; three_d -> b = 0.43; three_d -> c = -0.65; three_d -> d = -2.43; three_d -> e = 1; } constrain(three_d, NULL, 0, NULL); lyap(three_d, -1000000.0, 1000000.0, M_failure_limit); } return (void *)three_d; } void three_d_setup(void) { three_d_class = class_new(gensym("three_d"), (t_newmethod) three_d_new, 0, sizeof(three_d_struct), 0, A_GIMME, 0); class_addbang(three_d_class, (t_method) calculate); class_addmethod(three_d_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(three_d_class, (t_method) show, gensym("show"), 0); class_addmethod(three_d_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(three_d_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(three_d_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(three_d_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(three_d_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(three_d_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/libchaos.c0000644000076500007650000000516712076105251013066 0ustar hanshans#include #include #include "chaos.h" #define LY_ITERATIONS 50000 //#define LY_ABERATION 1e-6 #define LY_ABERATION 10e-15 /** * this expects the fractal to already be stable (ie iterate it a few hundred/thousand times). Steps as described by Julian Sprott 1. Start with any initial condition in the basin of attraction 2. Iterate until the orbit is on the attractor 3. Select (almost any) nearby point (separated by d0) 4. Advancce both orbits one iteration and calculate the new separation d1 5. Evaluate log(d1/d0) in any convienient base 6. Readjust one orbit so its separation is d0 in the same direction as d1 7. Repeat steps 4-6 many times and calculate the average of step 5 */ double lyapunov_eval(void *fractal, t_gotfn calc, int var_count, double *vars, double *test) { int i, j; double exponent = 0.0, sum = 0.0, d2, df, rs; double diff[MAX_VARS]; for(i = 0; i < LY_ITERATIONS; i++) { // 4. iterate each set calc(fractal, vars); calc(fractal, test); // 5. Evaluate d2 = 0.0; for(j = 0; j < var_count; j++) { diff[j] = test[j] - vars[j]; //fprintf(stderr, "vars[%d] = %0.30f\n test[%d] = %0.30f\n diff[%d] = %0.30f\n", // j, vars[j], j, test[j], j, diff[j]); d2 += diff[j] * diff[j]; } df = 1000000000000.0 * d2; rs = 1.0 / sqrt(df); sum += log(df); exponent = 0.721347 * sum / i; //fprintf(stderr, "%d\n d2 = %0.30f\n df = %0.30f\n rs = %0.30f\n sum = %0.30f\nexponent = %0.30f\n\n", // i, d2, df, rs, sum, exponent); // 6. adjust the orbit under test for(j = 0; j < var_count; j++) { test[j] = vars[j] + (rs * (test[j] - vars[j])); } } return exponent; } double lyapunov(void *fractal, t_gotfn calc, int var_count, double *vars) { int i; double test[MAX_VARS]; // 1. + 2. 'vars' is expected to be ready to start computing // 3. create a test set of variables test[0] = vars[0] + LY_ABERATION; for(i = 1; i < var_count; i++) { test[i] = vars[i]; } return lyapunov_eval(fractal, calc, var_count, vars, test); } double *lyapunov_full(void *fractal, t_gotfn calc, int var_count, double *vars, double *results) { int i, j; double initial[MAX_VARS]; double test[MAX_VARS]; // save the starting values for(i = 0; i < var_count; i++) { initial[i] = vars[i]; } for(i = 0; i < var_count; i++) { // aberate each variable in turn for(j = 0; j < var_count; j++) { if (j == i) { test[j] = vars[j] + LY_ABERATION; } else { test[j] = vars[j]; } } results[i] = lyapunov_eval(fractal, calc, var_count, vars, test); // set the vars back the initial values for(j = 0; j < var_count; j++) { vars[j] = initial[j]; } } return results; } chaos-0.2/LICENSE.txt0000644000076500007650000004325412076105251012760 0ustar hanshans GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. chaos-0.2/fractal-tools-help.pd0000644000076500007650000000147012076105251015154 0ustar hanshans#N canvas 680 295 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X floatatom 43 332 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 20 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 436 18 examples/readme-fractals; #X text 21 19 Base Attractor; #X obj 53 262 fractal-tools; #X obj 43 285 base3 0.1 1.18939 2.24148; #X msg 61 240 lyapunov 0 100 1000; #X obj 126 320 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 9 0 10 0; #X connect 10 0 2 0; #X connect 10 1 12 0; #X connect 10 2 12 1; #X connect 10 3 12 2; #X connect 11 0 9 0; #X connect 12 0 10 0; chaos-0.2/chaos.suo0000644000076500007650000001600012076105251012747 0ustar hanshansÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿþÿÿÿ þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot EntryÿÿÿÿÿÿÿÿÀß…wwO€ TaskListUserTasks$ÿÿÿÿIToolboxService ÿÿÿÿÿÿÿÿ…IVSMDPropertyBrowser*ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿþÿÿÿ!"þÿÿÿ$%&'()*+,þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðC Data XML Schema Dialog Editor Web Forms Components Windows FormsHTMLClipboard RingGeneralzE:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\DebuggerWatches  ÿÿÿÿDebuggerBreakpoints(ÿÿÿÿ†DebuggerExceptions&ÿÿÿÿÿÿÿÿDebuggerFindSource&ÿÿÿÿÿÿÿÿÿÿÿÿ –nC:\Program Files\Microsoft Visual Studio .NET\Vc7\crt\„C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\mfc\„C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\atl\DebuggerMemoryWindows, ÿÿÿÿTExternalFilesProjectContents:ÿÿÿÿÿÿÿÿÿÿÿÿDocumentWindowPositions0 ÿÿÿÿDocumentWindowUserData. ÿÿÿÿÿÿÿÿMultiStartupProj=;4{079DD347-F5E0-4784-9BCE-AF551691BA41}.dwStartupOpt=;StartupProjSolutionConfiguration,ÿÿÿÿÿÿÿÿÿÿÿÿ^ObjMgrContentsÿÿÿÿÿÿÿÿ?ClassViewContents$ÿÿÿÿþÿÿÿProjExplorerState$ÿÿÿÿÿÿÿÿ  ect=&{079DD347-F5E0-4784-9BCE-AF551691BA41};?{079DD347-F5E0-4784-9BCE-AF551691BA41}.Release|Win32.fBatchBld=;={079DD347-F5E0-4784-9BCE-AF551691BA41}.Debug|Win32.fBatchBld=; ActiveCfg=Debug;ç%Ò¯##G¶åá}'bm4Élü #Oÿ‡øÏ¤E chaos›Q ’E:\pd\add_ons\-=[ Ben Bogart ]=-\Chaos Math Externals\chaos\chaos.vcprojDebug|Win32DebugSettingsô.õ.ö. ø.÷.ù.ú.û.ü.ý. ÿ.,GeneralConfigSettingsVCBscMakeTool(EndConfigPropertiesRelUnloadedProjects"ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿchaos ÿÿÿÿÿÿÿÿÿÿÿÿ#lTaskListShortcuts$ÿÿÿÿÿÿÿÿÿÿÿÿ-ÿÿÿÿÿÿÿÿÿÿÿÿease|Win32DebugSettingsô.õ.ö. ø.÷.ù.ú.û.ü.ý. ÿ.,GeneralConfigSettingsVCBscMakeTool(EndConfigPropertiesXÏ chaos-0.2/henon-help.pd0000644000076500007650000000267612076105251013522 0ustar hanshans#N canvas 196 88 648 460 10; #X obj 263 81 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 314 82 5 0 0 0 - - -; #X floatatom 291 372 10 0 0 0 Y - -; #X floatatom 263 348 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 263 98 metro 50; #X obj 238 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 286 209 param 1.4 0.3; #X text 19 33 Chaos PD Externals - Copyright Ben Bogart 2002; #X text 20 17 Henon Attractor; #X obj 263 294 henon 1 1 1.4 0.3; #X msg 273 176 reset; #X text 318 176 Reset to initial state from creation arguments; #X text 390 209 Modify parameters; #X obj 310 318 search-tools; #X obj 26 187 metro 50; #X obj 26 163 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 77 162 5 0 0 0 - - -; #X floatatom 71 358 5 0 0 0 - - -; #X text 2 139 Calculate; #X text 55 234 Reset To Initial Conditions; #X text 53 273 Modify Parameters; #X floatatom 26 358 5 0 0 0 - - -; #X text 20 337 Output; #X msg 55 256 param 1.4 0.3; #X obj 26 300 henon; #X msg 56 216 reset 1 1; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 7 0 10 0; #X connect 10 0 3 0; #X connect 10 1 2 0; #X connect 10 2 14 0; #X connect 10 3 14 1; #X connect 10 4 14 2; #X connect 11 0 10 0; #X connect 14 0 10 0; #X connect 15 0 25 0; #X connect 16 0 15 0; #X connect 17 0 15 1; #X connect 24 0 25 0; #X connect 25 0 22 0; #X connect 25 1 18 0; #X connect 26 0 25 0; chaos-0.2/latoomutalpha-help.pd0000644000076500007650000000214412076105251015253 0ustar hanshans#N canvas 487 49 585 488 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X msg 111 243 param -0.966918 2.87988 0.756145 0.744728; #X msg 111 264 param -2.90515 -2.03043 1.44055 0.70307; #X floatatom 138 404 10 0 0 0 Y - -; #X floatatom 43 367 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 43 347 latoomutalpha 0.1 0.1 -2.90515 -2.03043 1.44055 0.70307 ; #X obj 289 374 search-tools; #X connect 0 0 12 0; #X connect 1 0 12 1; #X connect 4 0 15 0; #X connect 5 0 15 0; #X connect 6 0 15 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 15 0 8 0; #X connect 15 1 7 0; #X connect 15 2 16 0; #X connect 15 3 16 1; #X connect 15 4 16 2; #X connect 16 0 15 0; chaos-0.2/martin-help.pd0000644000076500007650000000220312076105251013667 0ustar hanshans#N canvas 203 283 593 496 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 32 8 -262144 -1 -1 0 1; #X floatatom 94 135 5 0 0 0 - - -; #X text 89 174 Reset To Initial Conditions; #X text 102 216 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X floatatom 51 451 10 0 0 0 Y - -; #X floatatom 42 427 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 42 347 martin; #X text 143 429 This fractal exhibits chaotic tendencies when A (param) is in the vicinity of an odd multiple of PI.; #X msg 97 237 param 3.14159; #X text 21 19 Martin Attractor; #X obj 68 379 search-tools; #X obj 204 344 print vars; #X obj 239 317 print param; #X connect 0 0 9 0; #X connect 1 0 9 1; #X connect 4 0 12 0; #X connect 9 0 12 0; #X connect 10 0 12 0; #X connect 12 0 6 0; #X connect 12 1 5 0; #X connect 12 2 16 0; #X connect 12 3 16 1; #X connect 12 3 17 0; #X connect 12 4 16 2; #X connect 12 4 18 0; #X connect 14 0 12 0; #X connect 16 0 12 0; chaos-0.2/latoomutalpha.c0000644000076500007650000003432312076105251014150 0ustar hanshans/* latoomutalpha Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -3 #define M_a_hi 3 #define M_b_lo -3 #define M_b_hi 3 #define M_c_lo 0.5 #define M_c_hi 1.5 #define M_d_lo 0.5 #define M_d_hi 1.5 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "latoomutalpha v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *latoomutalpha_class; typedef struct latoomutalpha_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } latoomutalpha_struct; static void calc(latoomutalpha_struct *latoomutalpha, double *vars) { double x_0, y_0; x_0 =sin(vars[M_y]*latoomutalpha -> b)+pow(sin(vars[M_x]*latoomutalpha -> b),2)+pow(sin(vars[M_x]*latoomutalpha -> b),3); y_0 =sin(vars[M_x]*latoomutalpha -> a)+pow(sin(vars[M_y]*latoomutalpha -> a),2)+pow(sin(vars[M_y]*latoomutalpha -> c),3); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(latoomutalpha_struct *latoomutalpha) { calc(latoomutalpha, latoomutalpha -> vars); outlet_float(latoomutalpha -> outlets[M_y - 1], latoomutalpha -> vars[M_y]); outlet_float(latoomutalpha -> x_obj.ob_outlet, latoomutalpha -> vars[M_x]); } // end calculate static void reset(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { latoomutalpha -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); latoomutalpha -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { latoomutalpha -> vars[M_x] = latoomutalpha -> vars_init[M_x]; latoomutalpha -> vars[M_y] = latoomutalpha -> vars_init[M_y]; } // end if } // end reset static char *classify(latoomutalpha_struct *latoomutalpha) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((latoomutalpha -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((latoomutalpha -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((latoomutalpha -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((latoomutalpha -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(latoomutalpha_struct *latoomutalpha) { SETFLOAT(&latoomutalpha -> search_out[0], latoomutalpha -> lyap_exp); SETSYMBOL(&latoomutalpha -> search_out[1], gensym(classify(latoomutalpha))); SETFLOAT(&latoomutalpha -> search_out[2], latoomutalpha -> failure_ratio); SETFLOAT(&latoomutalpha -> vars_out[M_x], latoomutalpha -> vars[M_x]); SETFLOAT(&latoomutalpha -> vars_out[M_y], latoomutalpha -> vars[M_y]); SETFLOAT(&latoomutalpha -> params_out[M_a], latoomutalpha -> a); SETFLOAT(&latoomutalpha -> params_out[M_b], latoomutalpha -> b); SETFLOAT(&latoomutalpha -> params_out[M_c], latoomutalpha -> c); SETFLOAT(&latoomutalpha -> params_out[M_d], latoomutalpha -> d); outlet_list(latoomutalpha -> params_outlet, gensym("list"), M_param_count, latoomutalpha -> params_out); outlet_list(latoomutalpha -> vars_outlet, gensym("list"), M_var_count, latoomutalpha -> vars_out); } static void show(latoomutalpha_struct *latoomutalpha) { make_results(latoomutalpha); outlet_anything(latoomutalpha -> search_outlet, gensym("show"), M_search_count, latoomutalpha -> search_out); } static void param(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for latoomutalpha fractal. Expecting 4 arguments."); return; } latoomutalpha -> a = (double) atom_getfloatarg(0, argc, argv); latoomutalpha -> b = (double) atom_getfloatarg(1, argc, argv); latoomutalpha -> c = (double) atom_getfloatarg(2, argc, argv); latoomutalpha -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(latoomutalpha_struct *latoomutalpha, t_floatarg l, t_floatarg h, t_floatarg lim) { latoomutalpha -> lyap_lo = l; latoomutalpha -> lyap_hi = h; latoomutalpha -> lyap_limit = (double) ((int) lim); } static void elyap(latoomutalpha_struct *latoomutalpha) { double results[M_var_count]; int i; if (lyapunov_full((void *) latoomutalpha, (t_gotfn) calc, M_var_count, latoomutalpha -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(latoomutalpha_struct *latoomutalpha) { if (latoomutalpha -> a_lo < M_a_lo) { latoomutalpha -> a_lo = M_a_lo; } if (latoomutalpha -> a_lo > M_a_hi) { latoomutalpha -> a_lo = M_a_hi; } if (latoomutalpha -> a_hi < M_a_lo) { latoomutalpha -> a_hi = M_a_lo; } if (latoomutalpha -> a_hi > M_a_hi) { latoomutalpha -> a_hi = M_a_hi; } if (latoomutalpha -> b_lo < M_b_lo) { latoomutalpha -> b_lo = M_b_lo; } if (latoomutalpha -> b_lo > M_b_hi) { latoomutalpha -> b_lo = M_b_hi; } if (latoomutalpha -> b_hi < M_b_lo) { latoomutalpha -> b_hi = M_b_lo; } if (latoomutalpha -> b_hi > M_b_hi) { latoomutalpha -> b_hi = M_b_hi; } if (latoomutalpha -> c_lo < M_c_lo) { latoomutalpha -> c_lo = M_c_lo; } if (latoomutalpha -> c_lo > M_c_hi) { latoomutalpha -> c_lo = M_c_hi; } if (latoomutalpha -> c_hi < M_c_lo) { latoomutalpha -> c_hi = M_c_lo; } if (latoomutalpha -> c_hi > M_c_hi) { latoomutalpha -> c_hi = M_c_hi; } if (latoomutalpha -> d_lo < M_d_lo) { latoomutalpha -> d_lo = M_d_lo; } if (latoomutalpha -> d_lo > M_d_hi) { latoomutalpha -> d_lo = M_d_hi; } if (latoomutalpha -> d_hi < M_d_lo) { latoomutalpha -> d_hi = M_d_lo; } if (latoomutalpha -> d_hi > M_d_hi) { latoomutalpha -> d_hi = M_d_hi; } } static void constrain(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges latoomutalpha -> a_lo = M_a_lo; latoomutalpha -> a_hi = M_a_hi; latoomutalpha -> b_lo = M_b_lo; latoomutalpha -> b_hi = M_b_hi; latoomutalpha -> c_lo = M_c_lo; latoomutalpha -> c_hi = M_c_hi; latoomutalpha -> d_lo = M_d_lo; latoomutalpha -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; latoomutalpha -> a_lo = latoomutalpha -> a - a_spread; latoomutalpha -> a_hi = latoomutalpha -> a + a_spread; latoomutalpha -> b_lo = latoomutalpha -> b - b_spread; latoomutalpha -> b_hi = latoomutalpha -> b + b_spread; latoomutalpha -> c_lo = latoomutalpha -> c - c_spread; latoomutalpha -> c_hi = latoomutalpha -> c + c_spread; latoomutalpha -> d_lo = latoomutalpha -> d - d_spread; latoomutalpha -> d_hi = latoomutalpha -> d + d_spread; limiter(latoomutalpha); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for latoomutalpha constraints, requires 8 values, got %d", argc); return; } latoomutalpha -> a_lo = atom_getfloat(arg++); latoomutalpha -> a_hi = atom_getfloat(arg++); latoomutalpha -> b_lo = atom_getfloat(arg++); latoomutalpha -> b_hi = atom_getfloat(arg++); latoomutalpha -> c_lo = atom_getfloat(arg++); latoomutalpha -> c_hi = atom_getfloat(arg++); latoomutalpha -> d_lo = atom_getfloat(arg++); latoomutalpha -> d_hi = atom_getfloat(arg++); limiter(latoomutalpha); } static void search(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = latoomutalpha -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = latoomutalpha -> a; double temp_b = latoomutalpha -> b; double temp_c = latoomutalpha -> c; double temp_d = latoomutalpha -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], latoomutalpha -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: latoomutalpha -> a = (drand48() * (latoomutalpha -> a_hi - latoomutalpha -> a_lo)) + latoomutalpha -> a_lo; latoomutalpha -> b = (drand48() * (latoomutalpha -> b_hi - latoomutalpha -> b_lo)) + latoomutalpha -> b_lo; latoomutalpha -> c = (drand48() * (latoomutalpha -> c_hi - latoomutalpha -> c_lo)) + latoomutalpha -> c_lo; latoomutalpha -> d = (drand48() * (latoomutalpha -> d_hi - latoomutalpha -> d_lo)) + latoomutalpha -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(latoomutalpha, NULL, argc, vars); do { calc(latoomutalpha, latoomutalpha -> vars); } while(jump--); latoomutalpha -> lyap_exp = lyapunov((void *) latoomutalpha, (t_gotfn) calc, M_var_count, (double *) latoomutalpha -> vars); if (isnan(latoomutalpha -> lyap_exp)) { not_found = 1; } if (latoomutalpha -> lyap_exp < latoomutalpha -> lyap_lo || latoomutalpha -> lyap_exp > latoomutalpha -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(latoomutalpha, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) latoomutalpha -> lyap_limit); post("Try using wider constraints."); latoomutalpha -> a = temp_a; latoomutalpha -> b = temp_b; latoomutalpha -> c = temp_c; latoomutalpha -> d = temp_d; outlet_anything(latoomutalpha -> search_outlet, gensym("invalid"), 0, NULL); } else { latoomutalpha -> failure_ratio = (latoomutalpha -> lyap_limit - not_expired) / latoomutalpha -> lyap_limit; make_results(latoomutalpha); outlet_anything(latoomutalpha -> search_outlet, gensym("search"), M_search_count, latoomutalpha -> search_out); } } void *latoomutalpha_new(t_symbol *s, int argc, t_atom *argv) { latoomutalpha_struct *latoomutalpha = (latoomutalpha_struct *) pd_new(latoomutalpha_class); if (latoomutalpha != NULL) { outlet_new(&latoomutalpha -> x_obj, &s_float); latoomutalpha -> outlets[0] = outlet_new(&latoomutalpha -> x_obj, &s_float); latoomutalpha -> search_outlet = outlet_new(&latoomutalpha -> x_obj, &s_list); latoomutalpha -> vars_outlet = outlet_new(&latoomutalpha -> x_obj, &s_list); latoomutalpha -> params_outlet = outlet_new(&latoomutalpha -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { latoomutalpha -> vars_init[M_x] = latoomutalpha -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); latoomutalpha -> vars_init[M_y] = latoomutalpha -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); latoomutalpha -> a = (double) atom_getfloatarg(2, argc, argv); latoomutalpha -> b = (double) atom_getfloatarg(3, argc, argv); latoomutalpha -> c = (double) atom_getfloatarg(4, argc, argv); latoomutalpha -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for latoomutalpha fractal. Expecting 6 arguments."); } latoomutalpha -> vars_init[M_x] = 0.1; latoomutalpha -> vars_init[M_y] = 0.1; latoomutalpha -> a = 1; latoomutalpha -> b = 1; latoomutalpha -> c = 1; latoomutalpha -> d = 1; } constrain(latoomutalpha, NULL, 0, NULL); lyap(latoomutalpha, -1000000.0, 1000000.0, M_failure_limit); } return (void *)latoomutalpha; } void latoomutalpha_setup(void) { latoomutalpha_class = class_new(gensym("latoomutalpha"), (t_newmethod) latoomutalpha_new, 0, sizeof(latoomutalpha_struct), 0, A_GIMME, 0); class_addbang(latoomutalpha_class, (t_method) calculate); class_addmethod(latoomutalpha_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(latoomutalpha_class, (t_method) show, gensym("show"), 0); class_addmethod(latoomutalpha_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(latoomutalpha_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(latoomutalpha_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(latoomutalpha_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(latoomutalpha_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(latoomutalpha_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/search-tools.pd0000644000076500007650000001324512076105251014062 0ustar hanshans#N canvas 619 310 464 533 10; #X obj -97 556 outlet; #X obj -97 2 cnv 15 450 220 empty empty Searching_Commands 2 9 1 10 -233017 -66577 0; #X msg 104 83 constrain; #X msg 104 104 constrain \$1; #X text -77 104 % Constraint; #X text -77 82 No Constraint; #X msg 104 30 search; #X obj 221 52 nbx 5 17 -1e+37 1e+37 0 0 \$0-search_v2 empty empty 0 -6 1153 10 -262144 -1 -1 0 256; #X obj 172 52 nbx 5 17 -1e+37 1e+37 0 0 \$0-search_v1 empty empty 0 -6 1153 10 -262144 -1 -1 0 256; #X text -78 48 Search w/ inits; #X text -78 29 Search w/ default inits; #X obj 86 143 bng 17 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text -76 142 Set Lyapunov Limits; #X obj 287 143 nbx 5 17 -1e+37 1e+37 0 0 \$0-lyapunov_v3 empty failure 0 -6 1153 10 -262144 -1 -1 0 256; #X obj 238 143 nbx 5 17 -1e+37 1e+37 0 0 \$0-lyapunov_v2 empty high 0 -6 1153 10 -262144 -1 -1 0 256; #X obj 189 143 nbx 5 17 -1e+37 1e+37 0 0 \$0-lyapunov_v1 empty low 0 -6 1153 10 -262144 -1 -1 0 256; #N canvas 0 22 509 236 lyapunov 0; #X obj 42 26 inlet; #X obj 83 26 r \$0-lyapunov_v1; #X obj 101 61 pack f f f; #X obj 203 27 r \$0-lyapunov_v2; #X obj 320 27 r \$0-lyapunov_v3; #X msg 101 84 lyapunov \$1 \$2 \$3; #X obj 101 108 s \$0-outlet; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 3 0 2 1; #X connect 4 0 2 2; #X connect 5 0 6 0; #X restore 106 143 pd lyapunov; #X obj 86 52 bng 17 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #N canvas 0 22 374 205 search 0; #X obj 104 104 pack f f; #X msg 104 127 search \$1 \$2; #X obj 83 26 r \$0-search_v1; #X obj 186 26 r \$0-search_v2; #X obj 94 63 f; #X obj 104 151 s \$0-outlet; #X obj 18 26 inlet; #X connect 0 0 1 0; #X connect 1 0 5 0; #X connect 2 0 4 1; #X connect 3 0 0 1; #X connect 4 0 0 0; #X connect 6 0 4 0; #X restore 104 52 pd search; #X text -76 164 Extended Lyapunov; #X msg 104 165 elyapunov; #X msg 104 186 show; #X text -75 198 Get Attractor Info; #X obj 104 226 s \$0-outlet; #X obj -97 535 r \$0-outlet; #X obj -14 535 inlet; #X obj -14 556 s \$0-inlet; #X obj -97 226 cnv 15 450 300 empty empty Search_Results 2 9 1 10 -233017 -66577 0; #N canvas 48 644 700 296 get_results 0; #X msg 5 39 set \$1; #X obj 5 17 symbol; #X obj 5 61 outlet; #X obj 150 38 s \$0-lyapunov; #X obj 190 89 s \$0-failure_rate; #X obj 319 32 s \$0-v1; #X obj 343 53 s \$0-v2; #X obj 367 75 s \$0-v3; #X obj 473 31 s \$0-p1; #X obj 497 52 s \$0-p2; #X obj 521 74 s \$0-p3; #X obj 170 62 s \$0-classification; #X obj 44 222 r \$0-classification; #X msg 44 243 set \$1; #X obj 44 264 outlet; #X obj 5 -6 r \$0-inlet; #X obj 80 117 print debug; #X obj 131 11 unpack s 0 s 0; #X obj 319 9 unpack 0 0 0 0 0 0; #X obj 391 96 s \$0-v4; #X obj 415 117 s \$0-v5; #X obj 440 138 s \$0-v6; #X obj 473 9 unpack 0 0 0 0 0 0; #X obj 545 96 s \$0-p4; #X obj 569 117 s \$0-p5; #X obj 594 137 s \$0-p6; #X obj 318 -12 r \$0-inlet_var; #X obj 473 -11 r \$0-inlet_param; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 15 0 1 0; #X connect 15 0 17 0; #X connect 17 1 3 0; #X connect 17 2 11 0; #X connect 17 3 4 0; #X connect 18 0 5 0; #X connect 18 1 6 0; #X connect 18 2 7 0; #X connect 18 3 19 0; #X connect 18 4 20 0; #X connect 18 5 21 0; #X connect 22 0 8 0; #X connect 22 1 9 0; #X connect 22 2 10 0; #X connect 22 3 23 0; #X connect 22 4 24 0; #X connect 22 5 25 0; #X connect 26 0 18 0; #X connect 27 0 22 0; #X restore -14 267 pd get_results; #X msg -14 288 search; #X msg 79 288 NOCBNS; #X text 184 290 Classification; #X obj 79 309 nbx 10 17 -1e+37 1e+37 0 0 empty \$0-lyapunov empty 0 -6 577 10 -262144 -1 -1 -0.482697 256; #X obj 79 330 nbx 10 17 -1e+37 1e+37 0 0 empty \$0-failure_rate empty 0 -6 577 10 -262144 -1 -1 0.005 256; #X obj -14 371 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v1 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj -14 391 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v2 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj -14 411 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v3 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj 111 371 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p1 empty 0 -6 577 10 -262144 -1 -1 0.17869 256; #X obj 111 391 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p2 empty 0 -6 577 10 -262144 -1 -1 0.437724 256; #X obj 111 411 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p3 empty 0 -6 577 10 -262144 -1 -1 -2.31304 256; #X text 183 331 Failure Rate; #X text 184 309 Lyapunov Exponent; #X text 48 372 Var 1; #X text 48 392 Var 2; #X text 48 412 Var 3; #X text 174 373 Param 1; #X text 174 393 Param 2; #X text 174 413 Param 3; #X obj 188 164 examples/readme-lyapunov; #X obj 171 29 examples/readme-searching; #X obj -14 431 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v4 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj -14 451 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v5 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj -14 471 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-v6 empty 0 -6 577 10 -262144 -1 -1 0 256; #X obj 111 431 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p4 empty 0 -6 577 10 -262144 -1 -1 -2.74459 256; #X obj 111 451 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p5 empty 0 -6 577 10 -262144 -1 -1 0.00541449 256; #X obj 111 471 nbx 5 17 -1e+37 1e+37 0 0 empty \$0-p6 empty 0 -6 577 10 -262144 -1 -1 1.3485 256; #X text 48 432 Var 4; #X text 48 452 Var 5; #X text 48 472 Var 6; #X text 174 433 Param 4; #X text 174 453 Param 5; #X text 174 473 Param 6; #X obj 62 535 inlet; #X obj 166 535 inlet; #X obj 62 556 s \$0-inlet_var; #X obj 166 556 s \$0-inlet_param; #X obj 198 104 nbx 5 17 -1e+37 1e+37 0 0 empty empty % 0 -6 1 10 -262144 -1 -1 0 256; #X connect 2 0 23 0; #X connect 3 0 23 0; #X connect 6 0 23 0; #X connect 11 0 16 0; #X connect 17 0 18 0; #X connect 20 0 23 0; #X connect 21 0 23 0; #X connect 24 0 0 0; #X connect 25 0 26 0; #X connect 28 0 29 0; #X connect 28 1 30 0; #X connect 62 0 64 0; #X connect 63 0 65 0; #X connect 66 0 3 0; chaos-0.2/rossler.c0000644000076500007650000003230712076105251012767 0ustar hanshans/* rossler Attractor PD External */ /* Copyright Ben Bogart, 2002 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_h_lo -1000 #define M_h_hi 1000 #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_h 0 #define M_a 1 #define M_b 2 #define M_c 3 #define M_x 0 #define M_y 1 #define M_z 2 #define M_param_count 4 #define M_var_count 3 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "rossler v0.0, by Ben Bogart, 2002"; t_class *rossler_class; typedef struct rossler_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double h, h_lo, h_hi, a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } rossler_struct; static void calc(rossler_struct *rossler, double *vars) { double x_0, y_0, z_0; x_0 =vars[M_x]+rossler -> h*(-vars[M_y]-vars[M_z]); y_0 =vars[M_y]+rossler -> h*(vars[M_x]+(rossler -> a*vars[M_y])); z_0 =vars[M_z]+rossler -> h*(rossler -> b+(vars[M_x]*vars[M_z])-(rossler -> c*vars[M_z])); vars[M_x] = x_0; vars[M_y] = y_0; vars[M_z] = z_0; } // end calc static void calculate(rossler_struct *rossler) { calc(rossler, rossler -> vars); outlet_float(rossler -> outlets[M_z - 1], rossler -> vars[M_z]); outlet_float(rossler -> outlets[M_y - 1], rossler -> vars[M_y]); outlet_float(rossler -> x_obj.ob_outlet, rossler -> vars[M_x]); } // end calculate static void reset(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { rossler -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); rossler -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); rossler -> vars[M_z] = (double) atom_getfloatarg(M_z, argc, argv); } else { rossler -> vars[M_x] = rossler -> vars_init[M_x]; rossler -> vars[M_y] = rossler -> vars_init[M_y]; rossler -> vars[M_z] = rossler -> vars_init[M_z]; } // end if } // end reset static char *classify(rossler_struct *rossler) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((rossler -> h - M_h_lo) * (1.0 / (M_h_hi - M_h_lo))) * 26)]; buff[1] = c[(int) (((rossler -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[2] = c[(int) (((rossler -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[3] = c[(int) (((rossler -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(rossler_struct *rossler) { SETFLOAT(&rossler -> search_out[0], rossler -> lyap_exp); SETSYMBOL(&rossler -> search_out[1], gensym(classify(rossler))); SETFLOAT(&rossler -> search_out[2], rossler -> failure_ratio); SETFLOAT(&rossler -> vars_out[M_x], rossler -> vars[M_x]); SETFLOAT(&rossler -> vars_out[M_y], rossler -> vars[M_y]); SETFLOAT(&rossler -> vars_out[M_z], rossler -> vars[M_z]); SETFLOAT(&rossler -> params_out[M_h], rossler -> h); SETFLOAT(&rossler -> params_out[M_a], rossler -> a); SETFLOAT(&rossler -> params_out[M_b], rossler -> b); SETFLOAT(&rossler -> params_out[M_c], rossler -> c); outlet_list(rossler -> params_outlet, gensym("list"), M_param_count, rossler -> params_out); outlet_list(rossler -> vars_outlet, gensym("list"), M_var_count, rossler -> vars_out); } static void show(rossler_struct *rossler) { make_results(rossler); outlet_anything(rossler -> search_outlet, gensym("show"), M_search_count, rossler -> search_out); } static void param(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for rossler fractal. Expecting 4 arguments."); return; } rossler -> h = (double) atom_getfloatarg(0, argc, argv); rossler -> a = (double) atom_getfloatarg(1, argc, argv); rossler -> b = (double) atom_getfloatarg(2, argc, argv); rossler -> c = (double) atom_getfloatarg(3, argc, argv); } static void seed(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(rossler_struct *rossler, t_floatarg l, t_floatarg h, t_floatarg lim) { rossler -> lyap_lo = l; rossler -> lyap_hi = h; rossler -> lyap_limit = (double) ((int) lim); } static void elyap(rossler_struct *rossler) { double results[M_var_count]; int i; if (lyapunov_full((void *) rossler, (t_gotfn) calc, M_var_count, rossler -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(rossler_struct *rossler) { if (rossler -> h_lo < M_h_lo) { rossler -> h_lo = M_h_lo; } if (rossler -> h_lo > M_h_hi) { rossler -> h_lo = M_h_hi; } if (rossler -> h_hi < M_h_lo) { rossler -> h_hi = M_h_lo; } if (rossler -> h_hi > M_h_hi) { rossler -> h_hi = M_h_hi; } if (rossler -> a_lo < M_a_lo) { rossler -> a_lo = M_a_lo; } if (rossler -> a_lo > M_a_hi) { rossler -> a_lo = M_a_hi; } if (rossler -> a_hi < M_a_lo) { rossler -> a_hi = M_a_lo; } if (rossler -> a_hi > M_a_hi) { rossler -> a_hi = M_a_hi; } if (rossler -> b_lo < M_b_lo) { rossler -> b_lo = M_b_lo; } if (rossler -> b_lo > M_b_hi) { rossler -> b_lo = M_b_hi; } if (rossler -> b_hi < M_b_lo) { rossler -> b_hi = M_b_lo; } if (rossler -> b_hi > M_b_hi) { rossler -> b_hi = M_b_hi; } if (rossler -> c_lo < M_c_lo) { rossler -> c_lo = M_c_lo; } if (rossler -> c_lo > M_c_hi) { rossler -> c_lo = M_c_hi; } if (rossler -> c_hi < M_c_lo) { rossler -> c_hi = M_c_lo; } if (rossler -> c_hi > M_c_hi) { rossler -> c_hi = M_c_hi; } } static void constrain(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges rossler -> h_lo = M_h_lo; rossler -> h_hi = M_h_hi; rossler -> a_lo = M_a_lo; rossler -> a_hi = M_a_hi; rossler -> b_lo = M_b_lo; rossler -> b_hi = M_b_hi; rossler -> c_lo = M_c_lo; rossler -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double h_spread = ((M_h_hi - M_h_lo) * percent) / 2; double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; rossler -> h_lo = rossler -> h - h_spread; rossler -> h_hi = rossler -> h + h_spread; rossler -> a_lo = rossler -> a - a_spread; rossler -> a_hi = rossler -> a + a_spread; rossler -> b_lo = rossler -> b - b_spread; rossler -> b_hi = rossler -> b + b_spread; rossler -> c_lo = rossler -> c - c_spread; rossler -> c_hi = rossler -> c + c_spread; limiter(rossler); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for rossler constraints, requires 8 values, got %d", argc); return; } rossler -> h_lo = atom_getfloat(arg++); rossler -> h_hi = atom_getfloat(arg++); rossler -> a_lo = atom_getfloat(arg++); rossler -> a_hi = atom_getfloat(arg++); rossler -> b_lo = atom_getfloat(arg++); rossler -> b_hi = atom_getfloat(arg++); rossler -> c_lo = atom_getfloat(arg++); rossler -> c_hi = atom_getfloat(arg++); limiter(rossler); } static void search(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = rossler -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_h = rossler -> h; double temp_a = rossler -> a; double temp_b = rossler -> b; double temp_c = rossler -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], rossler -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: rossler -> h = (drand48() * (rossler -> h_hi - rossler -> h_lo)) + rossler -> h_lo; rossler -> a = (drand48() * (rossler -> a_hi - rossler -> a_lo)) + rossler -> a_lo; rossler -> b = (drand48() * (rossler -> b_hi - rossler -> b_lo)) + rossler -> b_lo; rossler -> c = (drand48() * (rossler -> c_hi - rossler -> c_lo)) + rossler -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(rossler, NULL, argc, vars); do { calc(rossler, rossler -> vars); } while(jump--); rossler -> lyap_exp = lyapunov((void *) rossler, (t_gotfn) calc, M_var_count, (double *) rossler -> vars); if (isnan(rossler -> lyap_exp)) { not_found = 1; } if (rossler -> lyap_exp < rossler -> lyap_lo || rossler -> lyap_exp > rossler -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(rossler, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) rossler -> lyap_limit); post("Try using wider constraints."); rossler -> h = temp_h; rossler -> a = temp_a; rossler -> b = temp_b; rossler -> c = temp_c; outlet_anything(rossler -> search_outlet, gensym("invalid"), 0, NULL); } else { rossler -> failure_ratio = (rossler -> lyap_limit - not_expired) / rossler -> lyap_limit; make_results(rossler); outlet_anything(rossler -> search_outlet, gensym("search"), M_search_count, rossler -> search_out); } } void *rossler_new(t_symbol *s, int argc, t_atom *argv) { rossler_struct *rossler = (rossler_struct *) pd_new(rossler_class); if (rossler != NULL) { outlet_new(&rossler -> x_obj, &s_float); rossler -> outlets[0] = outlet_new(&rossler -> x_obj, &s_float); rossler -> outlets[1] = outlet_new(&rossler -> x_obj, &s_float); rossler -> search_outlet = outlet_new(&rossler -> x_obj, &s_list); rossler -> vars_outlet = outlet_new(&rossler -> x_obj, &s_list); rossler -> params_outlet = outlet_new(&rossler -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { rossler -> vars_init[M_x] = rossler -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); rossler -> vars_init[M_y] = rossler -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); rossler -> vars_init[M_z] = rossler -> vars[M_z] = (double) atom_getfloatarg(2, argc, argv); rossler -> h = (double) atom_getfloatarg(3, argc, argv); rossler -> a = (double) atom_getfloatarg(4, argc, argv); rossler -> b = (double) atom_getfloatarg(5, argc, argv); rossler -> c = (double) atom_getfloatarg(6, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for rossler fractal. Expecting 7 arguments."); } rossler -> vars_init[M_x] = 0.1; rossler -> vars_init[M_y] = 0; rossler -> vars_init[M_z] = 0; rossler -> h = 0.01; rossler -> a = 0.2; rossler -> b = 0.2; rossler -> c = 5.7; } constrain(rossler, NULL, 0, NULL); lyap(rossler, -1000000.0, 1000000.0, M_failure_limit); } return (void *)rossler; } void rossler_setup(void) { rossler_class = class_new(gensym("rossler"), (t_newmethod) rossler_new, 0, sizeof(rossler_struct), 0, A_GIMME, 0); class_addbang(rossler_class, (t_method) calculate); class_addmethod(rossler_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(rossler_class, (t_method) show, gensym("show"), 0); class_addmethod(rossler_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(rossler_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(rossler_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(rossler_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(rossler_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(rossler_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/base3-help.pd0000644000076500007650000000147012076105251013377 0ustar hanshans#N canvas 174 217 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X floatatom 43 332 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 20 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 436 18 examples/readme-fractals; #X text 21 19 Base Attractor; #X obj 53 262 fractal-tools; #X obj 43 285 base3 0.1 1.18939 2.24148; #X msg 61 240 lyapunov 0 100 1000; #X obj 126 320 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 9 0 10 0; #X connect 10 0 2 0; #X connect 10 1 12 0; #X connect 10 2 12 1; #X connect 10 3 12 2; #X connect 11 0 9 0; #X connect 12 0 10 0; chaos-0.2/Makefile0000644000076500007650000003702412076105251012573 0ustar hanshans## Pd library template version 1.0.11 # For instructions on how to use this template, see: # http://puredata.info/docs/developer/MakefileTemplate LIBRARY_NAME = chaos # add your .c source files, one object per file, to the SOURCES # variable, help files will be included automatically, and for GUI # objects, the matching .tcl file too SOURCES = attract1.c base3.c base.c dejong.c gingerbreadman.c henon.c hopalong.c ikeda.c latoocarfian.c latoomutalpha.c latoomutbeta.c latoomutgamma.c logistic.c lorenz.c lotkavolterra.c martin.c mlogistic.c pickover.c popcorn.c quadruptwo.c rossler.c standardmap.c strange1.c tent.c three_d.c threeply.c tinkerbell.c unity.c # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will # be included automatically PDOBJECTS = fractal-tools.pd search-tools.pd # example patches and related files, in the 'examples' subfolder EXAMPLES = loop.pd martin-test-help.pd popcorn-test-help.pd quaruptwo-test-help.pd readme-frac-format.pd readme-fractals.pd readme-gen-fractal.pd readme-lyapunov.pd readme-operation.pd readme-parameter-ranges.pd readme-searching.pd # manuals and related files, in the 'manual' subfolder MANUAL = # if you want to include any other files in the source and binary tarballs, # list them here. This can be anything from header files, test patches, # documentation, etc. README.txt and LICENSE.txt are required and therefore # automatically included EXTRA_DIST = chaos.ncb chaos.sln chaos.suo chaos.vcproj Makefile.nt # Customization Note: added to MinGW's ALL_CFLAGS below #------------------------------------------------------------------------------# # # things you might need to edit if you are using other C libraries # #------------------------------------------------------------------------------# ALL_CFLAGS = -I"$(PD_INCLUDE)" ALL_LDFLAGS = SHARED_LDFLAGS = ALL_LIBS = #------------------------------------------------------------------------------# # # you shouldn't need to edit anything below here, if we did it right :) # #------------------------------------------------------------------------------# # these can be set from outside without (usually) breaking the build CFLAGS = -Wall -W -g LDFLAGS = LIBS = # get library version from meta file LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd) ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"' PD_INCLUDE = $(PD_PATH)/include/pd # where to install the library, overridden below depending on platform prefix = /usr/local libdir = $(prefix)/lib pkglibdir = $(libdir)/pd-externals objectsdir = $(pkglibdir) INSTALL = install INSTALL_PROGRAM = $(INSTALL) -p -m 644 INSTALL_DATA = $(INSTALL) -p -m 644 INSTALL_DIR = $(INSTALL) -p -m 755 -d ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows) DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION) UNAME := $(shell uname -s) ifeq ($(UNAME),Darwin) CPU := $(shell uname -p) ifeq ($(CPU),arm) # iPhone/iPod Touch SOURCES += $(SOURCES_iphoneos) EXTENSION = pd_darwin SHARED_EXTENSION = dylib OS = iphoneos PD_PATH = /Applications/Pd-extended.app/Contents/Resources IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin CC=$(IPHONE_BASE)/gcc CPP=$(IPHONE_BASE)/cpp CXX=$(IPHONE_BASE)/g++ ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6 OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS) ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT) ALL_LIBS += -lc $(LIBS_iphoneos) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) else # Mac OS X SOURCES += $(SOURCES_macosx) EXTENSION = pd_darwin SHARED_EXTENSION = dylib OS = macosx PD_PATH = /Applications/Pd-extended.app/Contents/Resources OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast # build universal 32-bit on 10.4 and 32/64 on newer ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8) FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4 else FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 SOURCES += $(SOURCES_iphoneos) endif ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include # if the 'pd' binary exists, check the linking against it to aid with stripping BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd) ALL_LDFLAGS += $(FAT_FLAGS) -bundle $(BUNDLE_LOADER) -undefined dynamic_lookup -L/sw/lib SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \ -install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0 ALL_LIBS += -lc $(LIBS_macosx) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) # install into ~/Library/Pd on Mac OS X since /usr/local isn't used much pkglibdir=$(HOME)/Library/Pd endif endif # Tho Android uses Linux, we use this fake uname to provide an easy way to # setup all this things needed to cross-compile for Android using the NDK ifeq ($(UNAME),ANDROID) CPU := arm SOURCES += $(SOURCES_android) EXTENSION = pd_linux SHARED_EXTENSION = so OS = android PD_PATH = /usr NDK_BASE := /usr/local/android-ndk NDK_PLATFORM_VERSION := 5 NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]') NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86 CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT) OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer CFLAGS += LDFLAGS += -rdynamic -shared SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared LIBS += -lc $(LIBS_android) STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \ --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),Linux) CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),GNU) # GNU/Hurd, should work like GNU/Linux for basically all externals CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),GNU/kFreeBSD) # Debian GNU/kFreeBSD, should work like GNU/Linux for basically all externals CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_cygwin) EXTENSION = dll SHARED_EXTENSION = dll OS = cygwin PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc -lpd $(LIBS_cygwin) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif ifeq (MINGW,$(findstring MINGW,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_windows) EXTENSION = dll SHARED_EXTENSION = dll OS = windows PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd) # MinGW doesn't seem to include cc so force gcc CC=gcc OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -mms-bitfields -D'srand48(n)=srand((n))' -D'drand48()=((double)rand()/RAND_MAX)' ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" SHARED_LDFLAGS += -shared ALL_LIBS += -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 $(LIBS_windows) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif # in case somebody manually set the HELPPATCHES above HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd) ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) $(OPT_CFLAGS) ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS) ALL_LIBS := $(LIBS) $(ALL_LIBS) SHARED_SOURCE ?= $(shell test ! -e lib$(LIBRARY_NAME).c || \ echo lib$(LIBRARY_NAME).c ) SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h) SHARED_LIB = $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION)) .PHONY = install libdir_install single_install install-doc install-examples install-manual clean distclean dist etags $(LIBRARY_NAME) all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) %.o: %.c $(CC) $(ALL_CFLAGS) -o "$*.o" -c "$*.c" %.$(EXTENSION): %.o $(SHARED_LIB) $(CC) $(ALL_LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(ALL_LIBS) $(SHARED_LIB) chmod a-x "$*.$(EXTENSION)" # this links everything into a single binary file $(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(ALL_LIBS) chmod a-x $(LIBRARY_NAME).$(EXTENSION) $(SHARED_LIB): $(SHARED_SOURCE:.c=.o) $(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(LIBS) install: libdir_install # The meta and help files are explicitly installed to make sure they are # actually there. Those files are not optional, then need to be there. libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SOURCES))" || (\ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) test -z "$(strip $(SHARED_LIB))" || \ $(INSTALL_DATA) $(SHARED_LIB) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \ $(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) # install library linked as single binary single_install: $(LIBRARY_NAME) install-doc install-examples install-manual $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) install-doc: $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \ $(INSTALL_DATA) $(HELPPATCHES) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt install-examples: test -z "$(strip $(EXAMPLES))" || \ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \ for file in $(EXAMPLES); do \ $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \ done install-manual: test -z "$(strip $(MANUAL))" || \ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \ for file in $(MANUAL); do \ $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \ done clean: -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o) -rm -f -- $(SOURCES:.c=.$(EXTENSION)) -rm -f -- $(LIBRARY_NAME).o -rm -f -- $(LIBRARY_NAME).$(EXTENSION) -rm -f -- $(SHARED_LIB) distclean: clean -rm -f -- $(DISTBINDIR).tar.gz -rm -rf -- $(DISTBINDIR) -rm -f -- $(DISTDIR).tar.gz -rm -rf -- $(DISTDIR) -rm -f -- $(ORIGDIR).tar.gz -rm -rf -- $(ORIGDIR) $(DISTBINDIR): $(INSTALL_DIR) $(DISTBINDIR) libdir: all $(DISTBINDIR) $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR) $(INSTALL_DATA) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR) $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR) test -z "$(strip $(EXTRA_DIST))" || \ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR) # tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR) $(DISTDIR): $(INSTALL_DIR) $(DISTDIR) $(ORIGDIR): $(INSTALL_DIR) $(ORIGDIR) dist: $(DISTDIR) $(INSTALL_DATA) Makefile $(DISTDIR) $(INSTALL_DATA) README.txt $(DISTDIR) $(INSTALL_DATA) LICENSE.txt $(DISTDIR) $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR) test -z "$(strip $(ALLSOURCES))" || \ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR) test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \ $(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl)) $(DISTDIR) test -z "$(strip $(SHARED_HEADER))" || \ $(INSTALL_DATA) $(SHARED_HEADER) $(DISTDIR) test -z "$(strip $(SHARED_SOURCE))" || \ $(INSTALL_DATA) $(SHARED_SOURCE) $(DISTDIR) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR) test -z "$(strip $(HELPPATCHES))" || \ $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR) test -z "$(strip $(EXTRA_DIST))" || \ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR) test -z "$(strip $(EXAMPLES))" || \ $(INSTALL_DIR) $(DISTDIR)/examples && \ for file in $(EXAMPLES); do \ $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \ done test -z "$(strip $(MANUAL))" || \ $(INSTALL_DIR) $(DISTDIR)/manual && \ for file in $(MANUAL); do \ $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \ done tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR) # make a Debian source package dpkg-source: debclean make distclean dist mv $(DISTDIR) $(ORIGDIR) tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR) rm -f -- $(DISTDIR).tar.gz rm -rf -- $(DISTDIR) $(ORIGDIR) cd .. && dpkg-source -b $(LIBRARY_NAME) etags: etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h showsetup: @echo "CC: $(CC)" @echo "CFLAGS: $(CFLAGS)" @echo "LDFLAGS: $(LDFLAGS)" @echo "LIBS: $(LIBS)" @echo "ALL_CFLAGS: $(ALL_CFLAGS)" @echo "ALL_LDFLAGS: $(ALL_LDFLAGS)" @echo "ALL_LIBS: $(ALL_LIBS)" @echo "PD_INCLUDE: $(PD_INCLUDE)" @echo "PD_PATH: $(PD_PATH)" @echo "objectsdir: $(objectsdir)" @echo "LIBRARY_NAME: $(LIBRARY_NAME)" @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)" @echo "SOURCES: $(SOURCES)" @echo "SHARED_HEADER: $(SHARED_HEADER)" @echo "SHARED_SOURCE: $(SHARED_SOURCE)" @echo "SHARED_LIB: $(SHARED_LIB)" @echo "PDOBJECTS: $(PDOBJECTS)" @echo "ALLSOURCES: $(ALLSOURCES)" @echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))" @echo "UNAME: $(UNAME)" @echo "CPU: $(CPU)" @echo "pkglibdir: $(pkglibdir)" @echo "DISTDIR: $(DISTDIR)" @echo "ORIGDIR: $(ORIGDIR)" chaos-0.2/quadruptwo-help.pd0000644000076500007650000000223512076105251014615 0ustar hanshans#N canvas 492 119 593 496 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 79 201 Reset To Initial Conditions; #X text 99 246 Modify Parameters; #X msg 76 184 reset 0.1 0.1; #X floatatom 78 398 10 0 0 0 Y - -; #X floatatom 43 373 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 13 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X msg 95 226 param 2.35155; #X obj 43 347 quadruptwo 0.1 0 2.35155; #X text 98 441 This fractal seems to allow is sole parameter to range over a large range. As the value of the parameter rises \, so does the Lyapunov Exponent \, but it does not appear to be linear.; #X text 21 19 Quadruptwo Attractor (from Cliff Pickover); #X obj 126 373 search-tools; #X connect 0 0 9 0; #X connect 1 0 9 1; #X connect 4 0 13 0; #X connect 9 0 13 0; #X connect 10 0 13 0; #X connect 12 0 13 0; #X connect 13 0 6 0; #X connect 13 1 5 0; #X connect 13 2 16 0; #X connect 13 3 16 1; #X connect 13 4 16 2; #X connect 16 0 13 0; chaos-0.2/latoomutbeta-help.pd0000644000076500007650000000214412076105251015101 0ustar hanshans#N canvas 527 258 585 488 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X msg 88 191 reset 0.1 0.1; #X msg 111 243 param -0.966918 2.87988 0.756145 0.744728; #X msg 111 264 param -2.90515 -2.03043 1.44055 0.70307; #X floatatom 136 399 10 0 0 0 Y - -; #X floatatom 43 367 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X obj 43 347 latoomutbeta 0.1 0.1 -2.90515 -2.03043 1.44055 0.70307 ; #X obj 283 373 search-tools; #X connect 0 0 12 0; #X connect 1 0 12 1; #X connect 4 0 15 0; #X connect 5 0 15 0; #X connect 6 0 15 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 15 0 8 0; #X connect 15 1 7 0; #X connect 15 2 16 0; #X connect 15 3 16 1; #X connect 15 4 16 2; #X connect 16 0 15 0; chaos-0.2/henon.c0000644000076500007650000002435612076105251012412 0ustar hanshans/* henon Attractor PD External */ /* Copyright Ben Bogart, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1 #define M_a_hi 2 #define M_b_lo -1 #define M_b_hi 2 #define M_a 0 #define M_b 1 #define M_x 0 #define M_y 1 #define M_param_count 2 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "henon v0.0, by Ben Bogart, 2003"; t_class *henon_class; typedef struct henon_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } henon_struct; static void calc(henon_struct *henon, double *vars) { double x_0, y_0; x_0 =(vars[M_y]+1)-(henon -> a*pow(vars[M_x],2)); y_0 =henon -> b*vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(henon_struct *henon) { calc(henon, henon -> vars); outlet_float(henon -> outlets[M_y - 1], henon -> vars[M_y]); outlet_float(henon -> x_obj.ob_outlet, henon -> vars[M_x]); } // end calculate static void reset(henon_struct *henon, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { henon -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); henon -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { henon -> vars[M_x] = henon -> vars_init[M_x]; henon -> vars[M_y] = henon -> vars_init[M_y]; } // end if } // end reset static char *classify(henon_struct *henon) { static char buff[3]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((henon -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((henon -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = '\0'; return buff; } static void make_results(henon_struct *henon) { SETFLOAT(&henon -> search_out[0], henon -> lyap_exp); SETSYMBOL(&henon -> search_out[1], gensym(classify(henon))); SETFLOAT(&henon -> search_out[2], henon -> failure_ratio); SETFLOAT(&henon -> vars_out[M_x], henon -> vars[M_x]); SETFLOAT(&henon -> vars_out[M_y], henon -> vars[M_y]); SETFLOAT(&henon -> params_out[M_a], henon -> a); SETFLOAT(&henon -> params_out[M_b], henon -> b); outlet_list(henon -> params_outlet, gensym("list"), M_param_count, henon -> params_out); outlet_list(henon -> vars_outlet, gensym("list"), M_var_count, henon -> vars_out); } static void show(henon_struct *henon) { make_results(henon); outlet_anything(henon -> search_outlet, gensym("show"), M_search_count, henon -> search_out); } static void param(henon_struct *henon, t_symbol *s, int argc, t_atom *argv) { if (argc != 2) { post("Incorrect number of arguments for henon fractal. Expecting 2 arguments."); return; } henon -> a = (double) atom_getfloatarg(0, argc, argv); henon -> b = (double) atom_getfloatarg(1, argc, argv); } static void seed(henon_struct *henon, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(henon_struct *henon, t_floatarg l, t_floatarg h, t_floatarg lim) { henon -> lyap_lo = l; henon -> lyap_hi = h; henon -> lyap_limit = (double) ((int) lim); } static void elyap(henon_struct *henon) { double results[M_var_count]; int i; if (lyapunov_full((void *) henon, (t_gotfn) calc, M_var_count, henon -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(henon_struct *henon) { if (henon -> a_lo < M_a_lo) { henon -> a_lo = M_a_lo; } if (henon -> a_lo > M_a_hi) { henon -> a_lo = M_a_hi; } if (henon -> a_hi < M_a_lo) { henon -> a_hi = M_a_lo; } if (henon -> a_hi > M_a_hi) { henon -> a_hi = M_a_hi; } if (henon -> b_lo < M_b_lo) { henon -> b_lo = M_b_lo; } if (henon -> b_lo > M_b_hi) { henon -> b_lo = M_b_hi; } if (henon -> b_hi < M_b_lo) { henon -> b_hi = M_b_lo; } if (henon -> b_hi > M_b_hi) { henon -> b_hi = M_b_hi; } } static void constrain(henon_struct *henon, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges henon -> a_lo = M_a_lo; henon -> a_hi = M_a_hi; henon -> b_lo = M_b_lo; henon -> b_hi = M_b_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; henon -> a_lo = henon -> a - a_spread; henon -> a_hi = henon -> a + a_spread; henon -> b_lo = henon -> b - b_spread; henon -> b_hi = henon -> b + b_spread; limiter(henon); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for henon constraints, requires 4 values, got %d", argc); return; } henon -> a_lo = atom_getfloat(arg++); henon -> a_hi = atom_getfloat(arg++); henon -> b_lo = atom_getfloat(arg++); henon -> b_hi = atom_getfloat(arg++); limiter(henon); } static void search(henon_struct *henon, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = henon -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = henon -> a; double temp_b = henon -> b; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], henon -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: henon -> a = (drand48() * (henon -> a_hi - henon -> a_lo)) + henon -> a_lo; henon -> b = (drand48() * (henon -> b_hi - henon -> b_lo)) + henon -> b_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(henon, NULL, argc, vars); do { calc(henon, henon -> vars); } while(jump--); henon -> lyap_exp = lyapunov((void *) henon, (t_gotfn) calc, M_var_count, (double *) henon -> vars); if (isnan(henon -> lyap_exp)) { not_found = 1; } if (henon -> lyap_exp < henon -> lyap_lo || henon -> lyap_exp > henon -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(henon, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) henon -> lyap_limit); post("Try using wider constraints."); henon -> a = temp_a; henon -> b = temp_b; outlet_anything(henon -> search_outlet, gensym("invalid"), 0, NULL); } else { henon -> failure_ratio = (henon -> lyap_limit - not_expired) / henon -> lyap_limit; make_results(henon); outlet_anything(henon -> search_outlet, gensym("search"), M_search_count, henon -> search_out); } } void *henon_new(t_symbol *s, int argc, t_atom *argv) { henon_struct *henon = (henon_struct *) pd_new(henon_class); if (henon != NULL) { outlet_new(&henon -> x_obj, &s_float); henon -> outlets[0] = outlet_new(&henon -> x_obj, &s_float); henon -> search_outlet = outlet_new(&henon -> x_obj, &s_list); henon -> vars_outlet = outlet_new(&henon -> x_obj, &s_list); henon -> params_outlet = outlet_new(&henon -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { henon -> vars_init[M_x] = henon -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); henon -> vars_init[M_y] = henon -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); henon -> a = (double) atom_getfloatarg(2, argc, argv); henon -> b = (double) atom_getfloatarg(3, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for henon fractal. Expecting 4 arguments."); } henon -> vars_init[M_x] = 1; henon -> vars_init[M_y] = 1; henon -> a = 1.4; henon -> b = 0.3; } constrain(henon, NULL, 0, NULL); lyap(henon, -1000000.0, 1000000.0, M_failure_limit); } return (void *)henon; } void henon_setup(void) { henon_class = class_new(gensym("henon"), (t_newmethod) henon_new, 0, sizeof(henon_struct), 0, A_GIMME, 0); class_addbang(henon_class, (t_method) calculate); class_addmethod(henon_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(henon_class, (t_method) show, gensym("show"), 0); class_addmethod(henon_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(henon_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(henon_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(henon_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(henon_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(henon_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/hopalong.c0000644000076500007650000002761112076105251013107 0ustar hanshans/* hopalong Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_x 0 #define M_y 1 #define M_param_count 3 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "hopalong v0.0, by Michael McGonagle, from ??????, 2003"; t_class *hopalong_class; typedef struct hopalong_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } hopalong_struct; static void calc(hopalong_struct *hopalong, double *vars) { double x_0, y_0; x_0 =vars[M_y]-((vars[M_x]<0)?-1:1)*sqrt(abs(hopalong -> b*vars[M_x]-hopalong -> c)); y_0 =hopalong -> a-vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(hopalong_struct *hopalong) { calc(hopalong, hopalong -> vars); outlet_float(hopalong -> outlets[M_y - 1], hopalong -> vars[M_y]); outlet_float(hopalong -> x_obj.ob_outlet, hopalong -> vars[M_x]); } // end calculate static void reset(hopalong_struct *hopalong, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { hopalong -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); hopalong -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { hopalong -> vars[M_x] = hopalong -> vars_init[M_x]; hopalong -> vars[M_y] = hopalong -> vars_init[M_y]; } // end if } // end reset static char *classify(hopalong_struct *hopalong) { static char buff[4]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((hopalong -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((hopalong -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((hopalong -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = '\0'; return buff; } static void make_results(hopalong_struct *hopalong) { SETFLOAT(&hopalong -> search_out[0], hopalong -> lyap_exp); SETSYMBOL(&hopalong -> search_out[1], gensym(classify(hopalong))); SETFLOAT(&hopalong -> search_out[2], hopalong -> failure_ratio); SETFLOAT(&hopalong -> vars_out[M_x], hopalong -> vars[M_x]); SETFLOAT(&hopalong -> vars_out[M_y], hopalong -> vars[M_y]); SETFLOAT(&hopalong -> params_out[M_a], hopalong -> a); SETFLOAT(&hopalong -> params_out[M_b], hopalong -> b); SETFLOAT(&hopalong -> params_out[M_c], hopalong -> c); outlet_list(hopalong -> params_outlet, gensym("list"), M_param_count, hopalong -> params_out); outlet_list(hopalong -> vars_outlet, gensym("list"), M_var_count, hopalong -> vars_out); } static void show(hopalong_struct *hopalong) { make_results(hopalong); outlet_anything(hopalong -> search_outlet, gensym("show"), M_search_count, hopalong -> search_out); } static void param(hopalong_struct *hopalong, t_symbol *s, int argc, t_atom *argv) { if (argc != 3) { post("Incorrect number of arguments for hopalong fractal. Expecting 3 arguments."); return; } hopalong -> a = (double) atom_getfloatarg(0, argc, argv); hopalong -> b = (double) atom_getfloatarg(1, argc, argv); hopalong -> c = (double) atom_getfloatarg(2, argc, argv); } static void seed(hopalong_struct *hopalong, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(hopalong_struct *hopalong, t_floatarg l, t_floatarg h, t_floatarg lim) { hopalong -> lyap_lo = l; hopalong -> lyap_hi = h; hopalong -> lyap_limit = (double) ((int) lim); } static void elyap(hopalong_struct *hopalong) { double results[M_var_count]; int i; if (lyapunov_full((void *) hopalong, (t_gotfn) calc, M_var_count, hopalong -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(hopalong_struct *hopalong) { if (hopalong -> a_lo < M_a_lo) { hopalong -> a_lo = M_a_lo; } if (hopalong -> a_lo > M_a_hi) { hopalong -> a_lo = M_a_hi; } if (hopalong -> a_hi < M_a_lo) { hopalong -> a_hi = M_a_lo; } if (hopalong -> a_hi > M_a_hi) { hopalong -> a_hi = M_a_hi; } if (hopalong -> b_lo < M_b_lo) { hopalong -> b_lo = M_b_lo; } if (hopalong -> b_lo > M_b_hi) { hopalong -> b_lo = M_b_hi; } if (hopalong -> b_hi < M_b_lo) { hopalong -> b_hi = M_b_lo; } if (hopalong -> b_hi > M_b_hi) { hopalong -> b_hi = M_b_hi; } if (hopalong -> c_lo < M_c_lo) { hopalong -> c_lo = M_c_lo; } if (hopalong -> c_lo > M_c_hi) { hopalong -> c_lo = M_c_hi; } if (hopalong -> c_hi < M_c_lo) { hopalong -> c_hi = M_c_lo; } if (hopalong -> c_hi > M_c_hi) { hopalong -> c_hi = M_c_hi; } } static void constrain(hopalong_struct *hopalong, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges hopalong -> a_lo = M_a_lo; hopalong -> a_hi = M_a_hi; hopalong -> b_lo = M_b_lo; hopalong -> b_hi = M_b_hi; hopalong -> c_lo = M_c_lo; hopalong -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; hopalong -> a_lo = hopalong -> a - a_spread; hopalong -> a_hi = hopalong -> a + a_spread; hopalong -> b_lo = hopalong -> b - b_spread; hopalong -> b_hi = hopalong -> b + b_spread; hopalong -> c_lo = hopalong -> c - c_spread; hopalong -> c_hi = hopalong -> c + c_spread; limiter(hopalong); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for hopalong constraints, requires 6 values, got %d", argc); return; } hopalong -> a_lo = atom_getfloat(arg++); hopalong -> a_hi = atom_getfloat(arg++); hopalong -> b_lo = atom_getfloat(arg++); hopalong -> b_hi = atom_getfloat(arg++); hopalong -> c_lo = atom_getfloat(arg++); hopalong -> c_hi = atom_getfloat(arg++); limiter(hopalong); } static void search(hopalong_struct *hopalong, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = hopalong -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = hopalong -> a; double temp_b = hopalong -> b; double temp_c = hopalong -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], hopalong -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: hopalong -> a = (drand48() * (hopalong -> a_hi - hopalong -> a_lo)) + hopalong -> a_lo; hopalong -> b = (drand48() * (hopalong -> b_hi - hopalong -> b_lo)) + hopalong -> b_lo; hopalong -> c = (drand48() * (hopalong -> c_hi - hopalong -> c_lo)) + hopalong -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(hopalong, NULL, argc, vars); do { calc(hopalong, hopalong -> vars); } while(jump--); hopalong -> lyap_exp = lyapunov((void *) hopalong, (t_gotfn) calc, M_var_count, (double *) hopalong -> vars); if (isnan(hopalong -> lyap_exp)) { not_found = 1; } if (hopalong -> lyap_exp < hopalong -> lyap_lo || hopalong -> lyap_exp > hopalong -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(hopalong, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) hopalong -> lyap_limit); post("Try using wider constraints."); hopalong -> a = temp_a; hopalong -> b = temp_b; hopalong -> c = temp_c; outlet_anything(hopalong -> search_outlet, gensym("invalid"), 0, NULL); } else { hopalong -> failure_ratio = (hopalong -> lyap_limit - not_expired) / hopalong -> lyap_limit; make_results(hopalong); outlet_anything(hopalong -> search_outlet, gensym("search"), M_search_count, hopalong -> search_out); } } void *hopalong_new(t_symbol *s, int argc, t_atom *argv) { hopalong_struct *hopalong = (hopalong_struct *) pd_new(hopalong_class); if (hopalong != NULL) { outlet_new(&hopalong -> x_obj, &s_float); hopalong -> outlets[0] = outlet_new(&hopalong -> x_obj, &s_float); hopalong -> search_outlet = outlet_new(&hopalong -> x_obj, &s_list); hopalong -> vars_outlet = outlet_new(&hopalong -> x_obj, &s_list); hopalong -> params_outlet = outlet_new(&hopalong -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { hopalong -> vars_init[M_x] = hopalong -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); hopalong -> vars_init[M_y] = hopalong -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); hopalong -> a = (double) atom_getfloatarg(2, argc, argv); hopalong -> b = (double) atom_getfloatarg(3, argc, argv); hopalong -> c = (double) atom_getfloatarg(4, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for hopalong fractal. Expecting 5 arguments."); } hopalong -> vars_init[M_x] = 0.1; hopalong -> vars_init[M_y] = 0.1; hopalong -> a = 1; hopalong -> b = 1; hopalong -> c = 0; } constrain(hopalong, NULL, 0, NULL); lyap(hopalong, -1000000.0, 1000000.0, M_failure_limit); } return (void *)hopalong; } void hopalong_setup(void) { hopalong_class = class_new(gensym("hopalong"), (t_newmethod) hopalong_new, 0, sizeof(hopalong_struct), 0, A_GIMME, 0); class_addbang(hopalong_class, (t_method) calculate); class_addmethod(hopalong_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(hopalong_class, (t_method) show, gensym("show"), 0); class_addmethod(hopalong_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(hopalong_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(hopalong_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(hopalong_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(hopalong_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(hopalong_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/tinkerbell.c0000644000076500007650000003270312076105251013431 0ustar hanshans/* tinkerbell Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_d_lo -1000 #define M_d_hi 1000 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "tinkerbell v0.0, by Michael McGonagle, from ??????, 2003"; t_class *tinkerbell_class; typedef struct tinkerbell_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } tinkerbell_struct; static void calc(tinkerbell_struct *tinkerbell, double *vars) { double x_0, y_0; x_0 =vars[M_x]*vars[M_x]-vars[M_y]*vars[M_y]+tinkerbell -> a*vars[M_x]+tinkerbell -> b*vars[M_y]; y_0 =2*vars[M_x]*vars[M_y]-tinkerbell -> c*vars[M_x]+tinkerbell -> d*vars[M_y]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(tinkerbell_struct *tinkerbell) { calc(tinkerbell, tinkerbell -> vars); outlet_float(tinkerbell -> outlets[M_y - 1], tinkerbell -> vars[M_y]); outlet_float(tinkerbell -> x_obj.ob_outlet, tinkerbell -> vars[M_x]); } // end calculate static void reset(tinkerbell_struct *tinkerbell, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { tinkerbell -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); tinkerbell -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { tinkerbell -> vars[M_x] = tinkerbell -> vars_init[M_x]; tinkerbell -> vars[M_y] = tinkerbell -> vars_init[M_y]; } // end if } // end reset static char *classify(tinkerbell_struct *tinkerbell) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((tinkerbell -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((tinkerbell -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((tinkerbell -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((tinkerbell -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(tinkerbell_struct *tinkerbell) { SETFLOAT(&tinkerbell -> search_out[0], tinkerbell -> lyap_exp); SETSYMBOL(&tinkerbell -> search_out[1], gensym(classify(tinkerbell))); SETFLOAT(&tinkerbell -> search_out[2], tinkerbell -> failure_ratio); SETFLOAT(&tinkerbell -> vars_out[M_x], tinkerbell -> vars[M_x]); SETFLOAT(&tinkerbell -> vars_out[M_y], tinkerbell -> vars[M_y]); SETFLOAT(&tinkerbell -> params_out[M_a], tinkerbell -> a); SETFLOAT(&tinkerbell -> params_out[M_b], tinkerbell -> b); SETFLOAT(&tinkerbell -> params_out[M_c], tinkerbell -> c); SETFLOAT(&tinkerbell -> params_out[M_d], tinkerbell -> d); outlet_list(tinkerbell -> params_outlet, gensym("list"), M_param_count, tinkerbell -> params_out); outlet_list(tinkerbell -> vars_outlet, gensym("list"), M_var_count, tinkerbell -> vars_out); } static void show(tinkerbell_struct *tinkerbell) { make_results(tinkerbell); outlet_anything(tinkerbell -> search_outlet, gensym("show"), M_search_count, tinkerbell -> search_out); } static void param(tinkerbell_struct *tinkerbell, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for tinkerbell fractal. Expecting 4 arguments."); return; } tinkerbell -> a = (double) atom_getfloatarg(0, argc, argv); tinkerbell -> b = (double) atom_getfloatarg(1, argc, argv); tinkerbell -> c = (double) atom_getfloatarg(2, argc, argv); tinkerbell -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(tinkerbell_struct *tinkerbell, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(tinkerbell_struct *tinkerbell, t_floatarg l, t_floatarg h, t_floatarg lim) { tinkerbell -> lyap_lo = l; tinkerbell -> lyap_hi = h; tinkerbell -> lyap_limit = (double) ((int) lim); } static void elyap(tinkerbell_struct *tinkerbell) { double results[M_var_count]; int i; if (lyapunov_full((void *) tinkerbell, (t_gotfn) calc, M_var_count, tinkerbell -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(tinkerbell_struct *tinkerbell) { if (tinkerbell -> a_lo < M_a_lo) { tinkerbell -> a_lo = M_a_lo; } if (tinkerbell -> a_lo > M_a_hi) { tinkerbell -> a_lo = M_a_hi; } if (tinkerbell -> a_hi < M_a_lo) { tinkerbell -> a_hi = M_a_lo; } if (tinkerbell -> a_hi > M_a_hi) { tinkerbell -> a_hi = M_a_hi; } if (tinkerbell -> b_lo < M_b_lo) { tinkerbell -> b_lo = M_b_lo; } if (tinkerbell -> b_lo > M_b_hi) { tinkerbell -> b_lo = M_b_hi; } if (tinkerbell -> b_hi < M_b_lo) { tinkerbell -> b_hi = M_b_lo; } if (tinkerbell -> b_hi > M_b_hi) { tinkerbell -> b_hi = M_b_hi; } if (tinkerbell -> c_lo < M_c_lo) { tinkerbell -> c_lo = M_c_lo; } if (tinkerbell -> c_lo > M_c_hi) { tinkerbell -> c_lo = M_c_hi; } if (tinkerbell -> c_hi < M_c_lo) { tinkerbell -> c_hi = M_c_lo; } if (tinkerbell -> c_hi > M_c_hi) { tinkerbell -> c_hi = M_c_hi; } if (tinkerbell -> d_lo < M_d_lo) { tinkerbell -> d_lo = M_d_lo; } if (tinkerbell -> d_lo > M_d_hi) { tinkerbell -> d_lo = M_d_hi; } if (tinkerbell -> d_hi < M_d_lo) { tinkerbell -> d_hi = M_d_lo; } if (tinkerbell -> d_hi > M_d_hi) { tinkerbell -> d_hi = M_d_hi; } } static void constrain(tinkerbell_struct *tinkerbell, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges tinkerbell -> a_lo = M_a_lo; tinkerbell -> a_hi = M_a_hi; tinkerbell -> b_lo = M_b_lo; tinkerbell -> b_hi = M_b_hi; tinkerbell -> c_lo = M_c_lo; tinkerbell -> c_hi = M_c_hi; tinkerbell -> d_lo = M_d_lo; tinkerbell -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; tinkerbell -> a_lo = tinkerbell -> a - a_spread; tinkerbell -> a_hi = tinkerbell -> a + a_spread; tinkerbell -> b_lo = tinkerbell -> b - b_spread; tinkerbell -> b_hi = tinkerbell -> b + b_spread; tinkerbell -> c_lo = tinkerbell -> c - c_spread; tinkerbell -> c_hi = tinkerbell -> c + c_spread; tinkerbell -> d_lo = tinkerbell -> d - d_spread; tinkerbell -> d_hi = tinkerbell -> d + d_spread; limiter(tinkerbell); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for tinkerbell constraints, requires 8 values, got %d", argc); return; } tinkerbell -> a_lo = atom_getfloat(arg++); tinkerbell -> a_hi = atom_getfloat(arg++); tinkerbell -> b_lo = atom_getfloat(arg++); tinkerbell -> b_hi = atom_getfloat(arg++); tinkerbell -> c_lo = atom_getfloat(arg++); tinkerbell -> c_hi = atom_getfloat(arg++); tinkerbell -> d_lo = atom_getfloat(arg++); tinkerbell -> d_hi = atom_getfloat(arg++); limiter(tinkerbell); } static void search(tinkerbell_struct *tinkerbell, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = tinkerbell -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = tinkerbell -> a; double temp_b = tinkerbell -> b; double temp_c = tinkerbell -> c; double temp_d = tinkerbell -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], tinkerbell -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: tinkerbell -> a = (drand48() * (tinkerbell -> a_hi - tinkerbell -> a_lo)) + tinkerbell -> a_lo; tinkerbell -> b = (drand48() * (tinkerbell -> b_hi - tinkerbell -> b_lo)) + tinkerbell -> b_lo; tinkerbell -> c = (drand48() * (tinkerbell -> c_hi - tinkerbell -> c_lo)) + tinkerbell -> c_lo; tinkerbell -> d = (drand48() * (tinkerbell -> d_hi - tinkerbell -> d_lo)) + tinkerbell -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(tinkerbell, NULL, argc, vars); do { calc(tinkerbell, tinkerbell -> vars); } while(jump--); tinkerbell -> lyap_exp = lyapunov((void *) tinkerbell, (t_gotfn) calc, M_var_count, (double *) tinkerbell -> vars); if (isnan(tinkerbell -> lyap_exp)) { not_found = 1; } if (tinkerbell -> lyap_exp < tinkerbell -> lyap_lo || tinkerbell -> lyap_exp > tinkerbell -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(tinkerbell, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) tinkerbell -> lyap_limit); post("Try using wider constraints."); tinkerbell -> a = temp_a; tinkerbell -> b = temp_b; tinkerbell -> c = temp_c; tinkerbell -> d = temp_d; outlet_anything(tinkerbell -> search_outlet, gensym("invalid"), 0, NULL); } else { tinkerbell -> failure_ratio = (tinkerbell -> lyap_limit - not_expired) / tinkerbell -> lyap_limit; make_results(tinkerbell); outlet_anything(tinkerbell -> search_outlet, gensym("search"), M_search_count, tinkerbell -> search_out); } } void *tinkerbell_new(t_symbol *s, int argc, t_atom *argv) { tinkerbell_struct *tinkerbell = (tinkerbell_struct *) pd_new(tinkerbell_class); if (tinkerbell != NULL) { outlet_new(&tinkerbell -> x_obj, &s_float); tinkerbell -> outlets[0] = outlet_new(&tinkerbell -> x_obj, &s_float); tinkerbell -> search_outlet = outlet_new(&tinkerbell -> x_obj, &s_list); tinkerbell -> vars_outlet = outlet_new(&tinkerbell -> x_obj, &s_list); tinkerbell -> params_outlet = outlet_new(&tinkerbell -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { tinkerbell -> vars_init[M_x] = tinkerbell -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); tinkerbell -> vars_init[M_y] = tinkerbell -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); tinkerbell -> a = (double) atom_getfloatarg(2, argc, argv); tinkerbell -> b = (double) atom_getfloatarg(3, argc, argv); tinkerbell -> c = (double) atom_getfloatarg(4, argc, argv); tinkerbell -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for tinkerbell fractal. Expecting 6 arguments."); } tinkerbell -> vars_init[M_x] = 0.1; tinkerbell -> vars_init[M_y] = 0.1; tinkerbell -> a = 0.9; tinkerbell -> b = 0.6; tinkerbell -> c = 2; tinkerbell -> d = 0.5; } constrain(tinkerbell, NULL, 0, NULL); lyap(tinkerbell, -1000000.0, 1000000.0, M_failure_limit); } return (void *)tinkerbell; } void tinkerbell_setup(void) { tinkerbell_class = class_new(gensym("tinkerbell"), (t_newmethod) tinkerbell_new, 0, sizeof(tinkerbell_struct), 0, A_GIMME, 0); class_addbang(tinkerbell_class, (t_method) calculate); class_addmethod(tinkerbell_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(tinkerbell_class, (t_method) show, gensym("show"), 0); class_addmethod(tinkerbell_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(tinkerbell_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(tinkerbell_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(tinkerbell_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(tinkerbell_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(tinkerbell_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/attract1.c0000644000076500007650000003650012076105251013020 0ustar hanshans/* attract1 Attractor PD External */ /* Copyright Michael McGonagle, from 'attract.java' by Julian Sprott, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a0_lo -3 #define M_a0_hi 3 #define M_a1_lo -3 #define M_a1_hi 3 #define M_a2_lo -3 #define M_a2_hi 3 #define M_a3_lo -3 #define M_a3_hi 3 #define M_a4_lo -3 #define M_a4_hi 3 #define M_a5_lo -3 #define M_a5_hi 3 #define M_a0 0 #define M_a1 1 #define M_a2 2 #define M_a3 3 #define M_a4 4 #define M_a5 5 #define M_x 0 #define M_y 1 #define M_param_count 6 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "attract1 v0.0, by Michael McGonagle, from 'attract.java' by Julian Sprott, 2003"; t_class *attract1_class; typedef struct attract1_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a0, a0_lo, a0_hi, a1, a1_lo, a1_hi, a2, a2_lo, a2_hi, a3, a3_lo, a3_hi, a4, a4_lo, a4_hi, a5, a5_lo, a5_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } attract1_struct; static void calc(attract1_struct *attract1, double *vars) { double x_0, y_0; x_0 =attract1 -> a0+vars[M_x]*(attract1 -> a1+attract1 -> a2*vars[M_x]+attract1 -> a3*vars[M_y])+vars[M_y]*(attract1 -> a4+attract1 -> a5*vars[M_y]); y_0 =vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(attract1_struct *attract1) { calc(attract1, attract1 -> vars); outlet_float(attract1 -> outlets[M_y - 1], attract1 -> vars[M_y]); outlet_float(attract1 -> x_obj.ob_outlet, attract1 -> vars[M_x]); } // end calculate static void reset(attract1_struct *attract1, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { attract1 -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); attract1 -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { attract1 -> vars[M_x] = attract1 -> vars_init[M_x]; attract1 -> vars[M_y] = attract1 -> vars_init[M_y]; } // end if } // end reset static char *classify(attract1_struct *attract1) { static char buff[7]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((attract1 -> a0 - M_a0_lo) * (1.0 / (M_a0_hi - M_a0_lo))) * 26)]; buff[1] = c[(int) (((attract1 -> a1 - M_a1_lo) * (1.0 / (M_a1_hi - M_a1_lo))) * 26)]; buff[2] = c[(int) (((attract1 -> a2 - M_a2_lo) * (1.0 / (M_a2_hi - M_a2_lo))) * 26)]; buff[3] = c[(int) (((attract1 -> a3 - M_a3_lo) * (1.0 / (M_a3_hi - M_a3_lo))) * 26)]; buff[4] = c[(int) (((attract1 -> a4 - M_a4_lo) * (1.0 / (M_a4_hi - M_a4_lo))) * 26)]; buff[5] = c[(int) (((attract1 -> a5 - M_a5_lo) * (1.0 / (M_a5_hi - M_a5_lo))) * 26)]; buff[6] = '\0'; return buff; } static void make_results(attract1_struct *attract1) { SETFLOAT(&attract1 -> search_out[0], attract1 -> lyap_exp); SETSYMBOL(&attract1 -> search_out[1], gensym(classify(attract1))); SETFLOAT(&attract1 -> search_out[2], attract1 -> failure_ratio); SETFLOAT(&attract1 -> vars_out[M_x], attract1 -> vars[M_x]); SETFLOAT(&attract1 -> vars_out[M_y], attract1 -> vars[M_y]); SETFLOAT(&attract1 -> params_out[M_a0], attract1 -> a0); SETFLOAT(&attract1 -> params_out[M_a1], attract1 -> a1); SETFLOAT(&attract1 -> params_out[M_a2], attract1 -> a2); SETFLOAT(&attract1 -> params_out[M_a3], attract1 -> a3); SETFLOAT(&attract1 -> params_out[M_a4], attract1 -> a4); SETFLOAT(&attract1 -> params_out[M_a5], attract1 -> a5); outlet_list(attract1 -> params_outlet, gensym("list"), M_param_count, attract1 -> params_out); outlet_list(attract1 -> vars_outlet, gensym("list"), M_var_count, attract1 -> vars_out); } static void show(attract1_struct *attract1) { make_results(attract1); outlet_anything(attract1 -> search_outlet, gensym("show"), M_search_count, attract1 -> search_out); } static void param(attract1_struct *attract1, t_symbol *s, int argc, t_atom *argv) { if (argc != 6) { post("Incorrect number of arguments for attract1 fractal. Expecting 6 arguments."); return; } attract1 -> a0 = (double) atom_getfloatarg(0, argc, argv); attract1 -> a1 = (double) atom_getfloatarg(1, argc, argv); attract1 -> a2 = (double) atom_getfloatarg(2, argc, argv); attract1 -> a3 = (double) atom_getfloatarg(3, argc, argv); attract1 -> a4 = (double) atom_getfloatarg(4, argc, argv); attract1 -> a5 = (double) atom_getfloatarg(5, argc, argv); } static void seed(attract1_struct *attract1, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(attract1_struct *attract1, t_floatarg l, t_floatarg h, t_floatarg lim) { attract1 -> lyap_lo = l; attract1 -> lyap_hi = h; attract1 -> lyap_limit = (double) ((int) lim); } static void elyap(attract1_struct *attract1) { double results[M_var_count]; int i; if (lyapunov_full((void *) attract1, (t_gotfn) calc, M_var_count, attract1 -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(attract1_struct *attract1) { if (attract1 -> a0_lo < M_a0_lo) { attract1 -> a0_lo = M_a0_lo; } if (attract1 -> a0_lo > M_a0_hi) { attract1 -> a0_lo = M_a0_hi; } if (attract1 -> a0_hi < M_a0_lo) { attract1 -> a0_hi = M_a0_lo; } if (attract1 -> a0_hi > M_a0_hi) { attract1 -> a0_hi = M_a0_hi; } if (attract1 -> a1_lo < M_a1_lo) { attract1 -> a1_lo = M_a1_lo; } if (attract1 -> a1_lo > M_a1_hi) { attract1 -> a1_lo = M_a1_hi; } if (attract1 -> a1_hi < M_a1_lo) { attract1 -> a1_hi = M_a1_lo; } if (attract1 -> a1_hi > M_a1_hi) { attract1 -> a1_hi = M_a1_hi; } if (attract1 -> a2_lo < M_a2_lo) { attract1 -> a2_lo = M_a2_lo; } if (attract1 -> a2_lo > M_a2_hi) { attract1 -> a2_lo = M_a2_hi; } if (attract1 -> a2_hi < M_a2_lo) { attract1 -> a2_hi = M_a2_lo; } if (attract1 -> a2_hi > M_a2_hi) { attract1 -> a2_hi = M_a2_hi; } if (attract1 -> a3_lo < M_a3_lo) { attract1 -> a3_lo = M_a3_lo; } if (attract1 -> a3_lo > M_a3_hi) { attract1 -> a3_lo = M_a3_hi; } if (attract1 -> a3_hi < M_a3_lo) { attract1 -> a3_hi = M_a3_lo; } if (attract1 -> a3_hi > M_a3_hi) { attract1 -> a3_hi = M_a3_hi; } if (attract1 -> a4_lo < M_a4_lo) { attract1 -> a4_lo = M_a4_lo; } if (attract1 -> a4_lo > M_a4_hi) { attract1 -> a4_lo = M_a4_hi; } if (attract1 -> a4_hi < M_a4_lo) { attract1 -> a4_hi = M_a4_lo; } if (attract1 -> a4_hi > M_a4_hi) { attract1 -> a4_hi = M_a4_hi; } if (attract1 -> a5_lo < M_a5_lo) { attract1 -> a5_lo = M_a5_lo; } if (attract1 -> a5_lo > M_a5_hi) { attract1 -> a5_lo = M_a5_hi; } if (attract1 -> a5_hi < M_a5_lo) { attract1 -> a5_hi = M_a5_lo; } if (attract1 -> a5_hi > M_a5_hi) { attract1 -> a5_hi = M_a5_hi; } } static void constrain(attract1_struct *attract1, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges attract1 -> a0_lo = M_a0_lo; attract1 -> a0_hi = M_a0_hi; attract1 -> a1_lo = M_a1_lo; attract1 -> a1_hi = M_a1_hi; attract1 -> a2_lo = M_a2_lo; attract1 -> a2_hi = M_a2_hi; attract1 -> a3_lo = M_a3_lo; attract1 -> a3_hi = M_a3_hi; attract1 -> a4_lo = M_a4_lo; attract1 -> a4_hi = M_a4_hi; attract1 -> a5_lo = M_a5_lo; attract1 -> a5_hi = M_a5_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a0_spread = ((M_a0_hi - M_a0_lo) * percent) / 2; double a1_spread = ((M_a1_hi - M_a1_lo) * percent) / 2; double a2_spread = ((M_a2_hi - M_a2_lo) * percent) / 2; double a3_spread = ((M_a3_hi - M_a3_lo) * percent) / 2; double a4_spread = ((M_a4_hi - M_a4_lo) * percent) / 2; double a5_spread = ((M_a5_hi - M_a5_lo) * percent) / 2; attract1 -> a0_lo = attract1 -> a0 - a0_spread; attract1 -> a0_hi = attract1 -> a0 + a0_spread; attract1 -> a1_lo = attract1 -> a1 - a1_spread; attract1 -> a1_hi = attract1 -> a1 + a1_spread; attract1 -> a2_lo = attract1 -> a2 - a2_spread; attract1 -> a2_hi = attract1 -> a2 + a2_spread; attract1 -> a3_lo = attract1 -> a3 - a3_spread; attract1 -> a3_hi = attract1 -> a3 + a3_spread; attract1 -> a4_lo = attract1 -> a4 - a4_spread; attract1 -> a4_hi = attract1 -> a4 + a4_spread; attract1 -> a5_lo = attract1 -> a5 - a5_spread; attract1 -> a5_hi = attract1 -> a5 + a5_spread; limiter(attract1); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for attract1 constraints, requires 12 values, got %d", argc); return; } attract1 -> a0_lo = atom_getfloat(arg++); attract1 -> a0_hi = atom_getfloat(arg++); attract1 -> a1_lo = atom_getfloat(arg++); attract1 -> a1_hi = atom_getfloat(arg++); attract1 -> a2_lo = atom_getfloat(arg++); attract1 -> a2_hi = atom_getfloat(arg++); attract1 -> a3_lo = atom_getfloat(arg++); attract1 -> a3_hi = atom_getfloat(arg++); attract1 -> a4_lo = atom_getfloat(arg++); attract1 -> a4_hi = atom_getfloat(arg++); attract1 -> a5_lo = atom_getfloat(arg++); attract1 -> a5_hi = atom_getfloat(arg++); limiter(attract1); } static void search(attract1_struct *attract1, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = attract1 -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a0 = attract1 -> a0; double temp_a1 = attract1 -> a1; double temp_a2 = attract1 -> a2; double temp_a3 = attract1 -> a3; double temp_a4 = attract1 -> a4; double temp_a5 = attract1 -> a5; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], attract1 -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: attract1 -> a0 = (drand48() * (attract1 -> a0_hi - attract1 -> a0_lo)) + attract1 -> a0_lo; attract1 -> a1 = (drand48() * (attract1 -> a1_hi - attract1 -> a1_lo)) + attract1 -> a1_lo; attract1 -> a2 = (drand48() * (attract1 -> a2_hi - attract1 -> a2_lo)) + attract1 -> a2_lo; attract1 -> a3 = (drand48() * (attract1 -> a3_hi - attract1 -> a3_lo)) + attract1 -> a3_lo; attract1 -> a4 = (drand48() * (attract1 -> a4_hi - attract1 -> a4_lo)) + attract1 -> a4_lo; attract1 -> a5 = (drand48() * (attract1 -> a5_hi - attract1 -> a5_lo)) + attract1 -> a5_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(attract1, NULL, argc, vars); do { calc(attract1, attract1 -> vars); } while(jump--); attract1 -> lyap_exp = lyapunov((void *) attract1, (t_gotfn) calc, M_var_count, (double *) attract1 -> vars); if (isnan(attract1 -> lyap_exp)) { not_found = 1; } if (attract1 -> lyap_exp < attract1 -> lyap_lo || attract1 -> lyap_exp > attract1 -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(attract1, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) attract1 -> lyap_limit); post("Try using wider constraints."); attract1 -> a0 = temp_a0; attract1 -> a1 = temp_a1; attract1 -> a2 = temp_a2; attract1 -> a3 = temp_a3; attract1 -> a4 = temp_a4; attract1 -> a5 = temp_a5; outlet_anything(attract1 -> search_outlet, gensym("invalid"), 0, NULL); } else { attract1 -> failure_ratio = (attract1 -> lyap_limit - not_expired) / attract1 -> lyap_limit; make_results(attract1); outlet_anything(attract1 -> search_outlet, gensym("search"), M_search_count, attract1 -> search_out); } } void *attract1_new(t_symbol *s, int argc, t_atom *argv) { attract1_struct *attract1 = (attract1_struct *) pd_new(attract1_class); if (attract1 != NULL) { outlet_new(&attract1 -> x_obj, &s_float); attract1 -> outlets[0] = outlet_new(&attract1 -> x_obj, &s_float); attract1 -> search_outlet = outlet_new(&attract1 -> x_obj, &s_list); attract1 -> vars_outlet = outlet_new(&attract1 -> x_obj, &s_list); attract1 -> params_outlet = outlet_new(&attract1 -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { attract1 -> vars_init[M_x] = attract1 -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); attract1 -> vars_init[M_y] = attract1 -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); attract1 -> a0 = (double) atom_getfloatarg(2, argc, argv); attract1 -> a1 = (double) atom_getfloatarg(3, argc, argv); attract1 -> a2 = (double) atom_getfloatarg(4, argc, argv); attract1 -> a3 = (double) atom_getfloatarg(5, argc, argv); attract1 -> a4 = (double) atom_getfloatarg(6, argc, argv); attract1 -> a5 = (double) atom_getfloatarg(7, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for attract1 fractal. Expecting 8 arguments."); } attract1 -> vars_init[M_x] = 0; attract1 -> vars_init[M_y] = 0; attract1 -> a0 = 1; attract1 -> a1 = 1; attract1 -> a2 = 1; attract1 -> a3 = 1; attract1 -> a4 = 1; attract1 -> a5 = 1; } constrain(attract1, NULL, 0, NULL); lyap(attract1, -1000000.0, 1000000.0, M_failure_limit); } return (void *)attract1; } void attract1_setup(void) { attract1_class = class_new(gensym("attract1"), (t_newmethod) attract1_new, 0, sizeof(attract1_struct), 0, A_GIMME, 0); class_addbang(attract1_class, (t_method) calculate); class_addmethod(attract1_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(attract1_class, (t_method) show, gensym("show"), 0); class_addmethod(attract1_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(attract1_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(attract1_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(attract1_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(attract1_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(attract1_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/Makefile.nt0000644000076500007650000000607412076105251013214 0ustar hanshansNAME=chaos CSYM=chaos current: pd_nt pd_intel pd_linux pd_darwin # ----------------------- NT ----------------------- pd_nt: $(NAME).dll .SUFFIXES: .dll PDNTCFLAGS = /W3 /WX /MD /O2 /G6 /DNT /DPD /DMAXLIB /nologo VC="C:\Programme\Microsoft Visual Studio\VC98" PDNTINCLUDE = /I. /Ic:\pd\tcl\include /Ic:\pd\src /I$(VC)\include /Iinclude PDNTLDIR = $(VC)\Lib PDNTLIB = $(PDNTLDIR)\msvcrt.lib \ $(PDNTLDIR)\oldnames.lib \ $(PDNTLDIR)\kernel32.lib \ $(PDNTLDIR)\user32.lib \ $(PDNTLDIR)\uuid.lib \ $(PDNTLDIR)\ws2_32.lib \ $(PDNTLDIR)\pthreadVC.lib \ c:\pd\bin\pd.lib PDNTEXTERNALS = lyapunov.obj henon.obj hopalong.obj ikeda.obj latoocarfian.obj latoomutalpha.obj latoomutbeta.obj latoomutgamma.obj logistic.obj lorenz.obj mlogistic.obj rossler.obj standardmap.obj tent.obj three_d.obj .c.dll: cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c *.c link /dll /export:$(CSYM)_setup $*.obj $(PDNTEXTERNALS) $(PDNTLIB) # ----------------------- Mac OS X (Darwin) ----------------------- pd_darwin: $(NAME).pd_darwin .SUFFIXES: .pd_darwin DARWINCFLAGS = -DPD -DMAXLIB -DUNIX -DMACOSX -O2 \ -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch # where is your m_pd.h ??? DARWININCLUDE = -I../../src -I../../obj DARWINEXTERNALS = lyapunov.o attract1.o base.o base3.o dejong.o gingerbreadman.o henon.o hopalong.o ikeda.o latoocarfian.o latoomutalpha.o \ latoomutbeta.o latoomutgamma.o logistic.o lorenz.o martin.o mlogistic.o pickover.o popcorn.o quadruptwo.o rossler.o standardmap.o \ strange1.o tent.o three_d.o threeply.o tinkerbell.o unity.o lotka_volterra.o PD_LOCAL_EXTERNALS = $(HOME)/Library/Pd/Externals PD_LOCAL_HELP = $(HOME)/Library/Pd/Help PD_BINARY = /usr/local/pd/bin/pd MTARGET = $(NAME).pd_darwin MDARWININCLUDE = -I/usr/local/pd/src .c.o: cc $(DARWINCFLAGS) $(DARWININCLUDE) -c *.c .o.pd_darwin: cc -bundle -bundle_loader $(PD_BINARY) -flat_namespace -o $*.pd_darwin $*.o $(DARWINEXTERNALS) pd_darwin: $(DARWINEXTERNALS) rm -f $*.o ../$*.pd_darwin ln -s $*/$*.pd_darwin .. minstall: $(MTARGET) $(DARWINEXTERNALS) mv -f $(MTARGET) $(PD_LOCAL_EXTERNALS) cp -f help-*.pd $(PD_LOCAL_HELP) # ----------------------- LINUX i386 ----------------------- pd_linux: $(NAME).pd_linux .SUFFIXES: .pd_linux LINUXCFLAGS = -DPD -DUNIX -O2 -funroll-loops -fomit-frame-pointer \ -Wall -W -Wshadow \ -Wno-unused -Wno-parentheses -Wno-switch # where is your m_pd.h ??? LINUXINCLUDE = -I/usr/local/include LINUXEXTERNALS = lyapunov.o attract1.o base.o base3.o dejong.o gingerbreadman.o henon.o hopalong.o ikeda.o latoocarfian.o latoomutalpha.o \ latoomutbeta.o latoomutgamma.o logistic.o lorenz.o martin.o mlogistic.o pickover.o popcorn.o quadruptwo.o rossler.o standardmap.o \ strange1.o tent.o three_d.o threeply.o tinkerbell.o unity.o lotka_volterra.o .c.pd_linux: cc -O2 -Wall -DPD -fPIC $(LINUXCFLAGS) $(LINUXINCLUDE) -c *.c ld --export-dynamic -shared -o $*.pd_linux $*.o $(LINUXEXTERNALS) -lc strip --strip-unneeded $*.pd_linux # ---------------------------------------------------------- PDDIR=/usr/lib/pd clean: rm -f *.o *.pd_* so_locations chaos-0.2/base.c0000644000076500007650000002311712076105251012207 0ustar hanshans/* base Attractor PD External */ /* Copyright Michael McGonagle, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo 0 #define M_a_hi 3 #define M_b_lo 0.001 #define M_b_hi 2.6667 #define M_a 0 #define M_b 1 #define M_x 0 #define M_param_count 2 #define M_var_count 1 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "base v0.0, by Michael McGonagle, 2003"; t_class *base_class; typedef struct base_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; } base_struct; static void calc(base_struct *base, double *vars) { double x_0; x_0 =vars[M_x]+(base -> a*sin(pow(vars[M_x],base -> b))); vars[M_x] = x_0; } // end calc static void calculate(base_struct *base) { calc(base, base -> vars); outlet_float(base -> x_obj.ob_outlet, base -> vars[M_x]); } // end calculate static void reset(base_struct *base, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { base -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); } else { base -> vars[M_x] = base -> vars_init[M_x]; } // end if } // end reset static char *classify(base_struct *base) { static char buff[3]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((base -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((base -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = '\0'; return buff; } static void make_results(base_struct *base) { SETFLOAT(&base -> search_out[0], base -> lyap_exp); SETSYMBOL(&base -> search_out[1], gensym(classify(base))); SETFLOAT(&base -> search_out[2], base -> failure_ratio); SETFLOAT(&base -> vars_out[M_x], base -> vars[M_x]); SETFLOAT(&base -> params_out[M_a], base -> a); SETFLOAT(&base -> params_out[M_b], base -> b); outlet_list(base -> params_outlet, gensym("list"), M_param_count, base -> params_out); outlet_list(base -> vars_outlet, gensym("list"), M_var_count, base -> vars_out); } static void show(base_struct *base) { make_results(base); outlet_anything(base -> search_outlet, gensym("show"), M_search_count, base -> search_out); } static void param(base_struct *base, t_symbol *s, int argc, t_atom *argv) { if (argc != 2) { post("Incorrect number of arguments for base fractal. Expecting 2 arguments."); return; } base -> a = (double) atom_getfloatarg(0, argc, argv); base -> b = (double) atom_getfloatarg(1, argc, argv); } static void seed(base_struct *base, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(base_struct *base, t_floatarg l, t_floatarg h, t_floatarg lim) { base -> lyap_lo = l; base -> lyap_hi = h; base -> lyap_limit = (double) ((int) lim); } static void elyap(base_struct *base) { double results[M_var_count]; int i; if (lyapunov_full((void *) base, (t_gotfn) calc, M_var_count, base -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(base_struct *base) { if (base -> a_lo < M_a_lo) { base -> a_lo = M_a_lo; } if (base -> a_lo > M_a_hi) { base -> a_lo = M_a_hi; } if (base -> a_hi < M_a_lo) { base -> a_hi = M_a_lo; } if (base -> a_hi > M_a_hi) { base -> a_hi = M_a_hi; } if (base -> b_lo < M_b_lo) { base -> b_lo = M_b_lo; } if (base -> b_lo > M_b_hi) { base -> b_lo = M_b_hi; } if (base -> b_hi < M_b_lo) { base -> b_hi = M_b_lo; } if (base -> b_hi > M_b_hi) { base -> b_hi = M_b_hi; } } static void constrain(base_struct *base, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges base -> a_lo = M_a_lo; base -> a_hi = M_a_hi; base -> b_lo = M_b_lo; base -> b_hi = M_b_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; base -> a_lo = base -> a - a_spread; base -> a_hi = base -> a + a_spread; base -> b_lo = base -> b - b_spread; base -> b_hi = base -> b + b_spread; limiter(base); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for base constraints, requires 4 values, got %d", argc); return; } base -> a_lo = atom_getfloat(arg++); base -> a_hi = atom_getfloat(arg++); base -> b_lo = atom_getfloat(arg++); base -> b_hi = atom_getfloat(arg++); limiter(base); } static void search(base_struct *base, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = base -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = base -> a; double temp_b = base -> b; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], base -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: base -> a = (drand48() * (base -> a_hi - base -> a_lo)) + base -> a_lo; base -> b = (drand48() * (base -> b_hi - base -> b_lo)) + base -> b_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(base, NULL, argc, vars); do { calc(base, base -> vars); } while(jump--); base -> lyap_exp = lyapunov((void *) base, (t_gotfn) calc, M_var_count, (double *) base -> vars); if (isnan(base -> lyap_exp)) { not_found = 1; } if (base -> lyap_exp < base -> lyap_lo || base -> lyap_exp > base -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(base, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) base -> lyap_limit); post("Try using wider constraints."); base -> a = temp_a; base -> b = temp_b; outlet_anything(base -> search_outlet, gensym("invalid"), 0, NULL); } else { base -> failure_ratio = (base -> lyap_limit - not_expired) / base -> lyap_limit; make_results(base); outlet_anything(base -> search_outlet, gensym("search"), M_search_count, base -> search_out); } } void *base_new(t_symbol *s, int argc, t_atom *argv) { base_struct *base = (base_struct *) pd_new(base_class); if (base != NULL) { outlet_new(&base -> x_obj, &s_float); base -> search_outlet = outlet_new(&base -> x_obj, &s_list); base -> vars_outlet = outlet_new(&base -> x_obj, &s_list); base -> params_outlet = outlet_new(&base -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { base -> vars_init[M_x] = base -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); base -> a = (double) atom_getfloatarg(1, argc, argv); base -> b = (double) atom_getfloatarg(2, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for base fractal. Expecting 3 arguments."); } base -> vars_init[M_x] = 0.1; base -> a = 1; base -> b = 1; } constrain(base, NULL, 0, NULL); lyap(base, -1000000.0, 1000000.0, M_failure_limit); } return (void *)base; } void base_setup(void) { base_class = class_new(gensym("base"), (t_newmethod) base_new, 0, sizeof(base_struct), 0, A_GIMME, 0); class_addbang(base_class, (t_method) calculate); class_addmethod(base_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(base_class, (t_method) show, gensym("show"), 0); class_addmethod(base_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(base_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(base_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(base_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(base_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(base_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/lorenz-help.pd0000644000076500007650000000310512076105251013710 0ustar hanshans#N canvas 185 66 689 426 10; #X obj 318 105 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 369 106 5 0 0 0 - - -; #X text 407 162 Reset To Initial Conditions; #X floatatom 363 372 10 0 0 0 Y - -; #X floatatom 318 350 10 0 0 0 X - -; #X obj 318 122 metro 50; #X obj 293 121 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 373 192 param 0.02 10 28 2.66667; #X floatatom 408 399 10 0 0 0 Z - -; #X text 20 18 Lorenz Attractor; #X text 19 33 Chaos PD Externals - Copyright Ben Bogart 2002; #X obj 20 62 examples/readme-fractals; #X obj 318 318 lorenz 0.1 0 0 0.02 10 28 2.66667; #X text 550 194 Modify parameters; #X msg 363 162 reset; #X obj 459 345 search-tools; #X obj 29 174 metro 50; #X obj 29 150 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 80 149 5 0 0 0 - - -; #X obj 29 237 lorenz; #X floatatom 74 345 5 0 0 0 - - -; #X msg 115 254 param 0.02 10 28 2.667; #X text 5 126 Calculate; #X text 113 221 Reset To Initial Conditions; #X text 115 272 Modify Parameters; #X floatatom 29 345 5 0 0 0 - - -; #X floatatom 120 345 5 0 0 0 - - -; #X text 58 318 Output; #X msg 114 203 reset 0.1 0 0; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 12 0; #X connect 6 0 12 0; #X connect 7 0 12 0; #X connect 12 0 4 0; #X connect 12 1 3 0; #X connect 12 2 8 0; #X connect 12 3 15 0; #X connect 12 4 15 1; #X connect 12 5 15 2; #X connect 14 0 12 0; #X connect 15 0 12 0; #X connect 16 0 19 0; #X connect 17 0 16 0; #X connect 18 0 16 1; #X connect 19 0 25 0; #X connect 19 1 20 0; #X connect 19 2 26 0; #X connect 21 0 19 0; #X connect 28 0 19 0; chaos-0.2/popcorn-help.pd0000644000076500007650000000222712076105251014063 0ustar hanshans#N canvas 492 119 593 496 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 94 135 5 0 0 0 - - -; #X text 79 201 Reset To Initial Conditions; #X text 99 246 Modify Parameters; #X msg 76 184 reset 0.1 0.1; #X floatatom 78 398 10 0 0 0 Y - -; #X floatatom 43 373 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 13 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 25 83 examples/readme-fractals; #X msg 95 226 param 2.35155; #X obj 43 347 popcorn 0.1 0 2.35155; #X text 98 441 This fractal seems to allow is sole parameter to range over a large range. As the value of the parameter rises \, so does the Lyapunov Exponent \, but it does not appear to be linear.; #X text 21 19 Popcorn Attractor (from Cliff Pickover); #X obj 126 373 search-tools; #X connect 0 0 9 0; #X connect 1 0 9 1; #X connect 4 0 13 0; #X connect 9 0 13 0; #X connect 10 0 13 0; #X connect 12 0 13 0; #X connect 13 0 6 0; #X connect 13 1 5 0; #X connect 13 2 16 0; #X connect 13 3 16 1; #X connect 13 4 16 2; #X connect 16 0 13 0; chaos-0.2/threeply-help.pd0000644000076500007650000000204012076105251014230 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 threeply 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Threeply Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0; chaos-0.2/gingerbreadman.c0000644000076500007650000001026212076105251014237 0ustar hanshans/* gingerbreadman Attractor PD External */ /* Copyright Michael McGonagle, from ??????, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "m_pd.h" #define M_x 0 #define M_y 1 #define M_param_count 0 #define M_var_count 2 #define M_search_count 0 #define M_failure_limit 1000 static char *version = "gingerbreadman v0.0, by Michael McGonagle, from ??????, 2003"; t_class *gingerbreadman_class; typedef struct gingerbreadman_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_outlet *outlets[M_var_count - 1]; } gingerbreadman_struct; static void calc(gingerbreadman_struct *gingerbreadman, double *vars) { double x_0, y_0; x_0 =1-vars[M_y]+abs(vars[M_x]); y_0 =vars[M_x]; vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(gingerbreadman_struct *gingerbreadman) { calc(gingerbreadman, gingerbreadman -> vars); outlet_float(gingerbreadman -> outlets[M_y - 1], gingerbreadman -> vars[M_y]); outlet_float(gingerbreadman -> x_obj.ob_outlet, gingerbreadman -> vars[M_x]); } // end calculate static void reset(gingerbreadman_struct *gingerbreadman, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { gingerbreadman -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); gingerbreadman -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { gingerbreadman -> vars[M_x] = gingerbreadman -> vars_init[M_x]; gingerbreadman -> vars[M_y] = gingerbreadman -> vars_init[M_y]; } // end if } // end reset void *gingerbreadman_new(t_symbol *s, int argc, t_atom *argv) { gingerbreadman_struct *gingerbreadman = (gingerbreadman_struct *) pd_new(gingerbreadman_class); if (gingerbreadman != NULL) { outlet_new(&gingerbreadman -> x_obj, &s_float); gingerbreadman -> outlets[0] = outlet_new(&gingerbreadman -> x_obj, &s_float); if (argc == M_param_count + M_var_count) { gingerbreadman -> vars_init[M_x] = gingerbreadman -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); gingerbreadman -> vars_init[M_y] = gingerbreadman -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for gingerbreadman fractal. Expecting 2 arguments."); } gingerbreadman -> vars_init[M_x] = -0.1; gingerbreadman -> vars_init[M_y] = 0; } } return (void *)gingerbreadman; } void gingerbreadman_setup(void) { gingerbreadman_class = class_new(gensym("gingerbreadman"), (t_newmethod) gingerbreadman_new, 0, sizeof(gingerbreadman_struct), 0, A_GIMME, 0); class_addbang(gingerbreadman_class, (t_method) calculate); class_addmethod(gingerbreadman_class, (t_method) reset, gensym("reset"), A_GIMME, 0); } chaos-0.2/latoocarfian.c0000644000076500007650000003370112076105251013737 0ustar hanshans/* latoocarfian Attractor PD External */ /* Copyright Michael McGonagle, from Cliff Pickover, 2003 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_a_lo -3 #define M_a_hi 3 #define M_b_lo -3 #define M_b_hi 3 #define M_c_lo 0.5 #define M_c_hi 1.5 #define M_d_lo 0.5 #define M_d_hi 1.5 #define M_a 0 #define M_b 1 #define M_c 2 #define M_d 3 #define M_x 0 #define M_y 1 #define M_param_count 4 #define M_var_count 2 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "latoocarfian v0.0, by Michael McGonagle, from Cliff Pickover, 2003"; t_class *latoocarfian_class; typedef struct latoocarfian_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi, d, d_lo, d_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } latoocarfian_struct; static void calc(latoocarfian_struct *latoocarfian, double *vars) { double x_0, y_0; x_0 =sin(vars[M_y]*latoocarfian -> b)+(latoocarfian -> c*sin(vars[M_x]*latoocarfian -> b)); y_0 =sin(vars[M_x]*latoocarfian -> a)+(latoocarfian -> d*sin(vars[M_y]*latoocarfian -> a)); vars[M_x] = x_0; vars[M_y] = y_0; } // end calc static void calculate(latoocarfian_struct *latoocarfian) { calc(latoocarfian, latoocarfian -> vars); outlet_float(latoocarfian -> outlets[M_y - 1], latoocarfian -> vars[M_y]); outlet_float(latoocarfian -> x_obj.ob_outlet, latoocarfian -> vars[M_x]); } // end calculate static void reset(latoocarfian_struct *latoocarfian, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { latoocarfian -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); latoocarfian -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); } else { latoocarfian -> vars[M_x] = latoocarfian -> vars_init[M_x]; latoocarfian -> vars[M_y] = latoocarfian -> vars_init[M_y]; } // end if } // end reset static char *classify(latoocarfian_struct *latoocarfian) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((latoocarfian -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[1] = c[(int) (((latoocarfian -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[2] = c[(int) (((latoocarfian -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[3] = c[(int) (((latoocarfian -> d - M_d_lo) * (1.0 / (M_d_hi - M_d_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(latoocarfian_struct *latoocarfian) { SETFLOAT(&latoocarfian -> search_out[0], latoocarfian -> lyap_exp); SETSYMBOL(&latoocarfian -> search_out[1], gensym(classify(latoocarfian))); SETFLOAT(&latoocarfian -> search_out[2], latoocarfian -> failure_ratio); SETFLOAT(&latoocarfian -> vars_out[M_x], latoocarfian -> vars[M_x]); SETFLOAT(&latoocarfian -> vars_out[M_y], latoocarfian -> vars[M_y]); SETFLOAT(&latoocarfian -> params_out[M_a], latoocarfian -> a); SETFLOAT(&latoocarfian -> params_out[M_b], latoocarfian -> b); SETFLOAT(&latoocarfian -> params_out[M_c], latoocarfian -> c); SETFLOAT(&latoocarfian -> params_out[M_d], latoocarfian -> d); outlet_list(latoocarfian -> params_outlet, gensym("list"), M_param_count, latoocarfian -> params_out); outlet_list(latoocarfian -> vars_outlet, gensym("list"), M_var_count, latoocarfian -> vars_out); } static void show(latoocarfian_struct *latoocarfian) { make_results(latoocarfian); outlet_anything(latoocarfian -> search_outlet, gensym("show"), M_search_count, latoocarfian -> search_out); } static void param(latoocarfian_struct *latoocarfian, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for latoocarfian fractal. Expecting 4 arguments."); return; } latoocarfian -> a = (double) atom_getfloatarg(0, argc, argv); latoocarfian -> b = (double) atom_getfloatarg(1, argc, argv); latoocarfian -> c = (double) atom_getfloatarg(2, argc, argv); latoocarfian -> d = (double) atom_getfloatarg(3, argc, argv); } static void seed(latoocarfian_struct *latoocarfian, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(latoocarfian_struct *latoocarfian, t_floatarg l, t_floatarg h, t_floatarg lim) { latoocarfian -> lyap_lo = l; latoocarfian -> lyap_hi = h; latoocarfian -> lyap_limit = (double) ((int) lim); } static void elyap(latoocarfian_struct *latoocarfian) { double results[M_var_count]; int i; if (lyapunov_full((void *) latoocarfian, (t_gotfn) calc, M_var_count, latoocarfian -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(latoocarfian_struct *latoocarfian) { if (latoocarfian -> a_lo < M_a_lo) { latoocarfian -> a_lo = M_a_lo; } if (latoocarfian -> a_lo > M_a_hi) { latoocarfian -> a_lo = M_a_hi; } if (latoocarfian -> a_hi < M_a_lo) { latoocarfian -> a_hi = M_a_lo; } if (latoocarfian -> a_hi > M_a_hi) { latoocarfian -> a_hi = M_a_hi; } if (latoocarfian -> b_lo < M_b_lo) { latoocarfian -> b_lo = M_b_lo; } if (latoocarfian -> b_lo > M_b_hi) { latoocarfian -> b_lo = M_b_hi; } if (latoocarfian -> b_hi < M_b_lo) { latoocarfian -> b_hi = M_b_lo; } if (latoocarfian -> b_hi > M_b_hi) { latoocarfian -> b_hi = M_b_hi; } if (latoocarfian -> c_lo < M_c_lo) { latoocarfian -> c_lo = M_c_lo; } if (latoocarfian -> c_lo > M_c_hi) { latoocarfian -> c_lo = M_c_hi; } if (latoocarfian -> c_hi < M_c_lo) { latoocarfian -> c_hi = M_c_lo; } if (latoocarfian -> c_hi > M_c_hi) { latoocarfian -> c_hi = M_c_hi; } if (latoocarfian -> d_lo < M_d_lo) { latoocarfian -> d_lo = M_d_lo; } if (latoocarfian -> d_lo > M_d_hi) { latoocarfian -> d_lo = M_d_hi; } if (latoocarfian -> d_hi < M_d_lo) { latoocarfian -> d_hi = M_d_lo; } if (latoocarfian -> d_hi > M_d_hi) { latoocarfian -> d_hi = M_d_hi; } } static void constrain(latoocarfian_struct *latoocarfian, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges latoocarfian -> a_lo = M_a_lo; latoocarfian -> a_hi = M_a_hi; latoocarfian -> b_lo = M_b_lo; latoocarfian -> b_hi = M_b_hi; latoocarfian -> c_lo = M_c_lo; latoocarfian -> c_hi = M_c_hi; latoocarfian -> d_lo = M_d_lo; latoocarfian -> d_hi = M_d_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; double d_spread = ((M_d_hi - M_d_lo) * percent) / 2; latoocarfian -> a_lo = latoocarfian -> a - a_spread; latoocarfian -> a_hi = latoocarfian -> a + a_spread; latoocarfian -> b_lo = latoocarfian -> b - b_spread; latoocarfian -> b_hi = latoocarfian -> b + b_spread; latoocarfian -> c_lo = latoocarfian -> c - c_spread; latoocarfian -> c_hi = latoocarfian -> c + c_spread; latoocarfian -> d_lo = latoocarfian -> d - d_spread; latoocarfian -> d_hi = latoocarfian -> d + d_spread; limiter(latoocarfian); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for latoocarfian constraints, requires 8 values, got %d", argc); return; } latoocarfian -> a_lo = atom_getfloat(arg++); latoocarfian -> a_hi = atom_getfloat(arg++); latoocarfian -> b_lo = atom_getfloat(arg++); latoocarfian -> b_hi = atom_getfloat(arg++); latoocarfian -> c_lo = atom_getfloat(arg++); latoocarfian -> c_hi = atom_getfloat(arg++); latoocarfian -> d_lo = atom_getfloat(arg++); latoocarfian -> d_hi = atom_getfloat(arg++); limiter(latoocarfian); } static void search(latoocarfian_struct *latoocarfian, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = latoocarfian -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_a = latoocarfian -> a; double temp_b = latoocarfian -> b; double temp_c = latoocarfian -> c; double temp_d = latoocarfian -> d; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], latoocarfian -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: latoocarfian -> a = (drand48() * (latoocarfian -> a_hi - latoocarfian -> a_lo)) + latoocarfian -> a_lo; latoocarfian -> b = (drand48() * (latoocarfian -> b_hi - latoocarfian -> b_lo)) + latoocarfian -> b_lo; latoocarfian -> c = (drand48() * (latoocarfian -> c_hi - latoocarfian -> c_lo)) + latoocarfian -> c_lo; latoocarfian -> d = (drand48() * (latoocarfian -> d_hi - latoocarfian -> d_lo)) + latoocarfian -> d_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(latoocarfian, NULL, argc, vars); do { calc(latoocarfian, latoocarfian -> vars); } while(jump--); latoocarfian -> lyap_exp = lyapunov((void *) latoocarfian, (t_gotfn) calc, M_var_count, (double *) latoocarfian -> vars); if (isnan(latoocarfian -> lyap_exp)) { not_found = 1; } if (latoocarfian -> lyap_exp < latoocarfian -> lyap_lo || latoocarfian -> lyap_exp > latoocarfian -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(latoocarfian, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) latoocarfian -> lyap_limit); post("Try using wider constraints."); latoocarfian -> a = temp_a; latoocarfian -> b = temp_b; latoocarfian -> c = temp_c; latoocarfian -> d = temp_d; outlet_anything(latoocarfian -> search_outlet, gensym("invalid"), 0, NULL); } else { latoocarfian -> failure_ratio = (latoocarfian -> lyap_limit - not_expired) / latoocarfian -> lyap_limit; make_results(latoocarfian); outlet_anything(latoocarfian -> search_outlet, gensym("search"), M_search_count, latoocarfian -> search_out); } } void *latoocarfian_new(t_symbol *s, int argc, t_atom *argv) { latoocarfian_struct *latoocarfian = (latoocarfian_struct *) pd_new(latoocarfian_class); if (latoocarfian != NULL) { outlet_new(&latoocarfian -> x_obj, &s_float); latoocarfian -> outlets[0] = outlet_new(&latoocarfian -> x_obj, &s_float); latoocarfian -> search_outlet = outlet_new(&latoocarfian -> x_obj, &s_list); latoocarfian -> vars_outlet = outlet_new(&latoocarfian -> x_obj, &s_list); latoocarfian -> params_outlet = outlet_new(&latoocarfian -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { latoocarfian -> vars_init[M_x] = latoocarfian -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); latoocarfian -> vars_init[M_y] = latoocarfian -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); latoocarfian -> a = (double) atom_getfloatarg(2, argc, argv); latoocarfian -> b = (double) atom_getfloatarg(3, argc, argv); latoocarfian -> c = (double) atom_getfloatarg(4, argc, argv); latoocarfian -> d = (double) atom_getfloatarg(5, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for latoocarfian fractal. Expecting 6 arguments."); } latoocarfian -> vars_init[M_x] = 0.1; latoocarfian -> vars_init[M_y] = 0.1; latoocarfian -> a = -0.966918; latoocarfian -> b = 2.87988; latoocarfian -> c = 0.756145; latoocarfian -> d = 0.744728; } constrain(latoocarfian, NULL, 0, NULL); lyap(latoocarfian, -1000000.0, 1000000.0, M_failure_limit); } return (void *)latoocarfian; } void latoocarfian_setup(void) { latoocarfian_class = class_new(gensym("latoocarfian"), (t_newmethod) latoocarfian_new, 0, sizeof(latoocarfian_struct), 0, A_GIMME, 0); class_addbang(latoocarfian_class, (t_method) calculate); class_addmethod(latoocarfian_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(latoocarfian_class, (t_method) show, gensym("show"), 0); class_addmethod(latoocarfian_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(latoocarfian_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(latoocarfian_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(latoocarfian_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(latoocarfian_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(latoocarfian_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/examples/0000755000076500007650000000000012076110675012751 5ustar hanshanschaos-0.2/examples/quaruptwo-test-help.pd0000644000076500007650000000353712076105251017252 0ustar hanshans#N canvas 559 82 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 160 8 -262144 -1 -1 0 1; #X floatatom 94 135 5 0 0 0 - - -; #X text 91 208 Reset To Initial Conditions; #X text 114 281 Modify Parameters; #X floatatom 197 399 10 0 0 0 Y - -; #X floatatom 43 399 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 18 150 bng 15 250 50 0 empty empty empty 0 -6 160 8 -262144 -1 -1; #X obj 25 83 readme-fractals; #X msg 117 303 search; #X obj 327 394 print; #X text 21 19 QuadrupTwo Attractor; #X msg 111 243 param 0 1 2; #X msg 177 335 show; #X msg 88 191 reset; #N canvas 0 22 470 320 search 0; #X floatatom 187 89 5 0 0 0 - - -; #X obj 142 50 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 147 73 loop; #X floatatom 186 15 5 0 0 0 - - -; #X floatatom 192 31 5 0 0 0 - - -; #X floatatom 198 47 5 0 0 0 - - -; #X obj 31 259 outlet; #X obj 77 121 t b b f; #X msg 82 218 search; #X msg 48 167 param 34 1 \$1; #X msg 65 192 constrain 0.05; #X msg 190 149 constrain; #X msg 238 268 elyapunov; #X msg 198 198 constrain 0 100 0 2 0 100; #X msg 218 228 lyapunov 0 10 1000; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 2 1 0 0; #X connect 3 0 2 0; #X connect 4 0 2 1; #X connect 5 0 2 2; #X connect 7 0 8 0; #X connect 7 2 9 0; #X connect 8 0 6 0; #X connect 9 0 6 0; #X connect 10 0 6 0; #X connect 11 0 6 0; #X connect 12 0 6 0; #X connect 13 0 6 0; #X connect 14 0 6 0; #X restore 165 96 pd search; #X obj 172 123 print sit; #X obj 43 363 quadruptwo 0.1 0.1 34 1 5; #X connect 0 0 8 0; #X connect 1 0 8 1; #X connect 8 0 19 0; #X connect 9 0 19 0; #X connect 11 0 19 0; #X connect 14 0 19 0; #X connect 15 0 19 0; #X connect 16 0 19 0; #X connect 17 0 18 0; #X connect 17 0 19 0; #X connect 19 0 5 0; #X connect 19 1 4 0; #X connect 19 2 12 0; chaos-0.2/examples/readme-lyapunov.pd0000644000076500007650000000136212076105251016402 0ustar hanshans#N canvas 0 22 565 389 10; #X text 74 61 Lyapunov Exponent; #X text 25 82 This value is an estimate of the attractors potential for chaos. It will not necessarily be the same for any given run using any arbitrary fractal. The description below attempts to put "attractors" into three catagories.; #X text 48 262 Don't forget \, just because an "attractor" is not chaotic \, it does not mean that it will not generate an interesting stream of number \, if only until they converge.; #X text 40 151 < 0; #X text 78 151 These are not chaotic \, may produce a "short-term" stream of intrest; #X text 39 179 == 0; #X text 80 179 Attractors converge to one or more points; #X text 40 197 > 0; #X text 80 198 Chaos begins. Higher values indicate "more" chaos.; chaos-0.2/examples/readme-frac-format.pd0000644000076500007650000000220112076105251016717 0ustar hanshans#N canvas 171 208 685 432 10; #X text 31 36 The format of this file is pretty simple (or tries to be).; #X text 55 69 Line 1: name - this is used as the 'c' identifier; #X text 55 81 Line 2: - integer for each ; #X text 55 93 Line 3-x: - var name and start state; #X text 55 105 Line y-z: - param data; #X text 55 131 Line c: '.' - file must end with a single period '.' ; #X text 33 180 This file is used by 'gen_fractal_framework' to produce the 'C' source for the external.; #X text 62 225 ** - The pseudo-code must not have any spaces. Each line in the pseudo-code is considered to be a single "assignment" statement. There is no need to worry about creating storage for any intermediate (calculated) variables \, as that is done by the translation program. The pseudo-code represents variables and parameters with a '$' before the variable name. Locals are allowed \, but are preceded with a '#'. (Locals are used as 'intermediate' \, computed values that are not retained from iteration to iteration.); #X text 55 118 Line a-b: - line(s) of frac 'pseudo-code' **; chaos-0.2/examples/popcorn-test-help.pd0000644000076500007650000000327512076105251016662 0ustar hanshans#N canvas 575 260 589 492 10; #X obj 43 134 tgl 15 0 empty empty empty 0 -6 160 8 -262144 -1 -1 0 1; #X floatatom 94 135 5 0 0 0 - - -; #X text 79 201 Reset To Initial Conditions; #X text 99 246 Modify Parameters; #X msg 76 184 reset 0.1 0.1; #X floatatom 131 384 10 0 0 0 Y - -; #X floatatom 43 384 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 43 151 metro 50; #X obj 13 150 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 25 83 readme-fractals; #X msg 101 266 search; #X obj 212 381 print; #X msg 113 294 show; #X msg 95 226 param 2.35155; #X obj 43 347 popcorn 0.1 0 2.35155; #N canvas 83 103 466 316 search 1; #X floatatom 187 89 5 0 0 0 - - -; #X obj 142 50 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 147 73 loop; #X floatatom 186 15 5 0 0 0 - - -; #X floatatom 192 31 5 0 0 0 - - -; #X floatatom 198 47 5 0 0 0 - - -; #X obj 31 259 outlet; #X msg 48 167 param \$1; #X obj 77 121 t b b f; #X msg 82 218 search; #X msg 65 192 constrain 0.001; #X connect 1 0 2 0; #X connect 2 0 8 0; #X connect 2 1 0 0; #X connect 3 0 2 0; #X connect 4 0 2 1; #X connect 5 0 2 2; #X connect 7 0 6 0; #X connect 8 0 9 0; #X connect 8 1 10 0; #X connect 8 2 7 0; #X connect 9 0 6 0; #X connect 10 0 6 0; #X restore 229 286 pd search; #X obj 236 313 print sit; #X connect 0 0 10 0; #X connect 1 0 10 1; #X connect 4 0 17 0; #X connect 10 0 17 0; #X connect 11 0 17 0; #X connect 13 0 17 0; #X connect 15 0 17 0; #X connect 16 0 17 0; #X connect 17 0 6 0; #X connect 17 1 5 0; #X connect 17 2 14 0; #X connect 18 0 19 0; #X connect 18 0 17 0; chaos-0.2/examples/readme-operation.pd0000644000076500007650000000365212076105251016531 0ustar hanshans#N canvas 159 133 675 651 10; #X msg 56 219 reset ; #X msg 56 240 param ; #X text 36 280 As to the exact variable and parameter ranges to use \, you will have to consult each fractals help file. You can also use the "Searching" functions to randomly find a new attractor set \, and then use those values in either a set of messages to the fractal \, or in its creation arguments.; #X msg 56 198 reset; #X text 98 199 sets the variables back to their initial state **; #X text 181 221 sets the variables to an explicit state ***; #X text 195 242 sets parameters to explicit state ****; #X text 34 26 Create a fractal with or without a set of variables and parameters \, passed as creation arguments. Without the creation arguments \, the class defaults will be used for the fractal. With the arguments \, a new fractal is created using the arguments as the defaults.; #X text 35 104 To use a fractal \, create the instance \, and optionally pass it an initial state of variables and a set of parameters. Then repeatedly 'bang' on the input to iterate thru the fractals variable states. Using a 'reset' message will return the variables to their initial state \, or to the explicit values passed.; #X text 38 369 ** - The initial state can be explicitly set by passing the arguments at creation time for the fractal \, or (without creation arguments) the class default value will be used.; #X text 37 414 *** - When setting the variables to an arbitrary state \, the stream may not be in a "stable" state. You may need to iterate the fractal several hundred (or thousand) times to obtain a "stable" state. If you pass a set of variables that were taken from the 'search' (or 'show') results \, the values most likely will be in a "stable" condition.; #X text 38 500 **** - Do remember that not all combinations of parameters result in an attractor set.; #X text 234 577 chaos \, version 2 by Ben Bogart and Michael McGonagle. Copyright 2003; chaos-0.2/examples/loop.pd0000644000076500007650000000157112076105251014245 0ustar hanshans#N canvas 640 438 490 340 10; #X obj 52 26 inlet; #X obj 93 26 inlet; #X obj 134 26 inlet; #X obj 52 262 outlet; #X obj 52 44 route bang float; #X obj 74 118 f; #X obj 74 136 -; #X obj 74 154 /; #X obj 74 172 i; #X obj 74 190 + 1; #X obj 52 208 f; #X obj 52 226 until; #X obj 52 244 f; #X obj 79 244 +; #X obj 96 99 f; #X obj 52 62 t b b b; #X obj 130 262 outlet; #X obj 74 81 t b f; #X connect 0 0 4 0; #X connect 1 0 5 1; #X connect 2 0 13 1; #X connect 2 0 7 1; #X connect 4 0 15 0; #X connect 4 1 17 0; #X connect 5 0 6 0; #X connect 6 0 7 0; #X connect 7 0 8 0; #X connect 8 0 9 0; #X connect 9 0 10 1; #X connect 9 0 16 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 12 0 3 0; #X connect 13 0 12 1; #X connect 14 0 12 1; #X connect 15 0 10 0; #X connect 15 1 5 0; #X connect 15 2 14 0; #X connect 17 0 5 0; #X connect 17 1 14 1; #X connect 17 1 6 1; chaos-0.2/examples/readme-fractals.pd0000644000076500007650000000405012076105251016321 0ustar hanshans#N canvas 495 74 487 362 10; #X declare -lib chaos; #X obj 56 202 readme-frac-format; #X obj 56 221 readme-gen-fractal; #X text 37 183 if you want to add new fractals:; #X obj 56 144 readme-operation; #X obj 56 164 readme-searching; #X text 22 107 Additional Reading \,; #X text 41 126 if you want to us existing fractals:; #X obj 56 240 readme-parameter-ranges; #X text 270 269 Developed using PD 0.36; #X text 93 295 Copyright 2003 \, Ben Bogart and Michael McGonagle; #X text 276 282 Released under GNU GPL; #N canvas 302 96 575 579 available_fractals 0; #X obj 157 264 henon; #X obj 157 302 ikeda; #X obj 157 321 latoocarfian; #X obj 157 340 latoomutalpha; #X obj 157 359 latoomutbeta; #X obj 157 378 latoomutgamma; #X obj 69 208 logistic; #X obj 277 208 lorenz; #X obj 69 227 mlogistic; #X obj 277 246 rossler; #X obj 157 473 standardmap; #X obj 69 246 tent; #X obj 277 265 three_d; #X text 57 187 1 variable; #X text 157 187 2 variables; #X text 273 187 3 variables; #X text 24 136 The remaining outputs represent the variables \, corresponding from left to right as the variables from the '*.frac' data file.; #X text 24 16 Below \, there is an object for each of the fractals currently available in the ChaosII collection.; #X text 23 55 All fractals share the same common structure \, in that the right-most outlet is used as the "results" outlet. This is used during the "Searching" operations to return the results of the search to the user. see 'readme-searching' file for more info on the results of a search.; #X obj 157 207 attract1; #X obj 157 226 dejong; #X obj 157 245 gingerbreadman; #X obj 157 283 hopalong; #X obj 157 416 martin; #X obj 277 227 pickover; #X obj 157 435 popcorn; #X obj 157 454 quadruptwo; #X obj 157 492 strange1; #X obj 157 511 tinkerbell; #X obj 157 530 unity; #X obj 157 397 lotkavolterra; #X restore 43 78 pd available_fractals; #X text 27 28 The Chaos Library provides a means to generate multiple chaotic datastreams \, as well as the ability to search for new attractor sets that produce other chaotic datastreams.; #X obj 360 6 import chaos; chaos-0.2/examples/readme-searching.pd0000644000076500007650000001074512076105251016475 0ustar hanshans#N canvas 39 41 1031 669 10; #X declare -lib chaos; #X msg 471 344 show; #X msg 470 295 seed; #X msg 470 314 seed number; #X msg 469 234 elyapunov; #X msg 467 118 constrain; #X text 601 76 random search for an attractor; #X text 508 345 displays info on attractor to console; #X text 543 119 restores full param search area; #X text 632 138 based on current params \, limits to percentage of range; #X msg 465 76 search ; #X msg 467 137 constrain ; #X msg 467 156 constrain ; #X msg 468 200 lyapunov ; #X msg 465 57 search; #X text 516 57 random search for an attractor \, variables use defaults ; #X text 17 403 The search method implemented performs the following: ; #X text 41 418 1 Set the params randomly based on allowed ranges; #X text 41 432 2 Calculate the Lyapunov Exponent; #X text 41 447 3 If the Lyapunov Exponent is within allowed range \, return the attractor set; #X text 19 39 Searching for an attractor set can be as simple as sending a 'search' message to a fractal. This will search the fractals allowable parameter limits for an attractor set.; #X text 39 183 arg[1] = Lyapunov Exponent; #X msg 469 265 classify ; #X text 591 266 Used to set the "granularity" of the classification ; #X text 17 323 The Lyapunov Exponent for the attractor set will indicates one of three states \, (1) Convergence [a negative value] \, (2) Stability [0 \, of values close to 0] \, and (3) Chaos [a positive value]. Each class will have different ranges of Lyapunov Exponent.; #X text 39 196 arg[2] = Classification String ****; #X text 16 513 **** - The classification method was adopted from Julian Sprott's method of classification. While it is an arbitrary system \, and does not "uniquely" identify an attractor set \, it is used to show a relationship with other attractor sets with similar values. ; #X text 558 313 seeds search random number generator with number * ; #X text 507 296 seeds search random number generator with time *; #X text 543 235 calculates an extended Lyapunov Exponent **; #X text 648 157 params are limited to explicit ranges ***; #X text 473 419 * - all fractals of all classes currently share the same random number generator.; #X text 473 452 ** - this performs a Lyapunov Exponent calculation for each variable in the attractor. Ideally \, all results should be approximately the same. This is an experimental function.; #X text 473 502 *** - expects there to be a low and high range limit for each param in the fractal equation.; #X text 483 217 sets search limits and failure count for Lyapunov Exponent ; #X text 37 15 Searching - the art of chaos.; #N canvas 0 22 464 316 simple_example 0; #X obj 166 106 latoocarfian; #X msg 173 38 search; #X text 32 238 This example creates a 'latoocarfian' fractal with the class defaults. When a search is performed \, the initial state for the variables are set to the class defaults.; #X obj 131 14 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 166 211 10 0 0 0 X - -; #X floatatom 185 194 10 0 0 1 Y - -; #X msg 166 16 reset; #X msg 183 61 show; #X obj 205 173 print results; #X obj 225 152 print vars; #X obj 245 132 print params; #X connect 0 0 4 0; #X connect 0 1 5 0; #X connect 0 2 8 0; #X connect 0 3 9 0; #X connect 0 4 10 0; #X connect 1 0 0 0; #X connect 3 0 0 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X restore 286 18 pd simple_example; #X text 39 210 arg[3] = failure rate before solution *****; #X text 16 581 ***** - the failure rate is a percentage of the actual number of failures until a solution is found over the total number of times the search algorithm will be executed before giving up. This limit is set via the 'lyapunov' message. This number will also be influenced by the 'low' and 'high' ranges set.; #X text 19 93 The values returned from a 'search' message use the 'search' outlets. These three outlets encapsulate that three pieces of data of interest. The first of the 'search' outlets holds a list of the results. This includes:; #X text 39 170 arg[0] = 'show' \, 'search' \, or 'invalid'; #X text 18 269 Most likely \, you won't see any failures ('invalid') \, unless you mess with the 'constrain' or 'lyapunov' messages. 'show' is returned when you use the 'show' message.; #X obj 153 376 readme-lyapunov; #X text 43 475 4 If the Limit Count has been exceeded \, return 'invalid' \, else goto 1; #X text 18 154 Search Outlet 0:; #X text 18 227 Search Outlet 1: list of current variables; #X text 18 243 Search Outlet 2: list of parameter set; #X obj 926 9 import chaos; chaos-0.2/examples/martin-test-help.pd0000644000076500007650000000457512076105251016500 0ustar hanshans#N canvas 437 54 668 669 10; #X obj 35 179 tgl 15 0 empty empty empty 0 -6 32 8 -262144 -1 -1 0 1; #X floatatom 86 180 5 0 0 0 - - -; #X text 81 219 Reset To Initial Conditions; #X text 94 261 Modify Parameters; #X msg 80 236 reset 0.1 0.1; #X floatatom 59 444 10 0 0 0 Y - -; #X floatatom 32 464 10 0 0 0 X - -; #X text 19 50 (This attractor is not continuous); #X text 21 19 Latoocarfian Attractor (from Cliff Pickover); #X text 20 34 Chaos PD Externals - Copyright Michael McGonagle 2003 ; #X obj 35 196 metro 50; #X obj 14 197 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 25 83 readme-fractals; #X msg 98 307 search; #X obj 34 392 martin; #X msg 89 282 param 1; #X msg 113 330 show; #X msg 380 144 1000; #X obj 336 202 until; #X obj 279 384 route show search invalid; #X obj 335 441 print search; #X obj 279 460 print show; #X obj 392 422 print invalid; #X obj 449 403 print somethingelse; #X msg 346 115 100; #X msg 311 141 10; #X msg 309 169 1; #X obj 474 625 qlist; #X msg 491 567 print; #X msg 484 547 clear; #X msg 474 527 rewind; #N canvas 0 22 458 308 search 1; #X floatatom 187 89 5 0 0 0 - - -; #X obj 142 50 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 147 73 loop; #X floatatom 186 15 5 0 0 0 - - -; #X floatatom 192 31 5 0 0 0 - - -; #X floatatom 198 47 5 0 0 0 - - -; #X obj 31 259 outlet; #X msg 48 167 param \$1; #X msg 65 192 constrain 0.01; #X obj 77 121 t b b f; #X msg 82 218 search; #X connect 1 0 2 0; #X connect 2 0 9 0; #X connect 2 1 0 0; #X connect 3 0 2 0; #X connect 4 0 2 1; #X connect 5 0 2 2; #X connect 7 0 6 0; #X connect 8 0 6 0; #X connect 9 0 10 0; #X connect 9 1 8 0; #X connect 9 2 7 0; #X connect 10 0 6 0; #X restore 45 119 pd search; #X obj 52 146 print sit; #X msg 136 357 lyapunov 0 10 100; #X msg 465 504 add martin \$1 \$3 \$6; #X connect 0 0 10 0; #X connect 1 0 10 1; #X connect 4 0 14 0; #X connect 10 0 14 0; #X connect 11 0 14 0; #X connect 13 0 14 0; #X connect 14 0 6 0; #X connect 14 1 5 0; #X connect 14 2 19 0; #X connect 15 0 14 0; #X connect 16 0 14 0; #X connect 17 0 18 0; #X connect 18 0 13 0; #X connect 19 0 21 0; #X connect 19 1 20 0; #X connect 19 1 34 0; #X connect 19 2 22 0; #X connect 19 3 23 0; #X connect 24 0 18 0; #X connect 25 0 18 0; #X connect 26 0 18 0; #X connect 28 0 27 0; #X connect 29 0 27 0; #X connect 30 0 27 0; #X connect 31 0 32 0; #X connect 31 0 14 0; #X connect 33 0 14 0; #X connect 34 0 27 0; chaos-0.2/examples/readme-parameter-ranges.pd0000644000076500007650000000272012076105251017761 0ustar hanshans#N canvas 0 22 499 399 10; #X text 33 275 The "classification" of an attractor set uses the full range of the fractals acceptable parameter ranges. As this method of "classification" is relative \, it will not describe each fractal uniquely \, but rather can be used to compare attractor sets that have similar (closely related) parameter values. NOTE: there needs to be a way to increase the granularity of the classification system...; #X text 35 21 Parameter Ranges - Once you have an operational fractal external \, it is important to make sure that the assigned ranges for each of the parameters are "optimized" to limit the random number generator to those ranges. This is important when a variable can only range between (-1 .. 1) and you have declared that it can range from (-100 .. 100). Because of the much wider search space \, there is less likelyhood of finding anything useful \, or at least make the search times longer due to higher failure rates.; #X text 35 147 If you are unsure of what the ranges are \, you can either figure them out mathematically \, or use the "brute-force" method and iterate over ranges of the defined parameters. The points that return a fractal (even ones that converge) will give an indication as to the acceptable ranges for each param. Once you have determined those ranges \, adjust them in your '*.frac' file and re-make the external for your fractal. (Or you can just edit the Macros in the C code \, if you are comfortable with that.); chaos-0.2/examples/readme-gen-fractal.pd0000644000076500007650000000043212076105251016705 0ustar hanshans#N canvas 0 22 478 328 10; #X text 25 23 This will explain the usage of 'gen_fractal_framework' \, once the program has become more "stable" and generates what would be unique to each fractal. Currently \, there is still some redundancy in the code.; #X text 282 136 more later...; chaos-0.2/chaos.sln0000644000076500007650000000161612076105251012744 0ustar hanshansMicrosoft Visual Studio Solution File, Format Version 7.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chaos", "chaos.vcproj", "{079DD347-F5E0-4784-9BCE-AF551691BA41}" EndProject Global GlobalSection(SolutionConfiguration) = preSolution ConfigName.0 = Debug ConfigName.1 = Release EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {079DD347-F5E0-4784-9BCE-AF551691BA41}.Debug.ActiveCfg = Debug|Win32 {079DD347-F5E0-4784-9BCE-AF551691BA41}.Debug.Build.0 = Debug|Win32 {079DD347-F5E0-4784-9BCE-AF551691BA41}.Release.ActiveCfg = Release|Win32 {079DD347-F5E0-4784-9BCE-AF551691BA41}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal chaos-0.2/lorenz.c0000644000076500007650000003171212076105251012606 0ustar hanshans/* lorenz Attractor PD External */ /* Copyright Ben Bogart, 2002 */ /* This program is distributed under the params of the GNU Public License */ /////////////////////////////////////////////////////////////////////////////////// /* This file is part of Chaos PD Externals. */ /* */ /* Chaos PD Externals are free software; you can redistribute them and/or modify */ /* them under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* Chaos PD Externals are distributed in the hope that they will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with the Chaos PD Externals; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "chaos.h" #define M_h_lo -1000 #define M_h_hi 1000 #define M_a_lo -1000 #define M_a_hi 1000 #define M_b_lo -1000 #define M_b_hi 1000 #define M_c_lo -1000 #define M_c_hi 1000 #define M_h 0 #define M_a 1 #define M_b 2 #define M_c 3 #define M_x 0 #define M_y 1 #define M_z 2 #define M_param_count 4 #define M_var_count 3 #define M_search_count 3 #define M_failure_limit 1000 static char *version = "lorenz v0.0, by Ben Bogart, 2002"; t_class *lorenz_class; typedef struct lorenz_struct { t_object x_obj; double vars[M_var_count]; double vars_init[M_var_count]; t_atom vars_out[M_var_count]; t_outlet *vars_outlet; t_atom search_out[M_search_count]; t_outlet *search_outlet; double h, h_lo, h_hi, a, a_lo, a_hi, b, b_lo, b_hi, c, c_lo, c_hi; t_atom params_out[M_param_count]; t_outlet *params_outlet; double lyap_exp, lyap_lo, lyap_hi, lyap_limit, failure_ratio; t_outlet *outlets[M_var_count - 1]; } lorenz_struct; static void calc(lorenz_struct *lorenz, double *vars) { double x_0, y_0, z_0; x_0 =vars[M_x]+lorenz -> h*lorenz -> a*(vars[M_y]-vars[M_x]); y_0 =vars[M_y]+lorenz -> h*(vars[M_x]*(lorenz -> b-vars[M_z])-vars[M_y]); z_0 =vars[M_z]+lorenz -> h*(vars[M_x]*vars[M_y]-lorenz -> c*vars[M_z]); vars[M_x] = x_0; vars[M_y] = y_0; vars[M_z] = z_0; } // end calc static void calculate(lorenz_struct *lorenz) { calc(lorenz, lorenz -> vars); outlet_float(lorenz -> outlets[M_z - 1], lorenz -> vars[M_z]); outlet_float(lorenz -> outlets[M_y - 1], lorenz -> vars[M_y]); outlet_float(lorenz -> x_obj.ob_outlet, lorenz -> vars[M_x]); } // end calculate static void reset(lorenz_struct *lorenz, t_symbol *s, int argc, t_atom *argv) { if (argc == M_var_count) { lorenz -> vars[M_x] = (double) atom_getfloatarg(M_x, argc, argv); lorenz -> vars[M_y] = (double) atom_getfloatarg(M_y, argc, argv); lorenz -> vars[M_z] = (double) atom_getfloatarg(M_z, argc, argv); } else { lorenz -> vars[M_x] = lorenz -> vars_init[M_x]; lorenz -> vars[M_y] = lorenz -> vars_init[M_y]; lorenz -> vars[M_z] = lorenz -> vars_init[M_z]; } // end if } // end reset static char *classify(lorenz_struct *lorenz) { static char buff[5]; char *c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; buff[0] = c[(int) (((lorenz -> h - M_h_lo) * (1.0 / (M_h_hi - M_h_lo))) * 26)]; buff[1] = c[(int) (((lorenz -> a - M_a_lo) * (1.0 / (M_a_hi - M_a_lo))) * 26)]; buff[2] = c[(int) (((lorenz -> b - M_b_lo) * (1.0 / (M_b_hi - M_b_lo))) * 26)]; buff[3] = c[(int) (((lorenz -> c - M_c_lo) * (1.0 / (M_c_hi - M_c_lo))) * 26)]; buff[4] = '\0'; return buff; } static void make_results(lorenz_struct *lorenz) { SETFLOAT(&lorenz -> search_out[0], lorenz -> lyap_exp); SETSYMBOL(&lorenz -> search_out[1], gensym(classify(lorenz))); SETFLOAT(&lorenz -> search_out[2], lorenz -> failure_ratio); SETFLOAT(&lorenz -> vars_out[M_x], lorenz -> vars[M_x]); SETFLOAT(&lorenz -> vars_out[M_y], lorenz -> vars[M_y]); SETFLOAT(&lorenz -> vars_out[M_z], lorenz -> vars[M_z]); SETFLOAT(&lorenz -> params_out[M_h], lorenz -> h); SETFLOAT(&lorenz -> params_out[M_a], lorenz -> a); SETFLOAT(&lorenz -> params_out[M_b], lorenz -> b); SETFLOAT(&lorenz -> params_out[M_c], lorenz -> c); outlet_list(lorenz -> params_outlet, gensym("list"), M_param_count, lorenz -> params_out); outlet_list(lorenz -> vars_outlet, gensym("list"), M_var_count, lorenz -> vars_out); } static void show(lorenz_struct *lorenz) { make_results(lorenz); outlet_anything(lorenz -> search_outlet, gensym("show"), M_search_count, lorenz -> search_out); } static void param(lorenz_struct *lorenz, t_symbol *s, int argc, t_atom *argv) { if (argc != 4) { post("Incorrect number of arguments for lorenz fractal. Expecting 4 arguments."); return; } lorenz -> h = (double) atom_getfloatarg(0, argc, argv); lorenz -> a = (double) atom_getfloatarg(1, argc, argv); lorenz -> b = (double) atom_getfloatarg(2, argc, argv); lorenz -> c = (double) atom_getfloatarg(3, argc, argv); } static void seed(lorenz_struct *lorenz, t_symbol *s, int argc, t_atom *argv) { if (argc > 0) { srand48(((unsigned int)time(0))|1); } else { srand48((unsigned int) atom_getfloatarg(0, argc, argv)); } } static void lyap(lorenz_struct *lorenz, t_floatarg l, t_floatarg h, t_floatarg lim) { lorenz -> lyap_lo = l; lorenz -> lyap_hi = h; lorenz -> lyap_limit = (double) ((int) lim); } static void elyap(lorenz_struct *lorenz) { double results[M_var_count]; int i; if (lyapunov_full((void *) lorenz, (t_gotfn) calc, M_var_count, lorenz -> vars, results) != NULL) { post("elyapunov:"); for(i = 0; i < M_var_count; i++) { post("%d: %3.80f", i, results[i]); } } } static void limiter(lorenz_struct *lorenz) { if (lorenz -> h_lo < M_h_lo) { lorenz -> h_lo = M_h_lo; } if (lorenz -> h_lo > M_h_hi) { lorenz -> h_lo = M_h_hi; } if (lorenz -> h_hi < M_h_lo) { lorenz -> h_hi = M_h_lo; } if (lorenz -> h_hi > M_h_hi) { lorenz -> h_hi = M_h_hi; } if (lorenz -> a_lo < M_a_lo) { lorenz -> a_lo = M_a_lo; } if (lorenz -> a_lo > M_a_hi) { lorenz -> a_lo = M_a_hi; } if (lorenz -> a_hi < M_a_lo) { lorenz -> a_hi = M_a_lo; } if (lorenz -> a_hi > M_a_hi) { lorenz -> a_hi = M_a_hi; } if (lorenz -> b_lo < M_b_lo) { lorenz -> b_lo = M_b_lo; } if (lorenz -> b_lo > M_b_hi) { lorenz -> b_lo = M_b_hi; } if (lorenz -> b_hi < M_b_lo) { lorenz -> b_hi = M_b_lo; } if (lorenz -> b_hi > M_b_hi) { lorenz -> b_hi = M_b_hi; } if (lorenz -> c_lo < M_c_lo) { lorenz -> c_lo = M_c_lo; } if (lorenz -> c_lo > M_c_hi) { lorenz -> c_lo = M_c_hi; } if (lorenz -> c_hi < M_c_lo) { lorenz -> c_hi = M_c_lo; } if (lorenz -> c_hi > M_c_hi) { lorenz -> c_hi = M_c_hi; } } static void constrain(lorenz_struct *lorenz, t_symbol *s, int argc, t_atom *argv) { int i; t_atom *arg = argv; if (argc == 0) { // reset to full limits of search ranges lorenz -> h_lo = M_h_lo; lorenz -> h_hi = M_h_hi; lorenz -> a_lo = M_a_lo; lorenz -> a_hi = M_a_hi; lorenz -> b_lo = M_b_lo; lorenz -> b_hi = M_b_hi; lorenz -> c_lo = M_c_lo; lorenz -> c_hi = M_c_hi; return; } if (argc == 1) { // set the ranges based on percentage of full range double percent = atom_getfloat(arg); double h_spread = ((M_h_hi - M_h_lo) * percent) / 2; double a_spread = ((M_a_hi - M_a_lo) * percent) / 2; double b_spread = ((M_b_hi - M_b_lo) * percent) / 2; double c_spread = ((M_c_hi - M_c_lo) * percent) / 2; lorenz -> h_lo = lorenz -> h - h_spread; lorenz -> h_hi = lorenz -> h + h_spread; lorenz -> a_lo = lorenz -> a - a_spread; lorenz -> a_hi = lorenz -> a + a_spread; lorenz -> b_lo = lorenz -> b - b_spread; lorenz -> b_hi = lorenz -> b + b_spread; lorenz -> c_lo = lorenz -> c - c_spread; lorenz -> c_hi = lorenz -> c + c_spread; limiter(lorenz); return; } if (argc != M_param_count * 2) { post("Invalid number of arguments for lorenz constraints, requires 8 values, got %d", argc); return; } lorenz -> h_lo = atom_getfloat(arg++); lorenz -> h_hi = atom_getfloat(arg++); lorenz -> a_lo = atom_getfloat(arg++); lorenz -> a_hi = atom_getfloat(arg++); lorenz -> b_lo = atom_getfloat(arg++); lorenz -> b_hi = atom_getfloat(arg++); lorenz -> c_lo = atom_getfloat(arg++); lorenz -> c_hi = atom_getfloat(arg++); limiter(lorenz); } static void search(lorenz_struct *lorenz, t_symbol *s, int argc, t_atom *argv) { int not_found, not_expired = lorenz -> lyap_limit; int jump, i, iterations; t_atom vars[M_var_count]; double temp_h = lorenz -> h; double temp_a = lorenz -> a; double temp_b = lorenz -> b; double temp_c = lorenz -> c; if (argc > 0) { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], atom_getfloatarg(i, argc, argv)); } } else { for (i = 0; i < M_var_count; i++) { SETFLOAT(&vars[i], lorenz -> vars_init[i]); } } do { jump = 500; not_found = 0; iterations = 10000; bad_params: lorenz -> h = (drand48() * (lorenz -> h_hi - lorenz -> h_lo)) + lorenz -> h_lo; lorenz -> a = (drand48() * (lorenz -> a_hi - lorenz -> a_lo)) + lorenz -> a_lo; lorenz -> b = (drand48() * (lorenz -> b_hi - lorenz -> b_lo)) + lorenz -> b_lo; lorenz -> c = (drand48() * (lorenz -> c_hi - lorenz -> c_lo)) + lorenz -> c_lo; // put any preliminary checks specific to this fractal to eliminate bad_params reset(lorenz, NULL, argc, vars); do { calc(lorenz, lorenz -> vars); } while(jump--); lorenz -> lyap_exp = lyapunov((void *) lorenz, (t_gotfn) calc, M_var_count, (double *) lorenz -> vars); if (isnan(lorenz -> lyap_exp)) { not_found = 1; } if (lorenz -> lyap_exp < lorenz -> lyap_lo || lorenz -> lyap_exp > lorenz -> lyap_hi) { not_found = 1; } not_expired--; } while(not_found && not_expired); reset(lorenz, NULL, argc, vars); if (!not_expired) { post("Could not find a fractal after %d attempts.", (int) lorenz -> lyap_limit); post("Try using wider constraints."); lorenz -> h = temp_h; lorenz -> a = temp_a; lorenz -> b = temp_b; lorenz -> c = temp_c; outlet_anything(lorenz -> search_outlet, gensym("invalid"), 0, NULL); } else { lorenz -> failure_ratio = (lorenz -> lyap_limit - not_expired) / lorenz -> lyap_limit; make_results(lorenz); outlet_anything(lorenz -> search_outlet, gensym("search"), M_search_count, lorenz -> search_out); } } void *lorenz_new(t_symbol *s, int argc, t_atom *argv) { lorenz_struct *lorenz = (lorenz_struct *) pd_new(lorenz_class); if (lorenz != NULL) { outlet_new(&lorenz -> x_obj, &s_float); lorenz -> outlets[0] = outlet_new(&lorenz -> x_obj, &s_float); lorenz -> outlets[1] = outlet_new(&lorenz -> x_obj, &s_float); lorenz -> search_outlet = outlet_new(&lorenz -> x_obj, &s_list); lorenz -> vars_outlet = outlet_new(&lorenz -> x_obj, &s_list); lorenz -> params_outlet = outlet_new(&lorenz -> x_obj, &s_list); if (argc == M_param_count + M_var_count) { lorenz -> vars_init[M_x] = lorenz -> vars[M_x] = (double) atom_getfloatarg(0, argc, argv); lorenz -> vars_init[M_y] = lorenz -> vars[M_y] = (double) atom_getfloatarg(1, argc, argv); lorenz -> vars_init[M_z] = lorenz -> vars[M_z] = (double) atom_getfloatarg(2, argc, argv); lorenz -> h = (double) atom_getfloatarg(3, argc, argv); lorenz -> a = (double) atom_getfloatarg(4, argc, argv); lorenz -> b = (double) atom_getfloatarg(5, argc, argv); lorenz -> c = (double) atom_getfloatarg(6, argc, argv); } else { if (argc != 0 && argc != M_param_count + M_var_count) { post("Incorrect number of arguments for lorenz fractal. Expecting 7 arguments."); } lorenz -> vars_init[M_x] = 0.1; lorenz -> vars_init[M_y] = 0; lorenz -> vars_init[M_z] = 0; lorenz -> h = 0.01; lorenz -> a = 10; lorenz -> b = 28; lorenz -> c = 2.66667; } constrain(lorenz, NULL, 0, NULL); lyap(lorenz, -1000000.0, 1000000.0, M_failure_limit); } return (void *)lorenz; } void lorenz_setup(void) { lorenz_class = class_new(gensym("lorenz"), (t_newmethod) lorenz_new, 0, sizeof(lorenz_struct), 0, A_GIMME, 0); class_addbang(lorenz_class, (t_method) calculate); class_addmethod(lorenz_class, (t_method) reset, gensym("reset"), A_GIMME, 0); class_addmethod(lorenz_class, (t_method) show, gensym("show"), 0); class_addmethod(lorenz_class, (t_method) param, gensym("param"), A_GIMME, 0); class_addmethod(lorenz_class, (t_method) seed, gensym("seed"), A_GIMME, 0); class_addmethod(lorenz_class, (t_method) lyap, gensym("lyapunov"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(lorenz_class, (t_method) elyap, gensym("elyapunov"), 0); class_addmethod(lorenz_class, (t_method) search, gensym("search"), A_GIMME, 0); class_addmethod(lorenz_class, (t_method) constrain, gensym("constrain"), A_GIMME, 0); } chaos-0.2/mlogistic-help.pd0000644000076500007650000000017112076105251014371 0ustar hanshans#N canvas 149 395 450 300 10; #X text 71 41 1 variable; #X obj 248 24 examples/readme-fractals; #X obj 90 148 mlogistic; chaos-0.2/strange1-help.pd0000644000076500007650000000203612076105251014125 0ustar hanshans#N canvas 426 137 573 476 10; #X obj 44 115 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 95 116 5 0 0 0 - - -; #X floatatom 132 393 10 0 0 0 Y - -; #X floatatom 44 393 10 0 0 0 X - -; #X text 18 49 (This attractor is not continuous); #X obj 44 132 metro 50; #X obj 19 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 242 104 examples/readme-fractals; #X msg 87 245 search; #X text 138 246 Find a random attractor set; #X msg 98 266 show; #X obj 44 316 strange 0 0 -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X msg 78 195 param -0.0239362 -0.67834 2.50703 -0.0138538 -1.44072 2.47917; #X text 20 18 Strange Attractor; #X text 18 33 Chaos PD Externals - Copyright Michael McGonagle \, 2003 ; #X obj 278 367 search-tools; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 5 0 11 0; #X connect 6 0 11 0; #X connect 8 0 11 0; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 2 0; #X connect 11 2 15 0; #X connect 11 3 15 1; #X connect 11 4 15 2; #X connect 12 0 11 0; #X connect 15 0 11 0;