CHAOS Operators



I think I missed the post that suggests the 2 parameter R (which sounds good), can you update the API documentation you’ve got half way through the thread and put it in the top post to clarify where we’re at right now?


Thanks for updating the top post @sliderule. I like the API you define there and the break out of CA. How’s this sitting with others? Everyone good?


feel like i’m posting way to much in this thread, sorry
and particularly since i don’t relly have a horse in the race re: syntax

but actually no, the API as written does not work with the code as written. (assuming that you remove param scaling, because right now the code expects param to be normalized in [0, 10k.])

  • the value ranges are already scaled by each algorithm to [-10k, 10k]. (though logistic will only output positive values.) so setting the value to 15k won’t work. (well, it would be internally clamped to 10k and produce a boring orbit, but that’s not what you want.)

  • i restate belief that its confusing and actually wrong to not scale the parameter in the combined op. setting henon param to 3.5 won’t work. (well, it will explode the algorithm, which will then hard-clip its output to -10k or 10k, probably not what you want.)

you can split the algorithms into separate ops, or you can scale the parameter, but you can’t do neither. this would be exacerbated with each algo you add, if you add any.

i think it’s intuitive to scale the param to [0, 10k], same as the value scale, if it is a single op with multiple algos. just my opinion.

for separate ops, you could argue that param should be literal - so one could exploit e.g. the knowledge that logistic map has a bifurcation at a=3.2. it would also be more consistent with the CA op. on the other hand its less intuitive.


Your posts have been helpful for sure, nothing to apologize for. However, it would be good if someone who understands the algorithms as well as you who also has a sense of how to represent them in TT consistent with other ops could take a stab at rewriting the API’s. I’m feeling around in the dark here for sure, @sliderule is the most likely API author. Maybe we need to just give up trying to make the API ‘better’ until these things live in the wild for a while, assuming that there will be a breaking change if there’s ever an opportunity to make CHAOS more musical and TT friendly.

It’s also amazing that the above is essentially saying, “CHAOS can’t be tamed.” chaos wins. again.


Excluding “bugs in the existing code that may come from using this scheme”, both of these cases would be, in this scheme, a user error.

I think this highlights the contrast. Restating what has been said,

  • CHAOS has complex behavior, therefore
  • Using CHAOS will have a tendency to be difficult to understand, therefore
  • CHAOS will require extensive documentation, and
  • CHAOS will require careful usage and experience
  • There will be trade-off between
    • Accuracy
    • Flexibility
    • Ease-of-use

Design Options

1. Proposed Syntax in OP

Accuracy: ±

± R: 0.0000000 to 9.9999999
± Values: -1.5000 to 1.5000

Flexibility: +

+ All three algorithms
+ Can modulate ALG (if you understand it! :wink: )

Ease-of-use: +

+ Only 3 operators
- 2 scales, but
+ Both are decimal

2a. Split the algorithms

Accuracy: ±
± R: same as above
± V: same as above

Flexibility: -
- Can’t modulate ALG

Ease-of-use: ++
+ Algorithm name baked in

2b: Accurately-scaled R

Accuracy: ++
+ R: depends on algo, scaled to best usability and accuracy

Flexibility: ++
+ Better access to close orbits is useful

Ease-of-use: --
- Different scales for R between algorithms
- Scales are unintuitive


  • 2a and 2b can be combined and represent @zebra’s full proposal (I think.)


Thanks much for this and the subsequent explanations. I’ll try to summarize what I understood:
• The input states for the various CHAOS functions determine the maximum possible numeric “space” for the output values the CHAOS function might produce.
• The input states for the various CHAOS functions do not guarantee that the actual output values produced by the CHAOS function will actually use the complete numeric output value “space”. The actual output values might just use a fraction of the available output value “space”. But they will never be outside the output volume space.
Is this correct?


I hate to say it, but the more I try to understand the implementation of CHAOS the less useful it becomes in my mind. I hate to point to a thread that I created that doesn’t have explicit buy in from @tehn or the rest of the community, but based on the ideas expressed in TT ‘philosophy’ thread, I don’t see how this op benefits TT users and composers. It’s very interesting stuff, but I don’t see how to use it musically, and given the wildness of outputs it feels very very difficult to use effectively. EDIT 11/1/17 don’t agree with this anymore, wanted to clarify for future historians.

I may just move on and give CHAOS the side eye when it’s released. If that’s the case, I hope that in the future someone posts an amazing study or codex entry that helps me understand. :slight_smile:


um, ok… well on principle i don’t care to put much time into convincing anyone of the “musical utility” of anything.

but real quick here is a dumb demo of a sinewave arpeggio. pitch is the output of a logistic map, scaled to mid [48, 72] and quantized. parameter is scrubbing up and down in increments of 1/100th of the range.

this is in supercollider but is numerically equivalent to the TT code. this is using minimum R=3.0 as suggested by whoever suggested it, though i think its a little low since as you can hear, the output tends stay pretty predictable over most of the param range.

i don’t know if this is musically appealing to you, but i hypothesize that people exist who like to do this kind of thing.

SC code
s = Server.local;
s.waitForBoot {

	x = 0.77;
	r = 3.0;

	~set_r_norm = { arg rnorm;
		r = rnorm.linlin(0, 1, 3.0, 3.999);

	~iter = {	
		x = r*x*(1-x);

	~rnorm = 0.0;
	~rnorm_inc = 0.01;
	~rout = Routine {
		var hz; {
			~rnorm = ~rnorm + ~rnorm_inc;
			if(~rnorm > 1.0, { ~rnorm = 1.0; ~rnorm_inc = -0.01; });
			if(~rnorm < 0.0, { ~rnorm = 0.0; ~rnorm_inc = 0.01; });
			hz = x.linlin(0, 1.0, 48, 72).round.midicps;
			[x, hz].postln;
			{ ( * -12.dbamp
				*, doneAction:2)
			).dup }.play;
		} }.play;


i’ve already “taken a stab” at the API impliclty, by writing the code. i think it’s pretty simple and yall are seirously overhtinking it.

the state input and output is always [-10k, 10k].
the param input is [0, 10k]. (i didn’t think 100 steps was enough but i think 10000 steps is plenty and 100000000 steps is total overkill.)
if type is LOGISTIC, the output will always be positive.
for LOGISTIC and CUBIC, increasing the parameter generally increases how “random” the output seems. for HENON it’s more unpredictable, if you want to explore more unknown territory. (which some of us do.)

i really have no preference as to whether you want to split them up or have a mode switch, just trying to help by adding the update formulae.

i’m a little annoyed. like, just because you don’t quite understand this doesn’t make it useless. if you want to understand it better you could try downloading the test build or cloning the fork and playing with it for a few minutes.


Thank you so much for your code and participation, @zebra! You have explained your code and decisions quite well, and I appreciate it.

New thread subtitle? :laughing:

:arrow_down_small: I always appreciate your input, too, @cmcavoy.


Yikes, well I certainly didn’t mean to annoy you, nor was I asking to be convinced. I was acknowledging that I don’t understand the op, and don’t need to. I’m not a gate to its release. I understand how my message could be interpreted as a challenge or a demand, but I didn’t mean it that way. Certainly not trying to under value your or anyone else’s contribution, in the future if I don’t understand something I’ll just mutter to myself at my desk rather than type it out as a form of self-soothing.


I am playing with the test build nearly the whole day now and while I was a bit skeptical regarding the value ranges (still would love to have the first two algos start at 3.0) the more I explore it the more I love this. While it really needs a lot of dedication and learning there are a lot of beautiful patterns and tonal evolutions to achieve with this OP. I am really grateful that it is happening and appreciate all the work that has gone into it!

Now that I reached into modulating the algorithms with CHAOS.ALG X I tend to vote for keeping it as it is for now, exploring it further and maybe then rethinking what might be improvable.

What might be an idea for future features is starting such a thread with a comprehensible explanation what it is all about. I am very sorry that I did sound grumpy over the last days. It was out of frustration a bit. About not understanding complex explanations, feeling overlooked with my concerns and ideas and thus feeling a bit dumb for not being able to participate in something I expected to be highly interesting.


Regarding the CA algorithm: I think it is a small and two dimensional 8-bit version of the game of life thing, right? What I did not understand by now is what those 255 rules are. I still get hardly anything out of it with most of them - rule 75 is nice though and gets interesting with different starting points for CHAOS.



I have read the german wiki about it and as so often before my experience with science topics on wikipedia is that I hardly understand it if I don’t already know about it.

The mathworld link combined with the elevator pitch below got me to some better understanding though.


EDIT: Unnecessary rude sarcasm removed.


My feeling about complex math concepts is that they are easier to experience than to explain. That being said, Stephen Wolfrom’s A New Kind of Science is an extremely long-form explanation, but I have often found that when I am reaching for a Wolfram explanation, I should probably be reaching for a Rudy Rucker explanation instead.


link to wolfram mathworld above is the clearest writeup i’ve come across, basically a boiled down chapter from A New Kind of Science.

but for fun i’ll try an elevator pitch version.

as you say, this CA is a lower-dimensional version of the 2d “game of life”. normally one would say that this one is 1-d (it operates on a row of cells) down from 2d (operating on a grid of cells.)

the behavior is defined by two things:

  1. an initial state, say

and 2) an update rule. the rule says: to get the new value of a state, look at its old value and the value of its previous neighbors. so there are 8 possible configurations to look at, and we specify the desired result for each:

input:    111 110 101 100 011 010 001 000
output:    0   0   0   1   1   1   1   0

so the rule can be encoded as 8 bits in an integer. wolfram established a convention for doing this, by which the rule written above is equal to 0b00011110 = 0x1e = 30. so this is referred to in the literature as rule 30.

when we apply the rule to the initial state, and keep applying it to subsequent states, we get a sequence

1. 00100100
2. 01111110
3. 11000011
4. 01100110
5. 11011101
6. 00010001 

and so on. (assuming i didn’t mess that up.)

(by the way, in this implementation i am wrapping the edges; they could also be fixed. different behaviors; both are chaotic.)

these states likewise can be encoded as 8-bit integers. that representation is what the operator produces at its output and accepts as its input. i agree that it doesn’t make the output super intuitive; i think this structure is most useful when you can map the output bits to gates, which makes this an extremely fun sequencer.

if i have time this weekend i’ll dig up some supercollider grid apps that use these sequencers. with the grid you can interact with the rule and state in a direct, tactile way.


A dedicated Chaos module already exists in Euroland, and from what I understand it has a cult of die hard fans, incorporating several of them in their racks.
We could always take a look at how it exposes parameters and scales them that manages to gather so much interest .


but… that’s analog. it is some kind of coupled oscillator thing.

there is at least one module out there that does the stuff we’re talking about.


That’s the Lorenz Attractor.

The analog part can be somewhat imitated with slew on the TT outputs.

To clarify: I’m not suggesting a new algorithm. I’m just pointing out that the guy that made that module must have gone through a similar decision process and he found something that people liked.


this is a quibble really, and i could be wrong but am now looking at the schematic and i think it is actually an implementation of Chua’s circuit. it does have two attractors, like the lorenz system.

i appreciate the sentiment but don’t see any direct analogy for how to parameterize this system (or the lorenz system) and a recursive map. the maps are pretty easy to parameterize.

(I say “coupled osc”, you say “system of periodic differential equations”, tomato/tomatoe.)


for the record i endorse CHAOS

this is so freakin’ exciting to me, musically