I want to generate Chen's hyperchaotic sequence. Formulas are given as:Chen's hyperchaotic sequence equations

Code I have written is attached.

import math

a = 36
b = 3
c = 28
d = 16
k = 0.2


def chen(x0, y0, z0, q0):
    xdot = a * (y0 - x0)
    ydot = (-x0 * z0) + (d * x0) + (c * y0) - q0
    zdot = (x0 * y0) - (b * z0)
    qdot = x0 + k
    return xdot, ydot, zdot, qdot


def chaotic_seq(x0, y0, z0, q0, length):

    for i in range(length):
        xdot, ydot, zdot, qdot = chen(x0, y0, z0, q0)
        if math.isnan(xdot) or math.isnan(ydot) or math.isnan(zdot) or math.isnan(qdot):
            print(i)

        x0 = xdot
        y0 = ydot
        z0 = zdot
        q0 = qdot


if __name__ == '__main__':
    x0 = 0.3
    y0 = -0.4
    z0 = 1.2
    q0 = 1
    length = 2048
    chaotic_seq(x0=x0, y0=y0, z0=z0, q0=q0, length=length)

Problem I am facing is, after 'i=11' all the values (xdot, ydot, zdot, qdot) are NaN.

2

There are 2 best solutions below

1
On

Your code comes quite far from achieving what you wish: you're going to have to solve that differential equation at some point, which you aren't doing anywhere in the above sample. This explains why your values quickly diverge to infinity, then start becoming NaNs.

Using scipy to solve the differential equation we get the code below, which gives seemingly satisfactory results:

from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

a = 36
b = 3
c = 12
d = 7
k = 0.2

def chen(_, y):
    x0, y0, z0, q0 = y
    xdot = a * (y0 - x0)
    ydot = (-x0 * z0) + (d * x0) + (c * y0) - q0
    zdot = (x0 * y0) - (b * z0)
    qdot = x0 + k
    return xdot, ydot, zdot, qdot


def chaotic_seq(x0, y0, z0, q0, length):
    return solve_ivp(chen, [0, length], [x0, y0, z0, q0])

x0 = 0.3
y0 = -0.4
z0 = 1.2
q0 = 1
length = 50
sol = chaotic_seq(x0=x0, y0=y0, z0=z0, q0=q0, length=length).y
# plot x,y
plt.plot(sol[0], sol[1])
1
On

I think you have a couple problems.

One is that your functions quickly seem to run into overflow errors with the Python float, which returns nan values, so you'll need a data type that supports higher precision values than what the default float that the Python built-in data type provides. So you might look at using the numpy library's float128 data type (shown below) — or investigate using the decimal module (not shown).

Secondly, the dot notation represents the rate of change in the input variables. For example, xdot is shorthand notation for the differential expression dx/dt.

You can add a time increment variable (e.g., t) which changes the values of x0, y0, z0, and q0 in small increments, which simulates their respective differentials.

Here's a modified version of your script that runs for 2048 iterations:

#!/usr/bin/env python

import sys
import numpy as np

a = np.float128(36)
b = np.float128(3)
c = np.float128(28)
d = np.float128(16)
k = np.float128(0.2)
t = np.float128(0.001)

def chen(x0, y0, z0, q0):
    xdot = a * (y0 - x0)
    ydot = (-x0 * z0) + (d * x0) + (c * y0) - q0
    zdot = (x0 * y0) - (b * z0)
    qdot = q0 + k    
    return xdot, ydot, zdot, qdot

def chaotic_seq(x0, y0, z0, q0, length):
    for i in range(length):
        xdot, ydot, zdot, qdot = chen(x0, y0, z0, q0)
        if np.isnan(xdot) or np.isnan(ydot) or np.isnan(zdot) or np.isnan(qdot):
            raise OverflowError("Overflow in dot variable calculation")
        x0 += t * xdot
        y0 += t * ydot
        z0 += t * zdot
        q0 += t * qdot
        sys.stdout.write('after: [{}] {}\t{}\t{}\t{}\n'.format(i, x0, y0, z0, q0))

if __name__ == '__main__':
    x0 = np.float128(0.3)
    y0 = np.float128(-0.4)
    z0 = np.float128(1.2)
    q0 = np.float128(1)
    length = 2048
    chaotic_seq(x0=x0, y0=y0, z0=z0, q0=q0, length=length)