File: numpy.rst

package info (click to toggle)
python-ase 3.24.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 15,448 kB
  • sloc: python: 144,945; xml: 2,728; makefile: 113; javascript: 47
file content (84 lines) | stat: -rw-r--r-- 2,591 bytes parent folder | download
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
.. _numpy:

Numeric arrays in Python
========================

Links to NumPy's webpage:

* `Numpy and Scipy Documentation`_
* `Numpy user guide <https://docs.scipy.org/doc/numpy/user/index.html>`_


.. _Numpy and Scipy Documentation: https://docs.scipy.org/doc/

ASE makes heavy use of an extension to Python called NumPy.  The
NumPy module defines an ``ndarray`` type that can hold large arrays of
uniform multidimensional numeric data.  An array is similar to a
``list`` or a ``tuple``, but it is a lot more powerful and efficient.

XXX More examples from everyday ASE-life here ...

>>> import numpy as np
>>> a = np.zeros((3, 2))
>>> a[:, 1] = 1.0
>>> a[1] = 2.0
>>> a
array([[ 0.,  1.],
       [ 2.,  2.],
       [ 0.,  1.]])
>>> a.shape
(3, 2)
>>> a.ndim
2


The conventions of numpy's linear algebra package:

>>> import numpy as np
>>>
>>> # Make a random hermitian matrix, H
>>> H = np.random.rand(6, 6) + 1.j * np.random.rand(6, 6)
>>> H = H + H.T.conj()
>>>
>>> # Determine eigenvalues and rotation matrix
>>> eps, U = np.linalg.eigh(H)
>>>
>>> # Sort eigenvalues
>>> sorted_indices = eps.real.argsort()
>>> eps = eps[sorted_indices]
>>> U = U[:, sorted_indices]
>>>
>>> # Check that U diagonalizes H:
>>> print(np.dot(np.dot(U.T.conj(), H), U) - np.diag(eps))
>>> print(np.allclose(np.dot(np.dot(U.T.conj(), H), U), np.diag(eps)))
>>>
>>> # The eigenvectors of H are the *coloumns* of U:
>>> np.allclose(np.dot(H, U[:, 3]), eps[3] * U[:, 3])
>>> np.allclose(np.dot(H, U), eps * U)

The rules for multiplying 1D arrays with 2D arrays:

* 1D arrays and treated like shape (1, N) arrays (row vectors).
* left and right multiplications are treated identically.
* A length `m` *row* vector can be multiplied with an `n \times m`
  matrix, producing the same result as if replaced by a matrix with
  `n` copies of the vector as rows.
* A length `n` *column* vector can be multiplied with an `n \times m`
  matrix, producing the same result as if replaced by a matrix with
  `m` copies of the vector as columns.

Thus, for the arrays below:

>>> M = np.arange(5 * 6).reshape(5, 6) # A matrix af shape (5, 6)
>>> v5 = np.arange(5) + 10             # A vector of length 5
>>> v51 = v5[:, None]                  # A length 5 column vector
>>> v6 = np.arange(6) - 12             # A vector of length 6
>>> v16 = v6[None, :]                  # A length 6 row vector

The following identities hold::

  v6 * M == v16 * M == M * v6 == M * v16 == M * v16.repeat(5, 0)
  v51 * M == M * v51 == M * v51.repeat(6, 1)

The same rules apply for adding and subtracting 1D arrays to /
from 2D arrays.