Exploring Chaos Without Writing a Single Line of Code

Developed by the Institute for Future Intelligence, iFlow is a no-code programming environment that allows users to explore many different types of computational problems. This tutorial shows how it can be used by students to discover chaos without writing a single line of code.

The logistic map

Let’s start with a very simple system that exhibits chaotic behavior: the logistic map, which is defined by the following recurrence relation:

where xₙ is a number within [0, 1] that represents the ratio of an existing population to the carrying capacity of the environment in the n-th year and r is a parameter within [0, 4]. The equation considers two factors: 1) reproduction in which the population will increase at a rate proportional to the current population and 2) starvation in which the growth rate will decrease at a rate proportional to the carrying capacity minus the current population.

Use iFlow to solve the problem

To investigate this dynamic system, you can use any programming language (or even use a calculator like Mitchell Feigenbaum did a few decades ago when making his initial discovery in chaos). But iFlow provides a unique visual environment that may make your discovery of chaos more fun. The following screenshots show a visual computational solution that produces the results of xₙ when r assumes different values.

When r=1.2, x converges to one value.
When r=3.2, x converges to two values.
When r=3.5, x converges to four values.
When r=3.56, x converges to eight values.
When r=3.9, x becomes chaotic.

Who would have thought that such a simple deterministic system exhibits such a complex behavior! The discovery of chaos reminds us how unpredictable Mother Nature actually is.

If you are interested in playing with this computational experiment in iFlow, click here.

Now let’s see how you can create such a visual solution in iFlow by yourself.

Set up the recurrence relation

First, you need a block for defining the recurrence relation. Since there is only one variable x, we would normally use a Univariate Function block. But because we want to also pass the number n along with x, we need a Bundled Functions block, which is available in the Operators & Functions row of the Blocks Palette shown as below:

Once you drag and drop a Bundled Functions block onto the canvas, you can select it and then press the Enter key on your keyboard to open a dialog window for typing the expressions:

In this case, we can just type n and r*x*(1-x) in the Expressions area. Note that you must surround each expression with double quotes, separate the expressions by a comma, and enclose them in a pair of square brackets, as suggested in the window (this is just a convention from JavaScript to tell iFlow that you are inputting an array of expressions). Once you press the OK button, a Bundled Functions block will have an output port corresponding to each specified expression.

In a recurrence relation, we need to reuse n and x outside the bundled functions block. So these two variables must be declared as global. Instead of defining them as individual global variables, we will use a global object block to group them together. The global object block can be found in the Data Structures row of the Blocks Palette:

Once you drag and drop a global object block onto the canvas, you can select it and then press Enter to open a dialog window for setting the variables:

You need to type in the Keys field the names of the variables. Then you must surround them with double quotes, separate them by a comma, and enclose them in a pair of square brackets. You can set the initial values for these variables.

We also need to define r as a global variable. This time we can use a global variable block, which is also available in the Data Structures row:

Once you drag and drop a global variable block onto the canvas, you can select it and press Enter to invoke a dialog window for setting the variable:

Set up the graphs

The nice thing about using an object of two variables is that you can then connect it to a Space2D graph for plotting. The Space2D graph takes an input of an object with two variables and use them as (x, y) coordinates for a scatter plot. It can be found in the Inputs & Outputs row of the Blocks Palette:

Once you drag and drop a Space2D block onto the canvas, you can select it and press Enter to open a dialog window for customizing it:

It is important that you select the Input Type to be “Point” because you are accepting a point object, not two separate variables (“Dual”). There are a lot of other properties that you can set for this graph, such as color, width, and style for lines or color, size, and style for symbols.

To show how many values x actually converges to in the logistic map, it is also help to use a histogram to make that clear. You can set up a histogram in a similar way. It only needs the input from x (n is not needed).

Set up the worker

Having a recurrence relation defined in a function block and the graphs as displays does not produce any data. We need to introduce a worker to do the job of recurrence. Technically, a worker starts a computational process, which in this case is to evaluate the recurrence expression repeatedly. The worker block can be found in the Tools row of the Blocks Palette:

Once you drag and drop a worker block onto the canvas, you can select it and press Enter to open a dialog window for setting it up:

This window allows you to choose the output type. In this case, we just use the default, which is Natural Number. We can set the interval at which the worker will execute and the Repeat Times (how many steps it will run). A worker will also need a toggle switch to turn it on and off, as you can see from this example. We will omit the steps for adding a toggle switch block as they are pretty straightforward.

Set up the controllers

We now need a slider for changing r and a button for resetting the computation back to the initial condition. The slider block can be found in the Inputs & Outputs row of the Blocks Palette:

Once you drag and drop a slider block onto the canvas, you can select it and press Enter to invoke a dialog window for setting it up:

The reset button is a special case. It can be done through the action block, which can be found in the Tools row of the Blocks Palette:

Once you drag and drop an action block onto the canvas, you can select it and press Enter to open a dialog window that shows the available actions:

The default action is Reset.

Connect the blocks

We have added all the blocks needed to conduct this computational experiment. Now we just need to put them together using some computational logic, shown as follows:

The natural number output from the worker block is connected to the input port of the bundled functions block to update n and evaluate the r*x*(1-x) expression at the frequency and times specified by the worker. The output ports A and B of the bundled functions block are connected to the input ports of the global object block x(n) to set the values of n and x. The output port of the global object block x(n) is connected to the input port of the Space2D block so that the result can be shown in a scatter plot. The output port B of the bundled functions block is separately connected to the input port of the histogram block so that the result can be aggregated in a histogram. The slider block is linked to the global variable block to change the parameter r, which is critical to the onset of chaos.

Once the user turns on the Run switch, this iFlow diagram will produce an animation of the computational process and display the results in the graphs as we show above. The user can reset the diagram, change the parameter r, and then run the process again.

In this visual programming paradigm, users not only create a program to do some computation, but they also build a graphical user interface for interacting with the computational process more easily.

Computational Scientist, Physicist, & Inventor at the Institute for Future Intelligence https://intofuture.org