# CHAOS Operators

Is there a compelling reason why there is just one `CHAOS` OP with different algorithms instead of 4 different OPs that can be used simultaneously?

• `LOGSTC`
• `CUBIC`
• `HENON`
• `CELATM`

(or some other batch of names)

Do you know what a chaotic function is? I’m not talking about this `CHAOS` OP, but the mathematical definition of a chaotic function. Would you like me to have a go at explaining it?

(sorry to impose) i think the only real reason is happenstance; there was a CHAOS that did the logistic map and then i added the others.

LOGISTIC and CUBIC are closely related though. they take the same range of parameters and only really differ in that the first is unipolar and the second is bipolar. so i can imagine them as one thing with a polarity switch.

(that said, i somehow did not realize before doing this that teletype operators appear to be static objects - yeah? you can only have one of each? interesting.)

and i absolutely never turn down an offer to explain chaos theory.

3 Likes

Hm, both I think - my understanding of those functions is that they output somehow random values depending on their current state and then at some point might lock into a quasi stable state and output a repeating pattern.

More comprehensive explanations would be highly appreciated though. Reading through pages of mathematical formulas on the internet does not really help me. I think I have to be able to develop a somehow haptical or visual imagination connected to the diagrams to fully grasp it.

in the beginning I did not really understand what the actual operators do before being able to play with them now. I thought there would be just a set of values defined by the r parameter which then is randomly given out. But it seems that there also is an order specific and random at the same time.

After some experiments and with a slightly better practical understanding I would follow @wolfgangschaltung in that it is a little cumbersome to map the values to a useful range and try things out with different algorithms as also the useful range is a bit different on all of them. So I could think of individual OPs too - also seeing that this might limit the number of variations in the end. With a bit of practice the inclusive solution might work too - it’s just a feature/OP that is a bit harder to understand and has an unusual structure for tt code.

But maybe the only problem is that I still do not understand what is going on there?

What actually would be great would some practical advise for the cellular automate. I played with it and tried different parameter/value combinations but hardly get anything out of it in the sense of more than one ore two different values.

I m not sure how to understand this line. I thought we were discussing the implementation of CHAOS and what might be useful from a (in my case: quite simple) user perspective. I do not see any chance that I could change anything in the actual code and have no idea how this github thing works.

I like how the two alternating values develop with the lower parameter values increasing and would love to start from the common value at roughly 3.0 as a kind of a fix point.

ok, no problem. i am not requesting that you make any changes yourself. but in this thread we are discussing both the user and development perspectives. so i show where to make the requested change, for whoever makes it. (because despite appearances, i will not actually watch this thread forever and can’t commit to maintaining code that i won’t use.)

5 Likes

Path of least resistance plus the structure of @zebra’s code got me to the solution you see.

if there’s call for it, they can be separated. CA probably should be.

I think there’s two problems we need to solve,

Problem: CHAOS algorithms are hard to understand
The only recent example I can find of a new tool that wasn’t immediately understandable by most of the community is Euclidean Rhythms `ER`. In the documentation, there’s a link to information on them conceptually. I think `CHAOS` algorithms need some documentation pointers to help people understand them enough to use them musically. In the (something) of Teletype thread, there’s a strong belief that operators in TT should be emphasize use in music.

Proposed solution - documentation. If anyone is interested in working on this, it would make sense to start a new thread to discuss it.

Problem: Useful ranges for parameters and return values aren’t uniform for each algorithm
The current implementation allows for programatic choice of algorithm, so `CHAOS.ALG RRAND 1 4` is possible, which strikes me as being cool and useful. However, unless you then check the algorithm chosen, you can’t easily pass it appropriate parameters or predict how to use the returned values.

Proposed solution - There’s two possible approaches -

1. Rename the algorithms explicitely (@sam suggested this above, I did a while back as well.) so that it’s always clear what the ranges because you’re only able to call the algorithm explicitly. It also allows the use of multiple algorithms at the same time, which the current implementation doesn’t (there’s one `CHAOS` only).
2. Provide upper bound and lower bound getters on `CHAOS` once you’ve chosen the algorithm. @zebra points out that these bounds aren’t always obvious and can change, so any bounds we choose would be suggestions, not necessarily hard bounds. I suggested `CHAOS.RC // range ceiling` above but I think `CHAOS.UB` AND `CHAOS.LB` make more sense after sleeping on it.

Of the above two, my preference is the second - keep the current algorithm choice option but provide helpful bounds getters so that it’s easy to use `CHAOS` inside of TT.

Clearly the above is my interpretation of the conversation. I don’t have any special role in the discussion, and don’t meant to imply I do. Just wanted to try to clarify the problems we’ve identified and the solutions that have been proposed to make the discussion easier to resolve. If I missed something, or am totally wrong - please correct me.

As noted above, the only outlier for the value is 10000 = 1.0 is CA when you consider that 15000 fits in a 16-bit integer.

I still think that the best compromise for the `R` parameter is:

``````CHAOS.R 3750 1234     | 3.7501234
``````

One scale, easy to understand.

edit: although it means that the getter for `R` will need to be split into an upper and lower section, or eliminated entirely.

So really, there’s option 3:

1. Values at fixed scale 10000 = 1.0, 2-parameter R, CA spun off to different operator.

Yes, agreed - this is a good fix. I missed it when you suggested it. Unless anyone objects, I’d suggest making this the solution and update the top post in this thread to reflect the revised API and parameter values.

Does this mean the return values will also be scaled to a range?

How is the getter for R used? I know we allow getters on values as a standard rule, but - how would it be used in this case? If we can’t find a reasonable use for it, I’d suggest leaving it as is and allow the range of the getter to be dependent on the algorithm.

Yes. 1.0 => 10000, 10000 => 1.0 (equal bidirectional)

I personally don’t see the need for a getter, to be honest, but general purpose variables are scarce, so somebody may want to increment it without using one of them up to keep track.

I think that it’s not very intuitive to ask users to work with different scales on 16-bit signed integers. A 2-parameter `R` is easy to read and understand, IMO.

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?

1 Like

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?

1 Like

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.

2 Likes

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.

2 Likes

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! )

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

#### Notes

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

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?

1 Like

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.

1 Like

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);
x
};

~rnorm = 0.0;
~rnorm_inc = 0.01;
~rout = Routine {
var hz;
inf.do {
~iter.value;
~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; });
~set_r_norm.value(~rnorm);
r.postln;
hz = x.linlin(0, 1.0, 48, 72).round.midicps;
[x, hz].postln;

{ (SinOsc.ar(hz) * -12.dbamp
* EnvGen.ar(Env.perc(0.125), doneAction:2)
).dup }.play;
0.125.wait;

} }.play;

};

/*
s.prepareForRecord;
s.record;
~rout.stop;
s.stopRecording;
*/
``````

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.

8 Likes

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

I always appreciate your input, too, @cmcavoy.

4 Likes

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.

2 Likes

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.

2 Likes