ci: add linter to GitHub Workflows #1
Annotations
16 errors and 1 warning
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/bifurcations.py#L7
import sys
from lelib import Bifurcation, Map
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot the Bifurcation Diagram of Logistic, Cubic, and Sine Maps'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot the Bifurcation Diagram of Logistic, Cubic, and Sine Maps"
+ examples = """
%(prog)s -r 1:4
%(prog)s -r 4:6.5 --map=cubic
%(prog)s --map=sine -s 200 -n 200
%(prog)s -r 3.:4. -s 500 -n 600
- %(prog)s -r 3.5:3.6 -y .3:.6 -s 800 -n 1000'''
+ %(prog)s -r 3.5:3.6 -y .3:.6 -s 800 -n 1000"""
parser = argparser(descr, examples)
# By default, make 300 iterations (n) and do no plot the first 200 ones (s)
# By default select the Logistic Equation
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r",
- help="range of the growth rate parameter (default: the entire range)")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ help="range of the growth rate parameter (default: the entire range)",
+ )
parser.add_argument(
- "-y", "--people",
- action="store", dest="y",
- help="normalized range of the population (default: the entire range)")
+ "-y",
+ "--people",
+ action="store",
+ dest="y",
+ help="normalized range of the population (default: the entire range)",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=200,
- help="skip plotting the first 's' iterations (default: %(default)s)")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=200,
+ help="skip plotting the first 's' iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-n", "--steps",
- action="store", dest="n", type=int, default=100,
- help="number of iterations (default: %(default)s)")
+ "-n",
+ "--steps",
+ action="store",
+ dest="n",
+ type=int,
+ default=100,
+ help="number of iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default="logistic",
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
choices=["logistic", "cubic", "sine"],
- help="select the desired map (logistic, cubic, or sine)")
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
def main():
args = parse_args()
mapobj = Map(args.map_name)
# range to vector: "1:4" --> [1., 4.]
- r2v = (lambda a, minval, maxval :
- [float(i) for i in a.split(':')] if a else
- [minval, maxval])
+ r2v = (
+ lambda a, minval, maxval: [float(i) for i in a.split(":")]
+ if a
+ else [minval, maxval]
+ )
# Plot the entire diagram by default
Bifurcation(
r2v(args.r, mapobj.map_rmin, mapobj.map_rmax),
r2v(args.y, mapobj.map_ymin, mapobj.map_ymax),
args.n,
args.s,
- args.map_name
+ args.map_name,
).plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/finalstate.py#L7
import sys
from lelib import FinalState
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot of the Final State Diagram'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot of the Final State Diagram"
+ examples = """
%(prog)s -r 3.492
%(prog)s -r 3.614 -s 200 -n 300
%(prog)s -0 0.4 -r 3.2 -s 10 -n 50
- %(prog)s -0 0.8 -r 6.2 -n 20 --map=cubic'''
+ %(prog)s -0 0.8 -r 6.2 -n 20 --map=cubic"""
parser = argparser(descr, examples)
# By default, make 3000 iterations (n) and
# do no plot the first 2000 ones (s)
# By default select the Logistic Equation
parser.add_argument(
- "-0", "--x0",
- action="store", dest="x0", type=float, default=.5,
- help="initial condition (default: %(default)s)")
+ "-0",
+ "--x0",
+ action="store",
+ dest="x0",
+ type=float,
+ default=0.5,
+ help="initial condition (default: %(default)s)",
+ )
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r", type=float, required=True,
- help="growth rate parameter")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ type=float,
+ required=True,
+ help="growth rate parameter",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=2000,
- help="skip plotting the first 's' iterations (default: %(default)s)")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=2000,
+ help="skip plotting the first 's' iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-n", "--steps", dest="n", type=int, default=1000, action="store",
- help="number of iterations (default: %(default)s)")
+ "-n",
+ "--steps",
+ dest="n",
+ type=int,
+ default=1000,
+ action="store",
+ help="number of iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default = "logistic",
- choices = ["logistic", "cubic", "sine"],
- help = "select the desired map (logistic, cubic, or sine)")
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
+ choices=["logistic", "cubic", "sine"],
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
def main():
args = parse_args()
- FinalState(
- args.r,
- args.n,
- args.x0,
- args.s,
- args.map_name
- ).plot()
+ FinalState(args.r, args.n, args.x0, args.s, args.map_name).plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/legraph.py#L7
import sys
from lelib import Logistic, LogisticDiff
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot of Logistic Equation Time Series'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot of Logistic Equation Time Series"
+ examples = """
# time series with a stable fixed point
%(prog)s -0 0.4 -r 3.2 -n 50
%(prog)s -0 0.4 -1 0.45 -r 3.2 -n 50
# chaotic results (randon output)
%(prog)s --x0 0.2 --x1 0.2000001 -r 4.0 -n 50
%(prog)s -0 0.2 -r 3.6 -n 5000 --dots-only
%(prog)s -0 0.9 -r 4.5 -n 50 --map=cubic
- %(prog)s -0 0.4 -r 0.8 -n 50 --map=sine'''
+ %(prog)s -0 0.4 -r 0.8 -n 50 --map=sine"""
parser = argparser(descr, examples)
# By default select the Logistic Equation
parser.add_argument(
- "-0", "--x0",
- action="store", dest="x0", type=float, required=True,
- help="1st initial condition")
+ "-0",
+ "--x0",
+ action="store",
+ dest="x0",
+ type=float,
+ required=True,
+ help="1st initial condition",
+ )
parser.add_argument(
- "-1", "--x1",
- action="store", dest="x1", type=float,
- help="2nd initial condition (optional)")
+ "-1",
+ "--x1",
+ action="store",
+ dest="x1",
+ type=float,
+ help="2nd initial condition (optional)",
+ )
parser.add_argument(
- "-d", "--dots-only",
- action="store_true", dest="dotsonly",
- help="do not connect the dots with lines (default: %(default)s)")
+ "-d",
+ "--dots-only",
+ action="store_true",
+ dest="dotsonly",
+ help="do not connect the dots with lines (default: %(default)s)",
+ )
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r", type=float, required=True,
- help="growth rate parameter")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ type=float,
+ required=True,
+ help="growth rate parameter",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=0,
- help="skip plotting the first 's' iterations")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=0,
+ help="skip plotting the first 's' iterations",
+ )
parser.add_argument(
- "-n", "--steps",
- action="store", dest="n", type=int, required=True,
- help="number of iterations")
+ "-n",
+ "--steps",
+ action="store",
+ dest="n",
+ type=int,
+ required=True,
+ help="number of iterations",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default="logistic",
- choices = ["logistic", "cubic", "sine"],
- help = "select the desired map (logistic, cubic, or sine)")
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
+ choices=["logistic", "cubic", "sine"],
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
+
def main():
args = parse_args()
lemap = (
- LogisticDiff(
- args.r, args.n, args.x0, args.x1, args.s, args.map_name)
- if args.x1 else Logistic(
- args.r, args.n, args.x0, args.s, args.map_name))
+ LogisticDiff(args.r, args.n, args.x0, args.x1, args.s, args.map_name)
+ if args.x1
+ else Logistic(args.r, args.n, args.x0, args.s, args.map_name)
+ )
lemap.plotdots = not args.dotsonly
lemap.plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/lelib_test.py#L7
from __future__ import print_function
import numpy as np
from lelib import Map, Logistic, LogisticDiff
+
def test_class_map():
- """Test the class 'Map' """
+ """Test the class 'Map'"""
print("Running the tests for the class 'Map'...")
m = Map()
- m.ensure(m.map_name == 'logistic', "The default map should be 'logistic'")
- m.ensure(m.map_longname == 'Logistic Equation',
- "Logistic Map: bad long name")
- m.ensure(m.map_rmin == 0 and m.map_rmax == 4,
- "Logistic Map: bad range for r")
- m.ensure(m.map_ymin == 0 and m.map_ymax == 1,
- "Logistic Map: bad range for y")
- i = m.map(4,.25)
- m.ensure(i == .75,
- "Logistic Map: bad value for r=4 and x=.25: should be %f" % i)
+ m.ensure(m.map_name == "logistic", "The default map should be 'logistic'")
+ m.ensure(m.map_longname == "Logistic Equation", "Logistic Map: bad long name")
+ m.ensure(m.map_rmin == 0 and m.map_rmax == 4, "Logistic Map: bad range for r")
+ m.ensure(m.map_ymin == 0 and m.map_ymax == 1, "Logistic Map: bad range for y")
+ i = m.map(4, 0.25)
+ m.ensure(i == 0.75, "Logistic Map: bad value for r=4 and x=.25: should be %f" % i)
- m = Map('cubic')
- m.ensure(m.map_name == 'cubic', "Cubic Map: bad map selection")
- m.ensure(m.map_longname == 'Cubic Equation', "Cubic Map: bad long name")
- m.ensure(m.map_rmin == 0 and m.map_rmax == 6.5,
- "Cubic Map: bad range for r")
- m.ensure(m.map_ymin == 0 and m.map_ymax == 1,
- "Cubic Map: bad range for y")
- i = m.map(2,.5)
- m.ensure(i == .25,
- "Cubic Map: bad value for r=2 and x=.5, should be %f" % i)
+ m = Map("cubic")
+ m.ensure(m.map_name == "cubic", "Cubic Map: bad map selection")
+ m.ensure(m.map_longname == "Cubic Equation", "Cubic Map: bad long name")
+ m.ensure(m.map_rmin == 0 and m.map_rmax == 6.5, "Cubic Map: bad range for r")
+ m.ensure(m.map_ymin == 0 and m.map_ymax == 1, "Cubic Map: bad range for y")
+ i = m.map(2, 0.5)
+ m.ensure(i == 0.25, "Cubic Map: bad value for r=2 and x=.5, should be %f" % i)
- m = Map('sine')
- m.ensure(m.map_name == 'sine', "Sine Map: bad map selection")
- m.ensure(m.map_longname == 'Sine Equation', "Sine Map: bad long name")
+ m = Map("sine")
+ m.ensure(m.map_name == "sine", "Sine Map: bad map selection")
+ m.ensure(m.map_longname == "Sine Equation", "Sine Map: bad long name")
m.ensure(m.map_rmin == 0 and m.map_rmax == 2, "Sine Map: bad range for r")
m.ensure(m.map_ymin == 0 and m.map_ymax == 2, "Sine Map: bad range for y")
- i = m.map(0.5,1)
- m.ensure(i == .5,
- "Sine Map: bad value for r=0.5 and x=1: should be %f" % i)
+ i = m.map(0.5, 1)
+ m.ensure(i == 0.5, "Sine Map: bad value for r=0.5 and x=1: should be %f" % i)
+
def test_class_logistic():
- """Test the class 'Logistic' """
+ """Test the class 'Logistic'"""
print("Running the tests for the class 'Logistic'...")
r, n, x0 = 3.2, 100, 0.4
- le1 = Logistic(r, n, x0, False, 'logistic')
+ le1 = Logistic(r, n, x0, False, "logistic")
x, y1 = le1.getxy()
m = Map()
- m.ensure(len(x) == n+1, "x should be a vector of size %d" % (n+1))
+ m.ensure(len(x) == n + 1, "x should be a vector of size %d" % (n + 1))
m.ensure(x[0] == 0, "x[0] should be 0")
m.ensure(x[n] == n, "the last element of x should be equal to %d" % n)
- m.ensure(x.sum() == n*(n+1)/2,
- "the sum of the elements of x is not correct")
+ m.ensure(x.sum() == n * (n + 1) / 2, "the sum of the elements of x is not correct")
- m.ensure(len(y1) == n+1, "y1 should be a vector of size %d" % (n+1))
+ m.ensure(len(y1) == n + 1, "y1 should be a vector of size %d" % (n + 1))
m.ensure(y1[0] == x0, "the first element of y1 should be equal to x0")
- m.ensure(y1[n] == y1[n-2], "y1 is expected to be periodic with period 2")
- m.ensure(y1[n-1] == y1[n-3], "y1 is expected to be periodic with period 2")
+ m.ensure(y1[n] == y1[n - 2], "y1 is expected to be periodic with period 2")
+ m.ensure(y1[n - 1] == y1[n - 3], "y1 is expected to be periodic with period 2")
+
def test_class_logisticdiff():
- """Test the class 'LogisticDiff' """
+ """Test the class 'LogisticDiff'"""
print("Running the tests for the class 'LogisticDiff'...")
r, n, x0, x1 = 4.0, 50, 0.2, 0.2000001
- le2 = LogisticDiff(r, n, x0, x1, False, 'logistic')
+ le2 = LogisticDiff(r, n, x0, x1, False, "logistic")
x, y1, _ = le2.getxy()
m = Map()
- m.ensure(len(x) == n+1, "x should be a vector of size %d" % (n+1))
+ m.ensure(len(x) == n + 1, "x should be a vector of size %d" % (n + 1))
m.ensure(x[0] == 0, "x[0] should be 0")
m.ensure(x[n] == n, "the last element of x should be equal to %d" % n)
- m.ensure(x.sum() == n*(n+1)/2,
- "the sum of the elements of x is not correct")
+ m.ensure(x.sum() == n * (n + 1) / 2, "the sum of the elements of x is not correct")
- m.ensure(len(y1) == n+1, "y1 should be a vector of size %d" % (n+1))
+ m.ensure(len(y1) == n + 1, "y1 should be a vector of size %d" % (n + 1))
m.ensure(y1[0] == x0, "the first element of y1 should be equal to x0")
ydiff = le2.getdiffy()
- m.ensure(len(ydiff) == n+1,
- "the vector y2-y1 should have a size equal to %d" % (n+1))
- m.ensure(np.all(ydiff < 1e3) and np.all(ydiff > -1e3),
- "the diff vector should show the Butterfly Effect")
+ m.ensure(
+ len(ydiff) == n + 1, "the vector y2-y1 should have a size equal to %d" % (n + 1)
+ )
+ m.ensure(
+ np.all(ydiff < 1e3) and np.all(ydiff > -1e3),
+ "the diff vector should show the Butterfly Effect",
+ )
+
def tests():
test_class_map()
test_class_logistic()
test_class_logisticdiff()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/utils.py#L12
__status__ = "stable"
import argparse
import textwrap
+
def argparser(descr, examples):
- """Return a new ArgumentParser object """
+ """Return a new ArgumentParser object"""
return argparse.ArgumentParser(
- formatter_class = argparse.RawDescriptionHelpFormatter,
- description = copyleft(descr),
- epilog = "Examples:\n" + textwrap.dedent(examples))
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=copyleft(descr),
+ epilog="Examples:\n" + textwrap.dedent(examples),
+ )
+
def copyleft(descr):
- """Print the Copyright message and License """
+ """Print the Copyright message and License"""
- return ("{0} v.{1} ({2})\n{3} <{4}>\nLicense: {5}"
- .format(
- descr, __version__, __status__,
- __copyright__, __email__,
- __license__))
+ return "{0} v.{1} ({2})\n{3} <{4}>\nLicense: {5}".format(
+ descr, __version__, __status__, __copyright__, __email__, __license__
+ )
+
def die(exitcode, message):
- """Print and error message and exit with 'exitcode' """
+ """Print and error message and exit with 'exitcode'"""
progname = sys.argv[0]
- sys.stderr.write('%s: error: %s\n' % (progname, message))
+ sys.stderr.write("%s: error: %s\n" % (progname, message))
sys.exit(exitcode)
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/setup.py#L12
Logistic, Cubic, or Sine Map with two different starting points (along with the
plot of the differences between the two maps), and the Final State and
Bifurcation Diagrams.
"""
-DOCLINES = DESCRIPTION.split('\n')
+DOCLINES = DESCRIPTION.split("\n")
CLASSIFIERS = """\
Development Status :: 5 - Production/Stable
Intended Audience :: Education
Intended Audience :: Science/Research
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/setup.py#L29
Operating System :: POSIX
Operating System :: Unix
Operating System :: MacOS
"""
-VERSION = '2'
+VERSION = "2"
setup(
- name = 'dynamic-systems-and-chaos',
- description = DOCLINES[0],
- long_description = DESCRIPTION,
- version = VERSION,
- url = 'https://github.com/madrisan/dynamic-systems-and-chaos/',
-
- author = 'Davide Madrisan',
- author_email = 'davide.madrisan@gmail.com',
-
- license = 'Apache License 2.0',
- packages = ['dynamic-systems-and-chaos'],
-
- scripts = [
- 'dynamic-systems-and-chaos/bifurcations.py',
- 'dynamic-systems-and-chaos/finalstate.py',
- 'dynamic-systems-and-chaos/legraph.py',
+ name="dynamic-systems-and-chaos",
+ description=DOCLINES[0],
+ long_description=DESCRIPTION,
+ version=VERSION,
+ url="https://github.com/madrisan/dynamic-systems-and-chaos/",
+ author="Davide Madrisan",
+ author_email="davide.madrisan@gmail.com",
+ license="Apache License 2.0",
+ packages=["dynamic-systems-and-chaos"],
+ scripts=[
+ "dynamic-systems-and-chaos/bifurcations.py",
+ "dynamic-systems-and-chaos/finalstate.py",
+ "dynamic-systems-and-chaos/legraph.py",
],
-
- classifiers = [ _f for _f in CLASSIFIERS.split('\n') if _f ],
-
- install_requires = [
- 'numpy',
- 'matplotlib',
+ classifiers=[_f for _f in CLASSIFIERS.split("\n") if _f],
+ install_requires=[
+ "numpy",
+ "matplotlib",
],
-
- platforms = ["Linux", "Mac OS-X", "Windows"],
+ platforms=["Linux", "Mac OS-X", "Windows"],
)
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/lelib.py#L15
import numpy as np
import matplotlib.pyplot as plt
from math import pi, sin
+
class Map(object):
- """Class that provides the map functions along with r and y ranges """
-
- def __init__(self, mapname='logistic'):
+ """Class that provides the map functions along with r and y ranges"""
+
+ def __init__(self, mapname="logistic"):
params = {
- # rmin rmax ymin ymax function
- 'cubic' : [ 0, 6.5, 0, 1, lambda r, x: r * x**2 * (1.0 - x) ],
- 'logistic': [ 0, 4.0, 0, 1, lambda r, x: r * x * (1.0 - x) ],
- 'sine' : [ 0, 2.0, 0, 2, lambda r, x: r * sin(pi * x / 2.0) ]
+ # rmin rmax ymin ymax function
+ "cubic": [0, 6.5, 0, 1, lambda r, x: r * x**2 * (1.0 - x)],
+ "logistic": [0, 4.0, 0, 1, lambda r, x: r * x * (1.0 - x)],
+ "sine": [0, 2.0, 0, 2, lambda r, x: r * sin(pi * x / 2.0)],
}
self.map_name = mapname
self.map_longname = "%s Equation" % mapname.capitalize()
try:
- self.map_rmin, self.map_rmax, \
- self.map_ymin, self.map_ymax, \
- self.map_function = params[mapname]
+ (
+ self.map_rmin,
+ self.map_rmax,
+ self.map_ymin,
+ self.map_ymax,
+ self.map_function,
+ ) = params[mapname]
self.map = self._mapper
except Exception as e:
- raise type(e)('Unknown map name ' + mapname)
+ raise type(e)("Unknown map name " + mapname)
@staticmethod
def ensure(expression, message, *argv):
if not expression:
raise AssertionError(message % (argv) if argv else message)
def _mapper(self, r, x):
self.ensure(
(r >= self.map_rmin and r <= self.map_rmax),
- 'The growth parameter r must be between %g and %g',
- self.map_rmin, self.map_rmax)
+ "The growth parameter r must be between %g and %g",
+ self.map_rmin,
+ self.map_rmax,
+ )
return self.map_function(r, x)
+
class Logistic(Map):
- """Class for plotting a Logistic/Cubic/Sine Map """
-
- def __init__(self, r, n, x0, s=0, mapname='logistic'):
+ """Class for plotting a Logistic/Cubic/Sine Map"""
+
+ def __init__(self, r, n, x0, s=0, mapname="logistic"):
Map.__init__(self, mapname)
- self.r = r # Growth rate parameter
- self.n = n # Number of iterations
- self.s = s # Number of iterations to skip in the plot
+ self.r = r # Growth rate parameter
+ self.n = n # Number of iterations
+ self.s = s # Number of iterations to skip in the plot
self.x0 = x0 # The 1st initial condition
self.x = self.y1 = []
self._dotsonly = False
- self.ensure(n > 0, 'The number of iterations must be greater than zero.')
- self.ensure(s >= 0, 'You cannot skip a negative number of iterations.')
- self.ensure(x0 >= self.map_ymin and x0 <= self.map_ymax,
- 'The initial condition x0 should be in [%g, %g].',
- self.map_ymin, self.map_ymax)
+ self.ensure(n > 0, "The number of iterations must be greater than zero.")
+ self.ensure(s >= 0, "You cannot skip a negative number of iterations.")
+ self.ensure(
+ x0 >= self.map_ymin and x0 <= self.map_ymax,
+ "The initial condition x0 should be in [%g, %g].",
+ self.map_ymin,
+ self.map_ymax,
+ )
def _plotline(self, x, y, color):
"""Plot the dots (x, y) connected by straight lines
- if the parameter 'dotsonly' if set to False """
-
- self.ensure(x.any() and y.any(), '_plotline(): internal error')
- plt.plot(x, y, color=color, linestyle='',
- markerfacecolor=color, marker='o', markersize=5)
+ if the parameter 'dotsonly' if set to False"""
+
+ self.ensure(x.any() and y.any(), "_plotline(): internal error")
+ plt.plot(
+ x,
+ y,
+ color=color,
+ linestyle="",
+ markerfacecolor=color,
+ marker="o",
+ markersize=5,
+ )
if self.plotdots:
plt.plot(x, y, color=color, alpha=0.6)
def getxy(self, fill_value=None):
"""Set the numpy vectors 'x' and 'y1' containing
- the iterations (1..n) and the corresponding values
- of the choosen Map """
+ the iterations (1..n) and the corresponding values
+ of the choosen Map"""
# do not initialize twice the x and y1 vectors
- if len(self.x) > 0: return
+ if len(self.x) > 0:
+ return
vectlen = self.n + self.s + 1
self.x = np.arange(vectlen)
- self.y1 = np.arange(0, vectlen, 1.)
+ self.y1 = np.arange(0, vectlen, 1.0)
self.y1[0] = self.x0
for t in self.x[1:]:
- self.y1[t] = self.map(self.r, self.y1[t-1])
+ self.y1[t] = self.map(self.r, self.y1[t - 1])
return self.x, self.y1
def plot(self):
- """Plot a Logistic, Cubic or Sine map """
+ """Plot a Logistic, Cubic or Sine map"""
self.getxy()
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
plt.title(self.map_longname)
- plt.xlabel('time t')
+ plt.xlabel("time t")
plt.ylim([self.map_ymin, self.map_ymax])
plt.grid(True)
- self._plotline(self.x[self.s:], self.y1[self.s:], 'mediumseagreen')
+ self._plotline(self.x[self.s :], self.y1[self.s :], "mediumseagreen")
plt.show()
@Property
def plotdots(self):
return self._dotsonly
@plotdots.setter
def plotdots(self, value):
- """Set whether to plot or not the dots in a logistic graph """
+ """Set whether to plot or not the dots in a logistic graph"""
self._dotsonly = value
class FinalState(Logistic):
- """Derived class for plotting a Final State Diagram """
+ """Derived class for plotting a Final State Diagram"""
# By default, set the initial state to .5
# make 3000 iterations and do no plot the first 2000 ones
- def __init__(self, r, n=1000, x0=.5, s=2000, mapname='logistic'):
+ def __init__(self, r, n=1000, x0=0.5, s=2000, mapname="logistic"):
Logistic.__init__(self, r, n, x0, s, mapname)
- def getxy(self, fill_value=.5):
+ def getxy(self, fill_value=0.5):
"""Set the numpy vectors 'x' and 'y1' containing the values of the
- choosen Map for the first n iterations """
+ choosen Map for the first n iterations"""
# do not initialize twice the x and y1 vectors
- if len(self.x) > 0: return
+ if len(self.x) > 0:
+ return
vectlen = self.n + self.s + 1
self.x = np.full(vectlen, self.x0, dtype=np.float64)
for t in range(1, vectlen):
- self.x[t] = self.map(self.r, self.x[t-1])
+ self.x[t] = self.map(self.r, self.x[t - 1])
self.y1 = np.full(vectlen, fill_value, dtype=np.float)
return self.x, self.y1
def plot(self):
- """Plot a Final State Diagram """
+ """Plot a Final State Diagram"""
self.getxy()
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
- plt.title('Final State Diagram for the ' + self.map_longname)
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
+ plt.title("Final State Diagram for the " + self.map_longname)
plt.xlim([self.map_ymin, self.map_ymax])
- plt.ylim([0, 1.])
+ plt.ylim([0, 1.0])
plt.yticks([])
plt.grid(True)
- plt.plot([self.map_ymin, self.map_ymax], [.5, .5],
- color='black', lw=1)
- plt.plot(self.x[self.s:], self.y1[self.s:], color='black', linestyle='',
- markerfacecolor='black', marker='o', markersize=8)
- plt.text(.1 * self.map_ymax, .4, 'r = %g' % self.r, style='italic',
- bbox={'facecolor':'red', 'alpha':0.5, 'pad':10})
+ plt.plot([self.map_ymin, self.map_ymax], [0.5, 0.5], color="black", lw=1)
+ plt.plot(
+ self.x[self.s :],
+ self.y1[self.s :],
+ color="black",
+ linestyle="",
+ markerfacecolor="black",
+ marker="o",
+ markersize=8,
+ )
+ plt.text(
+ 0.1 * self.map_ymax,
+ 0.4,
+ "r = %g" % self.r,
+ style="italic",
+ bbox={"facecolor": "red", "alpha": 0.5, "pad": 10},
+ )
plt.show()
class LogisticDiff(Logistic):
"""Derived class for plotting a Logistic/Cubic/Sine Map
- with two different initial conditions, followed by a plot of
- their differences (for a visualization of the Butterfly Effect) """
-
- def __init__(self, r, n, x0, x1, s=0, mapname='logistic'):
+ with two different initial conditions, followed by a plot of
+ their differences (for a visualization of the Butterfly Effect)"""
+
+ def __init__(self, r, n, x0, x1, s=0, mapname="logistic"):
Logistic.__init__(self, r, n, x0, s, mapname)
- self.ensure(x1 >= self.map_ymin and x1 <= self.map_ymax,
- 'The initial condition x1 should be in [%g, %g].',
- self.map_ymin, self.map_ymax)
+ self.ensure(
+ x1 >= self.map_ymin and x1 <= self.map_ymax,
+ "The initial condition x1 should be in [%g, %g].",
+ self.map_ymin,
+ self.map_ymax,
+ )
self.x1 = x1 # The 2st initial condition
self.y2 = []
def getxy(self, fill_value=None):
"""Set the numpy vectors 'x', 'y1', and 'y2' containing
- the iterations (1..n) and the corresponding values
- of the choosen Map """
+ the iterations (1..n) and the corresponding values
+ of the choosen Map"""
x, y1 = super(LogisticDiff, self).getxy()
# do not initialize twice the vector y2
- if len(self.y2) > 0: return
-
- self.y2 = np.arange(0, self.n + self.s + 1, 1.)
+ if len(self.y2) > 0:
+ return
+
+ self.y2 = np.arange(0, self.n + self.s + 1, 1.0)
self.y2[0] = self.x1
for t in self.x[1:]:
- self.y2[t] = self.map(self.r, self.y2[t-1])
+ self.y2[t] = self.map(self.r, self.y2[t - 1])
return x, y1, self.y2
def getdiffy(self):
- """Return the difference between the two vectors y2 and y1 """
+ """Return the difference between the two vectors y2 and y1"""
return self.y2 - self.y1
def plot(self):
"""Plot a Logistic, Cubic or Sine map with two different seeds (two plots)
- followed by their difference """
+ followed by their difference"""
self.getxy()
plt.figure(1)
- plt.suptitle('Dynamic Systems and Chaos',
- fontsize=14, fontweight='bold')
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
plt.subplot(211)
- plt.title('Time series for a ' + self.map_longname + \
- ' with two different initial conditions')
- plt.ylabel(r'$y_1(t),\ y_2(t)$', fontsize=14)
+ plt.title(
+ "Time series for a "
+ + self.map_longname
+ + " with two different initial conditions"
+ )
+ plt.ylabel(r"$y_1(t),\ y_2(t)$", fontsize=14)
plt.ylim([self.map_ymin, self.map_ymax])
plt.grid(True)
- self._plotline(self.x[self.s:], self.y1[self.s:], 'indianred')
- self._plotline(self.x[self.s:], self.y2[self.s:], 'mediumseagreen')
+ self._plotline(self.x[self.s :], self.y1[self.s :], "indianred")
+ self._plotline(self.x[self.s :], self.y2[self.s :], "mediumseagreen")
ydiff = self.y2 - self.y1
plt.subplot(212)
- plt.title('Difference between the two time series')
- plt.xlabel('time t')
- plt.ylabel(r'$y_2(t) - y_1(t)$', fontsize=14)
+ plt.title("Difference between the two time series")
+ plt.xlabel("time t")
+ plt.ylabel(r"$y_2(t) - y_1(t)$", fontsize=14)
plt.grid(True)
- self._plotline(self.x[self.s:], ydiff[self.s:], 'royalblue')
+ self._plotline(self.x[self.s :], ydiff[self.s :], "royalblue")
plt.show()
class Bifurcation(Map):
- """Class for plotting a Logistic/Cubic/Sine Bifurcation Diagram """
- def __init__(self, r, y, n=100, s=200, mapname='logistic'):
+ """Class for plotting a Logistic/Cubic/Sine Bifurcation Diagram"""
+
+ def __init__(self, r, y, n=100, s=200, mapname="logistic"):
Map.__init__(self, mapname)
- self.ensure(len(r) == 2, 'The growth rate vector should contains two elements')
- self.ensure(r[0] >= self.map_rmin and r[0] < r[1] and r[1] <= self.map_rmax,
- ('The parameters [r0, r1] must be between %g and %g, '
- 'and in ascending order.'), self.map_rmin, self.map_rmax)
- self.ensure(len(y) == 2, 'The y range vector should contains two elements')
- self.ensure(y[0] >= self.map_ymin and y[0] < y[1] and y[1] <= self.map_ymax,
- ('The parameters [y0, y1] must be between %g and %g, '
- 'and in ascending order.'), self.map_ymin, self.map_ymax)
-
- self.rmin = r[0] # Range of the growth rate for plot()
+ self.ensure(len(r) == 2, "The growth rate vector should contains two elements")
+ self.ensure(
+ r[0] >= self.map_rmin and r[0] < r[1] and r[1] <= self.map_rmax,
+ (
+ "The parameters [r0, r1] must be between %g and %g, "
+ "and in ascending order."
+ ),
+ self.map_rmin,
+ self.map_rmax,
+ )
+ self.ensure(len(y) == 2, "The y range vector should contains two elements")
+ self.ensure(
+ y[0] >= self.map_ymin and y[0] < y[1] and y[1] <= self.map_ymax,
+ (
+ "The parameters [y0, y1] must be between %g and %g, "
+ "and in ascending order."
+ ),
+ self.map_ymin,
+ self.map_ymax,
+ )
+
+ self.rmin = r[0] # Range of the growth rate for plot()
self.rmax = r[1]
- self.ymin = y[0] # Range of the population for plot()
+ self.ymin = y[0] # Range of the population for plot()
self.ymax = y[1]
- self.ensure(n > 0, 'The number of iterations must be greater than zero.')
- self.n = n # Number of iterations
-
- self.ensure(s >= 0, 'You cannot skip a negative number of iterations.')
- self.s = s # Number of iterations to skip in the plot
+ self.ensure(n > 0, "The number of iterations must be greater than zero.")
+ self.n = n # Number of iterations
+
+ self.ensure(s >= 0, "You cannot skip a negative number of iterations.")
+ self.s = s # Number of iterations to skip in the plot
def plot(self):
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
- plt.title('Bifurcation Diagram for the ' + self.map_longname)
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
+ plt.title("Bifurcation Diagram for the " + self.map_longname)
plt.xlim([self.rmin, self.rmax])
plt.xticks([round(i, 1) for i in np.linspace(self.rmin, self.rmax, 5)])
- plt.xlabel('r')
+ plt.xlabel("r")
plt.ylim([self.ymin, self.ymax])
- plt.ylabel('final states')
+ plt.ylabel("final states")
for r in np.linspace(self.rmin, self.rmax, 1000):
- x, y = FinalState(r, self.n, .5, self.s, self.map_name).getxy(r)
- plt.plot(y[self.s:], x[self.s:], color='black', linestyle='',
- markerfacecolor='black', marker=',', markersize=1)
+ x, y = FinalState(r, self.n, 0.5, self.s, self.map_name).getxy(r)
+ plt.plot(
+ y[self.s :],
+ x[self.s :],
+ color="black",
+ linestyle="",
+ markerfacecolor="black",
+ marker=",",
+ markersize=1,
+ )
plt.show()
-if __name__ == '__main__':
+if __name__ == "__main__":
from lelib_test import tests
+
tests()
print("All tests successfully passed!")
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/finalstate.py#L7
import sys
from lelib import FinalState
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot of the Final State Diagram'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot of the Final State Diagram"
+ examples = """
%(prog)s -r 3.492
%(prog)s -r 3.614 -s 200 -n 300
%(prog)s -0 0.4 -r 3.2 -s 10 -n 50
- %(prog)s -0 0.8 -r 6.2 -n 20 --map=cubic'''
+ %(prog)s -0 0.8 -r 6.2 -n 20 --map=cubic"""
parser = argparser(descr, examples)
# By default, make 3000 iterations (n) and
# do no plot the first 2000 ones (s)
# By default select the Logistic Equation
parser.add_argument(
- "-0", "--x0",
- action="store", dest="x0", type=float, default=.5,
- help="initial condition (default: %(default)s)")
+ "-0",
+ "--x0",
+ action="store",
+ dest="x0",
+ type=float,
+ default=0.5,
+ help="initial condition (default: %(default)s)",
+ )
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r", type=float, required=True,
- help="growth rate parameter")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ type=float,
+ required=True,
+ help="growth rate parameter",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=2000,
- help="skip plotting the first 's' iterations (default: %(default)s)")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=2000,
+ help="skip plotting the first 's' iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-n", "--steps", dest="n", type=int, default=1000, action="store",
- help="number of iterations (default: %(default)s)")
+ "-n",
+ "--steps",
+ dest="n",
+ type=int,
+ default=1000,
+ action="store",
+ help="number of iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default = "logistic",
- choices = ["logistic", "cubic", "sine"],
- help = "select the desired map (logistic, cubic, or sine)")
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
+ choices=["logistic", "cubic", "sine"],
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
def main():
args = parse_args()
- FinalState(
- args.r,
- args.n,
- args.x0,
- args.s,
- args.map_name
- ).plot()
+ FinalState(args.r, args.n, args.x0, args.s, args.map_name).plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/bifurcations.py#L7
import sys
from lelib import Bifurcation, Map
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot the Bifurcation Diagram of Logistic, Cubic, and Sine Maps'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot the Bifurcation Diagram of Logistic, Cubic, and Sine Maps"
+ examples = """
%(prog)s -r 1:4
%(prog)s -r 4:6.5 --map=cubic
%(prog)s --map=sine -s 200 -n 200
%(prog)s -r 3.:4. -s 500 -n 600
- %(prog)s -r 3.5:3.6 -y .3:.6 -s 800 -n 1000'''
+ %(prog)s -r 3.5:3.6 -y .3:.6 -s 800 -n 1000"""
parser = argparser(descr, examples)
# By default, make 300 iterations (n) and do no plot the first 200 ones (s)
# By default select the Logistic Equation
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r",
- help="range of the growth rate parameter (default: the entire range)")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ help="range of the growth rate parameter (default: the entire range)",
+ )
parser.add_argument(
- "-y", "--people",
- action="store", dest="y",
- help="normalized range of the population (default: the entire range)")
+ "-y",
+ "--people",
+ action="store",
+ dest="y",
+ help="normalized range of the population (default: the entire range)",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=200,
- help="skip plotting the first 's' iterations (default: %(default)s)")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=200,
+ help="skip plotting the first 's' iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-n", "--steps",
- action="store", dest="n", type=int, default=100,
- help="number of iterations (default: %(default)s)")
+ "-n",
+ "--steps",
+ action="store",
+ dest="n",
+ type=int,
+ default=100,
+ help="number of iterations (default: %(default)s)",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default="logistic",
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
choices=["logistic", "cubic", "sine"],
- help="select the desired map (logistic, cubic, or sine)")
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
def main():
args = parse_args()
mapobj = Map(args.map_name)
# range to vector: "1:4" --> [1., 4.]
- r2v = (lambda a, minval, maxval :
- [float(i) for i in a.split(':')] if a else
- [minval, maxval])
+ r2v = (
+ lambda a, minval, maxval: [float(i) for i in a.split(":")]
+ if a
+ else [minval, maxval]
+ )
# Plot the entire diagram by default
Bifurcation(
r2v(args.r, mapobj.map_rmin, mapobj.map_rmax),
r2v(args.y, mapobj.map_ymin, mapobj.map_ymax),
args.n,
args.s,
- args.map_name
+ args.map_name,
).plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/legraph.py#L7
import sys
from lelib import Logistic, LogisticDiff
from utils import argparser, die
+
def parse_args():
- """This function parses and return arguments passed in """
- descr = 'Plot of Logistic Equation Time Series'
- examples = '''
+ """This function parses and return arguments passed in"""
+ descr = "Plot of Logistic Equation Time Series"
+ examples = """
# time series with a stable fixed point
%(prog)s -0 0.4 -r 3.2 -n 50
%(prog)s -0 0.4 -1 0.45 -r 3.2 -n 50
# chaotic results (randon output)
%(prog)s --x0 0.2 --x1 0.2000001 -r 4.0 -n 50
%(prog)s -0 0.2 -r 3.6 -n 5000 --dots-only
%(prog)s -0 0.9 -r 4.5 -n 50 --map=cubic
- %(prog)s -0 0.4 -r 0.8 -n 50 --map=sine'''
+ %(prog)s -0 0.4 -r 0.8 -n 50 --map=sine"""
parser = argparser(descr, examples)
# By default select the Logistic Equation
parser.add_argument(
- "-0", "--x0",
- action="store", dest="x0", type=float, required=True,
- help="1st initial condition")
+ "-0",
+ "--x0",
+ action="store",
+ dest="x0",
+ type=float,
+ required=True,
+ help="1st initial condition",
+ )
parser.add_argument(
- "-1", "--x1",
- action="store", dest="x1", type=float,
- help="2nd initial condition (optional)")
+ "-1",
+ "--x1",
+ action="store",
+ dest="x1",
+ type=float,
+ help="2nd initial condition (optional)",
+ )
parser.add_argument(
- "-d", "--dots-only",
- action="store_true", dest="dotsonly",
- help="do not connect the dots with lines (default: %(default)s)")
+ "-d",
+ "--dots-only",
+ action="store_true",
+ dest="dotsonly",
+ help="do not connect the dots with lines (default: %(default)s)",
+ )
parser.add_argument(
- "-r", "--rate",
- action="store", dest="r", type=float, required=True,
- help="growth rate parameter")
+ "-r",
+ "--rate",
+ action="store",
+ dest="r",
+ type=float,
+ required=True,
+ help="growth rate parameter",
+ )
parser.add_argument(
- "-s", "--skip",
- action="store", dest="s", type=int, default=0,
- help="skip plotting the first 's' iterations")
+ "-s",
+ "--skip",
+ action="store",
+ dest="s",
+ type=int,
+ default=0,
+ help="skip plotting the first 's' iterations",
+ )
parser.add_argument(
- "-n", "--steps",
- action="store", dest="n", type=int, required=True,
- help="number of iterations")
+ "-n",
+ "--steps",
+ action="store",
+ dest="n",
+ type=int,
+ required=True,
+ help="number of iterations",
+ )
parser.add_argument(
- "-m", "--map",
- action="store", dest="map_name", default="logistic",
- choices = ["logistic", "cubic", "sine"],
- help = "select the desired map (logistic, cubic, or sine)")
+ "-m",
+ "--map",
+ action="store",
+ dest="map_name",
+ default="logistic",
+ choices=["logistic", "cubic", "sine"],
+ help="select the desired map (logistic, cubic, or sine)",
+ )
return parser.parse_args()
+
def main():
args = parse_args()
lemap = (
- LogisticDiff(
- args.r, args.n, args.x0, args.x1, args.s, args.map_name)
- if args.x1 else Logistic(
- args.r, args.n, args.x0, args.s, args.map_name))
+ LogisticDiff(args.r, args.n, args.x0, args.x1, args.s, args.map_name)
+ if args.x1
+ else Logistic(args.r, args.n, args.x0, args.s, args.map_name)
+ )
lemap.plotdots = not args.dotsonly
lemap.plot()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- die(3, 'Exiting on user request')
+ die(3, "Exiting on user request")
sys.exit()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/lelib_test.py#L7
from __future__ import print_function
import numpy as np
from lelib import Map, Logistic, LogisticDiff
+
def test_class_map():
- """Test the class 'Map' """
+ """Test the class 'Map'"""
print("Running the tests for the class 'Map'...")
m = Map()
- m.ensure(m.map_name == 'logistic', "The default map should be 'logistic'")
- m.ensure(m.map_longname == 'Logistic Equation',
- "Logistic Map: bad long name")
- m.ensure(m.map_rmin == 0 and m.map_rmax == 4,
- "Logistic Map: bad range for r")
- m.ensure(m.map_ymin == 0 and m.map_ymax == 1,
- "Logistic Map: bad range for y")
- i = m.map(4,.25)
- m.ensure(i == .75,
- "Logistic Map: bad value for r=4 and x=.25: should be %f" % i)
+ m.ensure(m.map_name == "logistic", "The default map should be 'logistic'")
+ m.ensure(m.map_longname == "Logistic Equation", "Logistic Map: bad long name")
+ m.ensure(m.map_rmin == 0 and m.map_rmax == 4, "Logistic Map: bad range for r")
+ m.ensure(m.map_ymin == 0 and m.map_ymax == 1, "Logistic Map: bad range for y")
+ i = m.map(4, 0.25)
+ m.ensure(i == 0.75, "Logistic Map: bad value for r=4 and x=.25: should be %f" % i)
- m = Map('cubic')
- m.ensure(m.map_name == 'cubic', "Cubic Map: bad map selection")
- m.ensure(m.map_longname == 'Cubic Equation', "Cubic Map: bad long name")
- m.ensure(m.map_rmin == 0 and m.map_rmax == 6.5,
- "Cubic Map: bad range for r")
- m.ensure(m.map_ymin == 0 and m.map_ymax == 1,
- "Cubic Map: bad range for y")
- i = m.map(2,.5)
- m.ensure(i == .25,
- "Cubic Map: bad value for r=2 and x=.5, should be %f" % i)
+ m = Map("cubic")
+ m.ensure(m.map_name == "cubic", "Cubic Map: bad map selection")
+ m.ensure(m.map_longname == "Cubic Equation", "Cubic Map: bad long name")
+ m.ensure(m.map_rmin == 0 and m.map_rmax == 6.5, "Cubic Map: bad range for r")
+ m.ensure(m.map_ymin == 0 and m.map_ymax == 1, "Cubic Map: bad range for y")
+ i = m.map(2, 0.5)
+ m.ensure(i == 0.25, "Cubic Map: bad value for r=2 and x=.5, should be %f" % i)
- m = Map('sine')
- m.ensure(m.map_name == 'sine', "Sine Map: bad map selection")
- m.ensure(m.map_longname == 'Sine Equation', "Sine Map: bad long name")
+ m = Map("sine")
+ m.ensure(m.map_name == "sine", "Sine Map: bad map selection")
+ m.ensure(m.map_longname == "Sine Equation", "Sine Map: bad long name")
m.ensure(m.map_rmin == 0 and m.map_rmax == 2, "Sine Map: bad range for r")
m.ensure(m.map_ymin == 0 and m.map_ymax == 2, "Sine Map: bad range for y")
- i = m.map(0.5,1)
- m.ensure(i == .5,
- "Sine Map: bad value for r=0.5 and x=1: should be %f" % i)
+ i = m.map(0.5, 1)
+ m.ensure(i == 0.5, "Sine Map: bad value for r=0.5 and x=1: should be %f" % i)
+
def test_class_logistic():
- """Test the class 'Logistic' """
+ """Test the class 'Logistic'"""
print("Running the tests for the class 'Logistic'...")
r, n, x0 = 3.2, 100, 0.4
- le1 = Logistic(r, n, x0, False, 'logistic')
+ le1 = Logistic(r, n, x0, False, "logistic")
x, y1 = le1.getxy()
m = Map()
- m.ensure(len(x) == n+1, "x should be a vector of size %d" % (n+1))
+ m.ensure(len(x) == n + 1, "x should be a vector of size %d" % (n + 1))
m.ensure(x[0] == 0, "x[0] should be 0")
m.ensure(x[n] == n, "the last element of x should be equal to %d" % n)
- m.ensure(x.sum() == n*(n+1)/2,
- "the sum of the elements of x is not correct")
+ m.ensure(x.sum() == n * (n + 1) / 2, "the sum of the elements of x is not correct")
- m.ensure(len(y1) == n+1, "y1 should be a vector of size %d" % (n+1))
+ m.ensure(len(y1) == n + 1, "y1 should be a vector of size %d" % (n + 1))
m.ensure(y1[0] == x0, "the first element of y1 should be equal to x0")
- m.ensure(y1[n] == y1[n-2], "y1 is expected to be periodic with period 2")
- m.ensure(y1[n-1] == y1[n-3], "y1 is expected to be periodic with period 2")
+ m.ensure(y1[n] == y1[n - 2], "y1 is expected to be periodic with period 2")
+ m.ensure(y1[n - 1] == y1[n - 3], "y1 is expected to be periodic with period 2")
+
def test_class_logisticdiff():
- """Test the class 'LogisticDiff' """
+ """Test the class 'LogisticDiff'"""
print("Running the tests for the class 'LogisticDiff'...")
r, n, x0, x1 = 4.0, 50, 0.2, 0.2000001
- le2 = LogisticDiff(r, n, x0, x1, False, 'logistic')
+ le2 = LogisticDiff(r, n, x0, x1, False, "logistic")
x, y1, _ = le2.getxy()
m = Map()
- m.ensure(len(x) == n+1, "x should be a vector of size %d" % (n+1))
+ m.ensure(len(x) == n + 1, "x should be a vector of size %d" % (n + 1))
m.ensure(x[0] == 0, "x[0] should be 0")
m.ensure(x[n] == n, "the last element of x should be equal to %d" % n)
- m.ensure(x.sum() == n*(n+1)/2,
- "the sum of the elements of x is not correct")
+ m.ensure(x.sum() == n * (n + 1) / 2, "the sum of the elements of x is not correct")
- m.ensure(len(y1) == n+1, "y1 should be a vector of size %d" % (n+1))
+ m.ensure(len(y1) == n + 1, "y1 should be a vector of size %d" % (n + 1))
m.ensure(y1[0] == x0, "the first element of y1 should be equal to x0")
ydiff = le2.getdiffy()
- m.ensure(len(ydiff) == n+1,
- "the vector y2-y1 should have a size equal to %d" % (n+1))
- m.ensure(np.all(ydiff < 1e3) and np.all(ydiff > -1e3),
- "the diff vector should show the Butterfly Effect")
+ m.ensure(
+ len(ydiff) == n + 1, "the vector y2-y1 should have a size equal to %d" % (n + 1)
+ )
+ m.ensure(
+ np.all(ydiff < 1e3) and np.all(ydiff > -1e3),
+ "the diff vector should show the Butterfly Effect",
+ )
+
def tests():
test_class_map()
test_class_logistic()
test_class_logisticdiff()
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/utils.py#L12
__status__ = "stable"
import argparse
import textwrap
+
def argparser(descr, examples):
- """Return a new ArgumentParser object """
+ """Return a new ArgumentParser object"""
return argparse.ArgumentParser(
- formatter_class = argparse.RawDescriptionHelpFormatter,
- description = copyleft(descr),
- epilog = "Examples:\n" + textwrap.dedent(examples))
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=copyleft(descr),
+ epilog="Examples:\n" + textwrap.dedent(examples),
+ )
+
def copyleft(descr):
- """Print the Copyright message and License """
+ """Print the Copyright message and License"""
- return ("{0} v.{1} ({2})\n{3} <{4}>\nLicense: {5}"
- .format(
- descr, __version__, __status__,
- __copyright__, __email__,
- __license__))
+ return "{0} v.{1} ({2})\n{3} <{4}>\nLicense: {5}".format(
+ descr, __version__, __status__, __copyright__, __email__, __license__
+ )
+
def die(exitcode, message):
- """Print and error message and exit with 'exitcode' """
+ """Print and error message and exit with 'exitcode'"""
progname = sys.argv[0]
- sys.stderr.write('%s: error: %s\n' % (progname, message))
+ sys.stderr.write("%s: error: %s\n" % (progname, message))
sys.exit(exitcode)
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/setup.py#L12
Logistic, Cubic, or Sine Map with two different starting points (along with the
plot of the differences between the two maps), and the Final State and
Bifurcation Diagrams.
"""
-DOCLINES = DESCRIPTION.split('\n')
+DOCLINES = DESCRIPTION.split("\n")
CLASSIFIERS = """\
Development Status :: 5 - Production/Stable
Intended Audience :: Education
Intended Audience :: Science/Research
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/setup.py#L29
Operating System :: POSIX
Operating System :: Unix
Operating System :: MacOS
"""
-VERSION = '2'
+VERSION = "2"
setup(
- name = 'dynamic-systems-and-chaos',
- description = DOCLINES[0],
- long_description = DESCRIPTION,
- version = VERSION,
- url = 'https://github.com/madrisan/dynamic-systems-and-chaos/',
-
- author = 'Davide Madrisan',
- author_email = 'davide.madrisan@gmail.com',
-
- license = 'Apache License 2.0',
- packages = ['dynamic-systems-and-chaos'],
-
- scripts = [
- 'dynamic-systems-and-chaos/bifurcations.py',
- 'dynamic-systems-and-chaos/finalstate.py',
- 'dynamic-systems-and-chaos/legraph.py',
+ name="dynamic-systems-and-chaos",
+ description=DOCLINES[0],
+ long_description=DESCRIPTION,
+ version=VERSION,
+ url="https://github.com/madrisan/dynamic-systems-and-chaos/",
+ author="Davide Madrisan",
+ author_email="davide.madrisan@gmail.com",
+ license="Apache License 2.0",
+ packages=["dynamic-systems-and-chaos"],
+ scripts=[
+ "dynamic-systems-and-chaos/bifurcations.py",
+ "dynamic-systems-and-chaos/finalstate.py",
+ "dynamic-systems-and-chaos/legraph.py",
],
-
- classifiers = [ _f for _f in CLASSIFIERS.split('\n') if _f ],
-
- install_requires = [
- 'numpy',
- 'matplotlib',
+ classifiers=[_f for _f in CLASSIFIERS.split("\n") if _f],
+ install_requires=[
+ "numpy",
+ "matplotlib",
],
-
- platforms = ["Linux", "Mac OS-X", "Windows"],
+ platforms=["Linux", "Mac OS-X", "Windows"],
)
|
/home/runner/work/dynamic-systems-and-chaos/dynamic-systems-and-chaos/dynamic-systems-and-chaos/lelib.py#L15
import numpy as np
import matplotlib.pyplot as plt
from math import pi, sin
+
class Map(object):
- """Class that provides the map functions along with r and y ranges """
-
- def __init__(self, mapname='logistic'):
+ """Class that provides the map functions along with r and y ranges"""
+
+ def __init__(self, mapname="logistic"):
params = {
- # rmin rmax ymin ymax function
- 'cubic' : [ 0, 6.5, 0, 1, lambda r, x: r * x**2 * (1.0 - x) ],
- 'logistic': [ 0, 4.0, 0, 1, lambda r, x: r * x * (1.0 - x) ],
- 'sine' : [ 0, 2.0, 0, 2, lambda r, x: r * sin(pi * x / 2.0) ]
+ # rmin rmax ymin ymax function
+ "cubic": [0, 6.5, 0, 1, lambda r, x: r * x**2 * (1.0 - x)],
+ "logistic": [0, 4.0, 0, 1, lambda r, x: r * x * (1.0 - x)],
+ "sine": [0, 2.0, 0, 2, lambda r, x: r * sin(pi * x / 2.0)],
}
self.map_name = mapname
self.map_longname = "%s Equation" % mapname.capitalize()
try:
- self.map_rmin, self.map_rmax, \
- self.map_ymin, self.map_ymax, \
- self.map_function = params[mapname]
+ (
+ self.map_rmin,
+ self.map_rmax,
+ self.map_ymin,
+ self.map_ymax,
+ self.map_function,
+ ) = params[mapname]
self.map = self._mapper
except Exception as e:
- raise type(e)('Unknown map name ' + mapname)
+ raise type(e)("Unknown map name " + mapname)
@staticmethod
def ensure(expression, message, *argv):
if not expression:
raise AssertionError(message % (argv) if argv else message)
def _mapper(self, r, x):
self.ensure(
(r >= self.map_rmin and r <= self.map_rmax),
- 'The growth parameter r must be between %g and %g',
- self.map_rmin, self.map_rmax)
+ "The growth parameter r must be between %g and %g",
+ self.map_rmin,
+ self.map_rmax,
+ )
return self.map_function(r, x)
+
class Logistic(Map):
- """Class for plotting a Logistic/Cubic/Sine Map """
-
- def __init__(self, r, n, x0, s=0, mapname='logistic'):
+ """Class for plotting a Logistic/Cubic/Sine Map"""
+
+ def __init__(self, r, n, x0, s=0, mapname="logistic"):
Map.__init__(self, mapname)
- self.r = r # Growth rate parameter
- self.n = n # Number of iterations
- self.s = s # Number of iterations to skip in the plot
+ self.r = r # Growth rate parameter
+ self.n = n # Number of iterations
+ self.s = s # Number of iterations to skip in the plot
self.x0 = x0 # The 1st initial condition
self.x = self.y1 = []
self._dotsonly = False
- self.ensure(n > 0, 'The number of iterations must be greater than zero.')
- self.ensure(s >= 0, 'You cannot skip a negative number of iterations.')
- self.ensure(x0 >= self.map_ymin and x0 <= self.map_ymax,
- 'The initial condition x0 should be in [%g, %g].',
- self.map_ymin, self.map_ymax)
+ self.ensure(n > 0, "The number of iterations must be greater than zero.")
+ self.ensure(s >= 0, "You cannot skip a negative number of iterations.")
+ self.ensure(
+ x0 >= self.map_ymin and x0 <= self.map_ymax,
+ "The initial condition x0 should be in [%g, %g].",
+ self.map_ymin,
+ self.map_ymax,
+ )
def _plotline(self, x, y, color):
"""Plot the dots (x, y) connected by straight lines
- if the parameter 'dotsonly' if set to False """
-
- self.ensure(x.any() and y.any(), '_plotline(): internal error')
- plt.plot(x, y, color=color, linestyle='',
- markerfacecolor=color, marker='o', markersize=5)
+ if the parameter 'dotsonly' if set to False"""
+
+ self.ensure(x.any() and y.any(), "_plotline(): internal error")
+ plt.plot(
+ x,
+ y,
+ color=color,
+ linestyle="",
+ markerfacecolor=color,
+ marker="o",
+ markersize=5,
+ )
if self.plotdots:
plt.plot(x, y, color=color, alpha=0.6)
def getxy(self, fill_value=None):
"""Set the numpy vectors 'x' and 'y1' containing
- the iterations (1..n) and the corresponding values
- of the choosen Map """
+ the iterations (1..n) and the corresponding values
+ of the choosen Map"""
# do not initialize twice the x and y1 vectors
- if len(self.x) > 0: return
+ if len(self.x) > 0:
+ return
vectlen = self.n + self.s + 1
self.x = np.arange(vectlen)
- self.y1 = np.arange(0, vectlen, 1.)
+ self.y1 = np.arange(0, vectlen, 1.0)
self.y1[0] = self.x0
for t in self.x[1:]:
- self.y1[t] = self.map(self.r, self.y1[t-1])
+ self.y1[t] = self.map(self.r, self.y1[t - 1])
return self.x, self.y1
def plot(self):
- """Plot a Logistic, Cubic or Sine map """
+ """Plot a Logistic, Cubic or Sine map"""
self.getxy()
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
plt.title(self.map_longname)
- plt.xlabel('time t')
+ plt.xlabel("time t")
plt.ylim([self.map_ymin, self.map_ymax])
plt.grid(True)
- self._plotline(self.x[self.s:], self.y1[self.s:], 'mediumseagreen')
+ self._plotline(self.x[self.s :], self.y1[self.s :], "mediumseagreen")
plt.show()
@Property
def plotdots(self):
return self._dotsonly
@plotdots.setter
def plotdots(self, value):
- """Set whether to plot or not the dots in a logistic graph """
+ """Set whether to plot or not the dots in a logistic graph"""
self._dotsonly = value
class FinalState(Logistic):
- """Derived class for plotting a Final State Diagram """
+ """Derived class for plotting a Final State Diagram"""
# By default, set the initial state to .5
# make 3000 iterations and do no plot the first 2000 ones
- def __init__(self, r, n=1000, x0=.5, s=2000, mapname='logistic'):
+ def __init__(self, r, n=1000, x0=0.5, s=2000, mapname="logistic"):
Logistic.__init__(self, r, n, x0, s, mapname)
- def getxy(self, fill_value=.5):
+ def getxy(self, fill_value=0.5):
"""Set the numpy vectors 'x' and 'y1' containing the values of the
- choosen Map for the first n iterations """
+ choosen Map for the first n iterations"""
# do not initialize twice the x and y1 vectors
- if len(self.x) > 0: return
+ if len(self.x) > 0:
+ return
vectlen = self.n + self.s + 1
self.x = np.full(vectlen, self.x0, dtype=np.float64)
for t in range(1, vectlen):
- self.x[t] = self.map(self.r, self.x[t-1])
+ self.x[t] = self.map(self.r, self.x[t - 1])
self.y1 = np.full(vectlen, fill_value, dtype=np.float)
return self.x, self.y1
def plot(self):
- """Plot a Final State Diagram """
+ """Plot a Final State Diagram"""
self.getxy()
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
- plt.title('Final State Diagram for the ' + self.map_longname)
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
+ plt.title("Final State Diagram for the " + self.map_longname)
plt.xlim([self.map_ymin, self.map_ymax])
- plt.ylim([0, 1.])
+ plt.ylim([0, 1.0])
plt.yticks([])
plt.grid(True)
- plt.plot([self.map_ymin, self.map_ymax], [.5, .5],
- color='black', lw=1)
- plt.plot(self.x[self.s:], self.y1[self.s:], color='black', linestyle='',
- markerfacecolor='black', marker='o', markersize=8)
- plt.text(.1 * self.map_ymax, .4, 'r = %g' % self.r, style='italic',
- bbox={'facecolor':'red', 'alpha':0.5, 'pad':10})
+ plt.plot([self.map_ymin, self.map_ymax], [0.5, 0.5], color="black", lw=1)
+ plt.plot(
+ self.x[self.s :],
+ self.y1[self.s :],
+ color="black",
+ linestyle="",
+ markerfacecolor="black",
+ marker="o",
+ markersize=8,
+ )
+ plt.text(
+ 0.1 * self.map_ymax,
+ 0.4,
+ "r = %g" % self.r,
+ style="italic",
+ bbox={"facecolor": "red", "alpha": 0.5, "pad": 10},
+ )
plt.show()
class LogisticDiff(Logistic):
"""Derived class for plotting a Logistic/Cubic/Sine Map
- with two different initial conditions, followed by a plot of
- their differences (for a visualization of the Butterfly Effect) """
-
- def __init__(self, r, n, x0, x1, s=0, mapname='logistic'):
+ with two different initial conditions, followed by a plot of
+ their differences (for a visualization of the Butterfly Effect)"""
+
+ def __init__(self, r, n, x0, x1, s=0, mapname="logistic"):
Logistic.__init__(self, r, n, x0, s, mapname)
- self.ensure(x1 >= self.map_ymin and x1 <= self.map_ymax,
- 'The initial condition x1 should be in [%g, %g].',
- self.map_ymin, self.map_ymax)
+ self.ensure(
+ x1 >= self.map_ymin and x1 <= self.map_ymax,
+ "The initial condition x1 should be in [%g, %g].",
+ self.map_ymin,
+ self.map_ymax,
+ )
self.x1 = x1 # The 2st initial condition
self.y2 = []
def getxy(self, fill_value=None):
"""Set the numpy vectors 'x', 'y1', and 'y2' containing
- the iterations (1..n) and the corresponding values
- of the choosen Map """
+ the iterations (1..n) and the corresponding values
+ of the choosen Map"""
x, y1 = super(LogisticDiff, self).getxy()
# do not initialize twice the vector y2
- if len(self.y2) > 0: return
-
- self.y2 = np.arange(0, self.n + self.s + 1, 1.)
+ if len(self.y2) > 0:
+ return
+
+ self.y2 = np.arange(0, self.n + self.s + 1, 1.0)
self.y2[0] = self.x1
for t in self.x[1:]:
- self.y2[t] = self.map(self.r, self.y2[t-1])
+ self.y2[t] = self.map(self.r, self.y2[t - 1])
return x, y1, self.y2
def getdiffy(self):
- """Return the difference between the two vectors y2 and y1 """
+ """Return the difference between the two vectors y2 and y1"""
return self.y2 - self.y1
def plot(self):
"""Plot a Logistic, Cubic or Sine map with two different seeds (two plots)
- followed by their difference """
+ followed by their difference"""
self.getxy()
plt.figure(1)
- plt.suptitle('Dynamic Systems and Chaos',
- fontsize=14, fontweight='bold')
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
plt.subplot(211)
- plt.title('Time series for a ' + self.map_longname + \
- ' with two different initial conditions')
- plt.ylabel(r'$y_1(t),\ y_2(t)$', fontsize=14)
+ plt.title(
+ "Time series for a "
+ + self.map_longname
+ + " with two different initial conditions"
+ )
+ plt.ylabel(r"$y_1(t),\ y_2(t)$", fontsize=14)
plt.ylim([self.map_ymin, self.map_ymax])
plt.grid(True)
- self._plotline(self.x[self.s:], self.y1[self.s:], 'indianred')
- self._plotline(self.x[self.s:], self.y2[self.s:], 'mediumseagreen')
+ self._plotline(self.x[self.s :], self.y1[self.s :], "indianred")
+ self._plotline(self.x[self.s :], self.y2[self.s :], "mediumseagreen")
ydiff = self.y2 - self.y1
plt.subplot(212)
- plt.title('Difference between the two time series')
- plt.xlabel('time t')
- plt.ylabel(r'$y_2(t) - y_1(t)$', fontsize=14)
+ plt.title("Difference between the two time series")
+ plt.xlabel("time t")
+ plt.ylabel(r"$y_2(t) - y_1(t)$", fontsize=14)
plt.grid(True)
- self._plotline(self.x[self.s:], ydiff[self.s:], 'royalblue')
+ self._plotline(self.x[self.s :], ydiff[self.s :], "royalblue")
plt.show()
class Bifurcation(Map):
- """Class for plotting a Logistic/Cubic/Sine Bifurcation Diagram """
- def __init__(self, r, y, n=100, s=200, mapname='logistic'):
+ """Class for plotting a Logistic/Cubic/Sine Bifurcation Diagram"""
+
+ def __init__(self, r, y, n=100, s=200, mapname="logistic"):
Map.__init__(self, mapname)
- self.ensure(len(r) == 2, 'The growth rate vector should contains two elements')
- self.ensure(r[0] >= self.map_rmin and r[0] < r[1] and r[1] <= self.map_rmax,
- ('The parameters [r0, r1] must be between %g and %g, '
- 'and in ascending order.'), self.map_rmin, self.map_rmax)
- self.ensure(len(y) == 2, 'The y range vector should contains two elements')
- self.ensure(y[0] >= self.map_ymin and y[0] < y[1] and y[1] <= self.map_ymax,
- ('The parameters [y0, y1] must be between %g and %g, '
- 'and in ascending order.'), self.map_ymin, self.map_ymax)
-
- self.rmin = r[0] # Range of the growth rate for plot()
+ self.ensure(len(r) == 2, "The growth rate vector should contains two elements")
+ self.ensure(
+ r[0] >= self.map_rmin and r[0] < r[1] and r[1] <= self.map_rmax,
+ (
+ "The parameters [r0, r1] must be between %g and %g, "
+ "and in ascending order."
+ ),
+ self.map_rmin,
+ self.map_rmax,
+ )
+ self.ensure(len(y) == 2, "The y range vector should contains two elements")
+ self.ensure(
+ y[0] >= self.map_ymin and y[0] < y[1] and y[1] <= self.map_ymax,
+ (
+ "The parameters [y0, y1] must be between %g and %g, "
+ "and in ascending order."
+ ),
+ self.map_ymin,
+ self.map_ymax,
+ )
+
+ self.rmin = r[0] # Range of the growth rate for plot()
self.rmax = r[1]
- self.ymin = y[0] # Range of the population for plot()
+ self.ymin = y[0] # Range of the population for plot()
self.ymax = y[1]
- self.ensure(n > 0, 'The number of iterations must be greater than zero.')
- self.n = n # Number of iterations
-
- self.ensure(s >= 0, 'You cannot skip a negative number of iterations.')
- self.s = s # Number of iterations to skip in the plot
+ self.ensure(n > 0, "The number of iterations must be greater than zero.")
+ self.n = n # Number of iterations
+
+ self.ensure(s >= 0, "You cannot skip a negative number of iterations.")
+ self.s = s # Number of iterations to skip in the plot
def plot(self):
- plt.suptitle('Dynamic Systems and Chaos', fontsize=14, fontweight='bold')
- plt.title('Bifurcation Diagram for the ' + self.map_longname)
+ plt.suptitle("Dynamic Systems and Chaos", fontsize=14, fontweight="bold")
+ plt.title("Bifurcation Diagram for the " + self.map_longname)
plt.xlim([self.rmin, self.rmax])
plt.xticks([round(i, 1) for i in np.linspace(self.rmin, self.rmax, 5)])
- plt.xlabel('r')
+ plt.xlabel("r")
plt.ylim([self.ymin, self.ymax])
- plt.ylabel('final states')
+ plt.ylabel("final states")
for r in np.linspace(self.rmin, self.rmax, 1000):
- x, y = FinalState(r, self.n, .5, self.s, self.map_name).getxy(r)
- plt.plot(y[self.s:], x[self.s:], color='black', linestyle='',
- markerfacecolor='black', marker=',', markersize=1)
+ x, y = FinalState(r, self.n, 0.5, self.s, self.map_name).getxy(r)
+ plt.plot(
+ y[self.s :],
+ x[self.s :],
+ color="black",
+ linestyle="",
+ markerfacecolor="black",
+ marker=",",
+ markersize=1,
+ )
plt.show()
-if __name__ == '__main__':
+if __name__ == "__main__":
from lelib_test import tests
+
tests()
print("All tests successfully passed!")
|
Run linters
The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2, actions/setup-python@v1. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
|