Created
March 9, 2018 23:20
-
-
Save ev-br/d876c35903877efcf8eda5247da99681 to your computer and use it in GitHub Desktop.
cythonization example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Spatial evolutionary game simulator\n", | |
"\n", | |
"S. Kolotev, A. Malyutin, E. Burovski, S. Krashakov and L. Shchur, *Dynamic fractals in spatial evolutionary games*, Physica A **499**, 142 (2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np\n", | |
"import matplotlib.pyplot as plt\n", | |
"import matplotlib as mpl\n", | |
"from matplotlib import animation\n", | |
"\n", | |
"%matplotlib notebook" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"('python ', '2.7.13 |Anaconda 4.4.0 (64-bit)| (default, Dec 20 2016, 23:09:15) \\n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]')\n", | |
"('numpy', '1.12.1', ', matplotlib', '2.0.2', ', and Cython', '0.25.2')\n" | |
] | |
} | |
], | |
"source": [ | |
"import sys\n", | |
"import cython\n", | |
"\n", | |
"print(\"python \", sys.version)\n", | |
"print(\"numpy\", np.__version__, \", matplotlib\", mpl.__version__, \", and Cython\", cython.__version__)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Main update function:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def evolve2(field, b, num_steps=1):\n", | |
" L = field.shape[0]\n", | |
" current = np.zeros((L, L), dtype=int)\n", | |
" scores = np.zeros((L, L), dtype=float)\n", | |
" \n", | |
" for step in range(num_steps):\n", | |
" current = field.copy()\n", | |
" scores = np.zeros((L, L), dtype=float)\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" scores[x, y] += (1 - field[ix, jy])\n", | |
" \n", | |
" if field[x, y] == 1:\n", | |
" scores[x, y] *= b\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" bestX = x\n", | |
" bestY = y\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" if (scores[bestX, bestY] < scores[ix, jy]):\n", | |
" bestX = ix\n", | |
" bestY = jy\n", | |
" \n", | |
" field[x, y] = current[bestX, bestY]\n", | |
" return field" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Run the simulation and animate" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/javascript": [ | |
"/* Put everything inside the global mpl namespace */\n", | |
"window.mpl = {};\n", | |
"\n", | |
"\n", | |
"mpl.get_websocket_type = function() {\n", | |
" if (typeof(WebSocket) !== 'undefined') {\n", | |
" return WebSocket;\n", | |
" } else if (typeof(MozWebSocket) !== 'undefined') {\n", | |
" return MozWebSocket;\n", | |
" } else {\n", | |
" alert('Your browser does not have WebSocket support.' +\n", | |
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", | |
" 'Firefox 4 and 5 are also supported but you ' +\n", | |
" 'have to enable WebSockets in about:config.');\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", | |
" this.id = figure_id;\n", | |
"\n", | |
" this.ws = websocket;\n", | |
"\n", | |
" this.supports_binary = (this.ws.binaryType != undefined);\n", | |
"\n", | |
" if (!this.supports_binary) {\n", | |
" var warnings = document.getElementById(\"mpl-warnings\");\n", | |
" if (warnings) {\n", | |
" warnings.style.display = 'block';\n", | |
" warnings.textContent = (\n", | |
" \"This browser does not support binary websocket messages. \" +\n", | |
" \"Performance may be slow.\");\n", | |
" }\n", | |
" }\n", | |
"\n", | |
" this.imageObj = new Image();\n", | |
"\n", | |
" this.context = undefined;\n", | |
" this.message = undefined;\n", | |
" this.canvas = undefined;\n", | |
" this.rubberband_canvas = undefined;\n", | |
" this.rubberband_context = undefined;\n", | |
" this.format_dropdown = undefined;\n", | |
"\n", | |
" this.image_mode = 'full';\n", | |
"\n", | |
" this.root = $('<div/>');\n", | |
" this._root_extra_style(this.root)\n", | |
" this.root.attr('style', 'display: inline-block');\n", | |
"\n", | |
" $(parent_element).append(this.root);\n", | |
"\n", | |
" this._init_header(this);\n", | |
" this._init_canvas(this);\n", | |
" this._init_toolbar(this);\n", | |
"\n", | |
" var fig = this;\n", | |
"\n", | |
" this.waiting = false;\n", | |
"\n", | |
" this.ws.onopen = function () {\n", | |
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", | |
" fig.send_message(\"send_image_mode\", {});\n", | |
" if (mpl.ratio != 1) {\n", | |
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", | |
" }\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" }\n", | |
"\n", | |
" this.imageObj.onload = function() {\n", | |
" if (fig.image_mode == 'full') {\n", | |
" // Full images could contain transparency (where diff images\n", | |
" // almost always do), so we need to clear the canvas so that\n", | |
" // there is no ghosting.\n", | |
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", | |
" }\n", | |
" fig.context.drawImage(fig.imageObj, 0, 0);\n", | |
" };\n", | |
"\n", | |
" this.imageObj.onunload = function() {\n", | |
" this.ws.close();\n", | |
" }\n", | |
"\n", | |
" this.ws.onmessage = this._make_on_message_function(this);\n", | |
"\n", | |
" this.ondownload = ondownload;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_header = function() {\n", | |
" var titlebar = $(\n", | |
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", | |
" 'ui-helper-clearfix\"/>');\n", | |
" var titletext = $(\n", | |
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", | |
" 'text-align: center; padding: 3px;\"/>');\n", | |
" titlebar.append(titletext)\n", | |
" this.root.append(titlebar);\n", | |
" this.header = titletext[0];\n", | |
"}\n", | |
"\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_canvas = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var canvas_div = $('<div/>');\n", | |
"\n", | |
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", | |
"\n", | |
" function canvas_keyboard_event(event) {\n", | |
" return fig.key_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" canvas_div.keydown('key_press', canvas_keyboard_event);\n", | |
" canvas_div.keyup('key_release', canvas_keyboard_event);\n", | |
" this.canvas_div = canvas_div\n", | |
" this._canvas_extra_style(canvas_div)\n", | |
" this.root.append(canvas_div);\n", | |
"\n", | |
" var canvas = $('<canvas/>');\n", | |
" canvas.addClass('mpl-canvas');\n", | |
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", | |
"\n", | |
" this.canvas = canvas[0];\n", | |
" this.context = canvas[0].getContext(\"2d\");\n", | |
"\n", | |
" var backingStore = this.context.backingStorePixelRatio ||\n", | |
"\tthis.context.webkitBackingStorePixelRatio ||\n", | |
"\tthis.context.mozBackingStorePixelRatio ||\n", | |
"\tthis.context.msBackingStorePixelRatio ||\n", | |
"\tthis.context.oBackingStorePixelRatio ||\n", | |
"\tthis.context.backingStorePixelRatio || 1;\n", | |
"\n", | |
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", | |
"\n", | |
" var rubberband = $('<canvas/>');\n", | |
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", | |
"\n", | |
" var pass_mouse_events = true;\n", | |
"\n", | |
" canvas_div.resizable({\n", | |
" start: function(event, ui) {\n", | |
" pass_mouse_events = false;\n", | |
" },\n", | |
" resize: function(event, ui) {\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" stop: function(event, ui) {\n", | |
" pass_mouse_events = true;\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" });\n", | |
"\n", | |
" function mouse_event_fn(event) {\n", | |
" if (pass_mouse_events)\n", | |
" return fig.mouse_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" rubberband.mousedown('button_press', mouse_event_fn);\n", | |
" rubberband.mouseup('button_release', mouse_event_fn);\n", | |
" // Throttle sequential mouse events to 1 every 20ms.\n", | |
" rubberband.mousemove('motion_notify', mouse_event_fn);\n", | |
"\n", | |
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n", | |
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n", | |
"\n", | |
" canvas_div.on(\"wheel\", function (event) {\n", | |
" event = event.originalEvent;\n", | |
" event['data'] = 'scroll'\n", | |
" if (event.deltaY < 0) {\n", | |
" event.step = 1;\n", | |
" } else {\n", | |
" event.step = -1;\n", | |
" }\n", | |
" mouse_event_fn(event);\n", | |
" });\n", | |
"\n", | |
" canvas_div.append(canvas);\n", | |
" canvas_div.append(rubberband);\n", | |
"\n", | |
" this.rubberband = rubberband;\n", | |
" this.rubberband_canvas = rubberband[0];\n", | |
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n", | |
" this.rubberband_context.strokeStyle = \"#000000\";\n", | |
"\n", | |
" this._resize_canvas = function(width, height) {\n", | |
" // Keep the size of the canvas, canvas container, and rubber band\n", | |
" // canvas in synch.\n", | |
" canvas_div.css('width', width)\n", | |
" canvas_div.css('height', height)\n", | |
"\n", | |
" canvas.attr('width', width * mpl.ratio);\n", | |
" canvas.attr('height', height * mpl.ratio);\n", | |
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", | |
"\n", | |
" rubberband.attr('width', width);\n", | |
" rubberband.attr('height', height);\n", | |
" }\n", | |
"\n", | |
" // Set the figure to an initial 600x600px, this will subsequently be updated\n", | |
" // upon first draw.\n", | |
" this._resize_canvas(600, 600);\n", | |
"\n", | |
" // Disable right mouse context menu.\n", | |
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", | |
" return false;\n", | |
" });\n", | |
"\n", | |
" function set_focus () {\n", | |
" canvas.focus();\n", | |
" canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" window.setTimeout(set_focus, 100);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items) {\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) {\n", | |
" // put a spacer in here.\n", | |
" continue;\n", | |
" }\n", | |
" var button = $('<button/>');\n", | |
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", | |
" 'ui-button-icon-only');\n", | |
" button.attr('role', 'button');\n", | |
" button.attr('aria-disabled', 'false');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
"\n", | |
" var icon_img = $('<span/>');\n", | |
" icon_img.addClass('ui-button-icon-primary ui-icon');\n", | |
" icon_img.addClass(image);\n", | |
" icon_img.addClass('ui-corner-all');\n", | |
"\n", | |
" var tooltip_span = $('<span/>');\n", | |
" tooltip_span.addClass('ui-button-text');\n", | |
" tooltip_span.html(tooltip);\n", | |
"\n", | |
" button.append(icon_img);\n", | |
" button.append(tooltip_span);\n", | |
"\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" var fmt_picker_span = $('<span/>');\n", | |
"\n", | |
" var fmt_picker = $('<select/>');\n", | |
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", | |
" fmt_picker_span.append(fmt_picker);\n", | |
" nav_element.append(fmt_picker_span);\n", | |
" this.format_dropdown = fmt_picker[0];\n", | |
"\n", | |
" for (var ind in mpl.extensions) {\n", | |
" var fmt = mpl.extensions[ind];\n", | |
" var option = $(\n", | |
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", | |
" fmt_picker.append(option)\n", | |
" }\n", | |
"\n", | |
" // Add hover states to the ui-buttons\n", | |
" $( \".ui-button\" ).hover(\n", | |
" function() { $(this).addClass(\"ui-state-hover\");},\n", | |
" function() { $(this).removeClass(\"ui-state-hover\");}\n", | |
" );\n", | |
"\n", | |
" var status_bar = $('<span class=\"mpl-message\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", | |
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", | |
" // which will in turn request a refresh of the image.\n", | |
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_message = function(type, properties) {\n", | |
" properties['type'] = type;\n", | |
" properties['figure_id'] = this.id;\n", | |
" this.ws.send(JSON.stringify(properties));\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_draw_message = function() {\n", | |
" if (!this.waiting) {\n", | |
" this.waiting = true;\n", | |
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" var format_dropdown = fig.format_dropdown;\n", | |
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", | |
" fig.ondownload(fig, format);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n", | |
" var size = msg['size'];\n", | |
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", | |
" fig._resize_canvas(size[0], size[1]);\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", | |
" var x0 = msg['x0'] / mpl.ratio;\n", | |
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", | |
" var x1 = msg['x1'] / mpl.ratio;\n", | |
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", | |
" x0 = Math.floor(x0) + 0.5;\n", | |
" y0 = Math.floor(y0) + 0.5;\n", | |
" x1 = Math.floor(x1) + 0.5;\n", | |
" y1 = Math.floor(y1) + 0.5;\n", | |
" var min_x = Math.min(x0, x1);\n", | |
" var min_y = Math.min(y0, y1);\n", | |
" var width = Math.abs(x1 - x0);\n", | |
" var height = Math.abs(y1 - y0);\n", | |
"\n", | |
" fig.rubberband_context.clearRect(\n", | |
" 0, 0, fig.canvas.width, fig.canvas.height);\n", | |
"\n", | |
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n", | |
" // Updates the figure title.\n", | |
" fig.header.textContent = msg['label'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n", | |
" var cursor = msg['cursor'];\n", | |
" switch(cursor)\n", | |
" {\n", | |
" case 0:\n", | |
" cursor = 'pointer';\n", | |
" break;\n", | |
" case 1:\n", | |
" cursor = 'default';\n", | |
" break;\n", | |
" case 2:\n", | |
" cursor = 'crosshair';\n", | |
" break;\n", | |
" case 3:\n", | |
" cursor = 'move';\n", | |
" break;\n", | |
" }\n", | |
" fig.rubberband_canvas.style.cursor = cursor;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_message = function(fig, msg) {\n", | |
" fig.message.textContent = msg['message'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n", | |
" // Request the server to send over a new figure.\n", | |
" fig.send_draw_message();\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n", | |
" fig.image_mode = msg['mode'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Called whenever the canvas gets updated.\n", | |
" this.send_message(\"ack\", {});\n", | |
"}\n", | |
"\n", | |
"// A function to construct a web socket function for onmessage handling.\n", | |
"// Called in the figure constructor.\n", | |
"mpl.figure.prototype._make_on_message_function = function(fig) {\n", | |
" return function socket_on_message(evt) {\n", | |
" if (evt.data instanceof Blob) {\n", | |
" /* FIXME: We get \"Resource interpreted as Image but\n", | |
" * transferred with MIME type text/plain:\" errors on\n", | |
" * Chrome. But how to set the MIME type? It doesn't seem\n", | |
" * to be part of the websocket stream */\n", | |
" evt.data.type = \"image/png\";\n", | |
"\n", | |
" /* Free the memory for the previous frames */\n", | |
" if (fig.imageObj.src) {\n", | |
" (window.URL || window.webkitURL).revokeObjectURL(\n", | |
" fig.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", | |
" evt.data);\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n", | |
" fig.imageObj.src = evt.data;\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var msg = JSON.parse(evt.data);\n", | |
" var msg_type = msg['type'];\n", | |
"\n", | |
" // Call the \"handle_{type}\" callback, which takes\n", | |
" // the figure and JSON message as its only arguments.\n", | |
" try {\n", | |
" var callback = fig[\"handle_\" + msg_type];\n", | |
" } catch (e) {\n", | |
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" if (callback) {\n", | |
" try {\n", | |
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", | |
" callback(fig, msg);\n", | |
" } catch (e) {\n", | |
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n", | |
" }\n", | |
" }\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", | |
"mpl.findpos = function(e) {\n", | |
" //this section is from http://www.quirksmode.org/js/events_properties.html\n", | |
" var targ;\n", | |
" if (!e)\n", | |
" e = window.event;\n", | |
" if (e.target)\n", | |
" targ = e.target;\n", | |
" else if (e.srcElement)\n", | |
" targ = e.srcElement;\n", | |
" if (targ.nodeType == 3) // defeat Safari bug\n", | |
" targ = targ.parentNode;\n", | |
"\n", | |
" // jQuery normalizes the pageX and pageY\n", | |
" // pageX,Y are the mouse positions relative to the document\n", | |
" // offset() returns the position of the element relative to the document\n", | |
" var x = e.pageX - $(targ).offset().left;\n", | |
" var y = e.pageY - $(targ).offset().top;\n", | |
"\n", | |
" return {\"x\": x, \"y\": y};\n", | |
"};\n", | |
"\n", | |
"/*\n", | |
" * return a copy of an object with only non-object keys\n", | |
" * we need this to avoid circular references\n", | |
" * http://stackoverflow.com/a/24161582/3208463\n", | |
" */\n", | |
"function simpleKeys (original) {\n", | |
" return Object.keys(original).reduce(function (obj, key) {\n", | |
" if (typeof original[key] !== 'object')\n", | |
" obj[key] = original[key]\n", | |
" return obj;\n", | |
" }, {});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.mouse_event = function(event, name) {\n", | |
" var canvas_pos = mpl.findpos(event)\n", | |
"\n", | |
" if (name === 'button_press')\n", | |
" {\n", | |
" this.canvas.focus();\n", | |
" this.canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" var x = canvas_pos.x * mpl.ratio;\n", | |
" var y = canvas_pos.y * mpl.ratio;\n", | |
"\n", | |
" this.send_message(name, {x: x, y: y, button: event.button,\n", | |
" step: event.step,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
"\n", | |
" /* This prevents the web browser from automatically changing to\n", | |
" * the text insertion cursor when the button is pressed. We want\n", | |
" * to control all of the cursor setting manually through the\n", | |
" * 'cursor' event from matplotlib */\n", | |
" event.preventDefault();\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" // Handle any extra behaviour associated with a key event\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.key_event = function(event, name) {\n", | |
"\n", | |
" // Prevent repeat events\n", | |
" if (name == 'key_press')\n", | |
" {\n", | |
" if (event.which === this._key)\n", | |
" return;\n", | |
" else\n", | |
" this._key = event.which;\n", | |
" }\n", | |
" if (name == 'key_release')\n", | |
" this._key = null;\n", | |
"\n", | |
" var value = '';\n", | |
" if (event.ctrlKey && event.which != 17)\n", | |
" value += \"ctrl+\";\n", | |
" if (event.altKey && event.which != 18)\n", | |
" value += \"alt+\";\n", | |
" if (event.shiftKey && event.which != 16)\n", | |
" value += \"shift+\";\n", | |
"\n", | |
" value += 'k';\n", | |
" value += event.which.toString();\n", | |
"\n", | |
" this._key_event_extra(event, name);\n", | |
"\n", | |
" this.send_message(name, {key: value,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", | |
" if (name == 'download') {\n", | |
" this.handle_save(this, null);\n", | |
" } else {\n", | |
" this.send_message(\"toolbar_button\", {name: name});\n", | |
" }\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", | |
" this.message.textContent = tooltip;\n", | |
"};\n", | |
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", | |
"\n", | |
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", | |
"\n", | |
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", | |
" // Create a \"websocket\"-like object which calls the given IPython comm\n", | |
" // object with the appropriate methods. Currently this is a non binary\n", | |
" // socket, so there is still some room for performance tuning.\n", | |
" var ws = {};\n", | |
"\n", | |
" ws.close = function() {\n", | |
" comm.close()\n", | |
" };\n", | |
" ws.send = function(m) {\n", | |
" //console.log('sending', m);\n", | |
" comm.send(m);\n", | |
" };\n", | |
" // Register the callback with on_msg.\n", | |
" comm.on_msg(function(msg) {\n", | |
" //console.log('receiving', msg['content']['data'], msg);\n", | |
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", | |
" ws.onmessage(msg['content']['data'])\n", | |
" });\n", | |
" return ws;\n", | |
"}\n", | |
"\n", | |
"mpl.mpl_figure_comm = function(comm, msg) {\n", | |
" // This is the function which gets called when the mpl process\n", | |
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", | |
"\n", | |
" var id = msg.content.data.id;\n", | |
" // Get hold of the div created by the display call when the Comm\n", | |
" // socket was opened in Python.\n", | |
" var element = $(\"#\" + id);\n", | |
" var ws_proxy = comm_websocket_adapter(comm)\n", | |
"\n", | |
" function ondownload(figure, format) {\n", | |
" window.open(figure.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" var fig = new mpl.figure(id, ws_proxy,\n", | |
" ondownload,\n", | |
" element.get(0));\n", | |
"\n", | |
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", | |
" // web socket which is closed, not our websocket->open comm proxy.\n", | |
" ws_proxy.onopen();\n", | |
"\n", | |
" fig.parent_element = element.get(0);\n", | |
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", | |
" if (!fig.cell_info) {\n", | |
" console.error(\"Failed to find cell for figure\", id, fig);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var output_index = fig.cell_info[2]\n", | |
" var cell = fig.cell_info[0];\n", | |
"\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", | |
" var width = fig.canvas.width/mpl.ratio\n", | |
" fig.root.unbind('remove')\n", | |
"\n", | |
" // Update the output cell to use the data from the current canvas.\n", | |
" fig.push_to_output();\n", | |
" var dataURL = fig.canvas.toDataURL();\n", | |
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n", | |
" // the notebook keyboard shortcuts fail.\n", | |
" IPython.keyboard_manager.enable()\n", | |
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n", | |
" fig.close_ws(fig, msg);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.close_ws = function(fig, msg){\n", | |
" fig.send_message('closing', msg);\n", | |
" // fig.ws.close()\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n", | |
" // Turn the data on the canvas into data in the output cell.\n", | |
" var width = this.canvas.width/mpl.ratio\n", | |
" var dataURL = this.canvas.toDataURL();\n", | |
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Tell IPython that the notebook contents must change.\n", | |
" IPython.notebook.set_dirty(true);\n", | |
" this.send_message(\"ack\", {});\n", | |
" var fig = this;\n", | |
" // Wait a second, then push the new image to the DOM so\n", | |
" // that it is saved nicely (might be nice to debounce this).\n", | |
" setTimeout(function () { fig.push_to_output() }, 1000);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items){\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) { continue; };\n", | |
"\n", | |
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" // Add the status bar.\n", | |
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"\n", | |
" // Add the close button to the window.\n", | |
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n", | |
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n", | |
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", | |
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n", | |
" buttongrp.append(button);\n", | |
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", | |
" titlebar.prepend(buttongrp);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(el){\n", | |
" var fig = this\n", | |
" el.on(\"remove\", function(){\n", | |
"\tfig.close_ws(fig, {});\n", | |
" });\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(el){\n", | |
" // this is important to make the div 'focusable\n", | |
" el.attr('tabindex', 0)\n", | |
" // reach out to IPython and tell the keyboard manager to turn it's self\n", | |
" // off when our div gets focus\n", | |
"\n", | |
" // location in version 3\n", | |
" if (IPython.notebook.keyboard_manager) {\n", | |
" IPython.notebook.keyboard_manager.register_events(el);\n", | |
" }\n", | |
" else {\n", | |
" // location in version 2\n", | |
" IPython.keyboard_manager.register_events(el);\n", | |
" }\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" var manager = IPython.notebook.keyboard_manager;\n", | |
" if (!manager)\n", | |
" manager = IPython.keyboard_manager;\n", | |
"\n", | |
" // Check for shift+enter\n", | |
" if (event.shiftKey && event.which == 13) {\n", | |
" this.canvas_div.blur();\n", | |
" // select the cell after this one\n", | |
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", | |
" IPython.notebook.select(index + 1);\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" fig.ondownload(fig, null);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.find_output_cell = function(html_output) {\n", | |
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", | |
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", | |
" // IPython event is triggered only after the cells have been serialised, which for\n", | |
" // our purposes (turning an active figure into a static one), is too late.\n", | |
" var cells = IPython.notebook.get_cells();\n", | |
" var ncells = cells.length;\n", | |
" for (var i=0; i<ncells; i++) {\n", | |
" var cell = cells[i];\n", | |
" if (cell.cell_type === 'code'){\n", | |
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", | |
" var data = cell.output_area.outputs[j];\n", | |
" if (data.data) {\n", | |
" // IPython >= 3 moved mimebundle to data attribute of output\n", | |
" data = data.data;\n", | |
" }\n", | |
" if (data['text/html'] == html_output) {\n", | |
" return [cell, data, j];\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"// Register the function which deals with the matplotlib target/channel.\n", | |
"// The kernel may be null if the page has been refreshed.\n", | |
"if (IPython.notebook.kernel != null) {\n", | |
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", | |
"}\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"<img src=\"data:image/png;base64,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\" width=\"640\">" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"L = 75\n", | |
"field = np.zeros((L, L), dtype=int)\n", | |
"field[L//2, L//2] = 1\n", | |
"\n", | |
"# draw the initial field\n", | |
"fig = plt.figure()\n", | |
"im = plt.imshow(field, animated=True, cmap=plt.get_cmap('Paired'))\n", | |
"\n", | |
"# updater function\n", | |
"def updatefig(*args):\n", | |
" global field\n", | |
" field = evolve2(field, 1.81, 1)\n", | |
" im.set_array(field)\n", | |
" return im,\n", | |
"\n", | |
"# animate!\n", | |
"anim = animation.FuncAnimation(fig, updatefig, frames=200, interval=50, blit=True)\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Timings" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1 loop, best of 3: 345 ms per loop\n" | |
] | |
} | |
], | |
"source": [ | |
"L = 44\n", | |
"field = np.zeros((L, L), dtype=int)\n", | |
"field[L//2, L//2] = 1\n", | |
"\n", | |
"%timeit evolve2(field, 1.81, 10)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": true | |
}, | |
"source": [ | |
"# Enter Cython" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": true | |
}, | |
"source": [ | |
"In class, we started with the original code and did the conversion iteratively, removing yellow lines from the annotated output. Below is only the final result." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"%load_ext cython" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<!DOCTYPE html>\n", | |
"<!-- Generated by Cython 0.25.2 -->\n", | |
"<html>\n", | |
"<head>\n", | |
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n", | |
" <title>Cython: _cython_magic_4a51e9818ff378ac421ff64c016d5995.pyx</title>\n", | |
" <style type=\"text/css\">\n", | |
" \n", | |
"body.cython { font-family: courier; font-size: 12; }\n", | |
"\n", | |
".cython.tag { }\n", | |
".cython.line { margin: 0em }\n", | |
".cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; }\n", | |
"\n", | |
".cython.line .run { background-color: #B0FFB0; }\n", | |
".cython.line .mis { background-color: #FFB0B0; }\n", | |
".cython.code.run { border-left: 8px solid #B0FFB0; }\n", | |
".cython.code.mis { border-left: 8px solid #FFB0B0; }\n", | |
"\n", | |
".cython.code .py_c_api { color: red; }\n", | |
".cython.code .py_macro_api { color: #FF7000; }\n", | |
".cython.code .pyx_c_api { color: #FF3000; }\n", | |
".cython.code .pyx_macro_api { color: #FF7000; }\n", | |
".cython.code .refnanny { color: #FFA000; }\n", | |
".cython.code .trace { color: #FFA000; }\n", | |
".cython.code .error_goto { color: #FFA000; }\n", | |
"\n", | |
".cython.code .coerce { color: #008000; border: 1px dotted #008000 }\n", | |
".cython.code .py_attr { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_attr { color: #0000FF; }\n", | |
".cython.code .py_call { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_call { color: #0000FF; }\n", | |
"\n", | |
".cython.score-0 {background-color: #FFFFff;}\n", | |
".cython.score-1 {background-color: #FFFFe7;}\n", | |
".cython.score-2 {background-color: #FFFFd4;}\n", | |
".cython.score-3 {background-color: #FFFFc4;}\n", | |
".cython.score-4 {background-color: #FFFFb6;}\n", | |
".cython.score-5 {background-color: #FFFFaa;}\n", | |
".cython.score-6 {background-color: #FFFF9f;}\n", | |
".cython.score-7 {background-color: #FFFF96;}\n", | |
".cython.score-8 {background-color: #FFFF8d;}\n", | |
".cython.score-9 {background-color: #FFFF86;}\n", | |
".cython.score-10 {background-color: #FFFF7f;}\n", | |
".cython.score-11 {background-color: #FFFF79;}\n", | |
".cython.score-12 {background-color: #FFFF73;}\n", | |
".cython.score-13 {background-color: #FFFF6e;}\n", | |
".cython.score-14 {background-color: #FFFF6a;}\n", | |
".cython.score-15 {background-color: #FFFF66;}\n", | |
".cython.score-16 {background-color: #FFFF62;}\n", | |
".cython.score-17 {background-color: #FFFF5e;}\n", | |
".cython.score-18 {background-color: #FFFF5b;}\n", | |
".cython.score-19 {background-color: #FFFF57;}\n", | |
".cython.score-20 {background-color: #FFFF55;}\n", | |
".cython.score-21 {background-color: #FFFF52;}\n", | |
".cython.score-22 {background-color: #FFFF4f;}\n", | |
".cython.score-23 {background-color: #FFFF4d;}\n", | |
".cython.score-24 {background-color: #FFFF4b;}\n", | |
".cython.score-25 {background-color: #FFFF48;}\n", | |
".cython.score-26 {background-color: #FFFF46;}\n", | |
".cython.score-27 {background-color: #FFFF44;}\n", | |
".cython.score-28 {background-color: #FFFF43;}\n", | |
".cython.score-29 {background-color: #FFFF41;}\n", | |
".cython.score-30 {background-color: #FFFF3f;}\n", | |
".cython.score-31 {background-color: #FFFF3e;}\n", | |
".cython.score-32 {background-color: #FFFF3c;}\n", | |
".cython.score-33 {background-color: #FFFF3b;}\n", | |
".cython.score-34 {background-color: #FFFF39;}\n", | |
".cython.score-35 {background-color: #FFFF38;}\n", | |
".cython.score-36 {background-color: #FFFF37;}\n", | |
".cython.score-37 {background-color: #FFFF36;}\n", | |
".cython.score-38 {background-color: #FFFF35;}\n", | |
".cython.score-39 {background-color: #FFFF34;}\n", | |
".cython.score-40 {background-color: #FFFF33;}\n", | |
".cython.score-41 {background-color: #FFFF32;}\n", | |
".cython.score-42 {background-color: #FFFF31;}\n", | |
".cython.score-43 {background-color: #FFFF30;}\n", | |
".cython.score-44 {background-color: #FFFF2f;}\n", | |
".cython.score-45 {background-color: #FFFF2e;}\n", | |
".cython.score-46 {background-color: #FFFF2d;}\n", | |
".cython.score-47 {background-color: #FFFF2c;}\n", | |
".cython.score-48 {background-color: #FFFF2b;}\n", | |
".cython.score-49 {background-color: #FFFF2b;}\n", | |
".cython.score-50 {background-color: #FFFF2a;}\n", | |
".cython.score-51 {background-color: #FFFF29;}\n", | |
".cython.score-52 {background-color: #FFFF29;}\n", | |
".cython.score-53 {background-color: #FFFF28;}\n", | |
".cython.score-54 {background-color: #FFFF27;}\n", | |
".cython.score-55 {background-color: #FFFF27;}\n", | |
".cython.score-56 {background-color: #FFFF26;}\n", | |
".cython.score-57 {background-color: #FFFF26;}\n", | |
".cython.score-58 {background-color: #FFFF25;}\n", | |
".cython.score-59 {background-color: #FFFF24;}\n", | |
".cython.score-60 {background-color: #FFFF24;}\n", | |
".cython.score-61 {background-color: #FFFF23;}\n", | |
".cython.score-62 {background-color: #FFFF23;}\n", | |
".cython.score-63 {background-color: #FFFF22;}\n", | |
".cython.score-64 {background-color: #FFFF22;}\n", | |
".cython.score-65 {background-color: #FFFF22;}\n", | |
".cython.score-66 {background-color: #FFFF21;}\n", | |
".cython.score-67 {background-color: #FFFF21;}\n", | |
".cython.score-68 {background-color: #FFFF20;}\n", | |
".cython.score-69 {background-color: #FFFF20;}\n", | |
".cython.score-70 {background-color: #FFFF1f;}\n", | |
".cython.score-71 {background-color: #FFFF1f;}\n", | |
".cython.score-72 {background-color: #FFFF1f;}\n", | |
".cython.score-73 {background-color: #FFFF1e;}\n", | |
".cython.score-74 {background-color: #FFFF1e;}\n", | |
".cython.score-75 {background-color: #FFFF1e;}\n", | |
".cython.score-76 {background-color: #FFFF1d;}\n", | |
".cython.score-77 {background-color: #FFFF1d;}\n", | |
".cython.score-78 {background-color: #FFFF1c;}\n", | |
".cython.score-79 {background-color: #FFFF1c;}\n", | |
".cython.score-80 {background-color: #FFFF1c;}\n", | |
".cython.score-81 {background-color: #FFFF1c;}\n", | |
".cython.score-82 {background-color: #FFFF1b;}\n", | |
".cython.score-83 {background-color: #FFFF1b;}\n", | |
".cython.score-84 {background-color: #FFFF1b;}\n", | |
".cython.score-85 {background-color: #FFFF1a;}\n", | |
".cython.score-86 {background-color: #FFFF1a;}\n", | |
".cython.score-87 {background-color: #FFFF1a;}\n", | |
".cython.score-88 {background-color: #FFFF1a;}\n", | |
".cython.score-89 {background-color: #FFFF19;}\n", | |
".cython.score-90 {background-color: #FFFF19;}\n", | |
".cython.score-91 {background-color: #FFFF19;}\n", | |
".cython.score-92 {background-color: #FFFF19;}\n", | |
".cython.score-93 {background-color: #FFFF18;}\n", | |
".cython.score-94 {background-color: #FFFF18;}\n", | |
".cython.score-95 {background-color: #FFFF18;}\n", | |
".cython.score-96 {background-color: #FFFF18;}\n", | |
".cython.score-97 {background-color: #FFFF17;}\n", | |
".cython.score-98 {background-color: #FFFF17;}\n", | |
".cython.score-99 {background-color: #FFFF17;}\n", | |
".cython.score-100 {background-color: #FFFF17;}\n", | |
".cython.score-101 {background-color: #FFFF16;}\n", | |
".cython.score-102 {background-color: #FFFF16;}\n", | |
".cython.score-103 {background-color: #FFFF16;}\n", | |
".cython.score-104 {background-color: #FFFF16;}\n", | |
".cython.score-105 {background-color: #FFFF16;}\n", | |
".cython.score-106 {background-color: #FFFF15;}\n", | |
".cython.score-107 {background-color: #FFFF15;}\n", | |
".cython.score-108 {background-color: #FFFF15;}\n", | |
".cython.score-109 {background-color: #FFFF15;}\n", | |
".cython.score-110 {background-color: #FFFF15;}\n", | |
".cython.score-111 {background-color: #FFFF15;}\n", | |
".cython.score-112 {background-color: #FFFF14;}\n", | |
".cython.score-113 {background-color: #FFFF14;}\n", | |
".cython.score-114 {background-color: #FFFF14;}\n", | |
".cython.score-115 {background-color: #FFFF14;}\n", | |
".cython.score-116 {background-color: #FFFF14;}\n", | |
".cython.score-117 {background-color: #FFFF14;}\n", | |
".cython.score-118 {background-color: #FFFF13;}\n", | |
".cython.score-119 {background-color: #FFFF13;}\n", | |
".cython.score-120 {background-color: #FFFF13;}\n", | |
".cython.score-121 {background-color: #FFFF13;}\n", | |
".cython.score-122 {background-color: #FFFF13;}\n", | |
".cython.score-123 {background-color: #FFFF13;}\n", | |
".cython.score-124 {background-color: #FFFF13;}\n", | |
".cython.score-125 {background-color: #FFFF12;}\n", | |
".cython.score-126 {background-color: #FFFF12;}\n", | |
".cython.score-127 {background-color: #FFFF12;}\n", | |
".cython.score-128 {background-color: #FFFF12;}\n", | |
".cython.score-129 {background-color: #FFFF12;}\n", | |
".cython.score-130 {background-color: #FFFF12;}\n", | |
".cython.score-131 {background-color: #FFFF12;}\n", | |
".cython.score-132 {background-color: #FFFF11;}\n", | |
".cython.score-133 {background-color: #FFFF11;}\n", | |
".cython.score-134 {background-color: #FFFF11;}\n", | |
".cython.score-135 {background-color: #FFFF11;}\n", | |
".cython.score-136 {background-color: #FFFF11;}\n", | |
".cython.score-137 {background-color: #FFFF11;}\n", | |
".cython.score-138 {background-color: #FFFF11;}\n", | |
".cython.score-139 {background-color: #FFFF11;}\n", | |
".cython.score-140 {background-color: #FFFF11;}\n", | |
".cython.score-141 {background-color: #FFFF10;}\n", | |
".cython.score-142 {background-color: #FFFF10;}\n", | |
".cython.score-143 {background-color: #FFFF10;}\n", | |
".cython.score-144 {background-color: #FFFF10;}\n", | |
".cython.score-145 {background-color: #FFFF10;}\n", | |
".cython.score-146 {background-color: #FFFF10;}\n", | |
".cython.score-147 {background-color: #FFFF10;}\n", | |
".cython.score-148 {background-color: #FFFF10;}\n", | |
".cython.score-149 {background-color: #FFFF10;}\n", | |
".cython.score-150 {background-color: #FFFF0f;}\n", | |
".cython.score-151 {background-color: #FFFF0f;}\n", | |
".cython.score-152 {background-color: #FFFF0f;}\n", | |
".cython.score-153 {background-color: #FFFF0f;}\n", | |
".cython.score-154 {background-color: #FFFF0f;}\n", | |
".cython.score-155 {background-color: #FFFF0f;}\n", | |
".cython.score-156 {background-color: #FFFF0f;}\n", | |
".cython.score-157 {background-color: #FFFF0f;}\n", | |
".cython.score-158 {background-color: #FFFF0f;}\n", | |
".cython.score-159 {background-color: #FFFF0f;}\n", | |
".cython.score-160 {background-color: #FFFF0f;}\n", | |
".cython.score-161 {background-color: #FFFF0e;}\n", | |
".cython.score-162 {background-color: #FFFF0e;}\n", | |
".cython.score-163 {background-color: #FFFF0e;}\n", | |
".cython.score-164 {background-color: #FFFF0e;}\n", | |
".cython.score-165 {background-color: #FFFF0e;}\n", | |
".cython.score-166 {background-color: #FFFF0e;}\n", | |
".cython.score-167 {background-color: #FFFF0e;}\n", | |
".cython.score-168 {background-color: #FFFF0e;}\n", | |
".cython.score-169 {background-color: #FFFF0e;}\n", | |
".cython.score-170 {background-color: #FFFF0e;}\n", | |
".cython.score-171 {background-color: #FFFF0e;}\n", | |
".cython.score-172 {background-color: #FFFF0e;}\n", | |
".cython.score-173 {background-color: #FFFF0d;}\n", | |
".cython.score-174 {background-color: #FFFF0d;}\n", | |
".cython.score-175 {background-color: #FFFF0d;}\n", | |
".cython.score-176 {background-color: #FFFF0d;}\n", | |
".cython.score-177 {background-color: #FFFF0d;}\n", | |
".cython.score-178 {background-color: #FFFF0d;}\n", | |
".cython.score-179 {background-color: #FFFF0d;}\n", | |
".cython.score-180 {background-color: #FFFF0d;}\n", | |
".cython.score-181 {background-color: #FFFF0d;}\n", | |
".cython.score-182 {background-color: #FFFF0d;}\n", | |
".cython.score-183 {background-color: #FFFF0d;}\n", | |
".cython.score-184 {background-color: #FFFF0d;}\n", | |
".cython.score-185 {background-color: #FFFF0d;}\n", | |
".cython.score-186 {background-color: #FFFF0d;}\n", | |
".cython.score-187 {background-color: #FFFF0c;}\n", | |
".cython.score-188 {background-color: #FFFF0c;}\n", | |
".cython.score-189 {background-color: #FFFF0c;}\n", | |
".cython.score-190 {background-color: #FFFF0c;}\n", | |
".cython.score-191 {background-color: #FFFF0c;}\n", | |
".cython.score-192 {background-color: #FFFF0c;}\n", | |
".cython.score-193 {background-color: #FFFF0c;}\n", | |
".cython.score-194 {background-color: #FFFF0c;}\n", | |
".cython.score-195 {background-color: #FFFF0c;}\n", | |
".cython.score-196 {background-color: #FFFF0c;}\n", | |
".cython.score-197 {background-color: #FFFF0c;}\n", | |
".cython.score-198 {background-color: #FFFF0c;}\n", | |
".cython.score-199 {background-color: #FFFF0c;}\n", | |
".cython.score-200 {background-color: #FFFF0c;}\n", | |
".cython.score-201 {background-color: #FFFF0c;}\n", | |
".cython.score-202 {background-color: #FFFF0c;}\n", | |
".cython.score-203 {background-color: #FFFF0b;}\n", | |
".cython.score-204 {background-color: #FFFF0b;}\n", | |
".cython.score-205 {background-color: #FFFF0b;}\n", | |
".cython.score-206 {background-color: #FFFF0b;}\n", | |
".cython.score-207 {background-color: #FFFF0b;}\n", | |
".cython.score-208 {background-color: #FFFF0b;}\n", | |
".cython.score-209 {background-color: #FFFF0b;}\n", | |
".cython.score-210 {background-color: #FFFF0b;}\n", | |
".cython.score-211 {background-color: #FFFF0b;}\n", | |
".cython.score-212 {background-color: #FFFF0b;}\n", | |
".cython.score-213 {background-color: #FFFF0b;}\n", | |
".cython.score-214 {background-color: #FFFF0b;}\n", | |
".cython.score-215 {background-color: #FFFF0b;}\n", | |
".cython.score-216 {background-color: #FFFF0b;}\n", | |
".cython.score-217 {background-color: #FFFF0b;}\n", | |
".cython.score-218 {background-color: #FFFF0b;}\n", | |
".cython.score-219 {background-color: #FFFF0b;}\n", | |
".cython.score-220 {background-color: #FFFF0b;}\n", | |
".cython.score-221 {background-color: #FFFF0b;}\n", | |
".cython.score-222 {background-color: #FFFF0a;}\n", | |
".cython.score-223 {background-color: #FFFF0a;}\n", | |
".cython.score-224 {background-color: #FFFF0a;}\n", | |
".cython.score-225 {background-color: #FFFF0a;}\n", | |
".cython.score-226 {background-color: #FFFF0a;}\n", | |
".cython.score-227 {background-color: #FFFF0a;}\n", | |
".cython.score-228 {background-color: #FFFF0a;}\n", | |
".cython.score-229 {background-color: #FFFF0a;}\n", | |
".cython.score-230 {background-color: #FFFF0a;}\n", | |
".cython.score-231 {background-color: #FFFF0a;}\n", | |
".cython.score-232 {background-color: #FFFF0a;}\n", | |
".cython.score-233 {background-color: #FFFF0a;}\n", | |
".cython.score-234 {background-color: #FFFF0a;}\n", | |
".cython.score-235 {background-color: #FFFF0a;}\n", | |
".cython.score-236 {background-color: #FFFF0a;}\n", | |
".cython.score-237 {background-color: #FFFF0a;}\n", | |
".cython.score-238 {background-color: #FFFF0a;}\n", | |
".cython.score-239 {background-color: #FFFF0a;}\n", | |
".cython.score-240 {background-color: #FFFF0a;}\n", | |
".cython.score-241 {background-color: #FFFF0a;}\n", | |
".cython.score-242 {background-color: #FFFF0a;}\n", | |
".cython.score-243 {background-color: #FFFF0a;}\n", | |
".cython.score-244 {background-color: #FFFF0a;}\n", | |
".cython.score-245 {background-color: #FFFF0a;}\n", | |
".cython.score-246 {background-color: #FFFF09;}\n", | |
".cython.score-247 {background-color: #FFFF09;}\n", | |
".cython.score-248 {background-color: #FFFF09;}\n", | |
".cython.score-249 {background-color: #FFFF09;}\n", | |
".cython.score-250 {background-color: #FFFF09;}\n", | |
".cython.score-251 {background-color: #FFFF09;}\n", | |
".cython.score-252 {background-color: #FFFF09;}\n", | |
".cython.score-253 {background-color: #FFFF09;}\n", | |
".cython.score-254 {background-color: #FFFF09;}\n", | |
".cython .hll { background-color: #ffffcc }\n", | |
".cython { background: #f8f8f8; }\n", | |
".cython .c { color: #408080; font-style: italic } /* Comment */\n", | |
".cython .err { border: 1px solid #FF0000 } /* Error */\n", | |
".cython .k { color: #008000; font-weight: bold } /* Keyword */\n", | |
".cython .o { color: #666666 } /* Operator */\n", | |
".cython .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n", | |
".cython .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n", | |
".cython .cp { color: #BC7A00 } /* Comment.Preproc */\n", | |
".cython .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n", | |
".cython .c1 { color: #408080; font-style: italic } /* Comment.Single */\n", | |
".cython .cs { color: #408080; font-style: italic } /* Comment.Special */\n", | |
".cython .gd { color: #A00000 } /* Generic.Deleted */\n", | |
".cython .ge { font-style: italic } /* Generic.Emph */\n", | |
".cython .gr { color: #FF0000 } /* Generic.Error */\n", | |
".cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n", | |
".cython .gi { color: #00A000 } /* Generic.Inserted */\n", | |
".cython .go { color: #888888 } /* Generic.Output */\n", | |
".cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n", | |
".cython .gs { font-weight: bold } /* Generic.Strong */\n", | |
".cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n", | |
".cython .gt { color: #0044DD } /* Generic.Traceback */\n", | |
".cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n", | |
".cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n", | |
".cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n", | |
".cython .kp { color: #008000 } /* Keyword.Pseudo */\n", | |
".cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n", | |
".cython .kt { color: #B00040 } /* Keyword.Type */\n", | |
".cython .m { color: #666666 } /* Literal.Number */\n", | |
".cython .s { color: #BA2121 } /* Literal.String */\n", | |
".cython .na { color: #7D9029 } /* Name.Attribute */\n", | |
".cython .nb { color: #008000 } /* Name.Builtin */\n", | |
".cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n", | |
".cython .no { color: #880000 } /* Name.Constant */\n", | |
".cython .nd { color: #AA22FF } /* Name.Decorator */\n", | |
".cython .ni { color: #999999; font-weight: bold } /* Name.Entity */\n", | |
".cython .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n", | |
".cython .nf { color: #0000FF } /* Name.Function */\n", | |
".cython .nl { color: #A0A000 } /* Name.Label */\n", | |
".cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n", | |
".cython .nt { color: #008000; font-weight: bold } /* Name.Tag */\n", | |
".cython .nv { color: #19177C } /* Name.Variable */\n", | |
".cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n", | |
".cython .w { color: #bbbbbb } /* Text.Whitespace */\n", | |
".cython .mb { color: #666666 } /* Literal.Number.Bin */\n", | |
".cython .mf { color: #666666 } /* Literal.Number.Float */\n", | |
".cython .mh { color: #666666 } /* Literal.Number.Hex */\n", | |
".cython .mi { color: #666666 } /* Literal.Number.Integer */\n", | |
".cython .mo { color: #666666 } /* Literal.Number.Oct */\n", | |
".cython .sa { color: #BA2121 } /* Literal.String.Affix */\n", | |
".cython .sb { color: #BA2121 } /* Literal.String.Backtick */\n", | |
".cython .sc { color: #BA2121 } /* Literal.String.Char */\n", | |
".cython .dl { color: #BA2121 } /* Literal.String.Delimiter */\n", | |
".cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n", | |
".cython .s2 { color: #BA2121 } /* Literal.String.Double */\n", | |
".cython .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n", | |
".cython .sh { color: #BA2121 } /* Literal.String.Heredoc */\n", | |
".cython .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n", | |
".cython .sx { color: #008000 } /* Literal.String.Other */\n", | |
".cython .sr { color: #BB6688 } /* Literal.String.Regex */\n", | |
".cython .s1 { color: #BA2121 } /* Literal.String.Single */\n", | |
".cython .ss { color: #19177C } /* Literal.String.Symbol */\n", | |
".cython .bp { color: #008000 } /* Name.Builtin.Pseudo */\n", | |
".cython .fm { color: #0000FF } /* Name.Function.Magic */\n", | |
".cython .vc { color: #19177C } /* Name.Variable.Class */\n", | |
".cython .vg { color: #19177C } /* Name.Variable.Global */\n", | |
".cython .vi { color: #19177C } /* Name.Variable.Instance */\n", | |
".cython .vm { color: #19177C } /* Name.Variable.Magic */\n", | |
".cython .il { color: #666666 } /* Literal.Number.Integer.Long */\n", | |
" </style>\n", | |
" <script>\n", | |
" function toggleDiv(id) {\n", | |
" theDiv = id.nextElementSibling\n", | |
" if (theDiv.style.display != 'block') theDiv.style.display = 'block';\n", | |
" else theDiv.style.display = 'none';\n", | |
" }\n", | |
" </script>\n", | |
"</head>\n", | |
"<body class=\"cython\">\n", | |
"<p><span style=\"border-bottom: solid 1px grey;\">Generated by Cython 0.25.2</span></p>\n", | |
"<p>\n", | |
" <span style=\"background-color: #FFFF00\">Yellow lines</span> hint at Python interaction.<br />\n", | |
" Click on a line that starts with a \"<code>+</code>\" to see the C code that Cython generated for it.\n", | |
"</p>\n", | |
"<div class=\"cython\"><pre class=\"cython line score-0\"> <span class=\"\">01</span>: </pre>\n", | |
"<pre class=\"cython line score-19\" onclick='toggleDiv(this)'>+<span class=\"\">02</span>: <span class=\"k\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n", | |
"<pre class='cython code score-19 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"/* … */\n", | |
" __pyx_t_1 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">03</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">04</span>: <span class=\"k\">import</span> <span class=\"nn\">cython</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">05</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">06</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">cdivision</span><span class=\"p\">(</span><span class=\"bp\">True</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">07</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">boundscheck</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-75\" onclick='toggleDiv(this)'>+<span class=\"\">08</span>: <span class=\"k\">def</span> <span class=\"nf\">evolve2_1</span><span class=\"p\">(</span><span class=\"nb\">long</span><span class=\"p\">[:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">field</span><span class=\"p\">,</span> <span class=\"n\">double</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"nb\">int</span> <span class=\"n\">num_steps</span><span class=\"o\">=</span><span class=\"mf\">1</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-75 '>/* Python wrapper */\n", | |
"static PyObject *__pyx_pw_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_1evolve2_1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", | |
"static PyMethodDef __pyx_mdef_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_1evolve2_1 = {\"evolve2_1\", (PyCFunction)__pyx_pw_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_1evolve2_1, METH_VARARGS|METH_KEYWORDS, 0};\n", | |
"static PyObject *__pyx_pw_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_1evolve2_1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", | |
" __Pyx_memviewslice __pyx_v_field = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" double __pyx_v_b;\n", | |
" int __pyx_v_num_steps;\n", | |
" PyObject *__pyx_r = 0;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"evolve2_1 (wrapper)\", 0);\n", | |
" {\n", | |
" static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_field,&__pyx_n_s_b,&__pyx_n_s_num_steps,0};\n", | |
" PyObject* values[3] = {0,0,0};\n", | |
" if (unlikely(__pyx_kwds)) {\n", | |
" Py_ssize_t kw_args;\n", | |
" const Py_ssize_t pos_args = <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args);\n", | |
" switch (pos_args) {\n", | |
" case 3: values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" case 1: values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" case 0: break;\n", | |
" default: goto __pyx_L5_argtuple_error;\n", | |
" }\n", | |
" kw_args = <span class='py_c_api'>PyDict_Size</span>(__pyx_kwds);\n", | |
" switch (pos_args) {\n", | |
" case 0:\n", | |
" if (likely((values[0] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_field)) != 0)) kw_args--;\n", | |
" else goto __pyx_L5_argtuple_error;\n", | |
" case 1:\n", | |
" if (likely((values[1] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"evolve2_1\", 0, 2, 3, 1); __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" }\n", | |
" case 2:\n", | |
" if (kw_args > 0) {\n", | |
" PyObject* value = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_num_steps);\n", | |
" if (value) { values[2] = value; kw_args--; }\n", | |
" }\n", | |
" }\n", | |
" if (unlikely(kw_args > 0)) {\n", | |
" if (unlikely(<span class='pyx_c_api'>__Pyx_ParseOptionalKeywords</span>(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"evolve2_1\") < 0)) __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" }\n", | |
" } else {\n", | |
" switch (<span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)) {\n", | |
" case 3: values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" break;\n", | |
" default: goto __pyx_L5_argtuple_error;\n", | |
" }\n", | |
" }\n", | |
" __pyx_v_field = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_long</span>(values[0]); if (unlikely(!__pyx_v_field.memview)) __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" __pyx_v_b = __pyx_<span class='py_c_api'>PyFloat_AsDouble</span>(values[1]); if (unlikely((__pyx_v_b == (double)-1) && <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" if (values[2]) {\n", | |
" __pyx_v_num_steps = <span class='pyx_c_api'>__Pyx_PyInt_As_int</span>(values[2]); if (unlikely((__pyx_v_num_steps == (int)-1) && <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" } else {\n", | |
" __pyx_v_num_steps = ((int)1);\n", | |
" }\n", | |
" }\n", | |
" goto __pyx_L4_argument_unpacking_done;\n", | |
" __pyx_L5_argtuple_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"evolve2_1\", 0, 2, 3, <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)); __PYX_ERR(0, 8, __pyx_L3_error)\n", | |
" __pyx_L3_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_4a51e9818ff378ac421ff64c016d5995.evolve2_1\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return NULL;\n", | |
" __pyx_L4_argument_unpacking_done:;\n", | |
" __pyx_r = __pyx_pf_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_evolve2_1(__pyx_self, __pyx_v_field, __pyx_v_b, __pyx_v_num_steps);\n", | |
"\n", | |
" /* function exit code */\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"\n", | |
"static PyObject *__pyx_pf_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_evolve2_1(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_field, double __pyx_v_b, int __pyx_v_num_steps) {\n", | |
" int __pyx_v_x;\n", | |
" int __pyx_v_y;\n", | |
" int __pyx_v_L;\n", | |
" int __pyx_v_i;\n", | |
" int __pyx_v_j;\n", | |
" int __pyx_v_ix;\n", | |
" int __pyx_v_jy;\n", | |
" CYTHON_UNUSED int __pyx_v_step;\n", | |
" __Pyx_memviewslice __pyx_v_scores = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v__zeros = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_current = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" int __pyx_v_bestX;\n", | |
" int __pyx_v_bestY;\n", | |
" PyObject *__pyx_r = NULL;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"evolve2_1\", 0);\n", | |
"/* … */\n", | |
" /* function exit code */\n", | |
" __pyx_L1_error:;\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_4);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_4a51e9818ff378ac421ff64c016d5995.evolve2_1\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" __pyx_r = NULL;\n", | |
" __pyx_L0:;\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_scores, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v__zeros, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_current, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_field, 1);\n", | |
" <span class='refnanny'>__Pyx_XGIVEREF</span>(__pyx_r);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"/* … */\n", | |
" __pyx_tuple__14 = <span class='py_c_api'>PyTuple_Pack</span>(16, __pyx_n_s_field, __pyx_n_s_b, __pyx_n_s_num_steps, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_L, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_ix, __pyx_n_s_jy, __pyx_n_s_step, __pyx_n_s_scores, __pyx_n_s_zeros_2, __pyx_n_s_current, __pyx_n_s_bestX, __pyx_n_s_bestY); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 8, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_tuple__14);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_tuple__14);\n", | |
"/* … */\n", | |
" __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_4a51e9818ff378ac421ff64c016d5995_1evolve2_1, NULL, __pyx_n_s_cython_magic_4a51e9818ff378ac42); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_evolve2_1, __pyx_t_1) < 0) __PYX_ERR(0, 8, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_codeobj__15 = (PyObject*)<span class='pyx_c_api'>__Pyx_PyCode_New</span>(3, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_br_cache_ipython_cython__c, __pyx_n_s_evolve2_1, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 8, __pyx_L1_error)\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">09</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">10</span>: <span class=\"k\">cdef</span> <span class=\"kt\">int</span> <span class=\"nf\">x</span><span class=\"p\">,</span> <span class=\"nf\">y</span><span class=\"p\">,</span> <span class=\"nf\">L</span><span class=\"p\">,</span> <span class=\"nf\">i</span><span class=\"p\">,</span> <span class=\"nf\">j</span><span class=\"p\">,</span> <span class=\"nf\">ix</span><span class=\"p\">,</span> <span class=\"nf\">jy</span><span class=\"p\">,</span> <span class=\"nf\">step</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">11</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">12</span>: <span class=\"n\">L</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_L = (__pyx_v_field.shape[0]);\n", | |
"</pre><pre class=\"cython line score-40\" onclick='toggleDiv(this)'>+<span class=\"\">13</span>: <span class=\"k\">cdef</span> <span class=\"kt\">double</span>[<span class=\"p\">:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">scores</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">L</span><span class=\"p\">,</span> <span class=\"n\">L</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-40 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyInt_From_int</span>(__pyx_v_L); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyInt_From_int</span>(__pyx_v_L); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_1);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_3);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 1, __pyx_t_3);\n", | |
" __pyx_t_1 = 0;\n", | |
" __pyx_t_3 = 0;\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_4);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_4);\n", | |
" __pyx_t_4 = 0;\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_4, __pyx_n_s_dtype, ((PyObject *)(&PyFloat_Type))) < 0) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_double</span>(__pyx_t_1);\n", | |
" if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_v_scores = __pyx_t_5;\n", | |
" __pyx_t_5.memview = NULL;\n", | |
" __pyx_t_5.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">14</span>: </pre>\n", | |
"<pre class=\"cython line score-40\" onclick='toggleDiv(this)'>+<span class=\"\">15</span>: <span class=\"k\">cdef</span> <span class=\"kt\">double</span>[<span class=\"p\">:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">_zeros</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">L</span><span class=\"p\">,</span> <span class=\"n\">L</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-40 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyInt_From_int</span>(__pyx_v_L); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyInt_From_int</span>(__pyx_v_L); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyTuple_New</span>(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 0, __pyx_t_1);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_3);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 1, __pyx_t_3);\n", | |
" __pyx_t_1 = 0;\n", | |
" __pyx_t_3 = 0;\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_2);\n", | |
" __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_2, __pyx_n_s_dtype, ((PyObject *)(&PyFloat_Type))) < 0) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_double</span>(__pyx_t_1);\n", | |
" if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 15, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_v__zeros = __pyx_t_5;\n", | |
" __pyx_t_5.memview = NULL;\n", | |
" __pyx_t_5.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">16</span>: <span class=\"k\">cdef</span> <span class=\"kt\">long</span>[<span class=\"p\">:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_6 = __pyx_memoryview_copy_slice_d_dc_long_c(__pyx_v_field); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 16, __pyx_L1_error)\n", | |
" __pyx_v_current = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">17</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">18</span>: <span class=\"k\">for</span> <span class=\"n\">step</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_steps</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_7 = __pyx_v_num_steps;\n", | |
" for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {\n", | |
" __pyx_v_step = __pyx_t_8;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">19</span>: <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_6 = __pyx_memoryview_copy_slice_d_dc_long_c(__pyx_v_field); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 19, __pyx_L1_error)\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_current, 1);\n", | |
" __pyx_v_current = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">20</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"o\">...</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">_zeros</span></pre>\n", | |
"<pre class='cython code score-0 '> if (unlikely(__pyx_memoryview_copy_contents(__pyx_v__zeros, __pyx_v_scores, 2, 2, 0) < 0)) __PYX_ERR(0, 20, __pyx_L1_error)\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">21</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">22</span>: <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_9 = __pyx_v_L;\n", | |
" for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {\n", | |
" __pyx_v_x = __pyx_t_10;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">23</span>: <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_11 = __pyx_v_L;\n", | |
" for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {\n", | |
" __pyx_v_y = __pyx_t_12;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">24</span>: <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_13 = -1L; __pyx_t_13 < 2; __pyx_t_13+=1) {\n", | |
" __pyx_v_i = __pyx_t_13;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">25</span>: <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_14 = -1L; __pyx_t_14 < 2; __pyx_t_14+=1) {\n", | |
" __pyx_v_j = __pyx_t_14;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">26</span>: <span class=\"n\">ix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_ix = ((__pyx_v_x + __pyx_v_i) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">27</span>: <span class=\"n\">jy</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_jy = ((__pyx_v_y + __pyx_v_j) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">28</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"p\">(</span><span class=\"mf\">1</span> <span class=\"o\">-</span> <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">ix</span><span class=\"p\">,</span> <span class=\"n\">jy</span><span class=\"p\">])</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_15 = __pyx_v_ix;\n", | |
" __pyx_t_16 = __pyx_v_jy;\n", | |
" if (__pyx_t_15 < 0) __pyx_t_15 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_field.shape[1];\n", | |
" __pyx_t_17 = __pyx_v_x;\n", | |
" __pyx_t_18 = __pyx_v_y;\n", | |
" if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_scores.shape[1];\n", | |
" *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_17 * __pyx_v_scores.strides[0]) )) + __pyx_t_18)) )) += (1 - (*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_15 * __pyx_v_field.strides[0]) )) + __pyx_t_16)) ))));\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">29</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">30</span>: <span class=\"k\">if</span> <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mf\">1</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_19 = __pyx_v_x;\n", | |
" __pyx_t_20 = __pyx_v_y;\n", | |
" if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_v_field.shape[1];\n", | |
" __pyx_t_21 = (((*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_19 * __pyx_v_field.strides[0]) )) + __pyx_t_20)) ))) == 1) != 0);\n", | |
" if (__pyx_t_21) {\n", | |
"/* … */\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">31</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">*=</span> <span class=\"n\">b</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_22 = __pyx_v_x;\n", | |
" __pyx_t_23 = __pyx_v_y;\n", | |
" if (__pyx_t_22 < 0) __pyx_t_22 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_23 < 0) __pyx_t_23 += __pyx_v_scores.shape[1];\n", | |
" *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_22 * __pyx_v_scores.strides[0]) )) + __pyx_t_23)) )) *= __pyx_v_b;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">32</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">33</span>: <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_9 = __pyx_v_L;\n", | |
" for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {\n", | |
" __pyx_v_x = __pyx_t_10;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">34</span>: <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_11 = __pyx_v_L;\n", | |
" for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {\n", | |
" __pyx_v_y = __pyx_t_12;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">35</span>: <span class=\"n\">bestX</span> <span class=\"o\">=</span> <span class=\"n\">x</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestX = __pyx_v_x;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">36</span>: <span class=\"n\">bestY</span> <span class=\"o\">=</span> <span class=\"n\">y</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestY = __pyx_v_y;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">37</span>: <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_13 = -1L; __pyx_t_13 < 2; __pyx_t_13+=1) {\n", | |
" __pyx_v_i = __pyx_t_13;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">38</span>: <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_14 = -1L; __pyx_t_14 < 2; __pyx_t_14+=1) {\n", | |
" __pyx_v_j = __pyx_t_14;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">39</span>: <span class=\"n\">ix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_ix = ((__pyx_v_x + __pyx_v_i) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">40</span>: <span class=\"n\">jy</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_jy = ((__pyx_v_y + __pyx_v_j) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">41</span>: <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">bestX</span><span class=\"p\">,</span> <span class=\"n\">bestY</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">ix</span><span class=\"p\">,</span> <span class=\"n\">jy</span><span class=\"p\">]):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_24 = __pyx_v_bestX;\n", | |
" __pyx_t_25 = __pyx_v_bestY;\n", | |
" if (__pyx_t_24 < 0) __pyx_t_24 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_25 < 0) __pyx_t_25 += __pyx_v_scores.shape[1];\n", | |
" __pyx_t_26 = __pyx_v_ix;\n", | |
" __pyx_t_27 = __pyx_v_jy;\n", | |
" if (__pyx_t_26 < 0) __pyx_t_26 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_27 < 0) __pyx_t_27 += __pyx_v_scores.shape[1];\n", | |
" __pyx_t_21 = (((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_24 * __pyx_v_scores.strides[0]) )) + __pyx_t_25)) ))) < (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_26 * __pyx_v_scores.strides[0]) )) + __pyx_t_27)) )))) != 0);\n", | |
" if (__pyx_t_21) {\n", | |
"/* … */\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">42</span>: <span class=\"n\">bestX</span> <span class=\"o\">=</span> <span class=\"n\">ix</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestX = __pyx_v_ix;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">43</span>: <span class=\"n\">bestY</span> <span class=\"o\">=</span> <span class=\"n\">jy</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestY = __pyx_v_jy;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">44</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">45</span>: <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">current</span><span class=\"p\">[</span><span class=\"n\">bestX</span><span class=\"p\">,</span> <span class=\"n\">bestY</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_28 = __pyx_v_bestX;\n", | |
" __pyx_t_29 = __pyx_v_bestY;\n", | |
" if (__pyx_t_28 < 0) __pyx_t_28 += __pyx_v_current.shape[0];\n", | |
" if (__pyx_t_29 < 0) __pyx_t_29 += __pyx_v_current.shape[1];\n", | |
" __pyx_t_30 = __pyx_v_x;\n", | |
" __pyx_t_31 = __pyx_v_y;\n", | |
" if (__pyx_t_30 < 0) __pyx_t_30 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_31 < 0) __pyx_t_31 += __pyx_v_field.shape[1];\n", | |
" *((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_30 * __pyx_v_field.strides[0]) )) + __pyx_t_31)) )) = (*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_current.data + __pyx_t_28 * __pyx_v_current.strides[0]) )) + __pyx_t_29)) )));\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-1\" onclick='toggleDiv(this)'>+<span class=\"\">46</span>: <span class=\"k\">return</span> <span class=\"n\">field</span></pre>\n", | |
"<pre class='cython code score-1 '> <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_r);\n", | |
" __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_field, 2, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_r = __pyx_t_1;\n", | |
" __pyx_t_1 = 0;\n", | |
" goto __pyx_L0;\n", | |
"</pre></div></body></html>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%%cython -a\n", | |
"\n", | |
"import numpy as np\n", | |
"\n", | |
"import cython\n", | |
"\n", | |
"@cython.cdivision(True)\n", | |
"@cython.boundscheck(False)\n", | |
"def evolve2_1(long[:, ::1] field, double b, int num_steps=1):\n", | |
" \n", | |
" cdef int x, y, L, i, j, ix, jy, step\n", | |
" \n", | |
" L = field.shape[0]\n", | |
" cdef double[:, ::1] scores = np.zeros((L, L), dtype=float)\n", | |
" \n", | |
" cdef double[:, ::1] _zeros = np.zeros((L, L), dtype=float)\n", | |
" cdef long[:, ::1] current = field.copy()\n", | |
" \n", | |
" for step in range(num_steps):\n", | |
" current = field.copy()\n", | |
" scores[...] = _zeros\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" scores[x, y] += (1 - field[ix, jy])\n", | |
" \n", | |
" if field[x, y] == 1:\n", | |
" scores[x, y] *= b\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" bestX = x\n", | |
" bestY = y\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" if (scores[bestX, bestY] < scores[ix, jy]):\n", | |
" bestX = ix\n", | |
" bestY = jy\n", | |
" \n", | |
" field[x, y] = current[bestX, bestY]\n", | |
" return field" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"100 loops, best of 3: 1.98 ms per loop\n" | |
] | |
} | |
], | |
"source": [ | |
"L = 44\n", | |
"field = np.zeros((L, L), dtype=int)\n", | |
"field[L//2, L//2] = 1\n", | |
"\n", | |
"%timeit evolve2_1(field, 1.81, 10)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"174.24242424242425" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"345 / 1.98" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The recommended code structure is to have a python-facing `def` function which takes care of the input and output, allocated memory etc, and delegates all heavy lifting to an internal `cdef` function." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<!DOCTYPE html>\n", | |
"<!-- Generated by Cython 0.25.2 -->\n", | |
"<html>\n", | |
"<head>\n", | |
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n", | |
" <title>Cython: _cython_magic_451bc548913a9407f1c439613b3672aa.pyx</title>\n", | |
" <style type=\"text/css\">\n", | |
" \n", | |
"body.cython { font-family: courier; font-size: 12; }\n", | |
"\n", | |
".cython.tag { }\n", | |
".cython.line { margin: 0em }\n", | |
".cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; }\n", | |
"\n", | |
".cython.line .run { background-color: #B0FFB0; }\n", | |
".cython.line .mis { background-color: #FFB0B0; }\n", | |
".cython.code.run { border-left: 8px solid #B0FFB0; }\n", | |
".cython.code.mis { border-left: 8px solid #FFB0B0; }\n", | |
"\n", | |
".cython.code .py_c_api { color: red; }\n", | |
".cython.code .py_macro_api { color: #FF7000; }\n", | |
".cython.code .pyx_c_api { color: #FF3000; }\n", | |
".cython.code .pyx_macro_api { color: #FF7000; }\n", | |
".cython.code .refnanny { color: #FFA000; }\n", | |
".cython.code .trace { color: #FFA000; }\n", | |
".cython.code .error_goto { color: #FFA000; }\n", | |
"\n", | |
".cython.code .coerce { color: #008000; border: 1px dotted #008000 }\n", | |
".cython.code .py_attr { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_attr { color: #0000FF; }\n", | |
".cython.code .py_call { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_call { color: #0000FF; }\n", | |
"\n", | |
".cython.score-0 {background-color: #FFFFff;}\n", | |
".cython.score-1 {background-color: #FFFFe7;}\n", | |
".cython.score-2 {background-color: #FFFFd4;}\n", | |
".cython.score-3 {background-color: #FFFFc4;}\n", | |
".cython.score-4 {background-color: #FFFFb6;}\n", | |
".cython.score-5 {background-color: #FFFFaa;}\n", | |
".cython.score-6 {background-color: #FFFF9f;}\n", | |
".cython.score-7 {background-color: #FFFF96;}\n", | |
".cython.score-8 {background-color: #FFFF8d;}\n", | |
".cython.score-9 {background-color: #FFFF86;}\n", | |
".cython.score-10 {background-color: #FFFF7f;}\n", | |
".cython.score-11 {background-color: #FFFF79;}\n", | |
".cython.score-12 {background-color: #FFFF73;}\n", | |
".cython.score-13 {background-color: #FFFF6e;}\n", | |
".cython.score-14 {background-color: #FFFF6a;}\n", | |
".cython.score-15 {background-color: #FFFF66;}\n", | |
".cython.score-16 {background-color: #FFFF62;}\n", | |
".cython.score-17 {background-color: #FFFF5e;}\n", | |
".cython.score-18 {background-color: #FFFF5b;}\n", | |
".cython.score-19 {background-color: #FFFF57;}\n", | |
".cython.score-20 {background-color: #FFFF55;}\n", | |
".cython.score-21 {background-color: #FFFF52;}\n", | |
".cython.score-22 {background-color: #FFFF4f;}\n", | |
".cython.score-23 {background-color: #FFFF4d;}\n", | |
".cython.score-24 {background-color: #FFFF4b;}\n", | |
".cython.score-25 {background-color: #FFFF48;}\n", | |
".cython.score-26 {background-color: #FFFF46;}\n", | |
".cython.score-27 {background-color: #FFFF44;}\n", | |
".cython.score-28 {background-color: #FFFF43;}\n", | |
".cython.score-29 {background-color: #FFFF41;}\n", | |
".cython.score-30 {background-color: #FFFF3f;}\n", | |
".cython.score-31 {background-color: #FFFF3e;}\n", | |
".cython.score-32 {background-color: #FFFF3c;}\n", | |
".cython.score-33 {background-color: #FFFF3b;}\n", | |
".cython.score-34 {background-color: #FFFF39;}\n", | |
".cython.score-35 {background-color: #FFFF38;}\n", | |
".cython.score-36 {background-color: #FFFF37;}\n", | |
".cython.score-37 {background-color: #FFFF36;}\n", | |
".cython.score-38 {background-color: #FFFF35;}\n", | |
".cython.score-39 {background-color: #FFFF34;}\n", | |
".cython.score-40 {background-color: #FFFF33;}\n", | |
".cython.score-41 {background-color: #FFFF32;}\n", | |
".cython.score-42 {background-color: #FFFF31;}\n", | |
".cython.score-43 {background-color: #FFFF30;}\n", | |
".cython.score-44 {background-color: #FFFF2f;}\n", | |
".cython.score-45 {background-color: #FFFF2e;}\n", | |
".cython.score-46 {background-color: #FFFF2d;}\n", | |
".cython.score-47 {background-color: #FFFF2c;}\n", | |
".cython.score-48 {background-color: #FFFF2b;}\n", | |
".cython.score-49 {background-color: #FFFF2b;}\n", | |
".cython.score-50 {background-color: #FFFF2a;}\n", | |
".cython.score-51 {background-color: #FFFF29;}\n", | |
".cython.score-52 {background-color: #FFFF29;}\n", | |
".cython.score-53 {background-color: #FFFF28;}\n", | |
".cython.score-54 {background-color: #FFFF27;}\n", | |
".cython.score-55 {background-color: #FFFF27;}\n", | |
".cython.score-56 {background-color: #FFFF26;}\n", | |
".cython.score-57 {background-color: #FFFF26;}\n", | |
".cython.score-58 {background-color: #FFFF25;}\n", | |
".cython.score-59 {background-color: #FFFF24;}\n", | |
".cython.score-60 {background-color: #FFFF24;}\n", | |
".cython.score-61 {background-color: #FFFF23;}\n", | |
".cython.score-62 {background-color: #FFFF23;}\n", | |
".cython.score-63 {background-color: #FFFF22;}\n", | |
".cython.score-64 {background-color: #FFFF22;}\n", | |
".cython.score-65 {background-color: #FFFF22;}\n", | |
".cython.score-66 {background-color: #FFFF21;}\n", | |
".cython.score-67 {background-color: #FFFF21;}\n", | |
".cython.score-68 {background-color: #FFFF20;}\n", | |
".cython.score-69 {background-color: #FFFF20;}\n", | |
".cython.score-70 {background-color: #FFFF1f;}\n", | |
".cython.score-71 {background-color: #FFFF1f;}\n", | |
".cython.score-72 {background-color: #FFFF1f;}\n", | |
".cython.score-73 {background-color: #FFFF1e;}\n", | |
".cython.score-74 {background-color: #FFFF1e;}\n", | |
".cython.score-75 {background-color: #FFFF1e;}\n", | |
".cython.score-76 {background-color: #FFFF1d;}\n", | |
".cython.score-77 {background-color: #FFFF1d;}\n", | |
".cython.score-78 {background-color: #FFFF1c;}\n", | |
".cython.score-79 {background-color: #FFFF1c;}\n", | |
".cython.score-80 {background-color: #FFFF1c;}\n", | |
".cython.score-81 {background-color: #FFFF1c;}\n", | |
".cython.score-82 {background-color: #FFFF1b;}\n", | |
".cython.score-83 {background-color: #FFFF1b;}\n", | |
".cython.score-84 {background-color: #FFFF1b;}\n", | |
".cython.score-85 {background-color: #FFFF1a;}\n", | |
".cython.score-86 {background-color: #FFFF1a;}\n", | |
".cython.score-87 {background-color: #FFFF1a;}\n", | |
".cython.score-88 {background-color: #FFFF1a;}\n", | |
".cython.score-89 {background-color: #FFFF19;}\n", | |
".cython.score-90 {background-color: #FFFF19;}\n", | |
".cython.score-91 {background-color: #FFFF19;}\n", | |
".cython.score-92 {background-color: #FFFF19;}\n", | |
".cython.score-93 {background-color: #FFFF18;}\n", | |
".cython.score-94 {background-color: #FFFF18;}\n", | |
".cython.score-95 {background-color: #FFFF18;}\n", | |
".cython.score-96 {background-color: #FFFF18;}\n", | |
".cython.score-97 {background-color: #FFFF17;}\n", | |
".cython.score-98 {background-color: #FFFF17;}\n", | |
".cython.score-99 {background-color: #FFFF17;}\n", | |
".cython.score-100 {background-color: #FFFF17;}\n", | |
".cython.score-101 {background-color: #FFFF16;}\n", | |
".cython.score-102 {background-color: #FFFF16;}\n", | |
".cython.score-103 {background-color: #FFFF16;}\n", | |
".cython.score-104 {background-color: #FFFF16;}\n", | |
".cython.score-105 {background-color: #FFFF16;}\n", | |
".cython.score-106 {background-color: #FFFF15;}\n", | |
".cython.score-107 {background-color: #FFFF15;}\n", | |
".cython.score-108 {background-color: #FFFF15;}\n", | |
".cython.score-109 {background-color: #FFFF15;}\n", | |
".cython.score-110 {background-color: #FFFF15;}\n", | |
".cython.score-111 {background-color: #FFFF15;}\n", | |
".cython.score-112 {background-color: #FFFF14;}\n", | |
".cython.score-113 {background-color: #FFFF14;}\n", | |
".cython.score-114 {background-color: #FFFF14;}\n", | |
".cython.score-115 {background-color: #FFFF14;}\n", | |
".cython.score-116 {background-color: #FFFF14;}\n", | |
".cython.score-117 {background-color: #FFFF14;}\n", | |
".cython.score-118 {background-color: #FFFF13;}\n", | |
".cython.score-119 {background-color: #FFFF13;}\n", | |
".cython.score-120 {background-color: #FFFF13;}\n", | |
".cython.score-121 {background-color: #FFFF13;}\n", | |
".cython.score-122 {background-color: #FFFF13;}\n", | |
".cython.score-123 {background-color: #FFFF13;}\n", | |
".cython.score-124 {background-color: #FFFF13;}\n", | |
".cython.score-125 {background-color: #FFFF12;}\n", | |
".cython.score-126 {background-color: #FFFF12;}\n", | |
".cython.score-127 {background-color: #FFFF12;}\n", | |
".cython.score-128 {background-color: #FFFF12;}\n", | |
".cython.score-129 {background-color: #FFFF12;}\n", | |
".cython.score-130 {background-color: #FFFF12;}\n", | |
".cython.score-131 {background-color: #FFFF12;}\n", | |
".cython.score-132 {background-color: #FFFF11;}\n", | |
".cython.score-133 {background-color: #FFFF11;}\n", | |
".cython.score-134 {background-color: #FFFF11;}\n", | |
".cython.score-135 {background-color: #FFFF11;}\n", | |
".cython.score-136 {background-color: #FFFF11;}\n", | |
".cython.score-137 {background-color: #FFFF11;}\n", | |
".cython.score-138 {background-color: #FFFF11;}\n", | |
".cython.score-139 {background-color: #FFFF11;}\n", | |
".cython.score-140 {background-color: #FFFF11;}\n", | |
".cython.score-141 {background-color: #FFFF10;}\n", | |
".cython.score-142 {background-color: #FFFF10;}\n", | |
".cython.score-143 {background-color: #FFFF10;}\n", | |
".cython.score-144 {background-color: #FFFF10;}\n", | |
".cython.score-145 {background-color: #FFFF10;}\n", | |
".cython.score-146 {background-color: #FFFF10;}\n", | |
".cython.score-147 {background-color: #FFFF10;}\n", | |
".cython.score-148 {background-color: #FFFF10;}\n", | |
".cython.score-149 {background-color: #FFFF10;}\n", | |
".cython.score-150 {background-color: #FFFF0f;}\n", | |
".cython.score-151 {background-color: #FFFF0f;}\n", | |
".cython.score-152 {background-color: #FFFF0f;}\n", | |
".cython.score-153 {background-color: #FFFF0f;}\n", | |
".cython.score-154 {background-color: #FFFF0f;}\n", | |
".cython.score-155 {background-color: #FFFF0f;}\n", | |
".cython.score-156 {background-color: #FFFF0f;}\n", | |
".cython.score-157 {background-color: #FFFF0f;}\n", | |
".cython.score-158 {background-color: #FFFF0f;}\n", | |
".cython.score-159 {background-color: #FFFF0f;}\n", | |
".cython.score-160 {background-color: #FFFF0f;}\n", | |
".cython.score-161 {background-color: #FFFF0e;}\n", | |
".cython.score-162 {background-color: #FFFF0e;}\n", | |
".cython.score-163 {background-color: #FFFF0e;}\n", | |
".cython.score-164 {background-color: #FFFF0e;}\n", | |
".cython.score-165 {background-color: #FFFF0e;}\n", | |
".cython.score-166 {background-color: #FFFF0e;}\n", | |
".cython.score-167 {background-color: #FFFF0e;}\n", | |
".cython.score-168 {background-color: #FFFF0e;}\n", | |
".cython.score-169 {background-color: #FFFF0e;}\n", | |
".cython.score-170 {background-color: #FFFF0e;}\n", | |
".cython.score-171 {background-color: #FFFF0e;}\n", | |
".cython.score-172 {background-color: #FFFF0e;}\n", | |
".cython.score-173 {background-color: #FFFF0d;}\n", | |
".cython.score-174 {background-color: #FFFF0d;}\n", | |
".cython.score-175 {background-color: #FFFF0d;}\n", | |
".cython.score-176 {background-color: #FFFF0d;}\n", | |
".cython.score-177 {background-color: #FFFF0d;}\n", | |
".cython.score-178 {background-color: #FFFF0d;}\n", | |
".cython.score-179 {background-color: #FFFF0d;}\n", | |
".cython.score-180 {background-color: #FFFF0d;}\n", | |
".cython.score-181 {background-color: #FFFF0d;}\n", | |
".cython.score-182 {background-color: #FFFF0d;}\n", | |
".cython.score-183 {background-color: #FFFF0d;}\n", | |
".cython.score-184 {background-color: #FFFF0d;}\n", | |
".cython.score-185 {background-color: #FFFF0d;}\n", | |
".cython.score-186 {background-color: #FFFF0d;}\n", | |
".cython.score-187 {background-color: #FFFF0c;}\n", | |
".cython.score-188 {background-color: #FFFF0c;}\n", | |
".cython.score-189 {background-color: #FFFF0c;}\n", | |
".cython.score-190 {background-color: #FFFF0c;}\n", | |
".cython.score-191 {background-color: #FFFF0c;}\n", | |
".cython.score-192 {background-color: #FFFF0c;}\n", | |
".cython.score-193 {background-color: #FFFF0c;}\n", | |
".cython.score-194 {background-color: #FFFF0c;}\n", | |
".cython.score-195 {background-color: #FFFF0c;}\n", | |
".cython.score-196 {background-color: #FFFF0c;}\n", | |
".cython.score-197 {background-color: #FFFF0c;}\n", | |
".cython.score-198 {background-color: #FFFF0c;}\n", | |
".cython.score-199 {background-color: #FFFF0c;}\n", | |
".cython.score-200 {background-color: #FFFF0c;}\n", | |
".cython.score-201 {background-color: #FFFF0c;}\n", | |
".cython.score-202 {background-color: #FFFF0c;}\n", | |
".cython.score-203 {background-color: #FFFF0b;}\n", | |
".cython.score-204 {background-color: #FFFF0b;}\n", | |
".cython.score-205 {background-color: #FFFF0b;}\n", | |
".cython.score-206 {background-color: #FFFF0b;}\n", | |
".cython.score-207 {background-color: #FFFF0b;}\n", | |
".cython.score-208 {background-color: #FFFF0b;}\n", | |
".cython.score-209 {background-color: #FFFF0b;}\n", | |
".cython.score-210 {background-color: #FFFF0b;}\n", | |
".cython.score-211 {background-color: #FFFF0b;}\n", | |
".cython.score-212 {background-color: #FFFF0b;}\n", | |
".cython.score-213 {background-color: #FFFF0b;}\n", | |
".cython.score-214 {background-color: #FFFF0b;}\n", | |
".cython.score-215 {background-color: #FFFF0b;}\n", | |
".cython.score-216 {background-color: #FFFF0b;}\n", | |
".cython.score-217 {background-color: #FFFF0b;}\n", | |
".cython.score-218 {background-color: #FFFF0b;}\n", | |
".cython.score-219 {background-color: #FFFF0b;}\n", | |
".cython.score-220 {background-color: #FFFF0b;}\n", | |
".cython.score-221 {background-color: #FFFF0b;}\n", | |
".cython.score-222 {background-color: #FFFF0a;}\n", | |
".cython.score-223 {background-color: #FFFF0a;}\n", | |
".cython.score-224 {background-color: #FFFF0a;}\n", | |
".cython.score-225 {background-color: #FFFF0a;}\n", | |
".cython.score-226 {background-color: #FFFF0a;}\n", | |
".cython.score-227 {background-color: #FFFF0a;}\n", | |
".cython.score-228 {background-color: #FFFF0a;}\n", | |
".cython.score-229 {background-color: #FFFF0a;}\n", | |
".cython.score-230 {background-color: #FFFF0a;}\n", | |
".cython.score-231 {background-color: #FFFF0a;}\n", | |
".cython.score-232 {background-color: #FFFF0a;}\n", | |
".cython.score-233 {background-color: #FFFF0a;}\n", | |
".cython.score-234 {background-color: #FFFF0a;}\n", | |
".cython.score-235 {background-color: #FFFF0a;}\n", | |
".cython.score-236 {background-color: #FFFF0a;}\n", | |
".cython.score-237 {background-color: #FFFF0a;}\n", | |
".cython.score-238 {background-color: #FFFF0a;}\n", | |
".cython.score-239 {background-color: #FFFF0a;}\n", | |
".cython.score-240 {background-color: #FFFF0a;}\n", | |
".cython.score-241 {background-color: #FFFF0a;}\n", | |
".cython.score-242 {background-color: #FFFF0a;}\n", | |
".cython.score-243 {background-color: #FFFF0a;}\n", | |
".cython.score-244 {background-color: #FFFF0a;}\n", | |
".cython.score-245 {background-color: #FFFF0a;}\n", | |
".cython.score-246 {background-color: #FFFF09;}\n", | |
".cython.score-247 {background-color: #FFFF09;}\n", | |
".cython.score-248 {background-color: #FFFF09;}\n", | |
".cython.score-249 {background-color: #FFFF09;}\n", | |
".cython.score-250 {background-color: #FFFF09;}\n", | |
".cython.score-251 {background-color: #FFFF09;}\n", | |
".cython.score-252 {background-color: #FFFF09;}\n", | |
".cython.score-253 {background-color: #FFFF09;}\n", | |
".cython.score-254 {background-color: #FFFF09;}\n", | |
".cython .hll { background-color: #ffffcc }\n", | |
".cython { background: #f8f8f8; }\n", | |
".cython .c { color: #408080; font-style: italic } /* Comment */\n", | |
".cython .err { border: 1px solid #FF0000 } /* Error */\n", | |
".cython .k { color: #008000; font-weight: bold } /* Keyword */\n", | |
".cython .o { color: #666666 } /* Operator */\n", | |
".cython .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n", | |
".cython .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n", | |
".cython .cp { color: #BC7A00 } /* Comment.Preproc */\n", | |
".cython .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n", | |
".cython .c1 { color: #408080; font-style: italic } /* Comment.Single */\n", | |
".cython .cs { color: #408080; font-style: italic } /* Comment.Special */\n", | |
".cython .gd { color: #A00000 } /* Generic.Deleted */\n", | |
".cython .ge { font-style: italic } /* Generic.Emph */\n", | |
".cython .gr { color: #FF0000 } /* Generic.Error */\n", | |
".cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n", | |
".cython .gi { color: #00A000 } /* Generic.Inserted */\n", | |
".cython .go { color: #888888 } /* Generic.Output */\n", | |
".cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n", | |
".cython .gs { font-weight: bold } /* Generic.Strong */\n", | |
".cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n", | |
".cython .gt { color: #0044DD } /* Generic.Traceback */\n", | |
".cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n", | |
".cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n", | |
".cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n", | |
".cython .kp { color: #008000 } /* Keyword.Pseudo */\n", | |
".cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n", | |
".cython .kt { color: #B00040 } /* Keyword.Type */\n", | |
".cython .m { color: #666666 } /* Literal.Number */\n", | |
".cython .s { color: #BA2121 } /* Literal.String */\n", | |
".cython .na { color: #7D9029 } /* Name.Attribute */\n", | |
".cython .nb { color: #008000 } /* Name.Builtin */\n", | |
".cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n", | |
".cython .no { color: #880000 } /* Name.Constant */\n", | |
".cython .nd { color: #AA22FF } /* Name.Decorator */\n", | |
".cython .ni { color: #999999; font-weight: bold } /* Name.Entity */\n", | |
".cython .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n", | |
".cython .nf { color: #0000FF } /* Name.Function */\n", | |
".cython .nl { color: #A0A000 } /* Name.Label */\n", | |
".cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n", | |
".cython .nt { color: #008000; font-weight: bold } /* Name.Tag */\n", | |
".cython .nv { color: #19177C } /* Name.Variable */\n", | |
".cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n", | |
".cython .w { color: #bbbbbb } /* Text.Whitespace */\n", | |
".cython .mb { color: #666666 } /* Literal.Number.Bin */\n", | |
".cython .mf { color: #666666 } /* Literal.Number.Float */\n", | |
".cython .mh { color: #666666 } /* Literal.Number.Hex */\n", | |
".cython .mi { color: #666666 } /* Literal.Number.Integer */\n", | |
".cython .mo { color: #666666 } /* Literal.Number.Oct */\n", | |
".cython .sa { color: #BA2121 } /* Literal.String.Affix */\n", | |
".cython .sb { color: #BA2121 } /* Literal.String.Backtick */\n", | |
".cython .sc { color: #BA2121 } /* Literal.String.Char */\n", | |
".cython .dl { color: #BA2121 } /* Literal.String.Delimiter */\n", | |
".cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n", | |
".cython .s2 { color: #BA2121 } /* Literal.String.Double */\n", | |
".cython .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n", | |
".cython .sh { color: #BA2121 } /* Literal.String.Heredoc */\n", | |
".cython .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n", | |
".cython .sx { color: #008000 } /* Literal.String.Other */\n", | |
".cython .sr { color: #BB6688 } /* Literal.String.Regex */\n", | |
".cython .s1 { color: #BA2121 } /* Literal.String.Single */\n", | |
".cython .ss { color: #19177C } /* Literal.String.Symbol */\n", | |
".cython .bp { color: #008000 } /* Name.Builtin.Pseudo */\n", | |
".cython .fm { color: #0000FF } /* Name.Function.Magic */\n", | |
".cython .vc { color: #19177C } /* Name.Variable.Class */\n", | |
".cython .vg { color: #19177C } /* Name.Variable.Global */\n", | |
".cython .vi { color: #19177C } /* Name.Variable.Instance */\n", | |
".cython .vm { color: #19177C } /* Name.Variable.Magic */\n", | |
".cython .il { color: #666666 } /* Literal.Number.Integer.Long */\n", | |
" </style>\n", | |
" <script>\n", | |
" function toggleDiv(id) {\n", | |
" theDiv = id.nextElementSibling\n", | |
" if (theDiv.style.display != 'block') theDiv.style.display = 'block';\n", | |
" else theDiv.style.display = 'none';\n", | |
" }\n", | |
" </script>\n", | |
"</head>\n", | |
"<body class=\"cython\">\n", | |
"<p><span style=\"border-bottom: solid 1px grey;\">Generated by Cython 0.25.2</span></p>\n", | |
"<p>\n", | |
" <span style=\"background-color: #FFFF00\">Yellow lines</span> hint at Python interaction.<br />\n", | |
" Click on a line that starts with a \"<code>+</code>\" to see the C code that Cython generated for it.\n", | |
"</p>\n", | |
"<div class=\"cython\"><pre class=\"cython line score-0\"> <span class=\"\">01</span>: </pre>\n", | |
"<pre class=\"cython line score-19\" onclick='toggleDiv(this)'>+<span class=\"\">02</span>: <span class=\"k\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n", | |
"<pre class='cython code score-19 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"/* … */\n", | |
" __pyx_t_1 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">03</span>: <span class=\"k\">import</span> <span class=\"nn\">cython</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">04</span>: </pre>\n", | |
"<pre class=\"cython line score-62\" onclick='toggleDiv(this)'>+<span class=\"\">05</span>: <span class=\"k\">def</span> <span class=\"nf\">evolve2_2</span><span class=\"p\">(</span><span class=\"n\">field</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">num_steps</span><span class=\"o\">=</span><span class=\"mf\">1</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-62 '>/* Python wrapper */\n", | |
"static PyObject *__pyx_pw_46_cython_magic_451bc548913a9407f1c439613b3672aa_1evolve2_2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", | |
"static PyMethodDef __pyx_mdef_46_cython_magic_451bc548913a9407f1c439613b3672aa_1evolve2_2 = {\"evolve2_2\", (PyCFunction)__pyx_pw_46_cython_magic_451bc548913a9407f1c439613b3672aa_1evolve2_2, METH_VARARGS|METH_KEYWORDS, 0};\n", | |
"static PyObject *__pyx_pw_46_cython_magic_451bc548913a9407f1c439613b3672aa_1evolve2_2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", | |
" PyObject *__pyx_v_field = 0;\n", | |
" PyObject *__pyx_v_b = 0;\n", | |
" PyObject *__pyx_v_num_steps = 0;\n", | |
" PyObject *__pyx_r = 0;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"evolve2_2 (wrapper)\", 0);\n", | |
" {\n", | |
" static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_field,&__pyx_n_s_b,&__pyx_n_s_num_steps,0};\n", | |
" PyObject* values[3] = {0,0,0};\n", | |
" values[2] = ((PyObject *)__pyx_int_1);\n", | |
" if (unlikely(__pyx_kwds)) {\n", | |
" Py_ssize_t kw_args;\n", | |
" const Py_ssize_t pos_args = <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args);\n", | |
" switch (pos_args) {\n", | |
" case 3: values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" case 1: values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" case 0: break;\n", | |
" default: goto __pyx_L5_argtuple_error;\n", | |
" }\n", | |
" kw_args = <span class='py_c_api'>PyDict_Size</span>(__pyx_kwds);\n", | |
" switch (pos_args) {\n", | |
" case 0:\n", | |
" if (likely((values[0] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_field)) != 0)) kw_args--;\n", | |
" else goto __pyx_L5_argtuple_error;\n", | |
" case 1:\n", | |
" if (likely((values[1] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"evolve2_2\", 0, 2, 3, 1); __PYX_ERR(0, 5, __pyx_L3_error)\n", | |
" }\n", | |
" case 2:\n", | |
" if (kw_args > 0) {\n", | |
" PyObject* value = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_num_steps);\n", | |
" if (value) { values[2] = value; kw_args--; }\n", | |
" }\n", | |
" }\n", | |
" if (unlikely(kw_args > 0)) {\n", | |
" if (unlikely(<span class='pyx_c_api'>__Pyx_ParseOptionalKeywords</span>(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"evolve2_2\") < 0)) __PYX_ERR(0, 5, __pyx_L3_error)\n", | |
" }\n", | |
" } else {\n", | |
" switch (<span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)) {\n", | |
" case 3: values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" break;\n", | |
" default: goto __pyx_L5_argtuple_error;\n", | |
" }\n", | |
" }\n", | |
" __pyx_v_field = values[0];\n", | |
" __pyx_v_b = values[1];\n", | |
" __pyx_v_num_steps = values[2];\n", | |
" }\n", | |
" goto __pyx_L4_argument_unpacking_done;\n", | |
" __pyx_L5_argtuple_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"evolve2_2\", 0, 2, 3, <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)); __PYX_ERR(0, 5, __pyx_L3_error)\n", | |
" __pyx_L3_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_451bc548913a9407f1c439613b3672aa.evolve2_2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return NULL;\n", | |
" __pyx_L4_argument_unpacking_done:;\n", | |
" __pyx_r = __pyx_pf_46_cython_magic_451bc548913a9407f1c439613b3672aa_evolve2_2(__pyx_self, __pyx_v_field, __pyx_v_b, __pyx_v_num_steps);\n", | |
"\n", | |
" /* function exit code */\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"\n", | |
"static PyObject *__pyx_pf_46_cython_magic_451bc548913a9407f1c439613b3672aa_evolve2_2(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_field, PyObject *__pyx_v_b, PyObject *__pyx_v_num_steps) {\n", | |
" PyObject *__pyx_v_L = NULL;\n", | |
" PyObject *__pyx_v_scores = NULL;\n", | |
" PyObject *__pyx_v_current = NULL;\n", | |
" PyObject *__pyx_v__zeros = NULL;\n", | |
" int __pyx_v__num_steps;\n", | |
" double __pyx_v__b;\n", | |
" PyObject *__pyx_r = NULL;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"evolve2_2\", 0);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_field);\n", | |
"/* … */\n", | |
" /* function exit code */\n", | |
" __pyx_L1_error:;\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_4);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_451bc548913a9407f1c439613b3672aa.evolve2_2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" __pyx_r = NULL;\n", | |
" __pyx_L0:;\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_L);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_scores);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_current);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v__zeros);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_field);\n", | |
" <span class='refnanny'>__Pyx_XGIVEREF</span>(__pyx_r);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"/* … */\n", | |
" __pyx_tuple__14 = <span class='py_c_api'>PyTuple_Pack</span>(9, __pyx_n_s_field, __pyx_n_s_b, __pyx_n_s_num_steps, __pyx_n_s_L, __pyx_n_s_scores, __pyx_n_s_current, __pyx_n_s_zeros_2, __pyx_n_s_num_steps_2, __pyx_n_s_b_2); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 5, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_tuple__14);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_tuple__14);\n", | |
"/* … */\n", | |
" __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_451bc548913a9407f1c439613b3672aa_1evolve2_2, NULL, __pyx_n_s_cython_magic_451bc548913a9407f1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_evolve2_2, __pyx_t_1) < 0) __PYX_ERR(0, 5, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_codeobj__15 = (PyObject*)<span class='pyx_c_api'>__Pyx_PyCode_New</span>(3, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_br_cache_ipython_cython__c, __pyx_n_s_evolve2_2, 5, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 5, __pyx_L1_error)\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">06</span>: <span class=\"c\"># validate input here</span></pre>\n", | |
"<pre class=\"cython line score-43\" onclick='toggleDiv(this)'>+<span class=\"\">07</span>: <span class=\"n\">field</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">atleast_2d</span><span class=\"p\">(</span><span class=\"n\">field</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-43 '> __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_atleast_2d); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = NULL;\n", | |
" if (CYTHON_UNPACK_METHODS && unlikely(<span class='py_c_api'>PyMethod_Check</span>(__pyx_t_3))) {\n", | |
" __pyx_t_2 = <span class='py_macro_api'>PyMethod_GET_SELF</span>(__pyx_t_3);\n", | |
" if (likely(__pyx_t_2)) {\n", | |
" PyObject* function = <span class='py_macro_api'>PyMethod_GET_FUNCTION</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(function);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_t_3, function);\n", | |
" }\n", | |
" }\n", | |
" if (!__pyx_t_2) {\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_CallOneArg</span>(__pyx_t_3, __pyx_v_field); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else {\n", | |
" #if CYTHON_FAST_PYCALL\n", | |
" if (<span class='py_c_api'>PyFunction_Check</span>(__pyx_t_3)) {\n", | |
" PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_v_field};\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyFunction_FastCall</span>(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else\n", | |
" #endif\n", | |
" #if CYTHON_FAST_PYCCALL\n", | |
" if (<span class='pyx_c_api'>__Pyx_PyFastCFunction_Check</span>(__pyx_t_3)) {\n", | |
" PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_v_field};\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyCFunction_FastCall</span>(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else\n", | |
" #endif\n", | |
" {\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2); <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_2); __pyx_t_2 = NULL;\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_field);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_field);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0+1, __pyx_v_field);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" }\n", | |
" }\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_v_field, __pyx_t_1);\n", | |
" __pyx_t_1 = 0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">08</span>: <span class=\"c\"># XXX check that field is integer dtype etc</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">09</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">10</span>: <span class=\"c\"># allocate memory here</span></pre>\n", | |
"<pre class=\"cython line score-5\" onclick='toggleDiv(this)'>+<span class=\"\">11</span>: <span class=\"n\">L</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-5 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_v_field, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_GetItemInt</span>(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 11, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_v_L = __pyx_t_3;\n", | |
" __pyx_t_3 = 0;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">12</span>: <span class=\"n\">scores</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">L</span><span class=\"p\">,</span> <span class=\"n\">L</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_3 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_L);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_L);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_v_L);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_L);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_L);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 1, __pyx_v_L);\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_3);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_3);\n", | |
" __pyx_t_3 = 0;\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_3, __pyx_n_s_dtype, ((PyObject *)(&PyFloat_Type))) < 0) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_1, __pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 12, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" __pyx_v_scores = __pyx_t_2;\n", | |
" __pyx_t_2 = 0;\n", | |
"</pre><pre class=\"cython line score-18\" onclick='toggleDiv(this)'>+<span class=\"\">13</span>: <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span></pre>\n", | |
"<pre class='cython code score-18 '> __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_v_field, __pyx_n_s_copy); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" __pyx_t_4 = NULL;\n", | |
" if (CYTHON_UNPACK_METHODS && likely(<span class='py_c_api'>PyMethod_Check</span>(__pyx_t_3))) {\n", | |
" __pyx_t_4 = <span class='py_macro_api'>PyMethod_GET_SELF</span>(__pyx_t_3);\n", | |
" if (likely(__pyx_t_4)) {\n", | |
" PyObject* function = <span class='py_macro_api'>PyMethod_GET_FUNCTION</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(function);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_t_3, function);\n", | |
" }\n", | |
" }\n", | |
" if (__pyx_t_4) {\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_CallOneArg</span>(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" } else {\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_CallNoArg</span>(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)\n", | |
" }\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" __pyx_v_current = __pyx_t_2;\n", | |
" __pyx_t_2 = 0;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">14</span>: <span class=\"n\">_zeros</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">L</span><span class=\"p\">,</span> <span class=\"n\">L</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyTuple_New</span>(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_L);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_L);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 0, __pyx_v_L);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_L);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_L);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 1, __pyx_v_L);\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_2);\n", | |
" __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_2, __pyx_n_s_dtype, ((PyObject *)(&PyFloat_Type))) < 0) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_v__zeros = __pyx_t_1;\n", | |
" __pyx_t_1 = 0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">15</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">16</span>: <span class=\"k\">cdef</span><span class=\"p\">:</span></pre>\n", | |
"<pre class=\"cython line score-7\" onclick='toggleDiv(this)'>+<span class=\"\">17</span>: <span class=\"nb\">int</span> <span class=\"n\">_num_steps</span> <span class=\"o\">=</span> <span class=\"n\">num_steps</span></pre>\n", | |
"<pre class='cython code score-7 '> __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyInt_As_int</span>(__pyx_v_num_steps); if (unlikely((__pyx_t_5 == (int)-1) && <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 17, __pyx_L1_error)\n", | |
" __pyx_v__num_steps = __pyx_t_5;\n", | |
"</pre><pre class=\"cython line score-10\" onclick='toggleDiv(this)'>+<span class=\"\">18</span>: <span class=\"n\">double</span> <span class=\"n\">_b</span> <span class=\"o\">=</span> <span class=\"n\">b</span></pre>\n", | |
"<pre class='cython code score-10 '> __pyx_t_6 = __pyx_<span class='py_c_api'>PyFloat_AsDouble</span>(__pyx_v_b); if (unlikely((__pyx_t_6 == (double)-1) && <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 18, __pyx_L1_error)\n", | |
" __pyx_v__b = __pyx_t_6;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">19</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">20</span>: <span class=\"c\"># do the work (`field` array is updated in-place)</span></pre>\n", | |
"<pre class=\"cython line score-8\" onclick='toggleDiv(this)'>+<span class=\"\">21</span>: <span class=\"n\">_evolve2_2_impl</span><span class=\"p\">(</span><span class=\"n\">field</span><span class=\"p\">,</span> <span class=\"n\">_b</span><span class=\"p\">,</span> <span class=\"n\">_num_steps</span><span class=\"p\">,</span> <span class=\"n\">scores</span><span class=\"p\">,</span> <span class=\"n\">_zeros</span><span class=\"p\">,</span> <span class=\"n\">current</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-8 '> __pyx_t_7 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_long</span>(__pyx_v_field);\n", | |
" if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 21, __pyx_L1_error)\n", | |
" __pyx_t_8 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_double</span>(__pyx_v_scores);\n", | |
" if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 21, __pyx_L1_error)\n", | |
" __pyx_t_9 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_double</span>(__pyx_v__zeros);\n", | |
" if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 21, __pyx_L1_error)\n", | |
" __pyx_t_10 = <span class='pyx_c_api'>__Pyx_PyObject_to_MemoryviewSlice_d_dc_long</span>(__pyx_v_current);\n", | |
" if (unlikely(!__pyx_t_10.memview)) __PYX_ERR(0, 21, __pyx_L1_error)\n", | |
" __pyx_f_46_cython_magic_451bc548913a9407f1c439613b3672aa__evolve2_2_impl(__pyx_t_7, __pyx_v__b, __pyx_v__num_steps, __pyx_t_8, __pyx_t_9, __pyx_t_10);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);\n", | |
" __pyx_t_7.memview = NULL;\n", | |
" __pyx_t_7.data = NULL;\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);\n", | |
" __pyx_t_8.memview = NULL;\n", | |
" __pyx_t_8.data = NULL;\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);\n", | |
" __pyx_t_9.memview = NULL;\n", | |
" __pyx_t_9.data = NULL;\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);\n", | |
" __pyx_t_10.memview = NULL;\n", | |
" __pyx_t_10.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">22</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">23</span>: <span class=\"c\"># convert memoryviews to numpy arrays</span></pre>\n", | |
"<pre class=\"cython line score-43\" onclick='toggleDiv(this)'>+<span class=\"\">24</span>: <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">asarray</span><span class=\"p\">(</span><span class=\"n\">field</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-43 '> <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_r);\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_asarray); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = NULL;\n", | |
" if (CYTHON_UNPACK_METHODS && unlikely(<span class='py_c_api'>PyMethod_Check</span>(__pyx_t_4))) {\n", | |
" __pyx_t_2 = <span class='py_macro_api'>PyMethod_GET_SELF</span>(__pyx_t_4);\n", | |
" if (likely(__pyx_t_2)) {\n", | |
" PyObject* function = <span class='py_macro_api'>PyMethod_GET_FUNCTION</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(function);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_t_4, function);\n", | |
" }\n", | |
" }\n", | |
" if (!__pyx_t_2) {\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_CallOneArg</span>(__pyx_t_4, __pyx_v_field); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else {\n", | |
" #if CYTHON_FAST_PYCALL\n", | |
" if (<span class='py_c_api'>PyFunction_Check</span>(__pyx_t_4)) {\n", | |
" PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_v_field};\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyFunction_FastCall</span>(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else\n", | |
" #endif\n", | |
" #if CYTHON_FAST_PYCCALL\n", | |
" if (<span class='pyx_c_api'>__Pyx_PyFastCFunction_Check</span>(__pyx_t_4)) {\n", | |
" PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_v_field};\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyCFunction_FastCall</span>(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" } else\n", | |
" #endif\n", | |
" {\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2); <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_2); __pyx_t_2 = NULL;\n", | |
" <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_field);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_field);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0+1, __pyx_v_field);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" }\n", | |
" }\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_r = __pyx_t_1;\n", | |
" __pyx_t_1 = 0;\n", | |
" goto __pyx_L0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">25</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">26</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">27</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">cdivision</span><span class=\"p\">(</span><span class=\"bp\">True</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">28</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">boundscheck</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-2\" onclick='toggleDiv(this)'>+<span class=\"\">29</span>: <span class=\"k\">cdef</span> <span class=\"kt\">void</span> <span class=\"nf\">_evolve2_2_impl</span><span class=\"p\">(</span><span class=\"nb\">long</span><span class=\"p\">[:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">field</span><span class=\"p\">,</span> <span class=\"n\">double</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"nb\">int</span> <span class=\"n\">num_steps</span><span class=\"p\">,</span></pre>\n", | |
"<pre class='cython code score-2 '>static void __pyx_f_46_cython_magic_451bc548913a9407f1c439613b3672aa__evolve2_2_impl(__Pyx_memviewslice __pyx_v_field, double __pyx_v_b, int __pyx_v_num_steps, __Pyx_memviewslice __pyx_v_scores, __Pyx_memviewslice __pyx_v__zeros, __Pyx_memviewslice __pyx_v_current) {\n", | |
" int __pyx_v_x;\n", | |
" int __pyx_v_y;\n", | |
" int __pyx_v_L;\n", | |
" int __pyx_v_i;\n", | |
" int __pyx_v_j;\n", | |
" int __pyx_v_ix;\n", | |
" int __pyx_v_jy;\n", | |
" CYTHON_UNUSED int __pyx_v_step;\n", | |
" int __pyx_v_bestX;\n", | |
" int __pyx_v_bestY;\n", | |
"/* … */\n", | |
" /* function exit code */\n", | |
" goto __pyx_L0;\n", | |
" __pyx_L1_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_WriteUnraisable</span>(\"_cython_magic_451bc548913a9407f1c439613b3672aa._evolve2_2_impl\", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 1);\n", | |
" __pyx_L0:;\n", | |
"}\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">30</span>: <span class=\"n\">double</span><span class=\"p\">[:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">scores</span><span class=\"p\">,</span> <span class=\"n\">double</span><span class=\"p\">[:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">_zeros</span><span class=\"p\">,</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">31</span>: <span class=\"nb\">long</span><span class=\"p\">[:,</span> <span class=\"p\">::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">current</span><span class=\"p\">)</span> <span class=\"k\">nogil</span><span class=\"p\">:</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">32</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">33</span>: <span class=\"k\">cdef</span> <span class=\"kt\">int</span> <span class=\"nf\">x</span><span class=\"p\">,</span> <span class=\"nf\">y</span><span class=\"p\">,</span> <span class=\"nf\">L</span><span class=\"p\">,</span> <span class=\"nf\">i</span><span class=\"p\">,</span> <span class=\"nf\">j</span><span class=\"p\">,</span> <span class=\"nf\">ix</span><span class=\"p\">,</span> <span class=\"nf\">jy</span><span class=\"p\">,</span> <span class=\"nf\">step</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">34</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">35</span>: <span class=\"n\">L</span> <span class=\"o\">=</span> <span class=\"n\">field</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_L = (__pyx_v_field.shape[0]);\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">36</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">37</span>: <span class=\"k\">for</span> <span class=\"n\">step</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_steps</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_1 = __pyx_v_num_steps;\n", | |
" for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {\n", | |
" __pyx_v_step = __pyx_t_2;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">38</span>: <span class=\"n\">current</span><span class=\"p\">[</span><span class=\"o\">...</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">field</span></pre>\n", | |
"<pre class='cython code score-0 '> if (unlikely(__pyx_memoryview_copy_contents(__pyx_v_field, __pyx_v_current, 2, 2, 0) < 0)) __PYX_ERR(0, 38, __pyx_L1_error)\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">39</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"o\">...</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">_zeros</span></pre>\n", | |
"<pre class='cython code score-0 '> if (unlikely(__pyx_memoryview_copy_contents(__pyx_v__zeros, __pyx_v_scores, 2, 2, 0) < 0)) __PYX_ERR(0, 39, __pyx_L1_error)\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">40</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">41</span>: <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_3 = __pyx_v_L;\n", | |
" for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {\n", | |
" __pyx_v_x = __pyx_t_4;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">42</span>: <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_5 = __pyx_v_L;\n", | |
" for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {\n", | |
" __pyx_v_y = __pyx_t_6;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">43</span>: <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_7 = -1L; __pyx_t_7 < 2; __pyx_t_7+=1) {\n", | |
" __pyx_v_i = __pyx_t_7;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">44</span>: <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_8 = -1L; __pyx_t_8 < 2; __pyx_t_8+=1) {\n", | |
" __pyx_v_j = __pyx_t_8;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">45</span>: <span class=\"n\">ix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_ix = ((__pyx_v_x + __pyx_v_i) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">46</span>: <span class=\"n\">jy</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_jy = ((__pyx_v_y + __pyx_v_j) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">47</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"p\">(</span><span class=\"mf\">1</span> <span class=\"o\">-</span> <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">ix</span><span class=\"p\">,</span> <span class=\"n\">jy</span><span class=\"p\">])</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_9 = __pyx_v_ix;\n", | |
" __pyx_t_10 = __pyx_v_jy;\n", | |
" if (__pyx_t_9 < 0) __pyx_t_9 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_v_field.shape[1];\n", | |
" __pyx_t_11 = __pyx_v_x;\n", | |
" __pyx_t_12 = __pyx_v_y;\n", | |
" if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_scores.shape[1];\n", | |
" *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_11 * __pyx_v_scores.strides[0]) )) + __pyx_t_12)) )) += (1 - (*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_9 * __pyx_v_field.strides[0]) )) + __pyx_t_10)) ))));\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">48</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">49</span>: <span class=\"k\">if</span> <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mf\">1</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_13 = __pyx_v_x;\n", | |
" __pyx_t_14 = __pyx_v_y;\n", | |
" if (__pyx_t_13 < 0) __pyx_t_13 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_field.shape[1];\n", | |
" __pyx_t_15 = (((*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_13 * __pyx_v_field.strides[0]) )) + __pyx_t_14)) ))) == 1) != 0);\n", | |
" if (__pyx_t_15) {\n", | |
"/* … */\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">50</span>: <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">*=</span> <span class=\"n\">b</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_16 = __pyx_v_x;\n", | |
" __pyx_t_17 = __pyx_v_y;\n", | |
" if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_scores.shape[1];\n", | |
" *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_16 * __pyx_v_scores.strides[0]) )) + __pyx_t_17)) )) *= __pyx_v_b;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">51</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">52</span>: <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_3 = __pyx_v_L;\n", | |
" for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {\n", | |
" __pyx_v_x = __pyx_t_4;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">53</span>: <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">L</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_5 = __pyx_v_L;\n", | |
" for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {\n", | |
" __pyx_v_y = __pyx_t_6;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">54</span>: <span class=\"n\">bestX</span> <span class=\"o\">=</span> <span class=\"n\">x</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestX = __pyx_v_x;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">55</span>: <span class=\"n\">bestY</span> <span class=\"o\">=</span> <span class=\"n\">y</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestY = __pyx_v_y;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">56</span>: <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_7 = -1L; __pyx_t_7 < 2; __pyx_t_7+=1) {\n", | |
" __pyx_v_i = __pyx_t_7;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">57</span>: <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"mf\">2</span><span class=\"p\">):</span></pre>\n", | |
"<pre class='cython code score-0 '> for (__pyx_t_8 = -1L; __pyx_t_8 < 2; __pyx_t_8+=1) {\n", | |
" __pyx_v_j = __pyx_t_8;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">58</span>: <span class=\"n\">ix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_ix = ((__pyx_v_x + __pyx_v_i) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">59</span>: <span class=\"n\">jy</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">L</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_jy = ((__pyx_v_y + __pyx_v_j) % __pyx_v_L);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">60</span>: <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">bestX</span><span class=\"p\">,</span> <span class=\"n\">bestY</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">scores</span><span class=\"p\">[</span><span class=\"n\">ix</span><span class=\"p\">,</span> <span class=\"n\">jy</span><span class=\"p\">]):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_18 = __pyx_v_bestX;\n", | |
" __pyx_t_19 = __pyx_v_bestY;\n", | |
" if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_scores.shape[1];\n", | |
" __pyx_t_20 = __pyx_v_ix;\n", | |
" __pyx_t_21 = __pyx_v_jy;\n", | |
" if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_v_scores.shape[0];\n", | |
" if (__pyx_t_21 < 0) __pyx_t_21 += __pyx_v_scores.shape[1];\n", | |
" __pyx_t_15 = (((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_18 * __pyx_v_scores.strides[0]) )) + __pyx_t_19)) ))) < (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_scores.data + __pyx_t_20 * __pyx_v_scores.strides[0]) )) + __pyx_t_21)) )))) != 0);\n", | |
" if (__pyx_t_15) {\n", | |
"/* … */\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">61</span>: <span class=\"n\">bestX</span> <span class=\"o\">=</span> <span class=\"n\">ix</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestX = __pyx_v_ix;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">62</span>: <span class=\"n\">bestY</span> <span class=\"o\">=</span> <span class=\"n\">jy</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_bestY = __pyx_v_jy;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">63</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">64</span>: <span class=\"n\">field</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">current</span><span class=\"p\">[</span><span class=\"n\">bestX</span><span class=\"p\">,</span> <span class=\"n\">bestY</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_22 = __pyx_v_bestX;\n", | |
" __pyx_t_23 = __pyx_v_bestY;\n", | |
" if (__pyx_t_22 < 0) __pyx_t_22 += __pyx_v_current.shape[0];\n", | |
" if (__pyx_t_23 < 0) __pyx_t_23 += __pyx_v_current.shape[1];\n", | |
" __pyx_t_24 = __pyx_v_x;\n", | |
" __pyx_t_25 = __pyx_v_y;\n", | |
" if (__pyx_t_24 < 0) __pyx_t_24 += __pyx_v_field.shape[0];\n", | |
" if (__pyx_t_25 < 0) __pyx_t_25 += __pyx_v_field.shape[1];\n", | |
" *((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_field.data + __pyx_t_24 * __pyx_v_field.strides[0]) )) + __pyx_t_25)) )) = (*((long *) ( /* dim=1 */ ((char *) (((long *) ( /* dim=0 */ (__pyx_v_current.data + __pyx_t_22 * __pyx_v_current.strides[0]) )) + __pyx_t_23)) )));\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"</pre></div></body></html>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"execution_count": 12, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%%cython -a\n", | |
"\n", | |
"import numpy as np\n", | |
"import cython\n", | |
"\n", | |
"def evolve2_2(field, b, num_steps=1):\n", | |
" # validate input here\n", | |
" field = np.atleast_2d(field)\n", | |
" # XXX check that field is integer dtype etc\n", | |
" \n", | |
" # allocate memory here\n", | |
" L = field.shape[0]\n", | |
" scores = np.zeros((L, L), dtype=float)\n", | |
" current = field.copy()\n", | |
" _zeros = np.zeros((L, L), dtype=float)\n", | |
"\n", | |
" cdef:\n", | |
" int _num_steps = num_steps\n", | |
" double _b = b\n", | |
" \n", | |
" # do the work (`field` array is updated in-place)\n", | |
" _evolve2_2_impl(field, _b, _num_steps, scores, _zeros, current)\n", | |
" \n", | |
" # convert memoryviews to numpy arrays\n", | |
" return np.asarray(field)\n", | |
"\n", | |
"\n", | |
"@cython.cdivision(True)\n", | |
"@cython.boundscheck(False)\n", | |
"cdef void _evolve2_2_impl(long[:, ::1] field, double b, int num_steps,\n", | |
" double[:, ::1] scores, double[:, ::1] _zeros,\n", | |
" long[:, ::1] current) nogil:\n", | |
" \n", | |
" cdef int x, y, L, i, j, ix, jy, step\n", | |
" \n", | |
" L = field.shape[0]\n", | |
"\n", | |
" for step in range(num_steps):\n", | |
" current[...] = field\n", | |
" scores[...] = _zeros\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" scores[x, y] += (1 - field[ix, jy])\n", | |
" \n", | |
" if field[x, y] == 1:\n", | |
" scores[x, y] *= b\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" bestX = x\n", | |
" bestY = y\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" if (scores[bestX, bestY] < scores[ix, jy]):\n", | |
" bestX = ix\n", | |
" bestY = jy\n", | |
" \n", | |
" field[x, y] = current[bestX, bestY]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"L = 44\n", | |
"field = np.zeros((L, L), dtype=int)\n", | |
"field[L//2, L//2] = 1\n", | |
"\n", | |
"%timeit evolve2_2(field, 1.81, 10)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Now, for something completely different: `numba` just-in-time compilation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import numba" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def evolve3(field, b, num_steps=1):\n", | |
" L = field.shape[0]\n", | |
" _zeros = np.zeros((L, L), dtype=float)\n", | |
" _int_zeros = np.zeros((L, L), dtype=int)\n", | |
" current = _int_zeros.copy()\n", | |
" scores = _zeros.copy()\n", | |
" evolve3_impl(field, b, num_steps, _zeros, _int_zeros)\n", | |
" return field\n", | |
"\n", | |
"\n", | |
"# Note a single decorator: @jit\n", | |
"\n", | |
"\n", | |
"@numba.jit(nopython=True)\n", | |
"def evolve3_impl(field, b, num_steps, _zeros, _int_zeros):\n", | |
" L = field.shape[0]\n", | |
" current = _int_zeros.copy()\n", | |
" \n", | |
" for step in range(num_steps):\n", | |
" current = field.copy()\n", | |
" scores = _zeros.copy()\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" scores[x, y] += (1 - field[ix, jy])\n", | |
" \n", | |
" if field[x, y] == 1:\n", | |
" scores[x, y] *= b\n", | |
" \n", | |
" for x in range(L):\n", | |
" for y in range(L):\n", | |
" bestX = x\n", | |
" bestY = y\n", | |
" for i in range(-1, 2):\n", | |
" for j in range(-1, 2):\n", | |
" ix = (x + i) % L\n", | |
" jy = (y + j) % L\n", | |
" if (scores[bestX, bestY] < scores[ix, jy]):\n", | |
" bestX = ix\n", | |
" bestY = jy\n", | |
" \n", | |
" field[x, y] = current[bestX, bestY]\n", | |
" return field" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"100 loops, best of 3: 2.12 ms per loop\n" | |
] | |
} | |
], | |
"source": [ | |
"L = 44\n", | |
"field = np.zeros((L, L), dtype=int)\n", | |
"field[L//2, L//2] = 1\n", | |
"\n", | |
"%timeit evolve3(field, 1.81, 10)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.13" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment