CHAOS Operators



Yeah. Definitely lots of potential.


this is why

a) i think cubic map is maybe a tiny bit more useful than logistic for music - it always oscillates

b) you always want to constrain the params for the behavior you find interesting - i’d suggest r in [3.2, 4.0) for both of these if you want them to always be "obviously chaotic"
here’s my “low-res” bifurcation plot for cubic map; you can see that it is exactly like a symmetrically oscillating logistic

% cubic
Npre = 200;
Nplot = 100;
x = zeros(Nplot,1); 
rmin = 2.5;
rmax = 4.0;
rstep = 0.005;
i = 0;
for r = rmin:rstep:rmax
  % fake it til you make it...
  % using same initial value each time won't capture sign flipping
  i = i + 1;
  x(1) = 0.5 * (-1)^i;
  for n = 1:Npre
    x(1) = r*x(1)^3 + (1 - r)*x(1);
  for n = 1:Nplot-1
    x(n+1) = r*x(n)^3 + (1 - r)*x(n); 
  plot(r*ones(Nplot,1), x, '.', 'markersize', 1, 'Color', [0, 0, 0]); 
  hold on; 
title('cubic map bifurcation'); 
xlabel('r');  ylabel('x_n');
set(gca, 'xlim', [rmin rmax]); 
hold off;

i’d like to do one for henon too, but it’s trickier. 2 params so it’d have to be a “bifurcation surface” … hard to read… might as well just say that it looks much “noisier” throughout - periods of different lengths are interspersed across the range of parameters. but IIRC the period is always >=2.

[ed] heh, here is someone’s henon bifurcation from wikipedia, with one parameter fixed b=0.3 (a reasonable value)

the notes on the image give an idea of how non-trivial it is to create a meaningful bifurcation plot in this case (and many others)

also, in practical terms (@sliderule) i’d say if you want 1 output, 1 param, that henon oscillator is still useful and interesting if you just fix b=0.3 and take the newest value as output.

oh! for all these deterministic, iterative things, i also think it’s kinda important for musical purposes to be able to arbitrarily set the running state at any time. this lets you take advantage of the coolest thing about these processes - which is that they are repeatable.

pedantic point: it’s not strictly correct to say that some outputs of these functions are “chaotic” and some are “not chaotic.” being “chaotic” is a (somewhat subjectively-defined) property of the system, meaning just that it is a) sensitive to initial conditions, and b) orbits of different lengths lie close together in parameter space. if you wanna refer to output sequences that are “noisier” you can say that they have a longer period or orbit.

however, I guess it’d be reasonable to say, for instance, that above R=3.4 or something the logistic map “is chaotic” (orbits are closely spaced) and below that it is “not chaotic” cause the orbits are all basically the same. i’m still not super comfy with this because it emphasizes the subjectivity too much; your perception of “closely-spaced” is dependent on scale.



Thank you for the “pedantic” explanation. I like the cubic map too and the Henon looks very exciting.

I think my main point was that I would want to have the R parameter accessible all the time while using CHAOS. The reason for this is that I would want to move back and forth on the X axis of the graph and change the distribution over time. And it seems as if this is not possible, or at least a bit cumbersome if it is implemented as in the example above:

Also I would like to give a strong vote for the BELL/GAUSSIAN distribution @sam suggested.


agree, definitely would want to be able to modulate the chaos parmater. and preferably the state as well, somehow


Are there any would-be coders who would like to try their hand at implementing the algorithm? @zebra?

I’ve got a full implementation ready with a broken logistic map (which is chaotic and predictable, but not correct), so it’s just the math left.


Basic CHAOS implementation here:


CHAOS.R 375             | set r to 3.75, default
CHAOS 5000              | set val to 0.50, default
CHAOS                   | get next value
                        | 10000 = 1.0, -10000 = -1.0

Test Build:
teletype.hex (360.3 KB)
teletype.hex (360.5 KB)

Note that the test build not accurate but functional!

When I last built a user-configurable chaotic oscillator, one thing that I implemented was automatic response to static zero conditions. Was useful in that context, not sure it will be here.


hm ok, i’m looking and it seems like it should be correct. (sorry i don’t have TT hardware here right now.) in what way is it incorrect?

well, except for one obvious thing, which is that giving 5000 as the state input sets value to ~0.15, not 0.5. and the output range scaling would be [-1, 1] -> [-32768, 32767], not [-1, 1] -> [-10000, 10000] … right? (i’m assuming here that INT16_MAX is defined as 0x7fff and not 10000; apologies if i’m mistaken there.)

[ed] still, looks like it should be wiggly enough


Well I found one bug in the configuration of the operator callbacks. That fixes it! I’ll update the post above with a new build.

As to 5000, are you sure you didn’t type 50000?

edit: I might not have had the right commit pushed.

Also, I chose 10000 so that it would be decimal-analagous. I had it originally at INT16_MAX/MIN limits but it wasn’t intuitive to use.

No I thought you might have compiled the simulator :wink:


for posterity, steps to build and run simulator:

git clone --recursive
git fetch --all
git checkout chaos
cd teletype/simulator

(requires ragel and probably other stuff.)

ok, repeatedly typing CHAOS after setting param and state, gives me values flopping around in a logistic-map-looking way, roughly in the right range. i don’t know if i have it in me at the moment to build a proper test harness for this (i am procrastinating right now, trying to work on the Next Monome Thing.)

again, is there anything particularly bothering you about this? or do you just want to add more functions?

(btw, i’m freely deleting fumbling-around-with-toolchain posts, since they just add noise to the main topic under discussion)


Oh now that I fixed that one bug, I’m confident that it’s complete.

That said, the structure is there and if you implement alternate choas_get_val I can make it pluggable.

I’m not so mathy so if you have the skills and time to implement other algorithms, I can stitch CHAOS.ALG x together.


ok cool. i can probably do that quickly. though it’s not quite clear to me how you would select between different functions syntactically, i can just add different states for different ‘modes’ or whatever, and let you figure out how CHAOS.ALG x works

slightly OT, but is it easy to tell me how to repeatedly bang an operator in the simulator? i guess i can just pipe CHAOS\n into stdin over and over, and pipe stdout to plot it, but maybe there is an easier way (and sorry, i’m too lazy to look closely r/n)

also, sorry i’m honestly not really a teletype user. it’s all evolved rather a lot since the last time i even looked at the source code.


CTRL-D works, but is less than 20 characters.

Yeah I can do the rest of the code so you can keep your changes to chaos.c/h.

If you want to keep it simple, just make copies of chaos.c/h for each algorithm. Or separate branches and PR them all independently and I’ll handle the merge.


i just added an algorithm switch and more functions to chaos.h / chaos.c , and opened a pull request

its incomplete, still need to do cell-aut mode. also more tests. i think i’m out of time for the moment though.

[ed] went ahead and added logic for 1d binary cell-aut. output looks reasonable, though it’s a sort of weird and arbitrary interpretation: the cell states are bits in an 8b value; might be better to just return the sum of bits (rather than the value itself.)

[ed] hm, i keep going back and forth on this. ideally the 1d cell aut output should just be 8 gates. sorry, i don’t even know if TT has bitwise operators…

ok, now i really gotta be done for the night.


I am still missing a somehow comprehensible explanation of what this does. Just tried to install it to see if I can figure it out by myself but it seems to be just a cryptic text file…?



New test build: teletype.hex (366.3 KB)


CHAOS              | get next chaotic value
CHAOS 5000         | set current value to half (see below)
CHAOS.R            | get chaos parameter
CHAOS.R 5000       | set chaos parameter to half
CHAOS.ALG          | get current algorithm
CHAOS.ALG 0        | select LOGISTIC
CHAOS.ALG 1        | select CUIBIC
CHAOS.ALG 2        | select HENON

Algorithm Parameters:

Logistic Map

  • R (0-10000) ranges from 3.2 to 4
  • CHAOS (-10000-10000) ranges from -1 to 1

Cubic Map

  • R (0-10000) ranges from 3.2 to 4
  • CHAOS (-10000-10000) ranges from -1 to 1

Henon Map

  • R (0-10000) ranges from 1 to 1.4
  • CHAOS (-10000-10000) ranges from -1.5 to 1.5

Cellular Automata

  • R (0-255) selects the rule from 0 to 255
  • CHAOS (0-255) ranges from 0-255

(Teletype) 2.2 Release

When I change CV 3 CHAOS.R X (say from X 5000 to X 0) there seems to be a slew on the CV. Is that expected behaviour?


CHAOS.R 5000 does not return a value. It is a setter.

CV 3 CHAOS.R X is undefined, I think.


Yes, sorry - my fault! What I did was this:


Then changing CHAOS.R in live mode from 5000 to 0.

Also what strange stuff is happening when CHAOS.R is exceeding 10000?

I find it a bit hard to guess where on the logistic map (i.e. the Feigenbaum digram) I am. Is there some easy maths to calculate this? I see that the resolution is much higher now but I liked the 275 = 2.75 ratio you first suggested.

It would be nice to have the range starting at 3.0 to include the first branch on the logistic and cubic maps

I understand it a bit better now and I think it is a good idea!


I have to admit I find it confusing and counter-intuitive that the same values for R
and CHAOS seem to produce different output value ranges depending on the chosen algorithm. And why does only the cellular automata offer a 1:1 relationship between input values (0-255) and output values (0-255)?

This is likely just due to my complete lack of understanding of the subject,
but I expect to be able to define an output value range for Chaos,
and be able to change the behavior/type of Chaos while maintaining the output value range I specified.

Of course I can do this scaling after the chaos function, but wouldn’t that be a waste of resources and make finding a suitable chaos type harder, or in other words make things less friendly for experimentation? “Hm, I don’t know if I like this type of chaos function, let me try a different one, wait a sec, that’s not so easy, as I first have to look up which output value ranges the other chaos function produce, and then adopt the scaling function accordingly.”

I guess I am just not getting the point, so please help me understand where my thinking is wrong.


Paging @zebra to the thread to explain!