Skip to content

Commit 4f4e3a6

Browse files
authored
Merge pull request #63 from davidbradway/NumPy
numpy -> NumPy
2 parents 1269474 + dd66295 commit 4f4e3a6

10 files changed

+78
-78
lines changed

01-preface.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ Diseases`_, the Bordeaux laboratory for research in computer science
1919
(LaBRI_), the `University of Bordeaux`_ and the national center for scientific
2020
research (CNRS_).
2121

22-
He has been using Python for more than 15 years and numpy for more than 10
22+
He has been using Python for more than 15 years and NumPy for more than 10
2323
years for modeling in neuroscience, machine learning and for advanced
2424
visualization (OpenGL). Nicolas P. Rougier is the author of several online
25-
resources and tutorials (Matplotlib, numpy, OpenGL) and he's teaching Python,
26-
numpy and scientific visualization at the University of Bordeaux and in various
25+
resources and tutorials (Matplotlib, NumPy, OpenGL) and he's teaching Python,
26+
NumPy and scientific visualization at the University of Bordeaux and in various
2727
conferences and schools worldwide (SciPy, EuroScipy, etc). He's also the author
2828
of the popular article `Ten Simple Rules for Better Figures`_ and a popular
2929
`matplotlib tutorial
@@ -55,15 +55,15 @@ Prerequisites
5555
+++++++++++++
5656

5757
This is not a Python beginner guide and you should have an intermediate level in
58-
Python and ideally a beginner level in numpy. If this is not the case, have
58+
Python and ideally a beginner level in NumPy. If this is not the case, have
5959
a look at the bibliography_ for a curated list of resources.
6060

6161

6262
Conventions
6363
+++++++++++
6464

6565
We will use usual naming conventions. If not stated explicitly, each script
66-
should import numpy, scipy and matplotlib as:
66+
should import NumPy, scipy and matplotlib as:
6767

6868
.. code-block:: python
6969
@@ -80,7 +80,7 @@ Packages Version
8080
=========== =========
8181
Python 3.6.0
8282
----------- ---------
83-
Numpy 1.12.0
83+
NumPy 1.12.0
8484
----------- ---------
8585
Scipy 0.18.1
8686
----------- ---------

02-introduction.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Simple example
1515
such a case, you might want to use the magic command `%timeit` instead of the
1616
`custom one <code/tools.py>`_ I wrote.
1717

18-
Numpy is all about vectorization. If you are familiar with Python, this is the
18+
NumPy is all about vectorization. If you are familiar with Python, this is the
1919
main difficulty you'll face because you'll need to change your way of thinking
2020
and your new friends (among others) are named "vectors", "arrays", "views" or
2121
"ufuncs".
@@ -114,19 +114,19 @@ things faster:
114114
10 loops, best of 3: 2.21 msec per loop
115115
116116
We gained 85% of computation-time compared to the previous version, not so
117-
bad. But the advantage of this new version is that it makes numpy vectorization
118-
super simple. We just have to translate itertools call into numpy ones.
117+
bad. But the advantage of this new version is that it makes NumPy vectorization
118+
super simple. We just have to translate itertools call into NumPy ones.
119119

120120
.. code:: python
121121
122122
def random_walk_fastest(n=1000):
123-
# No 's' in numpy choice (Python offers choice & choices)
123+
# No 's' in NumPy choice (Python offers choice & choices)
124124
steps = np.random.choice([-1,+1], n)
125125
return np.cumsum(steps)
126126
127127
walk = random_walk_fastest(1000)
128128
129-
Not too difficult, but we gained a factor 500x using numpy:
129+
Not too difficult, but we gained a factor 500x using NumPy:
130130

131131
.. code:: pycon
132132
@@ -143,7 +143,7 @@ Readability vs speed
143143
--------------------
144144

145145
Before heading to the next chapter, I would like to warn you about a potential
146-
problem you may encounter once you'll have become familiar with numpy. It is a
146+
problem you may encounter once you'll have become familiar with NumPy. It is a
147147
very powerful library and you can make wonders with it but, most of the time,
148148
this comes at the price of readability. If you don't comment your code at the
149149
time of writing, you won't be able to tell what a function is doing after a few
@@ -166,5 +166,5 @@ and you don't need to read this book).
166166
return candidates[mask]
167167
168168
As you may have guessed, the second function is the
169-
vectorized-optimized-faster-numpy version of the first function. It is 10 times
169+
vectorized-optimized-faster-NumPy version of the first function. It is 10 times
170170
faster than the pure Python version, but it is hardly readable.

03-anatomy.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ Anatomy of an array
88
Introduction
99
------------
1010

11-
As explained in the Preface_, you should have a basic experience with numpy to
11+
As explained in the Preface_, you should have a basic experience with NumPy to
1212
read this book. If this is not the case, you'd better start with a beginner
1313
tutorial before coming back here. Consequently I'll only give here a quick
14-
reminder on the basic anatomy of numpy arrays, especially regarding the memory
14+
reminder on the basic anatomy of NumPy arrays, especially regarding the memory
1515
layout, view, copy and the data type. They are critical notions to
16-
understand if you want your computation to benefit from numpy philosophy.
16+
understand if you want your computation to benefit from NumPy philosophy.
1717

1818
Let's consider a simple example where we want to clear all the values from an
1919
array which has the dtype `np.float32`. How does one write it to maximize speed? The
20-
below syntax is rather obvious (at least for those familiar with numpy) but the
20+
below syntax is rather obvious (at least for those familiar with NumPy) but the
2121
above question asks to find the fastest operation.
2222

2323
.. code-block:: python
@@ -53,15 +53,15 @@ Interestingly enough, the obvious way of clearing all the values is not the
5353
fastest. By casting the array into a larger data type such as `np.float64`, we
5454
gained a 25% speed factor. But, by viewing the array as a byte array
5555
(`np.int8`), we gained a 50% factor. The reason for such speedup are to be
56-
found in the internal numpy machinery and the compiler optimization. This
57-
simple example illustrates the philosophy of numpy as we'll see in the next
56+
found in the internal NumPy machinery and the compiler optimization. This
57+
simple example illustrates the philosophy of NumPy as we'll see in the next
5858
section below.
5959

6060

6161
Memory layout
6262
-------------
6363

64-
The `numpy documentation
64+
The `NumPy documentation
6565
<https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html>`_ defines the
6666
ndarray class very clearly:
6767

@@ -333,7 +333,7 @@ copy:
333333
>>> print(Z2.base is None)
334334
True
335335
336-
Note that some numpy functions return a view when possible (e.g. `ravel
336+
Note that some NumPy functions return a view when possible (e.g. `ravel
337337
<https://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel.html>`_)
338338
while some others always return a copy (e.g. `flatten
339339
<https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flatten.html#numpy.ndarray.flatten>`_):

04-code-vectorization.rst

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Introduction
1010
------------
1111

1212
Code vectorization means that the problem you're trying to solve is inherently
13-
vectorizable and only requires a few numpy tricks to make it faster. Of course
13+
vectorizable and only requires a few NumPy tricks to make it faster. Of course
1414
it does not mean it is easy or straightforward, but at least it does not
1515
necessitate totally rethinking your problem (as it will be the case in the
1616
`Problem vectorization`_ chapter). Still, it may require some experience to see
@@ -23,7 +23,7 @@ is:
2323
def add_python(Z1,Z2):
2424
return [z1+z2 for (z1,z2) in zip(Z1,Z2)]
2525
26-
This first naive solution can be vectorized very easily using numpy:
26+
This first naive solution can be vectorized very easily using NumPy:
2727

2828
.. code-block:: python
2929
@@ -195,7 +195,7 @@ discovered by Richard K. Guy in 1970.
195195
:width: 100%
196196

197197

198-
Numpy implementation
198+
NumPy implementation
199199
++++++++++++++++++++
200200

201201
Starting from the Python version, the vectorization of the Game of Life
@@ -230,7 +230,7 @@ sure to consider all the eight neighbours.
230230
Z[1:-1, :-2] + Z[1:-1,2:] +
231231
Z[2: , :-2] + Z[2: ,1:-1] + Z[2: ,2:])
232232
233-
For the rule enforcement, we can write a first version using numpy's
233+
For the rule enforcement, we can write a first version using NumPy's
234234
`argwhere
235235
<http://docs.scipy.org/doc/numpy/reference/generated/numpy.argwhere.html>`_
236236
method that will give us the indices where a given condition is True.
@@ -259,7 +259,7 @@ method that will give us the indices where a given condition is True.
259259
Even if this first version does not use nested loops, it is far from optimal
260260
because of the use of the four `argwhere` calls that may be quite slow. We can
261261
instead factorize the rules into cells that will survive (stay at 1) and cells
262-
that will give birth. For doing this, we can take advantage of Numpy boolean
262+
that will give birth. For doing this, we can take advantage of NumPy boolean
263263
capability and write quite naturally:
264264

265265
.. note::
@@ -442,17 +442,17 @@ actually computes the sequence :math:`f_c(f_c(f_c ...)))`. The vectorization of
442442
such code is not totally straightforward because the internal `return` implies a
443443
differential processing of the element. Once it has diverged, we don't need to
444444
iterate any more and we can safely return the iteration count at
445-
divergence. The problem is to then do the same in numpy. But how?
445+
divergence. The problem is to then do the same in NumPy. But how?
446446

447-
Numpy implementation
447+
NumPy implementation
448448
++++++++++++++++++++
449449

450450
The trick is to search at each iteration values that have not yet
451451
diverged and update relevant information for these values and only
452452
these values. Because we start from :math:`Z = 0`, we know that each
453453
value will be updated at least once (when they're equal to :math:`0`,
454454
they have not yet diverged) and will stop being updated as soon as
455-
they've diverged. To do that, we'll use numpy fancy indexing with the
455+
they've diverged. To do that, we'll use NumPy fancy indexing with the
456456
`less(x1,x2)` function that return the truth value of `(x1 < x2)`
457457
element-wise.
458458

@@ -484,14 +484,14 @@ Here is the benchmark:
484484
1 loops, best of 3: 1.15 sec per loop
485485
486486
487-
Faster numpy implementation
487+
Faster NumPy implementation
488488
+++++++++++++++++++++++++++
489489

490490
The gain is roughly a 5x factor, not as much as we could have
491491
expected. Part of the problem is that the `np.less` function implies
492492
:math:`xn \times yn` tests at every iteration while we know that some
493493
values have already diverged. Even if these tests are performed at the
494-
C level (through numpy), the cost is nonetheless
494+
C level (through NumPy), the cost is nonetheless
495495
significant. Another approach proposed by `Dan Goodman
496496
<https://thesamovar.wordpress.com/>`_ is to work on a dynamic array at
497497
each iteration that stores only the points which have not yet
@@ -574,7 +574,7 @@ We now want to measure the fractal dimension of the Mandelbrot set using the
574574
<https://en.wikipedia.org/wiki/Minkowski–Bouligand_dimension>`_. To do that, we
575575
need to do box-counting with a decreasing box size (see figure below). As you
576576
can imagine, we cannot use pure Python because it would be way too slow. The goal of
577-
the exercise is to write a function using numpy that takes a two-dimensional
577+
the exercise is to write a function using NumPy that takes a two-dimensional
578578
float array and returns the dimension. We'll consider values in the array to be
579579
normalized (i.e. all values are between 0 and 1).
580580

@@ -602,7 +602,7 @@ References
602602

603603
* `How To Quickly Compute the Mandelbrot Set in Python <https://www.ibm.com/developerworks/community/blogs/jfp/entry/How_To_Compute_Mandelbrodt_Set_Quickly?lang=en>`_, Jean Francois Puget, 2015.
604604
* `My Christmas Gift: Mandelbrot Set Computation In Python <https://www.ibm.com/developerworks/community/blogs/jfp/entry/My_Christmas_Gift?lang=en>`_, Jean Francois Puget, 2015.
605-
* `Fast fractals with Python and Numpy <https://thesamovar.wordpress.com/2009/03/22/fast-fractals-with-python-and-numpy/>`_, Dan Goodman, 2009.
605+
* `Fast fractals with Python and NumPy <https://thesamovar.wordpress.com/2009/03/22/fast-fractals-with-python-and-numpy/>`_, Dan Goodman, 2009.
606606
* `Renormalizing the Mandelbrot Escape <http://linas.org/art-gallery/escape/escape.html>`_, Linas Vepstas, 1997.
607607

608608

@@ -724,7 +724,7 @@ To complete the picture, we can also create a `Flock` object:
724724
725725
Using this approach, we can have up to 50 boids until the computation
726726
time becomes too slow for a smooth animation. As you may have guessed,
727-
we can do much better using numpy, but let me first point out the main
727+
we can do much better using NumPy, but let me first point out the main
728728
problem with this Python implementation. If you look at the code, you
729729
will certainly notice there is a lot of redundancy. More precisely, we
730730
do not exploit the fact that the Euclidean distance is reflexive, that
@@ -736,10 +736,10 @@ caching the result for the other functions. In the end, we are
736736
computing :math:`3n^2` distances instead of :math:`\frac{n^2}{2}`.
737737

738738

739-
Numpy implementation
739+
NumPy implementation
740740
++++++++++++++++++++
741741

742-
As you might expect, the numpy implementation takes a different approach and
742+
As you might expect, the NumPy implementation takes a different approach and
743743
we'll gather all our boids into a `position` array and a `velocity` array:
744744

745745
.. code:: python

05-problem-vectorization.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ know it will be slow:
4444
4545
How to vectorize the problem then? If you remember your linear algebra course,
4646
you may have identified the expression `X[i] * Y[j]` to be very similar to a
47-
matrix product expression. So maybe we could benefit from some numpy
47+
matrix product expression. So maybe we could benefit from some NumPy
4848
speedup. One wrong solution would be to write:
4949

5050
.. code:: python
@@ -54,7 +54,7 @@ speedup. One wrong solution would be to write:
5454
5555
This is wrong because the `X*Y` expression will actually compute a new vector
5656
`Z` such that `Z[i] = X[i] * Y[i]` and this is not what we want. Instead, we
57-
can exploit numpy broadcasting by first reshaping the two vectors and then
57+
can exploit NumPy broadcasting by first reshaping the two vectors and then
5858
multiply them:
5959

6060
.. code:: python
@@ -145,15 +145,15 @@ factor of 70,000 with problem vectorization, just by writing our problem
145145
differently (even though you cannot expect such a huge speedup in all
146146
situations). However, code vectorization remains an important factor, and if we
147147
rewrite the last solution the Python way, the improvement is good but not as much as
148-
in the numpy version:
148+
in the NumPy version:
149149

150150
.. code:: python
151151
152152
def compute_python_better(x, y):
153153
return sum(x)*sum(y)
154154
155155
This new Python version is much faster than the previous Python version, but
156-
still, it is 50 times slower than the numpy version:
156+
still, it is 50 times slower than the NumPy version:
157157

158158
.. code:: python
159159
@@ -371,7 +371,7 @@ cell's new value is computed as the maximum value between the current cell value
371371
and the discounted (`gamma=0.9` in the case below) 4 neighbour values. The
372372
process starts as soon as the starting node value becomes strictly positive.
373373

374-
The numpy implementation is straightforward if we take advantage of the
374+
The NumPy implementation is straightforward if we take advantage of the
375375
`generic_filter` (from `scipy.ndimage`) for the diffusion process:
376376

377377
.. code:: python
@@ -497,12 +497,12 @@ two methods into a hybrid method.
497497

498498
However, the biggest problem for particle-based simulation is that particle
499499
interaction requires finding neighbouring particles and this has a cost as
500-
we've seen in the boids case. If we target Python and numpy only, it is probably
500+
we've seen in the boids case. If we target Python and NumPy only, it is probably
501501
better to choose the Eulerian method since vectorization will be almost trivial
502502
compared to the Lagrangian method.
503503

504504

505-
Numpy implementation
505+
NumPy implementation
506506
++++++++++++++++++++
507507

508508
I won't explain all the theory behind computational fluid dynamics because
@@ -518,7 +518,7 @@ wrote a very nice article for SIGGRAPH 1999 describing a technique to have
518518
stable fluids over time (i.e. whose solution in the long term does not
519519
diverge). `Alberto Santini <https://github.com/albertosantini/python-fluid>`_
520520
wrote a Python replication a long time ago (using numarray!) such that I only
521-
had to adapt it to modern numpy and accelerate it a bit using modern numpy
521+
had to adapt it to modern NumPy and accelerate it a bit using modern NumPy
522522
tricks.
523523

524524
I won't comment the code since it would be too long, but you can read the

0 commit comments

Comments
 (0)