Skip to content

Notes

As the instructions read I created a function that calculated for a given and in and are defined as logistic_equation in the bifurcation module. The iterative part took some to to wrap my head around how to solve this. As any developer do, I took some inspiration from stackoverflow. Reading some code where people have done similar things I finally managed to come up with a solution.

I created another another function named make_logistic_map in my bifurcation module where I specify number of points and iterations as parameters I then create two numpy arrays, one for values that linearly increase in the range [0,4] with the numbers of points which was given as a parameter. I then created the $x$ values randomly in the range [0,1], also this with the number of points that was given as an parameter. The function then iterates through the logistic equation and is returning the values and the after it has gone through the iteration.

I also created a function called plot_map that use the make_logistic_map function to create a still image. I also wanted to make a animation, which I never have done before. It was somewhat challenging to understand how the animation feature work in matplotlib. By reading lots of documentation and also, again turning my head to stackoverflow I came up with a solution that at least works. I created another function in the bifurcation module defined as animate_map that took the number of points and iterations that the animation should show. I then defined the figure without any data and styled it to my liking. Further more, I created a function called update which really is the engine here. This function creates the data for each frame in the animation. For each frame I called the make_logistic_map function to create the logistic map. Since I want to show how the map evolves for how many iterations it goes through I used the frame parameter as the iteration parameter in my make_logistic_map function creating a frame for each case in the range [0, iterations].

animate_map(points, iterations)

Parameters:

Name Type Description Default
points int

Number of points for the seed and anchor

required
iterations int

Number of times the map should be updated

required
Source code in src/course_package/bifurcation.py
def animate_map(points: int, iterations: int) -> None:
    """Animate the logistic map


    Args:
        points: Number of points for the seed and anchor
        iterations: Number of times the map should be updated
    """

    fig, ax = plt.subplots(figsize=(10, 10))
    (line,) = ax.plot([], [], ls="", marker=",", color="black", alpha=0.1)
    ax.set_xlim(-0.1, 4.1)
    ax.set_ylim(-0.05, 1.05)
    ax.set_xlabel("$r$", fontsize=15)
    ax.set_ylabel(r"$x_n$", fontsize=15)
    ax.spines[["right", "top"]].set_visible(False)

    def update(frame):
        r, x = make_logistic_map(points=points, iterations=frame)
        line.set_data(r, x)
        equation = r"$x_{n+1} = rx_{n}(1-x_{n})$, "
        counter = f"for n={frame}"
        line.set_label(equation + counter)
        ax.legend(loc="upper left", frameon=False)
        return (line,)

    ani = animation.FuncAnimation(fig, update, frames=iterations, interval=50)

logistic_equation(x, r)

Parameters:

Name Type Description Default
x ndarray

Seed for the logistic equation

required
r ndarray

Anchor for the logistic equation

required

Returns:

Type Description
ndarray

Updated seed

Source code in src/course_package/bifurcation.py
def logistic_equation(x: ndarray, r: ndarray) -> ndarray:
    """Calculates the logistic equation


    Args:
        x: Seed for the logistic equation
        r: Anchor for the logistic equation

    Returns:
        Updated seed
    """
    xn = r * x * (1 - x)
    return xn

make_logistic_map(points, iterations)

Parameters:

Name Type Description Default
points int

number of points for the seed and anchor

required
iterations int

Number of times the map should be updated

required

Returns:

Type Description
tuple

Updated values for the anchor and seed

Source code in src/course_package/bifurcation.py
def make_logistic_map(points: int, iterations: int) -> tuple:
    """Updates the map

    Args:
        points: number of points for the seed and anchor
        iterations: Number of times the map should be updated

    Returns:
        Updated values for the anchor and seed
    """
    r = np.linspace(0, 4, points)
    x = np.random.rand(points)
    for _ in range(iterations):
        x = logistic_equation(x, r)

    return r, x

plot_map(points, iterations, clib=bool)

Parameters:

Name Type Description Default
points int

Numbers of points for the seed and anchor

required
iterations int

Number of times the map should be updated

required
Source code in src/course_package/bifurcation.py
def plot_map(points: int, iterations: int, clib=bool) -> None:
    """Plotting the logistic map

    Args:
        points: Numbers of points for the seed and anchor
        iterations: Number of times the map should be updated
    """
    r, x = make_logistic_map(points=points, iterations=iterations)
    equation = r"$x_{n+1} = rx_{n}(1-x_{n})$, "
    counter = f"for n={iterations}"

    fig, ax = plt.subplots(figsize=(10, 10))
    ax.plot(r, x, ls="", marker=",", color="black", alpha=0.1, label=equation + counter)
    ax.set_xlim(-0.1, 4.1)
    ax.set_ylim(-0.05, 1.05)
    ax.set_xlabel("$r$", fontsize=15)
    ax.set_ylabel(r"$x_n$", fontsize=15)
    ax.legend(loc="upper left", frameon=False)
    ax.spines[["right", "top"]].set_visible(False)
    fig.savefig("logistic_map_plot.png", dpi=200)