1
1
//! Safe interface for NumPy ndarray
2
2
use ndarray:: * ;
3
- use npyffi:: { self , npy_intp, PY_ARRAY_API } ;
3
+ use npyffi:: { self , npy_intp, PY_ARRAY_API , NPY_ORDER } ;
4
4
use num_traits:: AsPrimitive ;
5
5
use pyo3:: * ;
6
6
use std:: iter:: ExactSizeIterator ;
@@ -11,18 +11,82 @@ use std::ptr;
11
11
12
12
use convert:: { NpyIndex , ToNpyDims } ;
13
13
use error:: { ErrorKind , IntoPyErr } ;
14
- use types:: { NpyDataType , TypeNum , NPY_ORDER } ;
15
-
16
- /// Interface for [NumPy ndarray](https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html).
14
+ use types:: { NpyDataType , TypeNum } ;
15
+
16
+ /// A safe, static-typed interface for
17
+ /// [NumPy ndarray](https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html).
18
+ ///
19
+ /// # Memory location
20
+ /// Numpy api allows to use a memory area allocated outside Pyhton.
21
+ ///
22
+ /// However, we designed `PyArray` to always **owns a memory area allocated in Python's private
23
+ /// heap**, where all memories are managed by GC.
24
+ ///
25
+ /// This means you always need to pay allocation cost when you create a `PyArray`, but don't need
26
+ /// to fear memory leak.
27
+ ///
28
+ /// # Reference
29
+ ///
30
+ /// Like [`new`](#method.new), most constractor methods of this type returns `&PyArray`.
31
+ ///
32
+ /// See [pyo3's document](https://pyo3.rs/master/doc/pyo3/index.html#ownership-and-lifetimes)
33
+ /// for the reason.
34
+ ///
35
+ /// # Mutation
36
+ /// You can do destructive changes to `PyArray` via &self methods like [`move_to`](#method.move_to).
37
+ ///
38
+ /// About this design, see
39
+ /// [pyo3's document](https://pyo3.rs/master/doc/pyo3/index.html#ownership-and-lifetimes), too.
40
+ ///
41
+ /// # Dimension
42
+ /// `PyArray` has 2 type parametes `T` and `D`. `T` represents its data type like `f32`, and `D`
43
+ /// represents its dimension.
44
+ ///
45
+ /// To specify the dimension, you can use types which implements
46
+ /// [Dimension](https://docs.rs/ndarray/0.12/ndarray/trait.Dimension.html).
47
+ ///
48
+ /// Typically, you can use `Ix1, Ix2, ..` for fixed size arrays, and use `IxDyn` for dynamic
49
+ /// dimensioned arrays. They're re-exported from `ndarray` crate.
50
+ ///
51
+ /// You can also use various type aliases we provide, like [`PyArray1`](./type.PyArray1.html)
52
+ /// or [`PyArrayDyn`](./type.PyArrayDyn.html).
53
+ ///
54
+ /// Many constructor methods takes a type which implements
55
+ /// [`IntoDimension`](https://docs.rs/ndarray/0.12/ndarray/dimension/conversion/trait.IntoDimension.html)
56
+ /// trait. Typically, you can use array(e.g. `[3, 4, 5]`) or tuple(e.g. `(3, 4, 5)`) as a dimension.
57
+ /// # Example
58
+ /// ```
59
+ /// # #[macro_use] extern crate ndarray; extern crate pyo3; extern crate numpy; fn main() {
60
+ /// use pyo3::{GILGuard, Python};
61
+ /// use numpy::PyArray;
62
+ /// use ndarray::Array;
63
+ /// let gil = Python::acquire_gil();
64
+ /// let pyarray = PyArray::arange(gil.python(), 0., 4., 1.).reshape([2, 2]).unwrap();
65
+ /// let array = array![[3., 4.], [5., 6.]];
66
+ /// assert_eq!(
67
+ /// array.dot(&pyarray.as_array().unwrap()),
68
+ /// array![[8., 15.], [12., 23.]]
69
+ /// );
70
+ /// # }
71
+ /// ```
17
72
pub struct PyArray < T , D > ( PyObject , PhantomData < T > , PhantomData < D > ) ;
73
+
74
+ /// one-dimensional array
18
75
pub type PyArray1 < T > = PyArray < T , Ix1 > ;
76
+ /// two-dimensional array
19
77
pub type PyArray2 < T > = PyArray < T , Ix2 > ;
78
+ /// three-dimensional array
20
79
pub type PyArray3 < T > = PyArray < T , Ix3 > ;
80
+ /// four-dimensional array
21
81
pub type PyArray4 < T > = PyArray < T , Ix4 > ;
82
+ /// five-dimensional array
22
83
pub type PyArray5 < T > = PyArray < T , Ix5 > ;
84
+ /// six-dimensional array
23
85
pub type PyArray6 < T > = PyArray < T , Ix6 > ;
86
+ /// dynamic-dimensional array
24
87
pub type PyArrayDyn < T > = PyArray < T , IxDyn > ;
25
88
89
+ /// Returns a array module.
26
90
pub fn get_array_module ( py : Python ) -> PyResult < & PyModule > {
27
91
PyModule :: import ( py, npyffi:: array:: MOD_NAME )
28
92
}
@@ -348,7 +412,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
348
412
unsafe { Ok ( ArrayView :: from_shape_ptr ( self . ndarray_shape ( ) , self . data ( ) ) ) }
349
413
}
350
414
351
- /// Get the mmutable view of the internal data of `PyArray`, as `ndarray:: ArrayViewMut`.
415
+ /// Almost same as [`as_array`](#method.as_array), but returns ` ArrayViewMut`.
352
416
pub fn as_array_mut ( & self ) -> Result < ArrayViewMut < T , D > , ErrorKind > {
353
417
self . type_check ( ) ?;
354
418
unsafe {
@@ -387,13 +451,13 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
387
451
/// # }
388
452
/// ```
389
453
/// But, for dinamic errors too long/short index returns `None`.
390
- /// ```compile_fail
454
+ /// ```
391
455
/// # extern crate pyo3; extern crate numpy; fn main() {
392
456
/// use numpy::PyArray;
393
457
/// let gil = pyo3::Python::acquire_gil();
394
458
/// let arr = PyArray::arange(gil.python(), 0, 16, 1).reshape([2, 2, 4]).unwrap();
395
459
/// let arr = arr.into_dyn();
396
- /// assert!(arr.get([1, 2]).is_none());
460
+ /// assert!(arr.get([1, 2].as_ref() ).is_none());
397
461
/// # }
398
462
/// ```
399
463
#[ inline( always) ]
0 commit comments