I don’t get it either - what is .R, what does 275 do, what 2.75 an what are the slashes for? Also does “next value” mean you basically define a more or less random sequence in the I script and then go through it with CHAOS without being able to alter any parameters. Like creating a still of the fancy diagram above at p=2.75?

I have never looked into its details, but Gendy seems to be a popular source of uncertainty in music. I think it was originally imagined as an audio source, but was later adopted for control purposes. Here is a cpp source. Also CSound files. A major problem will be deciding which parameters to expose.

2 Likes

ye olde cubic map is a nice simple recursive chaotic oscillator
x = a(x^3) + (1-a)*x

initial state should be in (-1, 1)

it has the cool property that x oscillate between positive and negative. so if you do interpolation by cosine segment it’s a sine oscillator, &c.

with a<3.2 or so it’s period=2, with amplitude kind of dependent on a. orbits tend to get longer and denser approaching a=4, whereupon it blows up.

Henon map is a fun 2-state recursive function that comes from celestial mechanics.

x(n+2) = 1 - a * x(n+1)^2 + b * x(n)

with a in, like, [1-2], b in, say, [0-1].

[edited for clarity]

this is denser and “crunchier” than cubic, and it’s fun to have different outputs for the different states.

lorenz attractor is another popular one but its a bit heavier to compute. (example omitted)

you can do a lot of fun things with coupled nonlinear force terms. here’s an oscillator based on th fermi-pasta-ulam-tsingou model. basically its a bunch of masses connected by springs, where the force term for the spring has a cubic term. you get differenet cool enharmonics by changing the “pickup position.” have found it very nice for LFO bank as well as audio rate.

[https://github.com/catfact/audio-externals/tree/master/fpu]

  1. i’ve seen a version of the logistic map with two variables, referred to as ‘twisted logistic’… will update here if i can dig up the details. it’s very musical.

  2. 1-d, binary cellular are always fun and very simple to implement. with continuous states you get what i’ve seen referred to as cellular dynamata… which can really model a large range of dynamical systems… and there’s a deep rabbit hole.


i gotta point out that gendy is stochastic. whole other can of worms. it is an implementation of the stochastic sieves xenakis used to produce waveforms for Metastasis (1955.) my opinion is that complex applications of random variables (gendy, markov chains) fall kinda outside the scope of a single TT operator. but it’s just an opinion.

if you do want to include a toolkit of basic non-uniform random distributions as operators, some of the usual suspects would be:

  • PINK (1/f) - best done by a “pinking filter” or something like Voss algorithm (which is basically sum of multirate uniform noise sources - see http://stenzel.waldorfmusic.de/post/pink/ for an efficient modern implementation)
  • BELL/GAUSS/NORMAL - a bell curve distribution, average of many uniform samples
  • BROWN - 1/f^2 , limit of random walk

these all require a uniform random variable as a starting point.


oh, BTW: can be hard to make even simple recursive functions behave properly with fixed-point arithmetic; rounding errors make it too noisy. i’d just use soft floats on AVR32 and eat the cycles. you probably realize this already.


and PS: in looking up the FPUT on wikipedia, i am over the moon to see that there has been some direction in officially crediting the person who actually programmed this important model, which was possibly the defining experiment in computational physics and one of the progenitive experiments for “chaos theory.”

mary tsingou was a woman of greek ancestry working at Los Alamos in 1955. it’s shameful that her name has been omitted from this groundbreaking work for half a century.

13 Likes

Interesting read! I’ll think about that one.

R is the parameter to the hypothetical CHAOS operator. Slashes are just a comment describing what 275 meant.

Your summary is accurate. :+1:

Cellular Automata might be worthy of an entire operator, but I could just as easily fold it into the chaotic generator. :+1:

1 Like

I am still trying to figure this out and am looking at this now:

Am I right that CHAOS would most of the time give exactly one or two values, then suddenly a lot of random values depending on what was put in the I script? So that the above example with 275 would just always output about 65?

If so I would include the parameter (here: 275) into the actual operator instead of having CHAOS.R 275 executed once in the I script.

Probably I still don’t get it but I hardly see any use of it like that while CV 1 CHAOS.R X with X dynamically varying between 0 and 400 might be interesting as it will happen nothing or something drastic in a way that is more unpredictable the higher X is. It also should be scaled to meaningful range then.

This is brain busting…

:nerd_face::boom:

EDIT: Starting from 0 also does not make sense, does it?

1 Like

Your understanding is correct.

At high levels of R, the sequence produced by repeated calls to CHAOS will be chaotic. At low levels of R, the sequence is not chaotic.

Isn’t the sequence at low levels of R not even a sequence?

[0, 0, 0, 0, 0, 0, 0, 0]

Is a sequence of zeroes.

…sounds interesting.

:man_teacher:

Yeah. Definitely lots of potential.
:slight_smile:

3 Likes

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

matlab
% 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);
  end
  for n = 1:Nplot-1
    x(n+1) = r*x(n)^3 + (1 - r)*x(n); 
  end 
  plot(r*ones(Nplot,1), x, '.', 'markersize', 1, 'Color', [0, 0, 0]); 
  hold on; 
end 
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.

</pedantry>

10 Likes

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:

https://github.com/burnsauce/teletype/tree/chaos

Syntax:

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 https://github.com/burnsauce/teletype.git
git fetch --all
git checkout chaos
cd teletype/simulator
make

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

4 Likes

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.