[go: up one dir, main page]

File: numpy_guide.rst

package info (click to toggle)
uncertainties 3.1.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 652 kB
  • sloc: python: 4,062; makefile: 94; sh: 16
file content (226 lines) | stat: -rw-r--r-- 7,389 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
.. index: NumPy support

=======================
Uncertainties in arrays
=======================

.. index:: unumpy

The unumpy package
==================

This package contains:

1. utilities that help with the **creation and manipulation** of
NumPy_ arrays and matrices of numbers with uncertainties;

2. **generalizations** of multiple NumPy functions so that they also
work with arrays that contain numbers with uncertainties.

While :ref:`basic operations on arrays <simple_array_use>` that
contain numbers with uncertainties can be performed without it, the
:mod:`unumpy` package is useful for more advanced uses.

Operations on arrays (including their cosine, etc.)  can thus be
performed transparently.

These features can be made available with

>>> from uncertainties import unumpy

.. Here, there is no need to mention unumpy.unlinalg, because it is indeed
   made available through "import unumpy".

Creation and manipulation of arrays and matrices
------------------------------------------------

.. index::
   single: arrays; creation and manipulation
   single: creation; arrays

Arrays
^^^^^^

Arrays of numbers with uncertainties can be built from values and
uncertainties:

>>> arr = unumpy.uarray([1, 2], [0.01, 0.002])
>>> print arr
[1.0+/-0.01 2.0+/-0.002]

NumPy arrays of numbers with uncertainties can also be built directly
through NumPy, thanks to NumPy's support of arrays of arbitrary objects:

>>> arr = numpy.array([ufloat(1, 0.1), ufloat(2, 0.002)])

.. index::
   single: matrices; creation and manipulation
   single: creation; matrices

Matrices
^^^^^^^^

Matrices of numbers with uncertainties are best created in one of
two ways.  The first way is similar to using :func:`uarray`:

>>> mat = unumpy.umatrix([1, 2], [0.01, 0.002])

Matrices can also be built by converting arrays of numbers with
uncertainties into matrices through the :class:`unumpy.matrix` class:

>>> mat = unumpy.matrix(arr)

:class:`unumpy.matrix` objects behave like :class:`numpy.matrix`
objects of numbers with uncertainties, but with better support for
some operations (such as matrix inversion).  For instance, regular
NumPy matrices cannot be inverted, if they contain numbers with
uncertainties (i.e., ``numpy.matrix([[ufloat(…), …]]).I`` does not
work).  This is why the :class:`unumpy.matrix` class is provided: both
the inverse and the pseudo-inverse of a matrix can be calculated in
the usual way: if :data:`mat` is a :class:`unumpy.matrix`,

>>> print mat.I

does calculate the inverse or pseudo-inverse of :data:`mat` with
uncertainties.

.. index::
   pair: nominal value; uniform access (array)
   pair: uncertainty; uniform access (array)
   pair: standard deviation; uniform access (array)

Uncertainties and nominal values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Nominal values and uncertainties in arrays (and matrices) can be
directly accessed (through functions that work on pure float arrays
too):

>>> unumpy.nominal_values(arr)
array([ 1.,  2.])
>>> unumpy.std_devs(mat)
matrix([[ 0.1  ,  0.002]])


.. index:: mathematical operation; on an array of numbers

Mathematical functions
----------------------

This module defines uncertainty-aware mathematical functions that
generalize those from :mod:`uncertainties.umath` so that they work on
NumPy arrays of numbers with uncertainties instead of just scalars:

>>> print unumpy.cos(arr)  # Cosine of each array element

NumPy's function names are used, and not those from the :mod:`math`
module (for instance, :func:`unumpy.arccos` is defined, like in NumPy,
and is not named :func:`acos` like in the :mod:`math` module).

The definition of the mathematical quantities calculated by these
functions is available in the documentation for
:mod:`uncertainties.umath` (which is accessible through :func:`help`
or ``pydoc``).

.. index::
   pair: testing and operations (in arrays); NaN

NaN testing and NaN-aware operations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

One particular function pertains to NaN testing: ``unumpy.isnan()``. It
returns true for each NaN *nominal value* (and false otherwise).

Since NaN±1 is *not* (the scalar) NaN, functions like
``numpy.nanmean()`` do not skip such values. This is where
``unumpy.isnan()`` is useful, as it can be used for masking out numbers
with a NaN nominal value:

>>> nan = float("nan")
>>> arr = numpy.array([nan, uncertainties.ufloat(nan, 1), uncertainties.ufloat(1, nan), 2])
>>> arr
array([nan, nan+/-1.0, 1.0+/-nan, 2], dtype=object)
>>> arr[~unumpy.isnan(arr)].mean()
1.5+/-nan

or equivalently, by using masked arrays:

>>> masked_arr = numpy.ma.array(arr, mask=unumpy.isnan(arr))
>>> masked_arr.mean()
1.5+/-nan

In this case the uncertainty is NaN as it should be, because one of
the numbers does have an undefined uncertainty, which makes the final
uncertainty undefined (but the average is well defined). In general,
uncertainties are not NaN and one obtains the mean of the non-NaN
values.

.. index:: saving to file; array
.. index:: reading from file; array

Storing arrays in text format
=============================

Arrays of numbers with uncertainties can be directly :ref:`pickled
<pickling>`, saved to file and read from a file. Pickling has the
advantage of preserving correlations between errors.

Storing instead arrays in **text format** loses correlations between
errors but has the advantage of being both computer- and
human-readable. This can be done through NumPy's :func:`savetxt` and
:func:`loadtxt`.

Writing the array to file can be done by asking NumPy to use the
*representation* of numbers with uncertainties (instead of the default
float conversion):

>>> numpy.savetxt('arr.txt', arr, fmt='%r')

This produces a file `arr.txt` that contains a text representation of
the array::

  1.0+/-0.01
  2.0+/-0.002

The file can then be read back by instructing NumPy to convert all the
columns with :func:`uncertainties.ufloat_fromstr`. The number
:data:`num_cols` of columns in the input file (1, in our example) must
be determined in advance, because NumPy requires a converter for each
column separately. For Python 2:

>>> converters = dict.fromkeys(range(num_cols), uncertainties.ufloat_fromstr)

For Python 3, since :func:`numpy.loadtxt` passes bytes to converters,
they must first be converted into a string:

>>> converters = dict.fromkeys(
        range(num_cols),
        lambda col_bytes: uncertainties.ufloat_fromstr(col_bytes.decode("latin1")))

(Latin 1 appears to in fact be the encoding used in
:func:`numpy.savetxt` [as of NumPy 1.12]. This encoding seems
to be the one hardcoded in :func:`numpy.compat.asbytes`.)

The array can then be loaded:

>>> arr = numpy.loadtxt('arr.txt', converters=converters, dtype=object)

.. index:: linear algebra; additional functions, ulinalg

Additional array functions: unumpy.ulinalg
==========================================

The :mod:`unumpy.ulinalg` module contains more uncertainty-aware
functions for arrays that contain numbers with uncertainties.

It currently offers generalizations of two functions from
:mod:`numpy.linalg` that work on arrays (or matrices) that contain
numbers with uncertainties, the **matrix inverse and pseudo-inverse**:

>>> unumpy.ulinalg.inv([[ufloat(2, 0.1)]])
array([[0.5+/-0.025]], dtype=object)
>>> unumpy.ulinalg.pinv(mat)
matrix([[0.2+/-0.0012419339757],
        [0.4+/-0.00161789987329]], dtype=object)

.. _NumPy: http://numpy.scipy.org/