Chris@87
|
1 """
|
Chris@87
|
2 =============
|
Chris@87
|
3 Miscellaneous
|
Chris@87
|
4 =============
|
Chris@87
|
5
|
Chris@87
|
6 IEEE 754 Floating Point Special Values
|
Chris@87
|
7 --------------------------------------
|
Chris@87
|
8
|
Chris@87
|
9 Special values defined in numpy: nan, inf,
|
Chris@87
|
10
|
Chris@87
|
11 NaNs can be used as a poor-man's mask (if you don't care what the
|
Chris@87
|
12 original value was)
|
Chris@87
|
13
|
Chris@87
|
14 Note: cannot use equality to test NaNs. E.g.: ::
|
Chris@87
|
15
|
Chris@87
|
16 >>> myarr = np.array([1., 0., np.nan, 3.])
|
Chris@87
|
17 >>> np.where(myarr == np.nan)
|
Chris@87
|
18 >>> np.nan == np.nan # is always False! Use special numpy functions instead.
|
Chris@87
|
19 False
|
Chris@87
|
20 >>> myarr[myarr == np.nan] = 0. # doesn't work
|
Chris@87
|
21 >>> myarr
|
Chris@87
|
22 array([ 1., 0., NaN, 3.])
|
Chris@87
|
23 >>> myarr[np.isnan(myarr)] = 0. # use this instead find
|
Chris@87
|
24 >>> myarr
|
Chris@87
|
25 array([ 1., 0., 0., 3.])
|
Chris@87
|
26
|
Chris@87
|
27 Other related special value functions: ::
|
Chris@87
|
28
|
Chris@87
|
29 isinf(): True if value is inf
|
Chris@87
|
30 isfinite(): True if not nan or inf
|
Chris@87
|
31 nan_to_num(): Map nan to 0, inf to max float, -inf to min float
|
Chris@87
|
32
|
Chris@87
|
33 The following corresponds to the usual functions except that nans are excluded
|
Chris@87
|
34 from the results: ::
|
Chris@87
|
35
|
Chris@87
|
36 nansum()
|
Chris@87
|
37 nanmax()
|
Chris@87
|
38 nanmin()
|
Chris@87
|
39 nanargmax()
|
Chris@87
|
40 nanargmin()
|
Chris@87
|
41
|
Chris@87
|
42 >>> x = np.arange(10.)
|
Chris@87
|
43 >>> x[3] = np.nan
|
Chris@87
|
44 >>> x.sum()
|
Chris@87
|
45 nan
|
Chris@87
|
46 >>> np.nansum(x)
|
Chris@87
|
47 42.0
|
Chris@87
|
48
|
Chris@87
|
49 How numpy handles numerical exceptions
|
Chris@87
|
50 --------------------------------------
|
Chris@87
|
51
|
Chris@87
|
52 The default is to ``'warn'`` for ``invalid``, ``divide``, and ``overflow``
|
Chris@87
|
53 and ``'ignore'`` for ``underflow``. But this can be changed, and it can be
|
Chris@87
|
54 set individually for different kinds of exceptions. The different behaviors
|
Chris@87
|
55 are:
|
Chris@87
|
56
|
Chris@87
|
57 - 'ignore' : Take no action when the exception occurs.
|
Chris@87
|
58 - 'warn' : Print a `RuntimeWarning` (via the Python `warnings` module).
|
Chris@87
|
59 - 'raise' : Raise a `FloatingPointError`.
|
Chris@87
|
60 - 'call' : Call a function specified using the `seterrcall` function.
|
Chris@87
|
61 - 'print' : Print a warning directly to ``stdout``.
|
Chris@87
|
62 - 'log' : Record error in a Log object specified by `seterrcall`.
|
Chris@87
|
63
|
Chris@87
|
64 These behaviors can be set for all kinds of errors or specific ones:
|
Chris@87
|
65
|
Chris@87
|
66 - all : apply to all numeric exceptions
|
Chris@87
|
67 - invalid : when NaNs are generated
|
Chris@87
|
68 - divide : divide by zero (for integers as well!)
|
Chris@87
|
69 - overflow : floating point overflows
|
Chris@87
|
70 - underflow : floating point underflows
|
Chris@87
|
71
|
Chris@87
|
72 Note that integer divide-by-zero is handled by the same machinery.
|
Chris@87
|
73 These behaviors are set on a per-thread basis.
|
Chris@87
|
74
|
Chris@87
|
75 Examples
|
Chris@87
|
76 --------
|
Chris@87
|
77
|
Chris@87
|
78 ::
|
Chris@87
|
79
|
Chris@87
|
80 >>> oldsettings = np.seterr(all='warn')
|
Chris@87
|
81 >>> np.zeros(5,dtype=np.float32)/0.
|
Chris@87
|
82 invalid value encountered in divide
|
Chris@87
|
83 >>> j = np.seterr(under='ignore')
|
Chris@87
|
84 >>> np.array([1.e-100])**10
|
Chris@87
|
85 >>> j = np.seterr(invalid='raise')
|
Chris@87
|
86 >>> np.sqrt(np.array([-1.]))
|
Chris@87
|
87 FloatingPointError: invalid value encountered in sqrt
|
Chris@87
|
88 >>> def errorhandler(errstr, errflag):
|
Chris@87
|
89 ... print "saw stupid error!"
|
Chris@87
|
90 >>> np.seterrcall(errorhandler)
|
Chris@87
|
91 <function err_handler at 0x...>
|
Chris@87
|
92 >>> j = np.seterr(all='call')
|
Chris@87
|
93 >>> np.zeros(5, dtype=np.int32)/0
|
Chris@87
|
94 FloatingPointError: invalid value encountered in divide
|
Chris@87
|
95 saw stupid error!
|
Chris@87
|
96 >>> j = np.seterr(**oldsettings) # restore previous
|
Chris@87
|
97 ... # error-handling settings
|
Chris@87
|
98
|
Chris@87
|
99 Interfacing to C
|
Chris@87
|
100 ----------------
|
Chris@87
|
101 Only a survey of the choices. Little detail on how each works.
|
Chris@87
|
102
|
Chris@87
|
103 1) Bare metal, wrap your own C-code manually.
|
Chris@87
|
104
|
Chris@87
|
105 - Plusses:
|
Chris@87
|
106
|
Chris@87
|
107 - Efficient
|
Chris@87
|
108 - No dependencies on other tools
|
Chris@87
|
109
|
Chris@87
|
110 - Minuses:
|
Chris@87
|
111
|
Chris@87
|
112 - Lots of learning overhead:
|
Chris@87
|
113
|
Chris@87
|
114 - need to learn basics of Python C API
|
Chris@87
|
115 - need to learn basics of numpy C API
|
Chris@87
|
116 - need to learn how to handle reference counting and love it.
|
Chris@87
|
117
|
Chris@87
|
118 - Reference counting often difficult to get right.
|
Chris@87
|
119
|
Chris@87
|
120 - getting it wrong leads to memory leaks, and worse, segfaults
|
Chris@87
|
121
|
Chris@87
|
122 - API will change for Python 3.0!
|
Chris@87
|
123
|
Chris@87
|
124 2) Cython
|
Chris@87
|
125
|
Chris@87
|
126 - Plusses:
|
Chris@87
|
127
|
Chris@87
|
128 - avoid learning C API's
|
Chris@87
|
129 - no dealing with reference counting
|
Chris@87
|
130 - can code in pseudo python and generate C code
|
Chris@87
|
131 - can also interface to existing C code
|
Chris@87
|
132 - should shield you from changes to Python C api
|
Chris@87
|
133 - has become the de-facto standard within the scientific Python community
|
Chris@87
|
134 - fast indexing support for arrays
|
Chris@87
|
135
|
Chris@87
|
136 - Minuses:
|
Chris@87
|
137
|
Chris@87
|
138 - Can write code in non-standard form which may become obsolete
|
Chris@87
|
139 - Not as flexible as manual wrapping
|
Chris@87
|
140
|
Chris@87
|
141 4) ctypes
|
Chris@87
|
142
|
Chris@87
|
143 - Plusses:
|
Chris@87
|
144
|
Chris@87
|
145 - part of Python standard library
|
Chris@87
|
146 - good for interfacing to existing sharable libraries, particularly
|
Chris@87
|
147 Windows DLLs
|
Chris@87
|
148 - avoids API/reference counting issues
|
Chris@87
|
149 - good numpy support: arrays have all these in their ctypes
|
Chris@87
|
150 attribute: ::
|
Chris@87
|
151
|
Chris@87
|
152 a.ctypes.data a.ctypes.get_strides
|
Chris@87
|
153 a.ctypes.data_as a.ctypes.shape
|
Chris@87
|
154 a.ctypes.get_as_parameter a.ctypes.shape_as
|
Chris@87
|
155 a.ctypes.get_data a.ctypes.strides
|
Chris@87
|
156 a.ctypes.get_shape a.ctypes.strides_as
|
Chris@87
|
157
|
Chris@87
|
158 - Minuses:
|
Chris@87
|
159
|
Chris@87
|
160 - can't use for writing code to be turned into C extensions, only a wrapper
|
Chris@87
|
161 tool.
|
Chris@87
|
162
|
Chris@87
|
163 5) SWIG (automatic wrapper generator)
|
Chris@87
|
164
|
Chris@87
|
165 - Plusses:
|
Chris@87
|
166
|
Chris@87
|
167 - around a long time
|
Chris@87
|
168 - multiple scripting language support
|
Chris@87
|
169 - C++ support
|
Chris@87
|
170 - Good for wrapping large (many functions) existing C libraries
|
Chris@87
|
171
|
Chris@87
|
172 - Minuses:
|
Chris@87
|
173
|
Chris@87
|
174 - generates lots of code between Python and the C code
|
Chris@87
|
175 - can cause performance problems that are nearly impossible to optimize
|
Chris@87
|
176 out
|
Chris@87
|
177 - interface files can be hard to write
|
Chris@87
|
178 - doesn't necessarily avoid reference counting issues or needing to know
|
Chris@87
|
179 API's
|
Chris@87
|
180
|
Chris@87
|
181 7) scipy.weave
|
Chris@87
|
182
|
Chris@87
|
183 - Plusses:
|
Chris@87
|
184
|
Chris@87
|
185 - can turn many numpy expressions into C code
|
Chris@87
|
186 - dynamic compiling and loading of generated C code
|
Chris@87
|
187 - can embed pure C code in Python module and have weave extract, generate
|
Chris@87
|
188 interfaces and compile, etc.
|
Chris@87
|
189
|
Chris@87
|
190 - Minuses:
|
Chris@87
|
191
|
Chris@87
|
192 - Future very uncertain: it's the only part of Scipy not ported to Python 3
|
Chris@87
|
193 and is effectively deprecated in favor of Cython.
|
Chris@87
|
194
|
Chris@87
|
195 8) Psyco
|
Chris@87
|
196
|
Chris@87
|
197 - Plusses:
|
Chris@87
|
198
|
Chris@87
|
199 - Turns pure python into efficient machine code through jit-like
|
Chris@87
|
200 optimizations
|
Chris@87
|
201 - very fast when it optimizes well
|
Chris@87
|
202
|
Chris@87
|
203 - Minuses:
|
Chris@87
|
204
|
Chris@87
|
205 - Only on intel (windows?)
|
Chris@87
|
206 - Doesn't do much for numpy?
|
Chris@87
|
207
|
Chris@87
|
208 Interfacing to Fortran:
|
Chris@87
|
209 -----------------------
|
Chris@87
|
210 The clear choice to wrap Fortran code is
|
Chris@87
|
211 `f2py <http://docs.scipy.org/doc/numpy-dev/f2py/>`_.
|
Chris@87
|
212
|
Chris@87
|
213 Pyfort is an older alternative, but not supported any longer.
|
Chris@87
|
214 Fwrap is a newer project that looked promising but isn't being developed any
|
Chris@87
|
215 longer.
|
Chris@87
|
216
|
Chris@87
|
217 Interfacing to C++:
|
Chris@87
|
218 -------------------
|
Chris@87
|
219 1) Cython
|
Chris@87
|
220 2) CXX
|
Chris@87
|
221 3) Boost.python
|
Chris@87
|
222 4) SWIG
|
Chris@87
|
223 5) SIP (used mainly in PyQT)
|
Chris@87
|
224
|
Chris@87
|
225 """
|
Chris@87
|
226 from __future__ import division, absolute_import, print_function
|