##// END OF EJS Templates
add name back into Cython Magics notebook
Erik Tollerud -
Show More
@@ -1,366 +1,366 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": "",
3 "name": "Cython Magics",
4 "signature": "sha256:c357b93e9480d6347c6677862bf43750745cef4b30129c5bc53cb879a19d4074"
4 "signature": "sha256:c357b93e9480d6347c6677862bf43750745cef4b30129c5bc53cb879a19d4074"
5 },
5 },
6 "nbformat": 3,
6 "nbformat": 3,
7 "nbformat_minor": 0,
7 "nbformat_minor": 0,
8 "worksheets": [
8 "worksheets": [
9 {
9 {
10 "cells": [
10 "cells": [
11 {
11 {
12 "cell_type": "heading",
12 "cell_type": "heading",
13 "level": 1,
13 "level": 1,
14 "metadata": {},
14 "metadata": {},
15 "source": [
15 "source": [
16 "Cython Magic Functions"
16 "Cython Magic Functions"
17 ]
17 ]
18 },
18 },
19 {
19 {
20 "cell_type": "heading",
20 "cell_type": "heading",
21 "level": 2,
21 "level": 2,
22 "metadata": {},
22 "metadata": {},
23 "source": [
23 "source": [
24 "Loading the extension"
24 "Loading the extension"
25 ]
25 ]
26 },
26 },
27 {
27 {
28 "cell_type": "markdown",
28 "cell_type": "markdown",
29 "metadata": {},
29 "metadata": {},
30 "source": [
30 "source": [
31 "IPython has a `cythonmagic` extension that contains a number of magic functions for working with Cython code. This extension can be loaded using the `%load_ext` magic as follows:"
31 "IPython has a `cythonmagic` extension that contains a number of magic functions for working with Cython code. This extension can be loaded using the `%load_ext` magic as follows:"
32 ]
32 ]
33 },
33 },
34 {
34 {
35 "cell_type": "code",
35 "cell_type": "code",
36 "collapsed": false,
36 "collapsed": false,
37 "input": [
37 "input": [
38 "%load_ext cythonmagic"
38 "%load_ext cythonmagic"
39 ],
39 ],
40 "language": "python",
40 "language": "python",
41 "metadata": {},
41 "metadata": {},
42 "outputs": [],
42 "outputs": [],
43 "prompt_number": 1
43 "prompt_number": 1
44 },
44 },
45 {
45 {
46 "cell_type": "heading",
46 "cell_type": "heading",
47 "level": 2,
47 "level": 2,
48 "metadata": {},
48 "metadata": {},
49 "source": [
49 "source": [
50 "The %cython_inline magic"
50 "The %cython_inline magic"
51 ]
51 ]
52 },
52 },
53 {
53 {
54 "cell_type": "markdown",
54 "cell_type": "markdown",
55 "metadata": {},
55 "metadata": {},
56 "source": [
56 "source": [
57 "The `%%cython_inline` magic uses `Cython.inline` to compile a Cython expression. This allows you to enter and run a function body with Cython code. Use a bare `return` statement to return values. "
57 "The `%%cython_inline` magic uses `Cython.inline` to compile a Cython expression. This allows you to enter and run a function body with Cython code. Use a bare `return` statement to return values. "
58 ]
58 ]
59 },
59 },
60 {
60 {
61 "cell_type": "code",
61 "cell_type": "code",
62 "collapsed": false,
62 "collapsed": false,
63 "input": [
63 "input": [
64 "a = 10\n",
64 "a = 10\n",
65 "b = 20"
65 "b = 20"
66 ],
66 ],
67 "language": "python",
67 "language": "python",
68 "metadata": {},
68 "metadata": {},
69 "outputs": [],
69 "outputs": [],
70 "prompt_number": 2
70 "prompt_number": 2
71 },
71 },
72 {
72 {
73 "cell_type": "code",
73 "cell_type": "code",
74 "collapsed": false,
74 "collapsed": false,
75 "input": [
75 "input": [
76 "%%cython_inline\n",
76 "%%cython_inline\n",
77 "return a+b"
77 "return a+b"
78 ],
78 ],
79 "language": "python",
79 "language": "python",
80 "metadata": {},
80 "metadata": {},
81 "outputs": [
81 "outputs": [
82 {
82 {
83 "metadata": {},
83 "metadata": {},
84 "output_type": "pyout",
84 "output_type": "pyout",
85 "prompt_number": 3,
85 "prompt_number": 3,
86 "text": [
86 "text": [
87 "30"
87 "30"
88 ]
88 ]
89 }
89 }
90 ],
90 ],
91 "prompt_number": 3
91 "prompt_number": 3
92 },
92 },
93 {
93 {
94 "cell_type": "heading",
94 "cell_type": "heading",
95 "level": 2,
95 "level": 2,
96 "metadata": {},
96 "metadata": {},
97 "source": [
97 "source": [
98 "The %cython_pyximport magic"
98 "The %cython_pyximport magic"
99 ]
99 ]
100 },
100 },
101 {
101 {
102 "cell_type": "markdown",
102 "cell_type": "markdown",
103 "metadata": {},
103 "metadata": {},
104 "source": [
104 "source": [
105 "The `%%cython_pyximport` magic allows you to enter arbitrary Cython code into a cell. That Cython code is written as a `.pyx` file in the current working directory and then imported using `pyximport`. You have the specify the name of the module that the Code will appear in. All symbols from the module are imported automatically by the magic function."
105 "The `%%cython_pyximport` magic allows you to enter arbitrary Cython code into a cell. That Cython code is written as a `.pyx` file in the current working directory and then imported using `pyximport`. You have the specify the name of the module that the Code will appear in. All symbols from the module are imported automatically by the magic function."
106 ]
106 ]
107 },
107 },
108 {
108 {
109 "cell_type": "code",
109 "cell_type": "code",
110 "collapsed": false,
110 "collapsed": false,
111 "input": [
111 "input": [
112 "%%cython_pyximport foo\n",
112 "%%cython_pyximport foo\n",
113 "def f(x):\n",
113 "def f(x):\n",
114 " return 4.0*x"
114 " return 4.0*x"
115 ],
115 ],
116 "language": "python",
116 "language": "python",
117 "metadata": {},
117 "metadata": {},
118 "outputs": [],
118 "outputs": [],
119 "prompt_number": 4
119 "prompt_number": 4
120 },
120 },
121 {
121 {
122 "cell_type": "code",
122 "cell_type": "code",
123 "collapsed": false,
123 "collapsed": false,
124 "input": [
124 "input": [
125 "f(10)"
125 "f(10)"
126 ],
126 ],
127 "language": "python",
127 "language": "python",
128 "metadata": {},
128 "metadata": {},
129 "outputs": [
129 "outputs": [
130 {
130 {
131 "metadata": {},
131 "metadata": {},
132 "output_type": "pyout",
132 "output_type": "pyout",
133 "prompt_number": 5,
133 "prompt_number": 5,
134 "text": [
134 "text": [
135 "40.0"
135 "40.0"
136 ]
136 ]
137 }
137 }
138 ],
138 ],
139 "prompt_number": 5
139 "prompt_number": 5
140 },
140 },
141 {
141 {
142 "cell_type": "heading",
142 "cell_type": "heading",
143 "level": 2,
143 "level": 2,
144 "metadata": {},
144 "metadata": {},
145 "source": [
145 "source": [
146 "The %cython magic"
146 "The %cython magic"
147 ]
147 ]
148 },
148 },
149 {
149 {
150 "cell_type": "markdown",
150 "cell_type": "markdown",
151 "metadata": {},
151 "metadata": {},
152 "source": [
152 "source": [
153 "Probably the most important magic is the `%cython` magic. This is similar to the `%%cython_pyximport` magic, but doesn't require you to specify a module name. Instead, the `%%cython` magic uses manages everything using temporary files in the `~/.cython/magic` directory. All of the symbols in the Cython module are imported automatically by the magic.\n",
153 "Probably the most important magic is the `%cython` magic. This is similar to the `%%cython_pyximport` magic, but doesn't require you to specify a module name. Instead, the `%%cython` magic uses manages everything using temporary files in the `~/.cython/magic` directory. All of the symbols in the Cython module are imported automatically by the magic.\n",
154 "\n",
154 "\n",
155 "Here is a simple example of a Black-Scholes options pricing algorithm written in Cython. Please note that this example might not compile on non-POSIX systems (e.g., Windows) because of a missing `erf` symbol."
155 "Here is a simple example of a Black-Scholes options pricing algorithm written in Cython. Please note that this example might not compile on non-POSIX systems (e.g., Windows) because of a missing `erf` symbol."
156 ]
156 ]
157 },
157 },
158 {
158 {
159 "cell_type": "code",
159 "cell_type": "code",
160 "collapsed": false,
160 "collapsed": false,
161 "input": [
161 "input": [
162 "%%cython\n",
162 "%%cython\n",
163 "cimport cython\n",
163 "cimport cython\n",
164 "from libc.math cimport exp, sqrt, pow, log, erf\n",
164 "from libc.math cimport exp, sqrt, pow, log, erf\n",
165 "\n",
165 "\n",
166 "@cython.cdivision(True)\n",
166 "@cython.cdivision(True)\n",
167 "cdef double std_norm_cdf_cy(double x) nogil:\n",
167 "cdef double std_norm_cdf_cy(double x) nogil:\n",
168 " return 0.5*(1+erf(x/sqrt(2.0)))\n",
168 " return 0.5*(1+erf(x/sqrt(2.0)))\n",
169 "\n",
169 "\n",
170 "@cython.cdivision(True)\n",
170 "@cython.cdivision(True)\n",
171 "def black_scholes_cy(double s, double k, double t, double v,\n",
171 "def black_scholes_cy(double s, double k, double t, double v,\n",
172 " double rf, double div, double cp):\n",
172 " double rf, double div, double cp):\n",
173 " \"\"\"Price an option using the Black-Scholes model.\n",
173 " \"\"\"Price an option using the Black-Scholes model.\n",
174 " \n",
174 " \n",
175 " s : initial stock price\n",
175 " s : initial stock price\n",
176 " k : strike price\n",
176 " k : strike price\n",
177 " t : expiration time\n",
177 " t : expiration time\n",
178 " v : volatility\n",
178 " v : volatility\n",
179 " rf : risk-free rate\n",
179 " rf : risk-free rate\n",
180 " div : dividend\n",
180 " div : dividend\n",
181 " cp : +1/-1 for call/put\n",
181 " cp : +1/-1 for call/put\n",
182 " \"\"\"\n",
182 " \"\"\"\n",
183 " cdef double d1, d2, optprice\n",
183 " cdef double d1, d2, optprice\n",
184 " with nogil:\n",
184 " with nogil:\n",
185 " d1 = (log(s/k)+(rf-div+0.5*pow(v,2))*t)/(v*sqrt(t))\n",
185 " d1 = (log(s/k)+(rf-div+0.5*pow(v,2))*t)/(v*sqrt(t))\n",
186 " d2 = d1 - v*sqrt(t)\n",
186 " d2 = d1 - v*sqrt(t)\n",
187 " optprice = cp*s*exp(-div*t)*std_norm_cdf_cy(cp*d1) - \\\n",
187 " optprice = cp*s*exp(-div*t)*std_norm_cdf_cy(cp*d1) - \\\n",
188 " cp*k*exp(-rf*t)*std_norm_cdf_cy(cp*d2)\n",
188 " cp*k*exp(-rf*t)*std_norm_cdf_cy(cp*d2)\n",
189 " return optprice"
189 " return optprice"
190 ],
190 ],
191 "language": "python",
191 "language": "python",
192 "metadata": {},
192 "metadata": {},
193 "outputs": [],
193 "outputs": [],
194 "prompt_number": 6
194 "prompt_number": 6
195 },
195 },
196 {
196 {
197 "cell_type": "code",
197 "cell_type": "code",
198 "collapsed": false,
198 "collapsed": false,
199 "input": [
199 "input": [
200 "black_scholes_cy(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
200 "black_scholes_cy(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
201 ],
201 ],
202 "language": "python",
202 "language": "python",
203 "metadata": {},
203 "metadata": {},
204 "outputs": [
204 "outputs": [
205 {
205 {
206 "metadata": {},
206 "metadata": {},
207 "output_type": "pyout",
207 "output_type": "pyout",
208 "prompt_number": 7,
208 "prompt_number": 7,
209 "text": [
209 "text": [
210 "10.327861752731728"
210 "10.327861752731728"
211 ]
211 ]
212 }
212 }
213 ],
213 ],
214 "prompt_number": 7
214 "prompt_number": 7
215 },
215 },
216 {
216 {
217 "cell_type": "markdown",
217 "cell_type": "markdown",
218 "metadata": {},
218 "metadata": {},
219 "source": [
219 "source": [
220 "For comparison, the same code is implemented here in pure python."
220 "For comparison, the same code is implemented here in pure python."
221 ]
221 ]
222 },
222 },
223 {
223 {
224 "cell_type": "code",
224 "cell_type": "code",
225 "collapsed": false,
225 "collapsed": false,
226 "input": [
226 "input": [
227 "from math import exp, sqrt, pow, log, erf\n",
227 "from math import exp, sqrt, pow, log, erf\n",
228 "\n",
228 "\n",
229 "def std_norm_cdf_py(x):\n",
229 "def std_norm_cdf_py(x):\n",
230 " return 0.5*(1+erf(x/sqrt(2.0)))\n",
230 " return 0.5*(1+erf(x/sqrt(2.0)))\n",
231 "\n",
231 "\n",
232 "def black_scholes_py(s, k, t, v, rf, div, cp):\n",
232 "def black_scholes_py(s, k, t, v, rf, div, cp):\n",
233 " \"\"\"Price an option using the Black-Scholes model.\n",
233 " \"\"\"Price an option using the Black-Scholes model.\n",
234 " \n",
234 " \n",
235 " s : initial stock price\n",
235 " s : initial stock price\n",
236 " k : strike price\n",
236 " k : strike price\n",
237 " t : expiration time\n",
237 " t : expiration time\n",
238 " v : volatility\n",
238 " v : volatility\n",
239 " rf : risk-free rate\n",
239 " rf : risk-free rate\n",
240 " div : dividend\n",
240 " div : dividend\n",
241 " cp : +1/-1 for call/put\n",
241 " cp : +1/-1 for call/put\n",
242 " \"\"\"\n",
242 " \"\"\"\n",
243 " d1 = (log(s/k)+(rf-div+0.5*pow(v,2))*t)/(v*sqrt(t))\n",
243 " d1 = (log(s/k)+(rf-div+0.5*pow(v,2))*t)/(v*sqrt(t))\n",
244 " d2 = d1 - v*sqrt(t)\n",
244 " d2 = d1 - v*sqrt(t)\n",
245 " optprice = cp*s*exp(-div*t)*std_norm_cdf_py(cp*d1) - \\\n",
245 " optprice = cp*s*exp(-div*t)*std_norm_cdf_py(cp*d1) - \\\n",
246 " cp*k*exp(-rf*t)*std_norm_cdf_py(cp*d2)\n",
246 " cp*k*exp(-rf*t)*std_norm_cdf_py(cp*d2)\n",
247 " return optprice"
247 " return optprice"
248 ],
248 ],
249 "language": "python",
249 "language": "python",
250 "metadata": {},
250 "metadata": {},
251 "outputs": [],
251 "outputs": [],
252 "prompt_number": 8
252 "prompt_number": 8
253 },
253 },
254 {
254 {
255 "cell_type": "code",
255 "cell_type": "code",
256 "collapsed": false,
256 "collapsed": false,
257 "input": [
257 "input": [
258 "black_scholes_py(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
258 "black_scholes_py(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
259 ],
259 ],
260 "language": "python",
260 "language": "python",
261 "metadata": {},
261 "metadata": {},
262 "outputs": [
262 "outputs": [
263 {
263 {
264 "metadata": {},
264 "metadata": {},
265 "output_type": "pyout",
265 "output_type": "pyout",
266 "prompt_number": 9,
266 "prompt_number": 9,
267 "text": [
267 "text": [
268 "10.327861752731728"
268 "10.327861752731728"
269 ]
269 ]
270 }
270 }
271 ],
271 ],
272 "prompt_number": 9
272 "prompt_number": 9
273 },
273 },
274 {
274 {
275 "cell_type": "markdown",
275 "cell_type": "markdown",
276 "metadata": {},
276 "metadata": {},
277 "source": [
277 "source": [
278 "Below we see the runtime of the two functions: the Cython version is nearly a factor of 10 faster."
278 "Below we see the runtime of the two functions: the Cython version is nearly a factor of 10 faster."
279 ]
279 ]
280 },
280 },
281 {
281 {
282 "cell_type": "code",
282 "cell_type": "code",
283 "collapsed": false,
283 "collapsed": false,
284 "input": [
284 "input": [
285 "%timeit black_scholes_cy(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
285 "%timeit black_scholes_cy(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
286 ],
286 ],
287 "language": "python",
287 "language": "python",
288 "metadata": {},
288 "metadata": {},
289 "outputs": [
289 "outputs": [
290 {
290 {
291 "output_type": "stream",
291 "output_type": "stream",
292 "stream": "stdout",
292 "stream": "stdout",
293 "text": [
293 "text": [
294 "1000000 loops, best of 3: 319 ns per loop\n"
294 "1000000 loops, best of 3: 319 ns per loop\n"
295 ]
295 ]
296 }
296 }
297 ],
297 ],
298 "prompt_number": 10
298 "prompt_number": 10
299 },
299 },
300 {
300 {
301 "cell_type": "code",
301 "cell_type": "code",
302 "collapsed": false,
302 "collapsed": false,
303 "input": [
303 "input": [
304 "%timeit black_scholes_py(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
304 "%timeit black_scholes_py(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
305 ],
305 ],
306 "language": "python",
306 "language": "python",
307 "metadata": {},
307 "metadata": {},
308 "outputs": [
308 "outputs": [
309 {
309 {
310 "output_type": "stream",
310 "output_type": "stream",
311 "stream": "stdout",
311 "stream": "stdout",
312 "text": [
312 "text": [
313 "100000 loops, best of 3: 2.28 \u00b5s per loop\n"
313 "100000 loops, best of 3: 2.28 \u00b5s per loop\n"
314 ]
314 ]
315 }
315 }
316 ],
316 ],
317 "prompt_number": 11
317 "prompt_number": 11
318 },
318 },
319 {
319 {
320 "cell_type": "heading",
320 "cell_type": "heading",
321 "level": 2,
321 "level": 2,
322 "metadata": {},
322 "metadata": {},
323 "source": [
323 "source": [
324 "External libraries"
324 "External libraries"
325 ]
325 ]
326 },
326 },
327 {
327 {
328 "cell_type": "markdown",
328 "cell_type": "markdown",
329 "metadata": {},
329 "metadata": {},
330 "source": [
330 "source": [
331 "Cython allows you to specify additional libraries to be linked with your extension, you can do so with the `-l` flag (also spelled `--lib`). Note that this flag can be passed more than once to specify multiple libraries, such as `-lm -llib2 --lib lib3`. Here's a simple example of how to access the system math library:"
331 "Cython allows you to specify additional libraries to be linked with your extension, you can do so with the `-l` flag (also spelled `--lib`). Note that this flag can be passed more than once to specify multiple libraries, such as `-lm -llib2 --lib lib3`. Here's a simple example of how to access the system math library:"
332 ]
332 ]
333 },
333 },
334 {
334 {
335 "cell_type": "code",
335 "cell_type": "code",
336 "collapsed": false,
336 "collapsed": false,
337 "input": [
337 "input": [
338 "%%cython -lm\n",
338 "%%cython -lm\n",
339 "from libc.math cimport sin\n",
339 "from libc.math cimport sin\n",
340 "print 'sin(1)=', sin(1)"
340 "print 'sin(1)=', sin(1)"
341 ],
341 ],
342 "language": "python",
342 "language": "python",
343 "metadata": {},
343 "metadata": {},
344 "outputs": [
344 "outputs": [
345 {
345 {
346 "output_type": "stream",
346 "output_type": "stream",
347 "stream": "stdout",
347 "stream": "stdout",
348 "text": [
348 "text": [
349 "sin(1)= 0.841470984808\n"
349 "sin(1)= 0.841470984808\n"
350 ]
350 ]
351 }
351 }
352 ],
352 ],
353 "prompt_number": 12
353 "prompt_number": 12
354 },
354 },
355 {
355 {
356 "cell_type": "markdown",
356 "cell_type": "markdown",
357 "metadata": {},
357 "metadata": {},
358 "source": [
358 "source": [
359 "You can similarly use the `-I/--include` flag to add include directories to the search path, and `-c/--compile-args` to add extra flags that are passed to Cython via the `extra_compile_args` of the distutils `Extension` class. Please see [the Cython docs on C library usage](http://docs.cython.org/src/tutorial/clibraries.html) for more details on the use of these flags."
359 "You can similarly use the `-I/--include` flag to add include directories to the search path, and `-c/--compile-args` to add extra flags that are passed to Cython via the `extra_compile_args` of the distutils `Extension` class. Please see [the Cython docs on C library usage](http://docs.cython.org/src/tutorial/clibraries.html) for more details on the use of these flags."
360 ]
360 ]
361 }
361 }
362 ],
362 ],
363 "metadata": {}
363 "metadata": {}
364 }
364 }
365 ]
365 ]
366 }
366 }
General Comments 0
You need to be logged in to leave comments. Login now