Making of-the-logistic-map-bifurcation-diagram
-
Upload
martsberger -
Category
Software
-
view
577 -
download
1
description
Transcript of Making of-the-logistic-map-bifurcation-diagram
![Page 1: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/1.jpg)
Making of:
The logistic mapbifurcation diagram
Brad Martsberger
![Page 2: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/2.jpg)
What is this talk about?Making a pretty picture
Squeezing performance out of python
PyPy, Cython, C extensions
With a toy physics model (chaos!)
![Page 3: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/3.jpg)
Fun with fractals
![Page 4: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/4.jpg)
Cool, but...Where did that come from?Can you show me some python already?
![Page 5: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/5.jpg)
The logistic mapMap a value, x, from [0, 1] to [0, 1] according to:
r * x * (1 - x)
Let's play...
x = 0.25 r = 2.5 for j in range(limit): print "x:", x x = r * x * (1 - x)
![Page 6: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/6.jpg)
What do we need to make thatsweet graph?
Python
Matplotlib
Patience ... lots of patience
![Page 7: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/7.jpg)
Simplified version bif_diag = [[0.0] * height] * width
for k in range(width): # histogram of how frequently each pixel is visited. h = logmap_histogram(r, x_len, x1, x2, height)
# Normalize the histogram to go from 0 to 1. h = divide_list(h, 1.0 * max(h))
# stick it in upside down to the image bif_diag[k - 1] = h[::-1]
plot_bif_diag(bif_diag, plt, cm, (x1, x2), (r_lower, r_upper))
![Page 8: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/8.jpg)
Inner loop def logmap_histogram(r, x_len, x1, x2, height): result = [0] * height dx = 1.0 * (x2 - x1) / (height - 1)
transient = 500 x = 0.25 for k in xrange(transient): x = x * r * (1 - x) for k in xrange(x_len): x = x * r * (1 - x) incr = int((x - x1) / dx) if incr >= 0 and incr < M: result[incr] += 1
return result
![Page 9: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/9.jpg)
Matplotlib bitdef plot_bif_diag(bif_diag, plt, cm, xlim, rlim): width, height, = len(bif_diag), len(bif_diag[1])
to_plot = [[1 - pix for pix in col] for col in bif_diag] to_plot = map(list, zip(*to_plot))
plt.imshow(to_plot, cm.gray, clim=(0.7, 1))
font = {'family': 'serif', 'size': 24} plt.xlabel('r', fontdict=font) plt.ylabel('x*', fontdict=font) plt.xticks(linspace(1, N, 9), ['%.2g' % r for r in linspace(rlim[0], rlim[1], 9)]) plt.yticks(linspace(1, M - 1, 5), ['%.2g' % x for x in linspace(xlim[1], xlim[0], 5)])
ax = plt.gca() ax.set_position([80. / (width + 100.), 80. / (height + 100.), width / (width + 100.), height / (height + plt.gcf().canvas.manager.window.geometry("{0}x{1}+30+30".format(width + 100, height +
plt.show()
![Page 10: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/10.jpg)
Let's run thisthing already...
![Page 11: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/11.jpg)
That was a little disappointingNot horrible, but too slow to do some cool stuff.
![Page 12: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/12.jpg)
Options for doing better0. Quit using python
1. PyPy
2. C extension
3. Cython
4. There are others (numpy with numexpr)
![Page 13: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/13.jpg)
PyPyStraight from pypy.org:
Fast, compliant alternative implementation of the Pythonlanguage (2.7.6 and 3.2.3) with several advantages:
Speed, due to Just-In-Time compiler
Takes less memory
Supports a number of third party libraries:
ctypes, django, sqlalchemy, twisted, etc.
Does not require any change to your code!
Unfortunately, matplotlib is not supported.
Numpy is partially supported.
![Page 14: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/14.jpg)
C extensionsWrite functions in C that are callable from python
Pass python objects as arguments that must be converted to Cvalues
Returns a python object, e.g., a list
Compiled and fast
Do this at least once
![Page 15: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/15.jpg)
Let's have a lookstatic PyObject *logmap_attractor_histogram(PyObject *self, PyObject *args) { double r1, r2, x, x1, x2; int xxlen, rrlen, M; int transient = 500; // Short transient for each r.
if (!PyArg_ParseTuple(args, "ddiiddi", &r1, &r2, &rrlen, &xxlen, &x1, &x2, &M)) { return NULL; }
// Store our histogram in an int array, copy it to a python list and return // the list as a PyObject* int array[M]; PyObject* list = PyList_New(M); // Initialize array to all zeros int j, k; for (j = 0; j < M; ++j) { array[j] = 0; }
double r, dr, dx; int incr;
// Set the amount we will step to get from r1 to r2 in rrlen-1 steps dr = 0; if (rrlen > 1) { dr = (r2 - r1)/(rrlen-1); }
// Histogram bin size dx = (x2 - x1)/(M - 1);
// loop over r (perhaps change to for (r=r1; r<=r2; r += dr) )
![Page 16: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/16.jpg)
Compiling to an importable moduleCreate a setup.py file, e.g:
from distutils.core import setup, Extension
setup(name='logmap', version='1.0', ext_modules=[Extension('logmap', ['logmapmodule.c'])])
Then install it
>>> python setup.py install
And it can be imported and called
import logmap
h = logmap.attractor_histogram(...)
![Page 17: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/17.jpg)
Let's see it already...
![Page 18: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/18.jpg)
CythonDirectly from cython.org:
Static compiler for python
Makes writing C extensions for python as easy as writingpython
Generates C code from your python code
Has the potential to deliver the speed gains that we get from a Cextension with less hassle
![Page 19: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/19.jpg)
How to make it workCreate setup.py file:
Build like this:
Then you can import fromlogistic_map_bifurcation_diagram_cython
from distutils.core import setupfrom Cython.Build import cythonize
setup( name = 'logmap_cython', ext_modules = cythonize("logistic_map_bifurcation_diagram_cython.pyx"),)
%>python setup.py build_ext --in_place
![Page 20: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/20.jpg)
Making cython fasterCython's code generation is helped by providing it hints in the
form of type declarations
def logmap_histogram(float r1, float r2, int rrlen, int xxlen, float x1, float x2, int M) result = [0] * M cdef float dx dx = 1.0 * (x2 - x1) / (M - 1)
transient = 500 cdef float x cdef float r cdef float k for r in linspace(r1, r2, rrlen): x = 0.25 for k in range(transient): x = x * r * (1 - x) for k in range(xxlen): x = x * r * (1 - x) incr = int((x - x1) / dx) if incr >= 0 and incr < M: result[incr] += 1
return result
![Page 21: Making of-the-logistic-map-bifurcation-diagram](https://reader033.fdocuments.in/reader033/viewer/2022052619/556e3dc8d8b42a16278b4b76/html5/thumbnails/21.jpg)
Questions...Comments, etc.